1 // File: PartSet_FeaturePrs.h
2 // Created: 04 Jun 2014
3 // Author: Natalia ERMOLAEVA
5 #include <PartSet_FeatureLinePrs.h>
6 #include <PartSet_Tools.h>
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>
14 #include <GeomDataAPI_Point2D.h>
15 #include <GeomAPI_Lin2d.h>
16 #include <GeomAPI_Pnt2d.h>
18 #include <ModelAPI_Data.h>
19 #include <ModelAPI_Document.h>
20 #include <ModelAPI_AttributeRefAttr.h>
21 #include <ModelAPI_AttributeRefList.h>
23 #include <Precision.hxx>
24 #include <V3d_View.hxx>
28 PartSet_FeatureLinePrs::PartSet_FeatureLinePrs(FeaturePtr theSketch)
29 : PartSet_FeaturePrs(theSketch)
33 std::string PartSet_FeatureLinePrs::getKind()
35 return SKETCH_LINE_KIND;
38 PartSet_SelectionMode PartSet_FeatureLinePrs::setPoint(double theX, double theY,
39 const PartSet_SelectionMode& theMode)
41 PartSet_SelectionMode aMode = theMode;
45 PartSet_Tools::setFeaturePoint(feature(), theX, theY, LINE_ATTR_START);
46 PartSet_Tools::setFeaturePoint(feature(), theX, theY, LINE_ATTR_END);
47 aMode = SM_SecondPoint;
50 case SM_SecondPoint: {
51 PartSet_Tools::setFeaturePoint(feature(), theX, theY, LINE_ATTR_END);
61 PartSet_SelectionMode PartSet_FeatureLinePrs::setFeature(FeaturePtr theFeature, const PartSet_SelectionMode& theMode)
63 PartSet_SelectionMode aMode = theMode;
64 if (feature() && theFeature && theMode == SM_FirstPoint)
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);
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 aMode = SM_SecondPoint;
82 std::string PartSet_FeatureLinePrs::getAttribute(const PartSet_SelectionMode& theMode) const
84 std::string aAttribute;
88 aAttribute = LINE_ATTR_START;
91 aAttribute = LINE_ATTR_END;
99 PartSet_SelectionMode PartSet_FeatureLinePrs::getNextMode(const std::string& theAttribute) const
101 PartSet_SelectionMode aMode;
103 if (theAttribute == LINE_ATTR_START)
104 aMode = SM_SecondPoint;
105 else if (theAttribute == LINE_ATTR_END)
106 aMode = SM_DonePoint;
110 void PartSet_FeatureLinePrs::move(double theDeltaX, double theDeltaY)
112 boost::shared_ptr<ModelAPI_Data> aData = feature()->data();
113 if (!aData->isValid())
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);
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);
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)
130 if (theFeature && theFeature->getKind() == getKind()) {
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);
139 case SM_FirstPoint: {
140 boost::shared_ptr<GeomAPI_Pnt2d> aResult = aFeatureLin->project(aPoint);
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);
166 double PartSet_FeatureLinePrs::distanceToPoint(FeaturePtr theFeature,
167 double theX, double theY)
170 if (!theFeature || theFeature->getKind() != getKind())
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));
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));
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);
187 aDelta = aLin2d.distance(aPoint);
193 boost::shared_ptr<GeomDataAPI_Point2D> PartSet_FeatureLinePrs::findPoint(FeaturePtr theFeature,
194 double theX, double theY)
196 boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D;
197 if (!theFeature || theFeature->getKind() != getKind())
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())
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())
215 boost::shared_ptr<GeomAPI_Lin2d> PartSet_FeatureLinePrs::createLin2d(FeaturePtr theFeature)
217 boost::shared_ptr<GeomAPI_Lin2d> aFeatureLin;
218 if (!theFeature || theFeature->getKind() != PartSet_FeatureLinePrs::getKind())
221 double aStartX, aStartY, anEndX, anEndY;
222 getLinePoint(theFeature, LINE_ATTR_START, aStartX, aStartY);
223 getLinePoint(theFeature, LINE_ATTR_END, anEndX, anEndY);
225 aFeatureLin = boost::shared_ptr<GeomAPI_Lin2d>
226 (new GeomAPI_Lin2d(aStartX, aStartY, anEndX, anEndY));
230 boost::shared_ptr<GeomDataAPI_Point2D> PartSet_FeatureLinePrs::featurePoint
231 (const PartSet_SelectionMode& theMode)
233 std::string aPointArg;
237 aPointArg = LINE_ATTR_START;
240 aPointArg = LINE_ATTR_END;
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));
251 void PartSet_FeatureLinePrs::getLinePoint(FeaturePtr theFeature, const std::string& theAttribute,
252 double& theX, double& theY)
254 if (!theFeature || theFeature->getKind() != PartSet_FeatureLinePrs::getKind())
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));