Salome HOME
refs #80 - Sketch base GUI: create/draw point, circle and arc
[modules/shaper.git] / src / PartSet / PartSet_FeatureLinePrs.cpp
index 53aa6befb1d4f36d48572ed5a140214a3607ae4a..4aa747a997ce4208246531c72af5c9cd6f21c996 100644 (file)
@@ -12,6 +12,8 @@
 #include <SketchPlugin_Constraint.h>
 
 #include <GeomDataAPI_Point2D.h>
+#include <GeomAPI_Lin2d.h>
+#include <GeomAPI_Pnt2d.h>
 
 #include <ModelAPI_Data.h>
 #include <ModelAPI_Document.h>
@@ -33,24 +35,6 @@ std::string PartSet_FeatureLinePrs::getKind()
   return SKETCH_LINE_KIND;
 }
 
-void PartSet_FeatureLinePrs::initFeature(FeaturePtr theFeature)
-{
-  if (feature() && theFeature)
-  {
-    // use the last point of the previous feature as the first of the new one
-    boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
-    boost::shared_ptr<GeomDataAPI_Point2D> anInitPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
-                                                                  (aData->attribute(LINE_ATTR_END));
-    PartSet_Tools::setFeaturePoint(feature(), anInitPoint->x(), anInitPoint->y(), LINE_ATTR_START);
-    PartSet_Tools::setFeaturePoint(feature(), anInitPoint->x(), anInitPoint->y(), LINE_ATTR_END);
-
-    aData = feature()->data();
-    boost::shared_ptr<GeomDataAPI_Point2D> aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
-                                                                 (aData->attribute(LINE_ATTR_START));
-    PartSet_Tools::createConstraint(sketch(), anInitPoint, aPoint);
-  }
-}
-
 PartSet_SelectionMode PartSet_FeatureLinePrs::setPoint(double theX, double theY,
                                                        const PartSet_SelectionMode& theMode)
 {
@@ -74,6 +58,27 @@ PartSet_SelectionMode PartSet_FeatureLinePrs::setPoint(double theX, double theY,
   return aMode;
 }
 
+PartSet_SelectionMode PartSet_FeatureLinePrs::setFeature(FeaturePtr theFeature, const PartSet_SelectionMode& theMode)
+{
+  PartSet_SelectionMode aMode = theMode;
+  if (feature() && theFeature && theMode == SM_FirstPoint)
+  {
+    // use the last point of the previous feature as the first of the new one
+    boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
+    boost::shared_ptr<GeomDataAPI_Point2D> anInitPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
+                                                                  (aData->attribute(LINE_ATTR_END));
+    PartSet_Tools::setFeaturePoint(feature(), anInitPoint->x(), anInitPoint->y(), LINE_ATTR_START);
+    PartSet_Tools::setFeaturePoint(feature(), anInitPoint->x(), anInitPoint->y(), LINE_ATTR_END);
+
+    aData = feature()->data();
+    boost::shared_ptr<GeomDataAPI_Point2D> aPoint = boost::dynamic_pointer_cast<GeomDataAPI_Point2D>
+                                                                 (aData->attribute(LINE_ATTR_START));
+    PartSet_Tools::createConstraint(sketch(), anInitPoint, aPoint);
+    aMode = SM_SecondPoint;
+  }
+  return aMode;
+}
+
 std::string PartSet_FeatureLinePrs::getAttribute(const PartSet_SelectionMode& theMode) const
 {
   std::string aAttribute;
@@ -107,20 +112,34 @@ void PartSet_FeatureLinePrs::projectPointOnLine(FeaturePtr theFeature,
                                                 const gp_Pnt& thePoint, Handle(V3d_View) theView,
                                                 double& theX, double& theY)
 {
-  if (theFeature) {
-    double X0, X1, X2, X3;
-    double Y0, Y1, Y2, Y3;
-    getLinePoint(theFeature, LINE_ATTR_START, X2, Y2);
-    getLinePoint(theFeature, LINE_ATTR_END, X3, Y3);
+  if (theFeature && theFeature->getKind() == getKind()) {
+    double X0, X1;
+    double Y0, Y1;
+
     PartSet_Tools::convertTo2D(thePoint, sketch(), theView, X1, Y1);
+    boost::shared_ptr<GeomAPI_Pnt2d> aPoint = boost::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(X1, Y1));
+    boost::shared_ptr<GeomAPI_Lin2d> aFeatureLin = PartSet_FeatureLinePrs::createLin2d(theFeature);
 
     switch (theMode) {
-      case SM_FirstPoint:
-        PartSet_Tools::projectPointOnLine(X2, Y2, X3, Y3, X1, Y1, theX, theY);
+      case SM_FirstPoint: {
+        boost::shared_ptr<GeomAPI_Pnt2d> aResult = aFeatureLin->project(aPoint);
+        theX = aResult->x();
+        theY = aResult->y();
+      }
       break;
       case SM_SecondPoint: {
         getLinePoint(feature(), LINE_ATTR_START, X0, Y0);
-        PartSet_Tools::intersectLines(X0, Y0, X1, Y1, X2, Y2, X3, Y3, theX, theY);
+        boost::shared_ptr<GeomAPI_Lin2d> aCurrentLin = boost::shared_ptr<GeomAPI_Lin2d>
+                                                           (new GeomAPI_Lin2d(X0, Y0, X1, Y1));
+        boost::shared_ptr<GeomAPI_Pnt2d> aResult = aFeatureLin->intersect(aCurrentLin);
+        boost::shared_ptr<GeomAPI_Pnt2d> aPoint0 = boost::shared_ptr<GeomAPI_Pnt2d>(new GeomAPI_Pnt2d(X0, Y0));
+        if (aResult->distance(aPoint0) < Precision::Confusion()) { // the start point is nearest to the line
+          // if the first point of a line belongs to the given line
+          // we need to project the second point on the same line
+          aResult = aFeatureLin->project(aPoint);
+        }
+        theX = aResult->x();
+        theY = aResult->y();
       }
       break;
       default:
@@ -129,36 +148,14 @@ void PartSet_FeatureLinePrs::projectPointOnLine(FeaturePtr theFeature,
   }
 }
 
-double PartSet_FeatureLinePrs::distanceToPoint(FeaturePtr theFeature,
-                                      double theX, double theY)
-{
-  double aDelta = 0;
-  if (!theFeature || theFeature->getKind() != SKETCH_LINE_KIND)
-    return aDelta;
-
-  boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
-  boost::shared_ptr<GeomDataAPI_Point2D> aPoint1 =
-        boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_START));
-  boost::shared_ptr<GeomDataAPI_Point2D> aPoint2 =
-        boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_END));
-
-  double aX, anY;
-  PartSet_Tools::projectPointOnLine(aPoint1->x(), aPoint1->y(), aPoint2->x(), aPoint2->y(), theX, theY, aX, anY);
-  aDelta = gp_Pnt(theX, theY, 0).Distance(gp_Pnt(aX, anY, 0));
-
-  return aDelta;
-}
-
 boost::shared_ptr<GeomDataAPI_Point2D> PartSet_FeatureLinePrs::findPoint(FeaturePtr theFeature,
                                                                          double theX, double theY)
 {
   boost::shared_ptr<GeomDataAPI_Point2D> aPoint2D;
-  if (!theFeature || theFeature->getKind() != SKETCH_LINE_KIND)
+  if (!theFeature || theFeature->getKind() != getKind())
     return aPoint2D;
 
   boost::shared_ptr<ModelAPI_Data> aData = theFeature->data();
-  aPoint2D = PartSet_FeatureLinePrs::findPoint(theFeature, theX, theY);
-
   boost::shared_ptr<GeomDataAPI_Point2D> aPoint =
         boost::dynamic_pointer_cast<GeomDataAPI_Point2D>(aData->attribute(LINE_ATTR_START));
   if (fabs(aPoint->x() - theX) < Precision::Confusion() &&
@@ -173,6 +170,21 @@ boost::shared_ptr<GeomDataAPI_Point2D> PartSet_FeatureLinePrs::findPoint(Feature
   return aPoint2D;
 }
 
+boost::shared_ptr<GeomAPI_Lin2d> PartSet_FeatureLinePrs::createLin2d(FeaturePtr theFeature)
+{
+  boost::shared_ptr<GeomAPI_Lin2d> aFeatureLin;
+  if (!theFeature || theFeature->getKind() != PartSet_FeatureLinePrs::getKind())
+    return aFeatureLin;
+
+  double aStartX, aStartY, anEndX, anEndY;
+  getLinePoint(theFeature, LINE_ATTR_START, aStartX, aStartY);
+  getLinePoint(theFeature, LINE_ATTR_END, anEndX, anEndY);
+
+  aFeatureLin = boost::shared_ptr<GeomAPI_Lin2d>
+                                        (new GeomAPI_Lin2d(aStartX, aStartY, anEndX, anEndY));
+  return aFeatureLin;
+}
+
 boost::shared_ptr<GeomDataAPI_Point2D> PartSet_FeatureLinePrs::featurePoint
                                                      (const PartSet_SelectionMode& theMode)
 {