Salome HOME
ef6e7c0059c4a3bfdbc974aafc197a62016b18a7
[modules/shaper.git] / src / PartSet / PartSet_FeatureLinePrs.cpp
1 // File:        PartSet_FeaturePrs.h
2 // Created:     04 Jun 2014
3 // Author:      Natalia ERMOLAEVA
4
5 #include <PartSet_FeatureLinePrs.h>
6 #include <PartSet_Tools.h>
7
8 #include <SketchPlugin_Feature.h>
9 #include <SketchPlugin_Sketch.h>
10 #include <SketchPlugin_ConstraintCoincidence.h>
11 #include <SketchPlugin_Line.h>
12 #include <SketchPlugin_Constraint.h>
13
14 #include <GeomDataAPI_Point2D.h>
15 #include <GeomAPI_Lin2d.h>
16 #include <GeomAPI_Pnt2d.h>
17
18 #include <ModelAPI_Data.h>
19 #include <ModelAPI_Document.h>
20 #include <ModelAPI_AttributeRefAttr.h>
21 #include <ModelAPI_AttributeRefList.h>
22
23 #include <Precision.hxx>
24 #include <V3d_View.hxx>
25
26 using namespace std;
27
28 PartSet_FeatureLinePrs::PartSet_FeatureLinePrs(FeaturePtr theSketch)
29 : PartSet_FeaturePrs(theSketch)
30 {
31 }
32
33 std::string PartSet_FeatureLinePrs::getKind()
34 {
35   return SKETCH_LINE_KIND;
36 }
37
38 PartSet_SelectionMode PartSet_FeatureLinePrs::setPoint(double theX, double theY,
39                                                        const PartSet_SelectionMode& theMode)
40 {
41   PartSet_SelectionMode aMode = theMode;
42   switch (theMode)
43   {
44     case SM_FirstPoint: {
45       PartSet_Tools::setFeaturePoint(feature(), theX, theY, LINE_ATTR_START);
46       PartSet_Tools::setFeaturePoint(feature(), theX, theY, LINE_ATTR_END);
47       aMode = SM_SecondPoint;
48     }
49     break;
50     case SM_SecondPoint: {
51       PartSet_Tools::setFeaturePoint(feature(), theX, theY, LINE_ATTR_END);
52       aMode = SM_DonePoint;
53    }
54     break;
55     default:
56       break;
57   }
58   return aMode;
59 }
60
61 bool PartSet_FeatureLinePrs::setFeature(FeaturePtr theFeature, const PartSet_SelectionMode& theMode)
62 {
63   bool aResult = false;
64   if (feature() && theFeature && theMode == SM_FirstPoint)
65   {
66     // use the last point of the previous feature as the first of the new one
67     boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
68     boost::shared_ptr<GeomDataAPI_Point2D> anInitPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
69                                                                   (aData->attribute(LINE_ATTR_END));
70     PartSet_Tools::setFeaturePoint(feature(), anInitPoint->x(), anInitPoint->y(), LINE_ATTR_START);
71     PartSet_Tools::setFeaturePoint(feature(), anInitPoint->x(), anInitPoint->y(), LINE_ATTR_END);
72
73     aData = feature()->data();
74     boost::shared_ptr<GeomDataAPI_Point2D> aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
75                                                                  (aData->attribute(LINE_ATTR_START));
76     PartSet_Tools::createConstraint(sketch(), anInitPoint, aPoint);
77     aResult = true;
78   }
79   return aResult;
80 }
81
82 std::string PartSet_FeatureLinePrs::getAttribute(const PartSet_SelectionMode& theMode) const
83 {
84   std::string aAttribute;
85   switch (theMode)
86   {
87     case SM_FirstPoint:
88       aAttribute = LINE_ATTR_START;
89     break;
90     case SM_SecondPoint:
91       aAttribute = LINE_ATTR_END;
92     break;
93     default:
94     break;
95   }
96   return aAttribute;
97 }
98
99 PartSet_SelectionMode PartSet_FeatureLinePrs::getNextMode(const std::string& theAttribute) const
100 {
101   PartSet_SelectionMode aMode;
102
103   if (theAttribute == LINE_ATTR_START)
104     aMode = SM_SecondPoint;
105   else if (theAttribute == LINE_ATTR_END)
106     aMode = SM_DonePoint;
107   return aMode;
108 }
109
110 void PartSet_FeatureLinePrs::move(double theDeltaX, double theDeltaY)
111 {
112   boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
113   if (!aData->isValid())
114     return;
115
116   boost::shared_ptr<GeomDataAPI_Point2D> aPoint1 =
117         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_START));
118   aPoint1->setValue(aPoint1->x() + theDeltaX, aPoint1->y() + theDeltaY);
119
120   boost::shared_ptr<GeomDataAPI_Point2D> aPoint2 =
121         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_END));
122   aPoint2->setValue(aPoint2->x() + theDeltaX, aPoint2->y() + theDeltaY);
123 }
124
125 void PartSet_FeatureLinePrs::projectPointOnLine(FeaturePtr theFeature,
126                                                 const PartSet_SelectionMode& theMode,
127                                                 const gp_Pnt& thePoint, Handle(V3d_View) theView,
128                                                 double& theX, double& theY)
129 {
130   if (theFeature && theFeature->getKind() == getKind()) {
131     double X0, X1;
132     double Y0, Y1;
133
134     PartSet_Tools::convertTo2D(thePoint, sketch(), theView, X1, Y1);
135     boost::shared_ptr<GeomAPI_Pnt2d> aPoint = boost::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(X1, Y1));
136     boost::shared_ptr<GeomAPI_Lin2d> aFeatureLin = PartSet_FeatureLinePrs::createLin2d(theFeature);
137
138     switch (theMode) {
139       case SM_FirstPoint: {
140         boost::shared_ptr<GeomAPI_Pnt2d> aResult = aFeatureLin->project(aPoint);
141         theX = aResult->x();
142         theY = aResult->y();
143       }
144       break;
145       case SM_SecondPoint: {
146         getLinePoint(feature(), LINE_ATTR_START, X0, Y0);
147         boost::shared_ptr<GeomAPI_Lin2d> aCurrentLin = boost::shared_ptr<GeomAPI_Lin2d>
148                                                            (new GeomAPI_Lin2d(X0, Y0, X1, Y1));
149         boost::shared_ptr<GeomAPI_Pnt2d> aResult = aFeatureLin->intersect(aCurrentLin);
150         boost::shared_ptr<GeomAPI_Pnt2d> aPoint0 = boost::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(X0, Y0));
151         if (aResult->distance(aPoint0) < Precision::Confusion()) { // the start point is nearest to the line
152           // if the first point of a line belongs to the given line
153           // we need to project the second point on the same line
154           aResult = aFeatureLin->project(aPoint);
155         }
156         theX = aResult->x();
157         theY = aResult->y();
158       }
159       break;
160       default:
161       break;
162     }
163   }
164 }
165
166 double PartSet_FeatureLinePrs::distanceToPoint(FeaturePtr theFeature,
167                                       double theX, double theY)
168 {
169   double aDelta = 0;
170   if (!theFeature || theFeature->getKind() != getKind())
171     return aDelta;
172
173   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
174   boost::shared_ptr<GeomDataAPI_Point2D> aPoint1 =
175         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_START));
176   boost::shared_ptr<GeomDataAPI_Point2D> aPoint2 =
177         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_END));
178
179   GeomAPI_Lin2d aLin2d(aPoint1->x(), aPoint1->y(), aPoint2->x(), aPoint2->y());
180   boost::shared_ptr<GeomAPI_Pnt2d> aPoint = boost::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(theX, theY));
181
182   if (false/*projection*/) { // TODO: if it has not been necessary, remove this block
183     boost::shared_ptr<GeomAPI_Pnt2d> aResult = aLin2d.project(aPoint);
184     aDelta = aResult->distance(aPoint);
185   }
186   else { // distance
187     aDelta = aLin2d.distance(aPoint);
188   }
189
190   return aDelta;
191 }
192
193 boost::shared_ptr<GeomDataAPI_Point2D> PartSet_FeatureLinePrs::findPoint(FeaturePtr theFeature,
194                                                                          double theX, double theY)
195 {
196   boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D;
197   if (!theFeature || theFeature->getKind() != getKind())
198     return aPoint2D;
199
200   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
201   boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
202         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_START));
203   if (fabs(aPoint->x() - theX) < Precision::Confusion() &&
204       fabs(aPoint->y() - theY) < Precision::Confusion())
205     aPoint2D = aPoint;
206   else {
207     aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_END));
208     if (fabs(aPoint->x() - theX) < Precision::Confusion() &&
209         fabs(aPoint->y() - theY) < Precision::Confusion())
210       aPoint2D = aPoint;
211   }
212   return aPoint2D;
213 }
214
215 boost::shared_ptr<GeomAPI_Lin2d> PartSet_FeatureLinePrs::createLin2d(FeaturePtr theFeature)
216 {
217   boost::shared_ptr<GeomAPI_Lin2d> aFeatureLin;
218   if (!theFeature || theFeature->getKind() != PartSet_FeatureLinePrs::getKind())
219     return aFeatureLin;
220
221   double aStartX, aStartY, anEndX, anEndY;
222   getLinePoint(theFeature, LINE_ATTR_START, aStartX, aStartY);
223   getLinePoint(theFeature, LINE_ATTR_END, anEndX, anEndY);
224
225   aFeatureLin = boost::shared_ptr<GeomAPI_Lin2d>
226                                         (new GeomAPI_Lin2d(aStartX, aStartY, anEndX, anEndY));
227   return aFeatureLin;
228 }
229
230 boost::shared_ptr<GeomDataAPI_Point2D> PartSet_FeatureLinePrs::featurePoint
231                                                      (const PartSet_SelectionMode& theMode)
232 {
233   std::string aPointArg;
234   switch (theMode)
235   {
236     case SM_FirstPoint:
237       aPointArg = LINE_ATTR_START;
238       break;
239     case SM_SecondPoint:
240       aPointArg = LINE_ATTR_END;
241       break;
242     default:
243       break;
244   }
245   boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
246   boost::shared_ptr<GeomDataAPI_Point2D> aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
247                                                               (aData->attribute(aPointArg));
248   return aPoint;
249 }
250
251 void PartSet_FeatureLinePrs::getLinePoint(FeaturePtr theFeature, const std::string& theAttribute,
252                                           double& theX, double& theY)
253 {
254   if (!theFeature || theFeature->getKind() != PartSet_FeatureLinePrs::getKind())
255     return;
256   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
257   boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
258         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(theAttribute));
259   theX = aPoint->x();
260   theY = aPoint->y();
261 }