]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketcherPrs/SketcherPrs_Angle.cpp
Salome HOME
Issue 1299 Angle presentation: complementary angle.
[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   SketcherPrs_Tools::AngleType anAngleType = (SketcherPrs_Tools::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 SketcherPrs_Tools::ANGLE_DIRECT: {
119       SetGeometryOrientedAngle(true, false);
120       SetArrowVisible(Standard_False, Standard_True);
121       SetMeasuredGeometry(aEdge1, aEdge2);
122     }
123     break;
124     case SketcherPrs_Tools::ANGLE_COMPLEMENTARY: {
125       // to calculate center, first and end points
126       SetGeometryOrientedAngle(false, false);
127       SetMeasuredGeometry(aEdge1, aEdge2);
128       gp_Pnt aCenterPnt = CenterPoint();
129       gp_Pnt aFirstPnt = FirstPoint();
130       gp_Pnt aSecondPnt = SecondPoint();
131       double anEdge2Length = aCenterPnt.Distance(aSecondPnt);
132       aSecondPnt = aCenterPnt.Translated (gp_Vec(aCenterPnt, aSecondPnt).Normalized() * (-anEdge2Length));
133       SetArrowVisible(Standard_True, Standard_False);
134       SetMeasuredGeometry(aFirstPnt, aCenterPnt, aSecondPnt);
135     }
136     break;
137     case SketcherPrs_Tools::ANGLE_BACKWARD: {
138       SetGeometryOrientedAngle(true, true);
139       SetArrowVisible(Standard_False, Standard_True);
140       SetMeasuredGeometry(aEdge1, aEdge2);
141     }
142     break;
143     default:
144       break;
145   }
146
147
148   const gp_Pnt& aCenter = CenterPoint();
149   const gp_Pnt& aFirst = FirstPoint();
150   const gp_Pnt& aSecond = SecondPoint();
151
152   gp_Dir aBisector((aFirst.XYZ() + aSecond.XYZ()) * 0.5 - aCenter.XYZ());
153
154   gp_Pnt aFlyPnt(aFlyoutPnt->x(), aFlyoutPnt->y(), aFlyoutPnt->z());
155   gp_XYZ aFlyDir = aFlyPnt.XYZ() - aCenter.XYZ();
156   double aDist = aFlyDir.Dot(aBisector.XYZ());
157   SetFlyout(aDist);
158
159   // Angle value is in degrees
160   AttributeDoublePtr aVal = aData->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID());
161   SetCustomValue(aVal->value() * PI / 180.0);
162
163   myAspect->SetExtensionSize(myAspect->ArrowAspect()->Length());
164   myAspect->SetArrowTailSize(myAspect->ArrowAspect()->Length());
165
166   AttributeDoublePtr aValue = myConstraint->data()->real(SketchPlugin_ConstraintAngle::ANGLE_VALUE_ID());
167   SketcherPrs_Tools::setDisplaySpecialSymbol(this, aValue->usedParameters().size() > 0);
168
169   AIS_AngleDimension::Compute(thePresentationManager, thePresentation, theMode);
170 }
171
172 void SketcherPrs_Angle::ComputeSelection(const Handle(SelectMgr_Selection)& aSelection,
173                                                    const Standard_Integer theMode)
174 {
175   Standard_Integer aMode;
176   switch (theMode) {
177   case 0: // we should use selection of all objects
178     aMode = 0;
179     break;
180   case SketcherPrs_Tools::Sel_Dimension_All:
181     aMode = 0;
182     break;
183   case SketcherPrs_Tools::Sel_Dimension_Line:
184     aMode = 1;
185     break;
186   case SketcherPrs_Tools::Sel_Dimension_Text:
187     aMode = 2;
188     break;
189   default: {
190     // there are own selection modes, so the others should be ignored
191     // otherwise, the text selection appears in the viewer
192     return; 
193   }
194   }
195   AIS_AngleDimension::ComputeSelection(aSelection, aMode);
196 }