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