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