Salome HOME
70e6ba7b2e9a9f4430b3c9de61a0b18ce14d7367
[modules/shaper.git] / src / PartSet / PartSet_ConstraintRadiusPrs.cpp
1 // File:        PartSet_FeaturePrs.h
2 // Created:     16 Jun 2014
3 // Author:      Natalia ERMOLAEVA
4
5 #include <PartSet_ConstraintRadiusPrs.h>
6 #include <PartSet_Tools.h>
7
8 #include <PartSet_FeatureCirclePrs.h>
9 #include <PartSet_FeatureArcPrs.h>
10
11 #include <SketchPlugin_Feature.h>
12 #include <SketchPlugin_Sketch.h>
13 #include <SketchPlugin_Line.h>
14 #include <SketchPlugin_Circle.h>
15 #include <SketchPlugin_Arc.h>
16 #include <SketchPlugin_ConstraintRadius.h>
17
18 #include <GeomDataAPI_Point.h>
19 #include <GeomDataAPI_Point2D.h>
20 #include <GeomDataAPI_Dir.h>
21 #include <GeomAPI_Pnt2d.h>
22 #include <GeomAPI_Lin2d.h>
23 #include <GeomAPI_Pln.h>
24 #include <GeomAPI_Dir.h>
25
26 #include <GeomAlgoAPI_EdgeBuilder.h>
27
28 #include <ModelAPI_Data.h>
29 #include <ModelAPI_Document.h>
30 #include <ModelAPI_AttributeRefAttr.h>
31 #include <ModelAPI_AttributeRefList.h>
32 #include <ModelAPI_AttributeDouble.h>
33
34 #include <AIS_InteractiveObject.hxx>
35 #include <AIS_RadiusDimension.hxx>
36 #include <Precision.hxx>
37 #include <gp_Circ.hxx>
38 #include <V3d_View.hxx>
39
40 using namespace std;
41
42 PartSet_ConstraintRadiusPrs::PartSet_ConstraintRadiusPrs(FeaturePtr theSketch)
43 : PartSet_FeaturePrs(theSketch)
44 {
45 }
46
47 std::string PartSet_ConstraintRadiusPrs::getKind()
48 {
49   return SKETCH_CONSTRAINT_RADIUS_KIND;
50 }
51
52 bool PartSet_ConstraintRadiusPrs::setFeature(FeaturePtr theFeature, const PartSet_SelectionMode& theMode)
53 {
54   bool aResult = false;
55   if (!feature() || theMode != SM_FirstPoint || !theFeature) {
56     return aResult;
57   }
58   std::string aKind = theFeature->getKind();
59   if (aKind == SKETCH_CIRCLE_KIND || aKind == SKETCH_ARC_KIND) {
60     // set length feature
61     boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
62     boost::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
63           boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(CONSTRAINT_ATTR_ENTITY_A));
64     aRef->setFeature(theFeature);
65
66     double aLength = 50;
67     bool isValid;
68     if (aKind == SKETCH_CIRCLE_KIND) {
69       aLength = PartSet_Tools::featureValue(theFeature, CIRCLE_ATTR_RADIUS, isValid);
70     }
71     else if (aKind == SKETCH_ARC_KIND) {
72       aLength = PartSet_FeatureArcPrs::radius(theFeature);
73     }
74
75     PartSet_Tools::setFeatureValue(feature(), aLength, CONSTRAINT_ATTR_VALUE);
76     aResult = true;
77   }
78   return aResult;
79 }
80
81 PartSet_SelectionMode PartSet_ConstraintRadiusPrs::setPoint(double theX, double theY,
82                                                          const PartSet_SelectionMode& theMode)
83 {
84   PartSet_SelectionMode aMode = theMode;
85   switch (theMode)
86   {
87     case SM_SecondPoint: {
88       boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
89
90       boost::shared_ptr<GeomAPI_Pnt2d> aPoint = boost::shared_ptr<GeomAPI_Pnt2d>
91                                                              (new GeomAPI_Pnt2d(theX, theY));
92
93       PartSet_Tools::setFeaturePoint(feature(), theX, theY, SKETCH_CONSTRAINT_ATTR_CIRCLE_POINT);
94
95       //double aDistance = 40;
96       //AttributeDoublePtr aFlyoutAttr = 
97       //    boost::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aData->attribute(CONSTRAINT_ATTR_FLYOUT_VALUE));
98       //aFlyoutAttr->setValue(aDistance);
99
100       aMode = SM_DonePoint;
101     }
102     break;
103     default:
104       break;
105   }
106   return aMode;
107 }
108
109 Handle(AIS_InteractiveObject) PartSet_ConstraintRadiusPrs::createPresentation(FeaturePtr theFeature,
110                                                        FeaturePtr theSketch,
111                                                        Handle(AIS_InteractiveObject) thePreviuos)
112 {
113   Handle(AIS_InteractiveObject) anAIS = thePreviuos;
114   if (!theFeature || !theSketch)
115     return anAIS;
116
117   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
118   boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = 
119           boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(CONSTRAINT_ATTR_ENTITY_A));
120   if (!anAttr)
121     return anAIS;
122   FeaturePtr aFeature = anAttr->feature();
123   std::string aKind = aFeature ? aFeature->getKind() : "";
124   if (aKind != SKETCH_CIRCLE_KIND && aKind != SKETCH_ARC_KIND)
125     return anAIS;
126
127   //boost::shared_ptr<ModelAPI_AttributeDouble> aFlyoutAttr = 
128   //        boost::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aData->attribute(CONSTRAINT_ATTR_FLYOUT_VALUE));
129   //double aFlyout = aFlyoutAttr->value();
130   boost::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = 
131           boost::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aData->attribute(CONSTRAINT_ATTR_VALUE));
132   double aValue = aValueAttr->value();
133
134   // an anchor point
135   boost::shared_ptr<GeomDataAPI_Point2D> aAnchorAttr = 
136     boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(theFeature->data()->attribute
137                                                         (SKETCH_CONSTRAINT_ATTR_CIRCLE_POINT));
138   boost::shared_ptr<GeomAPI_Pnt2d> anAnchor2D = aAnchorAttr->pnt();
139   boost::shared_ptr<GeomAPI_Pnt> anAnchor = PartSet_Tools::point3D(anAnchor2D, theSketch);
140   gp_Pnt anAnchorPoint = anAnchor->impl<gp_Pnt>();
141
142   std::string aCenterArgument;
143   double aRadius;
144   if (aKind == SKETCH_CIRCLE_KIND) {
145     aCenterArgument = CIRCLE_ATTR_CENTER;
146     bool isValid;
147     aRadius = PartSet_Tools::featureValue(aFeature, CIRCLE_ATTR_RADIUS, isValid);
148   }
149   else if (aKind == SKETCH_ARC_KIND) {
150     aCenterArgument = ARC_ATTR_CENTER;
151     aRadius = PartSet_FeatureArcPrs::radius(aFeature);
152   }
153
154   // a circle
155   boost::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = 
156     boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aFeature->data()->attribute(aCenterArgument));
157   boost::shared_ptr<GeomAPI_Pnt2d> aCenter2D = aCenterAttr->pnt();
158   boost::shared_ptr<GeomAPI_Pnt> aCenter = PartSet_Tools::point3D(aCenter2D, theSketch);
159
160   boost::shared_ptr<GeomDataAPI_Dir> aNDir = 
161     boost::dynamic_pointer_cast<GeomDataAPI_Dir>(theSketch->data()->attribute(SKETCH_ATTR_NORM));
162   boost::shared_ptr<GeomAPI_Dir> aNormal(new GeomAPI_Dir(aNDir->x(), aNDir->y(), aNDir->z()));
163   const gp_Dir& aDir = aNormal->impl<gp_Dir>();
164
165   gp_Circ aCircle = gp_Circ(gp_Ax2(aCenter->impl<gp_Pnt>(), aDir), aRadius);
166   //boost::shared_ptr<GeomAPI_Shape> aShape;
167   //aShape = GeomAlgoAPI_EdgeBuilder::line(aCenter, anAnchor);
168     //boost::shared_ptr<GeomAPI_Pnt> theStart, boost::shared_ptr<GeomAPI_Pnt> theEnd)
169
170   if (anAIS.IsNull())
171   {
172     Handle(AIS_RadiusDimension) aDimAIS = new AIS_RadiusDimension(aCircle, anAnchorPoint);
173     aDimAIS->SetCustomValue(aValue);
174     //Handle(AIS_RadiusDimension) aDimAIS = new AIS_RadiusDimension(aShape->impl<TopoDS_Shape>());
175
176     Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
177     anAspect->MakeArrows3d (Standard_False);
178     anAspect->MakeText3d(false);
179     anAspect->TextAspect()->SetHeight(CONSTRAINT_TEXT_HEIGHT);
180     anAspect->MakeTextShaded(false);
181     aDimAIS->DimensionAspect()->MakeUnitsDisplayed(false);
182     aDimAIS->SetDimensionAspect (anAspect);
183     //aDimAIS->SetFlyout(aFlyout);
184     aDimAIS->SetSelToleranceForText2d(CONSTRAINT_TEXT_SELECTION_TOLERANCE);
185
186     anAIS = aDimAIS;
187   }
188   else {
189     // update presentation
190     Handle(AIS_RadiusDimension) aDimAIS = Handle(AIS_RadiusDimension)::DownCast(anAIS);
191     if (!aDimAIS.IsNull()) {
192       gp_Pnt anAPoint(anAnchorPoint.X(),anAnchorPoint.Y(),anAnchorPoint.Z());
193
194       aDimAIS->SetMeasuredGeometry(aCircle, anAnchorPoint);
195       aDimAIS->SetCustomValue(aValue);
196       //aDimAIS->SetMeasuredGeometry(aShape->impl<TopoDS_Shape>());
197       //aDimAIS->SetFlyout(aFlyout);
198       aDimAIS->Redisplay(Standard_True);
199     }
200   }
201   return anAIS;
202 }
203
204 void PartSet_ConstraintRadiusPrs::projectPointOnFeature(FeaturePtr theFeature, FeaturePtr theSketch,
205                                                         gp_Pnt& thePoint, Handle(V3d_View) theView,
206                                                         double& theX, double& theY)
207 {
208   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
209   boost::shared_ptr<ModelAPI_AttributeRefAttr> anAttr = 
210           boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(CONSTRAINT_ATTR_ENTITY_A));
211   if (!anAttr)
212     return;
213   FeaturePtr aFeature = anAttr->feature();
214   if (!aFeature)
215     return;
216
217   gp_Circ aCircle;
218   gp_Pnt anAnchorPoint;
219   if (aFeature->getKind() == SKETCH_CIRCLE_KIND) {
220     PartSet_FeatureCirclePrs::projectPointOnFeature(aFeature, theSketch, thePoint, theView, theX, theY);
221   }
222   else if (aFeature->getKind() == SKETCH_ARC_KIND) {
223     PartSet_FeatureArcPrs::projectPointOnFeature(aFeature, theSketch, thePoint, theView, theX, theY);
224   }
225   // TODO: a bug in AIS_RadiusDimension:
226   // The anchor point can't be myCirc.Location() - an exception is raised.
227   // But we need exactly this case...
228   // We want to show a radius dimension starting from the circle centre and 
229   // ending at the user-defined point.
230   // Also, if anchor point coincides with myP2, the radius dimension is not displayed at all.
231   double aDelta = 1/1000.0;
232   theX += aDelta;
233   theY += aDelta;
234 }
235
236 std::string PartSet_ConstraintRadiusPrs::getAttribute(const PartSet_SelectionMode& theMode) const
237 {
238   return "";
239 }
240
241 PartSet_SelectionMode PartSet_ConstraintRadiusPrs::getNextMode(const std::string& theAttribute) const
242 {
243   return SM_FirstPoint;
244 }
245
246 void PartSet_ConstraintRadiusPrs::move(double theDeltaX, double theDeltaY)
247 {
248 }
249
250 double PartSet_ConstraintRadiusPrs::distanceToPoint(FeaturePtr theFeature,
251                                                  double theX, double theY)
252 {
253   return 0;
254 }
255
256 boost::shared_ptr<GeomDataAPI_Point2D> PartSet_ConstraintRadiusPrs::findPoint(FeaturePtr theFeature,
257                                                                            double theX, double theY)
258 {
259   boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D;
260   return aPoint2D;
261 }
262
263 boost::shared_ptr<GeomDataAPI_Point2D> PartSet_ConstraintRadiusPrs::featurePoint
264                                                      (const PartSet_SelectionMode& theMode)
265 {
266   return boost::shared_ptr<GeomDataAPI_Point2D>();
267 }