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