Salome HOME
661061efd2da5e47baa6aba2c3459ec541d0c244
[modules/shaper.git] / src / PartSet / PartSet_ConstraintDistancePrs.cpp
1 // File:        PartSet_FeaturePrs.h
2 // Created:     16 Jun 2014
3 // Author:      Natalia ERMOLAEVA
4
5 #include <PartSet_ConstraintDistancePrs.h>
6 #include <PartSet_Tools.h>
7
8 #include <PartSet_FeatureLinePrs.h>
9
10 #include <SketchPlugin_Feature.h>
11 #include <SketchPlugin_Sketch.h>
12 #include <SketchPlugin_Line.h>
13 #include <SketchPlugin_Point.h>
14 #include <SketchPlugin_ConstraintDistance.h>
15
16 #include <GeomDataAPI_Point2D.h>
17 #include <GeomAPI_Pnt2d.h>
18 #include <GeomAPI_Lin2d.h>
19 #include <GeomAPI_Pln.h>
20
21 #include <ModelAPI_Data.h>
22 #include <ModelAPI_Document.h>
23 #include <ModelAPI_AttributeRefAttr.h>
24 #include <ModelAPI_AttributeRefList.h>
25 #include <ModelAPI_AttributeDouble.h>
26
27 #include <AIS_InteractiveObject.hxx>
28 #include <AIS_LengthDimension.hxx>
29
30 #include <Precision.hxx>
31 #include <gp_Pln.hxx>
32
33 using namespace std;
34
35 PartSet_ConstraintDistancePrs::PartSet_ConstraintDistancePrs(FeaturePtr theSketch)
36 : PartSet_FeaturePrs(theSketch)
37 {
38 }
39
40 std::string PartSet_ConstraintDistancePrs::getKind()
41 {
42   return SKETCH_CONSTRAINT_DISTANCE_KIND;
43 }
44
45 PartSet_SelectionMode PartSet_ConstraintDistancePrs::setFeature(FeaturePtr theFeature, const PartSet_SelectionMode& theMode)
46 {
47   PartSet_SelectionMode aMode = theMode;
48   if (!feature() || !theFeature)
49     return aMode;
50
51   std::string anArgument;
52   if (theMode == SM_FirstPoint) {
53     anArgument = CONSTRAINT_ATTR_ENTITY_A;
54     aMode = SM_SecondPoint;
55   }
56   else if (theMode == SM_SecondPoint) {
57     anArgument = CONSTRAINT_ATTR_ENTITY_B;
58     aMode = SM_LastPoint;
59   }
60   if (theFeature->getKind() == SKETCH_POINT_KIND)
61   {
62     // set length feature
63     boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
64     boost::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
65           boost::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aData->attribute(anArgument));
66     aRef->setFeature(theFeature);
67   }
68
69   if (theMode == SM_SecondPoint) {
70     // set length value
71     boost::shared_ptr<GeomDataAPI_Point2D> aPoint_A = getFeaturePoint(feature(), CONSTRAINT_ATTR_ENTITY_A);
72     boost::shared_ptr<GeomDataAPI_Point2D> aPoint_B = getFeaturePoint(feature(), CONSTRAINT_ATTR_ENTITY_B);
73
74     if (aPoint_A && aPoint_B) {
75       double aLenght = aPoint_A->pnt()->distance(aPoint_B->pnt());
76       PartSet_Tools::setFeatureValue(feature(), aLenght, CONSTRAINT_ATTR_VALUE);
77     }
78   }
79
80   return aMode;
81 }
82
83 PartSet_SelectionMode PartSet_ConstraintDistancePrs::setPoint(double theX, double theY,
84                                                          const PartSet_SelectionMode& theMode)
85 {
86   PartSet_SelectionMode aMode = theMode;
87   switch (theMode)
88   {
89     case SM_LastPoint: {
90       boost::shared_ptr<GeomDataAPI_Point2D> aFlyOutAttr = 
91         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(feature()->data()->attribute(CONSTRAINT_ATTR_FLYOUT_VALUE_PNT));
92       aFlyOutAttr->setValue(boost::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(theX, theY)));
93
94       boost::shared_ptr<GeomAPI_Pnt2d> aFlyOutPnt = aFlyOutAttr->pnt();
95
96       aMode = SM_DonePoint;
97     }
98     break;
99     default:
100       break;
101   }
102   return aMode;
103 }
104
105 Handle(AIS_InteractiveObject) PartSet_ConstraintDistancePrs::createPresentation(FeaturePtr theFeature,
106                                                        FeaturePtr theSketch,
107                                                        Handle(AIS_InteractiveObject) thePreviuos)
108 {
109   Handle(AIS_InteractiveObject) anAIS = thePreviuos;
110   if (!theFeature || !theSketch)
111     return anAIS;
112   boost::shared_ptr<GeomAPI_Pln> aGPlane = PartSet_Tools::sketchPlane(theSketch);
113   gp_Pln aPlane = aGPlane->impl<gp_Pln>();
114
115   boost::shared_ptr<GeomDataAPI_Point2D> aPoint_A = getFeaturePoint(theFeature, CONSTRAINT_ATTR_ENTITY_A);
116   boost::shared_ptr<GeomDataAPI_Point2D> aPoint_B = getFeaturePoint(theFeature, CONSTRAINT_ATTR_ENTITY_B);
117   if (!aPoint_A || !aPoint_B)
118     return anAIS;
119
120   // fly out calculation
121   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
122   boost::shared_ptr<GeomDataAPI_Point2D> aFlyOutAttr = 
123     boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(CONSTRAINT_ATTR_FLYOUT_VALUE_PNT));
124   boost::shared_ptr<GeomAPI_Pnt2d> aFlyOutPnt = aFlyOutAttr->pnt();
125
126   boost::shared_ptr<GeomAPI_Lin2d> aFeatureLin = boost::shared_ptr<GeomAPI_Lin2d>
127                                     (new GeomAPI_Lin2d(aPoint_A->x(), aPoint_A->y(),
128                                                         aPoint_B->x(), aPoint_B->y()));
129   boost::shared_ptr<GeomAPI_Pnt2d> aResult = aFeatureLin->project(aFlyOutPnt);
130   double aDistance = aFlyOutPnt->distance(aResult);
131
132   if (!aFeatureLin->isRight(aFlyOutPnt))
133     aDistance = -aDistance;
134   double aFlyout = aDistance;
135
136   gp_Pnt aPoint1, aPoint2;
137   PartSet_Tools::convertTo3D(aPoint_A->x(), aPoint_A->y(), theSketch, aPoint1);
138   PartSet_Tools::convertTo3D(aPoint_B->x(), aPoint_B->y(), theSketch, aPoint2);
139
140   //Build dimension here
141   gp_Pnt aP1 = aPoint1;
142   gp_Pnt aP2 = aPoint2;
143   if (aFlyout < 0) {
144     aP1 = aPoint2;
145     aP2 = aPoint1;
146   }
147
148   // value calculation
149   boost::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = 
150          boost::dynamic_pointer_cast<ModelAPI_AttributeDouble>(aData->attribute(CONSTRAINT_ATTR_VALUE));
151   double aValue = aValueAttr->value();
152   if (aValue == 0) { // TODO! the default value
153     aValue = aP1.Distance(aP2);
154   }
155
156   if (anAIS.IsNull())
157   {
158     Handle(AIS_LengthDimension) aDimAIS = new AIS_LengthDimension(aP1, aP2, aPlane);
159     aDimAIS->SetCustomValue(aValue);
160
161     Handle(Prs3d_DimensionAspect) anAspect = new Prs3d_DimensionAspect();
162     anAspect->MakeArrows3d (Standard_False);
163     anAspect->MakeText3d(false);
164     anAspect->TextAspect()->SetHeight(CONSTRAINT_TEXT_HEIGHT);
165     anAspect->MakeTextShaded(false);
166     aDimAIS->DimensionAspect()->MakeUnitsDisplayed(false);
167     aDimAIS->SetDimensionAspect (anAspect);
168     aDimAIS->SetFlyout(aFlyout);
169     aDimAIS->SetSelToleranceForText2d(CONSTRAINT_TEXT_SELECTION_TOLERANCE);
170
171     anAIS = aDimAIS;
172   }
173   else {
174     // update presentation
175     Handle(AIS_LengthDimension) aDimAIS = Handle(AIS_LengthDimension)::DownCast(anAIS);
176     if (!aDimAIS.IsNull()) {
177       aDimAIS->SetMeasuredGeometry(aPoint1, aPoint2, aPlane);
178       aDimAIS->SetCustomValue(aValue);
179       aDimAIS->SetFlyout(aFlyout);
180
181       aDimAIS->Redisplay(Standard_True);
182     }
183   }
184   return anAIS;
185 }
186
187 boost::shared_ptr<GeomDataAPI_Point2D> PartSet_ConstraintDistancePrs::getFeaturePoint
188                                                                (FeaturePtr theFeature,
189                                                                 const std::string& theAttribute)
190 {
191   boost::shared_ptr<GeomDataAPI_Point2D> aPointAttr;
192
193   FeaturePtr aFeature = PartSet_Tools::feature(theFeature, theAttribute, SKETCH_POINT_KIND);
194   if (aFeature)
195     aPointAttr = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
196                                            (aFeature->data()->attribute(POINT_ATTR_COORD));
197   return aPointAttr;
198 }
199
200 std::string PartSet_ConstraintDistancePrs::getAttribute(const PartSet_SelectionMode& theMode) const
201 {
202   return "";
203 }
204
205 PartSet_SelectionMode PartSet_ConstraintDistancePrs::getNextMode(const std::string& theAttribute) const
206 {
207   return SM_FirstPoint;
208 }
209
210 boost::shared_ptr<GeomDataAPI_Point2D> PartSet_ConstraintDistancePrs::findPoint(FeaturePtr theFeature,
211                                                                            double theX, double theY)
212 {
213   boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D;
214   return aPoint2D;
215 }
216
217 boost::shared_ptr<GeomDataAPI_Point2D> PartSet_ConstraintDistancePrs::featurePoint
218                                                      (const PartSet_SelectionMode& theMode)
219 {
220   return boost::shared_ptr<GeomDataAPI_Point2D>();
221 }