]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketcherPrs/SketcherPrs_Angle.cpp
Salome HOME
Issue 1299 Angle constraint: support of additional and complementary angles. Test...
[modules/shaper.git] / src / SketcherPrs / SketcherPrs_Angle.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        SketcherPrs_Angle.cpp
4 // Created:     20 August 2015
5 // Author:      Vitaly SMETANNIKOV
6
7 #include "SketcherPrs_Angle.h"
8 #include "SketcherPrs_Tools.h"
9
10 #include <SketchPlugin_ConstraintAngle.h>
11 #include <SketchPlugin_Constraint.h>
12
13 #include <GeomAPI_Edge.h>
14 #include <GeomAPI_Lin.h>
15 #include <GeomDataAPI_Point2D.h>
16
17 #include <ModelAPI_AttributeRefAttr.h>
18 #include <ModelAPI_AttributeDouble.h>
19 #include <ModelAPI_AttributeInteger.h>
20
21 #include <TopExp.hxx>
22 #include <BRep_Tool.hxx>
23
24 #include <Events_Error.h>
25
26 #define PI 3.1415926535897932
27
28 IMPLEMENT_STANDARD_HANDLE(SketcherPrs_Angle, AIS_AngleDimension);
29 IMPLEMENT_STANDARD_RTTIEXT(SketcherPrs_Angle, AIS_AngleDimension);
30
31 SketcherPrs_Angle::SketcherPrs_Angle(ModelAPI_Feature* theConstraint, 
32                                      const std::shared_ptr<GeomAPI_Ax3>& thePlane)
33 : AIS_AngleDimension(gp_Pnt(0,0,0), gp_Pnt(1,0,0), gp_Pnt(0,1,0)), myConstraint(theConstraint), myPlane(thePlane)
34 {
35   myAspect = new Prs3d_DimensionAspect();
36   myAspect->MakeArrows3d(false);
37   myAspect->MakeText3d(false);
38   myAspect->MakeTextShaded(false);
39   myAspect->MakeUnitsDisplayed(false);
40   myAspect->TextAspect()->SetHeight(SketcherPrs_Tools::getDefaultTextHeight());
41   myAspect->ArrowAspect()->SetLength(SketcherPrs_Tools::getArrowSize());
42   
43   SetDimensionAspect(myAspect);
44   SetSelToleranceForText2d(SketcherPrs_Tools::getDefaultTextHeight());
45 }
46
47 bool SketcherPrs_Angle::IsReadyToDisplay(ModelAPI_Feature* theConstraint,
48                                          const std::shared_ptr<GeomAPI_Ax3>&/* thePlane*/)
49 {
50   bool aReadyToDisplay = false;
51
52   DataPtr aData = theConstraint->data();
53
54   // Flyout point
55   std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr = 
56     std::dynamic_pointer_cast<GeomDataAPI_Point2D>
57     (aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
58   if (!aFlyoutAttr->isInitialized())
59     return aReadyToDisplay; // can not create a good presentation
60
61   AttributeRefAttrPtr anAttr1 = aData->refattr(SketchPlugin_Constraint::ENTITY_A());
62   if (!anAttr1->isInitialized())
63     return aReadyToDisplay;
64
65   AttributeRefAttrPtr anAttr2 = aData->refattr(SketchPlugin_Constraint::ENTITY_B());
66   if (!anAttr2->isInitialized())
67     return aReadyToDisplay;
68
69   // Get angle edges
70   ObjectPtr aObj1 = anAttr1->object();
71   ObjectPtr aObj2 = anAttr2->object();
72
73   std::shared_ptr<GeomAPI_Shape> aShape1 = SketcherPrs_Tools::getShape(aObj1);
74   std::shared_ptr<GeomAPI_Shape> aShape2 = SketcherPrs_Tools::getShape(aObj2);
75
76   aReadyToDisplay = aShape1.get() && aShape2.get();
77   return aReadyToDisplay;
78 }
79
80 void SketcherPrs_Angle::Compute(const Handle(PrsMgr_PresentationManager3d)& thePresentationManager,
81                                 const Handle(Prs3d_Presentation)& thePresentation, 
82                                 const Standard_Integer theMode)
83 {
84   DataPtr aData = myConstraint->data();
85
86   if (!IsReadyToDisplay(myConstraint, myPlane)) {
87     Events_Error::throwException("An empty AIS presentation: SketcherPrs_Angle");
88     return; // can not create a good presentation
89   }
90
91   std::shared_ptr<ModelAPI_AttributeInteger> aTypeAttr = std::dynamic_pointer_cast<
92       ModelAPI_AttributeInteger>(aData->attribute(SketchPlugin_ConstraintAngle::TYPE_ID()));
93   AngleType anAngleType = (AngleType)(aTypeAttr->value());
94
95   // Flyout point
96   std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr = 
97     std::dynamic_pointer_cast<GeomDataAPI_Point2D>
98     (aData->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
99   std::shared_ptr<GeomAPI_Pnt> aFlyoutPnt = myPlane->to3D(aFlyoutAttr->x(), aFlyoutAttr->y());
100
101   AttributeRefAttrPtr anAttr1 = aData->refattr(SketchPlugin_Constraint::ENTITY_A());
102   AttributeRefAttrPtr anAttr2 = aData->refattr(SketchPlugin_Constraint::ENTITY_B());
103
104   // Get angle edges
105   ObjectPtr aObj1 = anAttr1->object();
106   ObjectPtr aObj2 = anAttr2->object();
107
108   std::shared_ptr<GeomAPI_Shape> aShape1 = SketcherPrs_Tools::getShape(aObj1);
109   std::shared_ptr<GeomAPI_Shape> aShape2 = SketcherPrs_Tools::getShape(aObj2);
110
111   TopoDS_Shape aTEdge1 = aShape1->impl<TopoDS_Shape>();
112   TopoDS_Shape aTEdge2 = aShape2->impl<TopoDS_Shape>();
113
114   TopoDS_Edge aEdge1 = TopoDS::Edge(aTEdge1);
115   TopoDS_Edge aEdge2 = TopoDS::Edge(aTEdge2);
116
117   switch (anAngleType) {
118     case ANGLE_DIRECT: {
119       /*gp_Pnt aPnt1(200, 100, 0);
120       gp_Pnt aPnt2(100, 100, 0);
121       gp_Pnt aPnt3(200, 200, 0);
122       //SetMeasuredGeometry(aPnt1, aPnt2, aPnt3);
123       SetMeasuredGeometry(aPnt3, aPnt2, aPnt1);
124       gp_Pln aPlane(aPnt2, gp_Dir(0, 0, 1));
125       SetCustomPlane(aPlane);
126       */
127       SetMeasuredGeometry(aEdge1, aEdge2);
128     }
129     break;
130     case ANGLE_SUPPLEMENTARY: {
131       // to calculate center, first and end points
132       SetMeasuredGeometry(aEdge1, aEdge2);
133       /*
134       gp_Pnt aCenterPnt = CenterPoint();
135       gp_Pnt aFirstPnt = FirstPoint();
136       gp_Pnt aSecondPnt = SecondPoint();
137
138       //gp_Pnt aFirstPnt(200, 100, 0);
139       //gp_Pnt aCenterPnt(100, 100, 0);
140       //gp_Pnt aSecondPnt(200, 200, 0);
141       double anEdge2Length = aCenterPnt.Distance(aSecondPnt);
142
143       aSecondPnt = aCenterPnt.Translated (gp_Vec(aCenterPnt, aSecondPnt).Normalized() * (-anEdge2Length));
144       SetMeasuredGeometry(aFirstPnt, aCenterPnt, aSecondPnt);
145       */
146     }
147     break;
148     case ANGLE_BACKWARD: {
149       SetMeasuredGeometry(aEdge2, aEdge1);
150     }
151     break;
152     default:
153       break;
154   }
155
156
157   const gp_Pnt& aCenter = CenterPoint();
158   const gp_Pnt& aFirst = FirstPoint();
159   const gp_Pnt& aSecond = SecondPoint();
160
161   gp_Dir aBisector((aFirst.XYZ() + aSecond.XYZ()) * 0.5 - aCenter.XYZ());
162
163   gp_Pnt aFlyPnt(aFlyoutPnt->x(), aFlyoutPnt->y(), aFlyoutPnt->z());
164   gp_XYZ aFlyDir = aFlyPnt.XYZ() - aCenter.XYZ();
165   double aDist = aFlyDir.Dot(aBisector.XYZ());
166   SetFlyout(aDist);
167
168   // Angle value is in degrees
169   AttributeDoublePtr aVal = aData->real(SketchPlugin_Constraint::VALUE());
170   SetCustomValue(aVal->value() * PI / 180.0);
171
172   myAspect->SetExtensionSize(myAspect->ArrowAspect()->Length());
173   myAspect->SetArrowTailSize(myAspect->ArrowAspect()->Length());
174
175   AttributeDoublePtr aValue = myConstraint->data()->real(SketchPlugin_Constraint::VALUE());
176   SketcherPrs_Tools::setDisplaySpecialSymbol(this, aValue->usedParameters().size() > 0);
177
178   AIS_AngleDimension::Compute(thePresentationManager, thePresentation, theMode);
179 }
180
181 void SketcherPrs_Angle::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
182                                                    const Standard_Integer theMode)
183 {
184   Standard_Integer aMode;
185   switch (theMode) {
186   case 0: // we should use selection of all objects
187     aMode = 0;
188     break;
189   case SketcherPrs_Tools::Sel_Dimension_All:
190     aMode = 0;
191     break;
192   case SketcherPrs_Tools::Sel_Dimension_Line:
193     aMode = 1;
194     break;
195   case SketcherPrs_Tools::Sel_Dimension_Text:
196     aMode = 2;
197     break;
198   default: {
199     // there are own selection modes, so the others should be ignored
200     // otherwise, the text selection appears in the viewer
201     return; 
202   }
203   }
204   AIS_AngleDimension::ComputeSelection(aSelection, aMode);
205 }