Salome HOME
54af4c9737b90afa6240782dee35da4360d765ac
[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
16 #include <ModelAPI_Data.h>
17 #include <ModelAPI_Document.h>
18 #include <ModelAPI_AttributeRefAttr.h>
19 #include <ModelAPI_AttributeRefList.h>
20
21 #include <Precision.hxx>
22 #include <V3d_View.hxx>
23
24 using namespace std;
25
26 PartSet_FeatureLinePrs::PartSet_FeatureLinePrs(FeaturePtr theSketch)
27 : PartSet_FeaturePrs(theSketch)
28 {
29 }
30
31 std::string PartSet_FeatureLinePrs::getKind()
32 {
33   return SKETCH_LINE_KIND;
34 }
35
36 void PartSet_FeatureLinePrs::initFeature(FeaturePtr theFeature)
37 {
38   if (feature() && theFeature)
39   {
40     // use the last point of the previous feature as the first of the new one
41     boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
42     boost::shared_ptr<GeomDataAPI_Point2D> anInitPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
43                                                                   (aData->attribute(LINE_ATTR_END));
44     PartSet_Tools::setFeaturePoint(feature(), anInitPoint->x(), anInitPoint->y(), LINE_ATTR_START);
45     PartSet_Tools::setFeaturePoint(feature(), anInitPoint->x(), anInitPoint->y(), LINE_ATTR_END);
46
47     aData = feature()->data();
48     boost::shared_ptr<GeomDataAPI_Point2D> aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
49                                                                  (aData->attribute(LINE_ATTR_START));
50     PartSet_Tools::createConstraint(sketch(), anInitPoint, aPoint);
51   }
52 }
53
54 PartSet_SelectionMode PartSet_FeatureLinePrs::setPoint(double theX, double theY,
55                                                        const PartSet_SelectionMode& theMode)
56 {
57   PartSet_SelectionMode aMode = theMode;
58   switch (theMode)
59   {
60     case SM_FirstPoint: {
61       PartSet_Tools::setFeaturePoint(feature(), theX, theY, LINE_ATTR_START);
62       PartSet_Tools::setFeaturePoint(feature(), theX, theY, LINE_ATTR_END);
63       aMode = SM_SecondPoint;
64     }
65     break;
66     case SM_SecondPoint: {
67       PartSet_Tools::setFeaturePoint(feature(), theX, theY, LINE_ATTR_END);
68       aMode = SM_DonePoint;
69    }
70     break;
71     default:
72       break;
73   }
74   return aMode;
75 }
76
77 std::string PartSet_FeatureLinePrs::getAttribute(const PartSet_SelectionMode& theMode) const
78 {
79   std::string aAttribute;
80   switch (theMode)
81   {
82     case SM_FirstPoint:
83       aAttribute = LINE_ATTR_START;
84     break;
85     case SM_SecondPoint:
86       aAttribute = LINE_ATTR_END;
87     break;
88     default:
89     break;
90   }
91   return aAttribute;
92 }
93
94 PartSet_SelectionMode PartSet_FeatureLinePrs::getNextMode(const std::string& theAttribute) const
95 {
96   PartSet_SelectionMode aMode;
97
98   if (theAttribute == LINE_ATTR_START)
99     aMode = SM_SecondPoint;
100   else if (theAttribute == LINE_ATTR_END)
101     aMode = SM_DonePoint;
102   return aMode;
103 }
104
105 void PartSet_FeatureLinePrs::move(double theDeltaX, double theDeltaY)
106 {
107   boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
108   if (!aData->isValid())
109     return;
110
111   boost::shared_ptr<GeomDataAPI_Point2D> aPoint1 =
112         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_START));
113   aPoint1->setValue(aPoint1->x() + theDeltaX, aPoint1->y() + theDeltaY);
114
115   boost::shared_ptr<GeomDataAPI_Point2D> aPoint2 =
116         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_END));
117   aPoint2->setValue(aPoint2->x() + theDeltaX, aPoint2->y() + theDeltaY);
118 }
119
120 void PartSet_FeatureLinePrs::projectPointOnLine(FeaturePtr theFeature,
121                                                 const PartSet_SelectionMode& theMode,
122                                                 const gp_Pnt& thePoint, Handle(V3d_View) theView,
123                                                 double& theX, double& theY)
124 {
125   if (theFeature) {
126     double X0, X1, X2, X3;
127     double Y0, Y1, Y2, Y3;
128     getLinePoint(theFeature, LINE_ATTR_START, X2, Y2);
129     getLinePoint(theFeature, LINE_ATTR_END, X3, Y3);
130     PartSet_Tools::convertTo2D(thePoint, sketch(), theView, X1, Y1);
131
132     switch (theMode) {
133       case SM_FirstPoint:
134         PartSet_Tools::projectPointOnLine(X2, Y2, X3, Y3, X1, Y1, theX, theY);
135       break;
136       case SM_SecondPoint: {
137         getLinePoint(feature(), LINE_ATTR_START, X0, Y0);
138         PartSet_Tools::intersectLines(X0, Y0, X1, Y1, X2, Y2, X3, Y3, theX, theY);
139       }
140       break;
141       default:
142       break;
143     }
144   }
145 }
146
147 double PartSet_FeatureLinePrs::distanceToPoint(FeaturePtr theFeature,
148                                       double theX, double theY)
149 {
150   double aDelta = 0;
151   if (!theFeature || theFeature->getKind() != getKind())
152     return aDelta;
153
154   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
155   boost::shared_ptr<GeomDataAPI_Point2D> aPoint1 =
156         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_START));
157   boost::shared_ptr<GeomDataAPI_Point2D> aPoint2 =
158         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_END));
159
160   double aX, anY;
161   PartSet_Tools::projectPointOnLine(aPoint1->x(), aPoint1->y(), aPoint2->x(), aPoint2->y(), theX, theY, aX, anY);
162   aDelta = gp_Pnt(theX, theY, 0).Distance(gp_Pnt(aX, anY, 0));
163
164   return aDelta;
165 }
166
167 boost::shared_ptr<GeomDataAPI_Point2D> PartSet_FeatureLinePrs::findPoint(FeaturePtr theFeature,
168                                                                          double theX, double theY)
169 {
170   boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D;
171   if (!theFeature || theFeature->getKind() != getKind())
172     return aPoint2D;
173
174   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
175   boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
176         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_START));
177   if (fabs(aPoint->x() - theX) < Precision::Confusion() &&
178       fabs(aPoint->y() - theY) < Precision::Confusion())
179     aPoint2D = aPoint;
180   else {
181     aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_END));
182     if (fabs(aPoint->x() - theX) < Precision::Confusion() &&
183         fabs(aPoint->y() - theY) < Precision::Confusion())
184       aPoint2D = aPoint;
185   }
186   return aPoint2D;
187 }
188
189 boost::shared_ptr<GeomDataAPI_Point2D> PartSet_FeatureLinePrs::featurePoint
190                                                      (const PartSet_SelectionMode& theMode)
191 {
192   std::string aPointArg;
193   switch (theMode)
194   {
195     case SM_FirstPoint:
196       aPointArg = LINE_ATTR_START;
197       break;
198     case SM_SecondPoint:
199       aPointArg = LINE_ATTR_END;
200       break;
201     default:
202       break;
203   }
204   boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
205   boost::shared_ptr<GeomDataAPI_Point2D> aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
206                                                               (aData->attribute(aPointArg));
207   return aPoint;
208 }
209
210 void PartSet_FeatureLinePrs::getLinePoint(FeaturePtr theFeature, const std::string& theAttribute,
211                                           double& theX, double& theY)
212 {
213   if (!theFeature || theFeature->getKind() != PartSet_FeatureLinePrs::getKind())
214     return;
215   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
216   boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
217         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(theAttribute));
218   theX = aPoint->x();
219   theY = aPoint->y();
220 }