]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #2024: Redesign of circle and arc of circle
authorazv <azv@opencascade.com>
Sat, 25 Mar 2017 14:20:16 +0000 (17:20 +0300)
committerdbv <dbv@opencascade.com>
Mon, 27 Mar 2017 06:56:57 +0000 (09:56 +0300)
* Prepare shape for MacroArc according to already selected points.

src/GeomAPI/GeomAPI_Circ2d.cpp
src/SketchAPI/SketchAPI_MacroArc.cpp
src/SketchAPI/SketchAPI_MacroArc.h
src/SketchPlugin/SketchPlugin_MacroArc.cpp
src/SketchPlugin/SketchPlugin_MacroArc.h
src/SketchPlugin/SketchPlugin_MacroCircle.cpp
src/SketchPlugin/SketchPlugin_Tools.cpp
src/SketchPlugin/SketchPlugin_Tools.h
src/SketchPlugin/SketchPlugin_Validators.cpp
src/SketchPlugin/SketchPlugin_Validators.h
src/SketchPlugin/plugin-Sketch.xml

index 743b44db29134a3b7c972ac2060500a4266028fa..a50e343ca11607142790e9b3a18450690d3826cb 100644 (file)
@@ -67,10 +67,10 @@ public:
 
     double aFirst, aLast;
     TopLoc_Location aLoc;
-    CurveAdaptorPtr aCurve(new Geom2dAdaptor_Curve(
-        BRep_Tool::CurveOnSurface(anEdge, myPlane, aLoc, aFirst, aLast)));
+    Handle(Geom2d_Curve) aCurve = BRep_Tool::CurveOnSurface(anEdge, myPlane, aLoc, aFirst, aLast);
+    CurveAdaptorPtr aCurveAdaptor(new Geom2dAdaptor_Curve(aCurve, aFirst, aLast));
 
-    myTangentShapes.push_back(aCurve);
+    myTangentShapes.push_back(aCurveAdaptor);
   }
 
   void addPassingPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
index 2fa73d5a3616e0f3549c0450fcdb90ecdb158e8c..a82f44a709028c85b128a4e012f2076b38b67bd7 100644 (file)
@@ -28,10 +28,10 @@ SketchAPI_MacroArc::SketchAPI_MacroArc(const std::shared_ptr<ModelAPI_Feature> &
 
 //================================================================================================
 SketchAPI_MacroArc::SketchAPI_MacroArc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-                             double theCenterX, double theCenterY,
-                             double theStartX, double theStartY,
-                             double theEndX, double theEndY,
-                             bool theInversed)
+                                       double theCenterX, double theCenterY,
+                                       double theStartX, double theStartY,
+                                       double theEndX, double theEndY,
+                                       bool theInversed)
 : SketchAPI_SketchEntity(theFeature)
 {
   if(initialize()) {
@@ -42,10 +42,10 @@ SketchAPI_MacroArc::SketchAPI_MacroArc(const std::shared_ptr<ModelAPI_Feature>&
 
 //================================================================================================
 SketchAPI_MacroArc::SketchAPI_MacroArc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-                             const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
-                             const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
-                             const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
-                             bool theInversed)
+                                       const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
+                                       const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
+                                       const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
+                                       bool theInversed)
 : SketchAPI_SketchEntity(theFeature)
 {
   if(initialize()) {
@@ -55,9 +55,9 @@ SketchAPI_MacroArc::SketchAPI_MacroArc(const std::shared_ptr<ModelAPI_Feature>&
 
 //================================================================================================
 SketchAPI_MacroArc::SketchAPI_MacroArc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-                             double theStartX, double theStartY,
-                             double theEndX, double theEndY,
-                             double thePassedX, double thePassedY)
+                                       double theStartX, double theStartY,
+                                       double theEndX, double theEndY,
+                                       double thePassedX, double thePassedY)
 : SketchAPI_SketchEntity(theFeature)
 {
   if (initialize()) {
@@ -67,9 +67,9 @@ SketchAPI_MacroArc::SketchAPI_MacroArc(const std::shared_ptr<ModelAPI_Feature>&
 
 //===============================================================================================
 SketchAPI_MacroArc::SketchAPI_MacroArc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-                             const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
-                             const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
-                             const std::shared_ptr<GeomAPI_Pnt2d>& thePassed)
+                                       const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
+                                       const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
+                                       const std::shared_ptr<GeomAPI_Pnt2d>& thePassed)
 : SketchAPI_SketchEntity(theFeature)
 {
   if (initialize()) {
@@ -79,9 +79,9 @@ SketchAPI_MacroArc::SketchAPI_MacroArc(const std::shared_ptr<ModelAPI_Feature>&
 
 //================================================================================================
 SketchAPI_MacroArc::SketchAPI_MacroArc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-                             const ModelHighAPI_RefAttr& theTangentPoint,
-                             double theEndX, double theEndY,
-                             bool theInversed)
+                                       const ModelHighAPI_RefAttr& theTangentPoint,
+                                       double theEndX, double theEndY,
+                                       bool theInversed)
 : SketchAPI_SketchEntity(theFeature)
 {
   if (initialize()) {
@@ -91,9 +91,9 @@ SketchAPI_MacroArc::SketchAPI_MacroArc(const std::shared_ptr<ModelAPI_Feature>&
 
 //================================================================================================
 SketchAPI_MacroArc::SketchAPI_MacroArc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
-                             const ModelHighAPI_RefAttr& theTangentPoint,
-                             const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
-                             bool theInversed)
+                                       const ModelHighAPI_RefAttr& theTangentPoint,
+                                       const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
+                                       bool theInversed)
 : SketchAPI_SketchEntity(theFeature)
 {
   if (initialize()) {
@@ -109,14 +109,14 @@ SketchAPI_MacroArc::~SketchAPI_MacroArc()
 
 //================================================================================================
 void SketchAPI_MacroArc::setByCenterStartEnd(double theCenterX, double theCenterY,
-                                        double theStartX, double theStartY,
-                                        double theEndX, double theEndY,
-                                        bool theInversed)
+                                             double theStartX, double theStartY,
+                                             double theEndX, double theEndY,
+                                             bool theInversed)
 {
   fillAttribute(SketchPlugin_MacroArc::ARC_TYPE_BY_CENTER_AND_POINTS(), myarcType);
   fillAttribute(center(), theCenterX, theCenterY);
-  fillAttribute(startPoint1(), theStartX, theStartY);
-  fillAttribute(endPoint1(), theEndX, theEndY);
+  fillAttribute(startPoint(), theStartX, theStartY);
+  fillAttribute(endPoint(), theEndX, theEndY);
   fillAttribute(theInversed, myreversed);
 
   execute();
@@ -124,14 +124,14 @@ void SketchAPI_MacroArc::setByCenterStartEnd(double theCenterX, double theCenter
 
 //================================================================================================
 void SketchAPI_MacroArc::setByCenterStartEnd(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
-                                        const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
-                                        const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
-                                        bool theInversed)
+                                             const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
+                                             const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
+                                             bool theInversed)
 {
   fillAttribute(SketchPlugin_MacroArc::ARC_TYPE_BY_CENTER_AND_POINTS(), myarcType);
   fillAttribute(theCenter, mycenter);
-  fillAttribute(theStart, mystartPoint1);
-  fillAttribute(theEnd, myendPoint1);
+  fillAttribute(theStart, mystartPoint);
+  fillAttribute(theEnd, myendPoint);
   fillAttribute(theInversed, myreversed);
 
   execute();
@@ -139,12 +139,12 @@ void SketchAPI_MacroArc::setByCenterStartEnd(const std::shared_ptr<GeomAPI_Pnt2d
 
 //================================================================================================
 void SketchAPI_MacroArc::setByStartEndPassed(double theStartX, double theStartY,
-                                        double theEndX, double theEndY,
-                                        double thePassedX, double thePassedY)
+                                             double theEndX, double theEndY,
+                                             double thePassedX, double thePassedY)
 {
   fillAttribute(SketchPlugin_MacroArc::ARC_TYPE_BY_THREE_POINTS(), myarcType);
-  fillAttribute(startPoint2(), theStartX, theStartY);
-  fillAttribute(endPoint2(), theEndX, theEndY);
+  fillAttribute(startPoint(), theStartX, theStartY);
+  fillAttribute(endPoint(), theEndX, theEndY);
   fillAttribute(passedPoint(), thePassedX, thePassedY);
 
   execute();
@@ -152,12 +152,12 @@ void SketchAPI_MacroArc::setByStartEndPassed(double theStartX, double theStartY,
 
 //================================================================================================
 void SketchAPI_MacroArc::setByStartEndPassed(const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
-                                        const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
-                                        const std::shared_ptr<GeomAPI_Pnt2d>& thePassed)
+                                             const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
+                                             const std::shared_ptr<GeomAPI_Pnt2d>& thePassed)
 {
   fillAttribute(SketchPlugin_MacroArc::ARC_TYPE_BY_THREE_POINTS(), myarcType);
-  fillAttribute(theStart, mystartPoint2);
-  fillAttribute(theEnd, myendPoint2);
+  fillAttribute(theStart, mystartPoint);
+  fillAttribute(theEnd, myendPoint);
   fillAttribute(thePassed, mypassedPoint);
 
   execute();
@@ -165,12 +165,12 @@ void SketchAPI_MacroArc::setByStartEndPassed(const std::shared_ptr<GeomAPI_Pnt2d
 
 //================================================================================================
 void SketchAPI_MacroArc::setByTangent(const ModelHighAPI_RefAttr& theTangentPoint,
-                                 double theEndX, double theEndY,
-                                 bool theInversed)
+                                      double theEndX, double theEndY,
+                                      bool theInversed)
 {
   fillAttribute(SketchPlugin_MacroArc::ARC_TYPE_BY_TANGENT_EDGE(), myarcType);
   fillAttribute(theTangentPoint, mytangentPoint);
-  fillAttribute(endPoint3(), theEndX, theEndY);
+  fillAttribute(endPoint(), theEndX, theEndY);
   fillAttribute(theInversed, myreversed);
 
   execute();
@@ -178,12 +178,12 @@ void SketchAPI_MacroArc::setByTangent(const ModelHighAPI_RefAttr& theTangentPoin
 
 //================================================================================================
 void SketchAPI_MacroArc::setByTangent(const ModelHighAPI_RefAttr& theTangentPoint,
-                                 const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
-                                 bool theInversed)
+                                      const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
+                                      bool theInversed)
 {
   fillAttribute(SketchPlugin_MacroArc::ARC_TYPE_BY_TANGENT_EDGE(), myarcType);
   fillAttribute(theTangentPoint, mytangentPoint);
-  fillAttribute(theEnd, myendPoint3);
+  fillAttribute(theEnd, myendPoint);
   fillAttribute(theInversed, myreversed);
 
   execute();
index c24e24750f74bec9aa1fe57b45c711fd4d2e5f56..9350e54277c7837e76cc8d8fa1e4a7bebdab69c9 100644 (file)
@@ -79,31 +79,25 @@ public:
     SketchPlugin_MacroArc::ID();
   }
 
-  INTERFACE_12(SketchPlugin_MacroArc::ID(),
-               arcType, SketchPlugin_MacroArc::ARC_TYPE(),
-               ModelAPI_AttributeString, /** Arc type */,
-               center, SketchPlugin_MacroArc::CENTER_POINT_ID(),
-               GeomDataAPI_Point2D, /** Center point */,
-               startPoint1, SketchPlugin_MacroArc::START_POINT_1_ID(),
-               GeomDataAPI_Point2D, /** Start point */,
-               endPoint1, SketchPlugin_MacroArc::END_POINT_1_ID(),
-               GeomDataAPI_Point2D, /** End point */,
-               startPoint2, SketchPlugin_MacroArc::START_POINT_2_ID(),
-               GeomDataAPI_Point2D, /** Start point */,
-               endPoint2, SketchPlugin_MacroArc::END_POINT_2_ID(),
-               GeomDataAPI_Point2D, /** End point */,
-               passedPoint, SketchPlugin_MacroArc::PASSED_POINT_ID(),
-               GeomDataAPI_Point2D, /** Passed point */,
-               tangentPoint, SketchPlugin_MacroArc::TANGENT_POINT_ID(),
-               ModelAPI_AttributeRefAttr, /** Tangent point */,
-               endPoint3, SketchPlugin_MacroArc::END_POINT_3_ID(),
-               GeomDataAPI_Point2D, /** End point */,
-               reversed, SketchPlugin_MacroArc::REVERSED_ID(),
-               ModelAPI_AttributeBoolean, /** Reversed flag */,
-               radius, SketchPlugin_MacroArc::RADIUS_ID(),
-               ModelAPI_AttributeDouble, /** Radius */,
-               angle, SketchPlugin_MacroArc::ANGLE_ID(),
-               ModelAPI_AttributeDouble, /** Angle */)
+  INTERFACE_9(SketchPlugin_MacroArc::ID(),
+              arcType, SketchPlugin_MacroArc::ARC_TYPE(),
+              ModelAPI_AttributeString, /** Arc type */,
+              center, SketchPlugin_MacroArc::CENTER_POINT_ID(),
+              GeomDataAPI_Point2D, /** Center point */,
+              startPoint, SketchPlugin_MacroArc::START_POINT_ID(),
+              GeomDataAPI_Point2D, /** Start point */,
+              endPoint, SketchPlugin_MacroArc::END_POINT_ID(),
+              GeomDataAPI_Point2D, /** End point */,
+              passedPoint, SketchPlugin_MacroArc::PASSED_POINT_ID(),
+              GeomDataAPI_Point2D, /** Passed point */,
+              tangentPoint, SketchPlugin_MacroArc::TANGENT_POINT_ID(),
+              ModelAPI_AttributeRefAttr, /** Tangent point */,
+              reversed, SketchPlugin_MacroArc::REVERSED_ID(),
+              ModelAPI_AttributeBoolean, /** Reversed flag */,
+              radius, SketchPlugin_MacroArc::RADIUS_ID(),
+              ModelAPI_AttributeDouble, /** Radius */,
+              angle, SketchPlugin_MacroArc::ANGLE_ID(),
+              ModelAPI_AttributeDouble, /** Angle */)
 
 private:
 
index 6528ca24700a6a5e2f9188f3079b8dee232fa154..c1affb73688bfd65560c5b64e36ec48aba7afcaa 100644 (file)
@@ -18,6 +18,7 @@
 
 #include <GeomAPI_Circ.h>
 #include <GeomAPI_Circ2d.h>
+#include <GeomAPI_Curve.h>
 #include <GeomAPI_Dir2d.h>
 #include <GeomAPI_Edge.h>
 #include <GeomAPI_Lin.h>
@@ -39,6 +40,13 @@ const double tolerance = 1e-7;
 const double paramTolerance = 1.e-4;
 const double PI = 3.141592653589793238463;
 
+static void projectPointOnCircle(AttributePoint2DPtr& thePoint, const GeomAPI_Circ2d& theCircle)
+{
+  std::shared_ptr<GeomAPI_Pnt2d> aProjection = theCircle.project(thePoint->pnt());
+  if(aProjection.get())
+    thePoint->setValue(aProjection);
+}
+
 
 SketchPlugin_MacroArc::SketchPlugin_MacroArc()
 : SketchPlugin_SketchEntity(),
@@ -51,15 +59,12 @@ void SketchPlugin_MacroArc::initAttributes()
   data()->addAttribute(ARC_TYPE(), ModelAPI_AttributeString::typeId());
 
   data()->addAttribute(CENTER_POINT_ID(), GeomDataAPI_Point2D::typeId());
-  data()->addAttribute(START_POINT_1_ID(), GeomDataAPI_Point2D::typeId());
-  data()->addAttribute(END_POINT_1_ID(), GeomDataAPI_Point2D::typeId());
+  data()->addAttribute(START_POINT_ID(), GeomDataAPI_Point2D::typeId());
+  data()->addAttribute(END_POINT_ID(), GeomDataAPI_Point2D::typeId());
 
-  data()->addAttribute(START_POINT_2_ID(), GeomDataAPI_Point2D::typeId());
-  data()->addAttribute(END_POINT_2_ID(), GeomDataAPI_Point2D::typeId());
   data()->addAttribute(PASSED_POINT_ID(), GeomDataAPI_Point2D::typeId());
 
   data()->addAttribute(TANGENT_POINT_ID(), ModelAPI_AttributeRefAttr::typeId());
-  data()->addAttribute(END_POINT_3_ID(), GeomDataAPI_Point2D::typeId());
 
   data()->addAttribute(REVERSED_ID(), ModelAPI_AttributeBoolean::typeId());
 
@@ -87,185 +92,30 @@ void SketchPlugin_MacroArc::attributeChanged(const std::string& theID)
 
   // If arc type switched reset according attributes.
   if(theID == ARC_TYPE()) {
-    std::string aType = string(ARC_TYPE())->value();
-    if(aType == ARC_TYPE_BY_CENTER_AND_POINTS()) {
-      SketchPlugin_Tools::resetAttribute(this, CENTER_POINT_ID());
-      SketchPlugin_Tools::resetAttribute(this, CENTER_POINT_REF_ID());
-      SketchPlugin_Tools::resetAttribute(this, START_POINT_1_ID());
-      SketchPlugin_Tools::resetAttribute(this, START_POINT_REF_ID());
-      SketchPlugin_Tools::resetAttribute(this, END_POINT_1_ID());
-      SketchPlugin_Tools::resetAttribute(this, END_POINT_REF_ID());
-    } else if(aType == ARC_TYPE_BY_THREE_POINTS()) {
-      SketchPlugin_Tools::resetAttribute(this, START_POINT_2_ID());
-      SketchPlugin_Tools::resetAttribute(this, START_POINT_REF_ID());
-      SketchPlugin_Tools::resetAttribute(this, END_POINT_2_ID());
-      SketchPlugin_Tools::resetAttribute(this, END_POINT_REF_ID());
-      SketchPlugin_Tools::resetAttribute(this, PASSED_POINT_ID());
-      SketchPlugin_Tools::resetAttribute(this, PASSED_POINT_REF_ID());
-    } else if(aType == ARC_TYPE_BY_TANGENT_EDGE()) {
-      SketchPlugin_Tools::resetAttribute(this, TANGENT_POINT_ID());
-      SketchPlugin_Tools::resetAttribute(this, END_POINT_3_ID());
-      SketchPlugin_Tools::resetAttribute(this, END_POINT_REF_ID());
-    }
+    SketchPlugin_Tools::resetAttribute(this, CENTER_POINT_ID());
+    SketchPlugin_Tools::resetAttribute(this, CENTER_POINT_REF_ID());
+    SketchPlugin_Tools::resetAttribute(this, START_POINT_ID());
+    SketchPlugin_Tools::resetAttribute(this, START_POINT_REF_ID());
+    SketchPlugin_Tools::resetAttribute(this, END_POINT_ID());
+    SketchPlugin_Tools::resetAttribute(this, END_POINT_REF_ID());
+    SketchPlugin_Tools::resetAttribute(this, PASSED_POINT_ID());
+    SketchPlugin_Tools::resetAttribute(this, PASSED_POINT_REF_ID());
+    SketchPlugin_Tools::resetAttribute(this, TANGENT_POINT_ID());
+    SketchPlugin_Tools::resetAttribute(this, REVERSED_ID());
+    SketchPlugin_Tools::resetAttribute(this, RADIUS_ID());
+    SketchPlugin_Tools::resetAttribute(this, ANGLE_ID());
 
     myCenter.reset();
     myStart.reset();
     myEnd.reset();
     boolean(REVERSED_ID())->setValue(false);
     myParamBefore = 0.0;
-  } else if(anArcType == ARC_TYPE_BY_CENTER_AND_POINTS()) {
-    std::shared_ptr<GeomDataAPI_Point2D> aCenterPointAttr =
-        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_POINT_ID()));
-    if(!aCenterPointAttr->isInitialized()) {
-      return;
-    }
-    std::shared_ptr<GeomDataAPI_Point2D> aStartPointAttr =
-        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_POINT_1_ID()));
-    if(!aStartPointAttr->isInitialized()) {
-      return;
-    }
-
-    myCenter = aCenterPointAttr->pnt();
-    myStart = aStartPointAttr->pnt();
-    myEnd = myStart;
-
-    std::shared_ptr<GeomDataAPI_Point2D> anEndPointAttr =
-        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(END_POINT_1_ID()));
-    if(anEndPointAttr->isInitialized()) {
-      // End point should be a projection on circle.
-      GeomAPI_Circ2d aCircleForArc(myCenter, myStart);
-      std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc.project(anEndPointAttr->pnt());
-      if(aProjection.get()) {
-        bool aWasBlocked = data()->blockSendAttributeUpdated(true);
-        anEndPointAttr->setValue(aProjection);
-        data()->blockSendAttributeUpdated(aWasBlocked, false);
-      }
-      myEnd = anEndPointAttr->pnt();
-
-      double aParameterNew = 0.0;
-      if(aCircleForArc.parameter(myEnd, paramTolerance, aParameterNew)) {
-        if(myParamBefore <= PI / 2.0 && aParameterNew >= PI * 1.5) {
-          boolean(REVERSED_ID())->setValue(true);
-        } else if(myParamBefore >= PI * 1.5 && aParameterNew <= PI / 2.0) {
-          boolean(REVERSED_ID())->setValue(false);
-        }
-      }
-      myParamBefore = aParameterNew;
-    }
-  } else if(anArcType == ARC_TYPE_BY_THREE_POINTS()) {
-    std::shared_ptr<GeomDataAPI_Point2D> aStartPointAttr =
-        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_POINT_2_ID()));
-    if(!aStartPointAttr->isInitialized()) {
-      return;
-    }
-    std::shared_ptr<GeomDataAPI_Point2D> anEndPointAttr =
-        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(END_POINT_2_ID()));
-    if(!anEndPointAttr->isInitialized()) {
-      return;
-    }
-
-    myStart = aStartPointAttr->pnt();
-    myEnd = anEndPointAttr->pnt();
-
-    std::shared_ptr<GeomDataAPI_Point2D> aPassedPointAttr =
-        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(PASSED_POINT_ID()));
-    if(aPassedPointAttr->isInitialized()) {
-      std::shared_ptr<GeomAPI_Pnt2d> aPassed = aPassedPointAttr->pnt();
-      GeomAPI_Circ2d aCircle(myStart, myEnd, aPassed);
-      myCenter = aCircle.center();
-      aCircle = GeomAPI_Circ2d(myCenter, myStart);
-      double anEndParam, aPassedParam;
-      aCircle.parameter(myEnd, paramTolerance, anEndParam);
-      aCircle.parameter(aPassed, paramTolerance, aPassedParam);
-      if(aPassedParam > anEndParam) {
-        boolean(REVERSED_ID())->setValue(true);
-      } else {
-        boolean(REVERSED_ID())->setValue(false);
-      }
-    } else {
-      std::shared_ptr<GeomAPI_XY> aDir = myEnd->xy()->decreased(myStart->xy())->multiplied(0.5);
-      double x = aDir->x();
-      double y = aDir->y();
-      aDir->setX(x - y);
-      aDir->setY(y + x);
-      myCenter.reset(new GeomAPI_Pnt2d(myStart->xy()->added(aDir)));
-    }
-  } else if(anArcType == ARC_TYPE_BY_TANGENT_EDGE()) {
-    AttributeRefAttrPtr aTangentAttr = refattr(TANGENT_POINT_ID());
-    if(!aTangentAttr->isInitialized()) {
-      return;
-    }
-    std::shared_ptr<GeomDataAPI_Point2D> aTangentPointAttr =
-        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aTangentAttr->attr());
-    if(!aTangentPointAttr->isInitialized()) {
-      return;
-    }
-    std::shared_ptr<GeomDataAPI_Point2D> anEndPointAttr =
-        std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(END_POINT_3_ID()));
-    if(!anEndPointAttr->isInitialized()) {
-      return;
-    }
-
-    myStart = aTangentPointAttr->pnt();
-    myEnd = anEndPointAttr->pnt();
-
-    if(myStart->isEqual(myEnd)) {
-      return;
-    }
-
-    SketchPlugin_Sketch* aSketch = sketch();
-    if(!aSketch) {
-      return;
-    }
-
-    std::shared_ptr<GeomAPI_Dir2d> anOrthoDir;
-    FeaturePtr aTangFeature = ModelAPI_Feature::feature(aTangentPointAttr->owner());
-    std::shared_ptr<GeomAPI_Edge> aTangEdge =
-      std::dynamic_pointer_cast<GeomAPI_Edge>(aTangFeature->lastResult()->shape());
-    if(aTangEdge->isLine()) {
-      std::shared_ptr<GeomAPI_Dir> aDir = aTangEdge->line()->direction();
-      std::shared_ptr<GeomAPI_Pnt> aPnt(new GeomAPI_Pnt(aDir->x(), aDir->y(), aDir->z()));
-      std::shared_ptr<GeomAPI_Pnt2d> aPnt2d = aSketch->to2D(aPnt);
-      anOrthoDir = std::shared_ptr<GeomAPI_Dir2d>(new GeomAPI_Dir2d(-aPnt2d->y(), aPnt2d->x()));
-    }
-    else if (aTangEdge->isArc()) {
-      std::shared_ptr<GeomAPI_Pnt> aCenter = aTangEdge->circle()->center();
-      std::shared_ptr<GeomAPI_Pnt2d> aCenter2d = aSketch->to2D(aCenter);
-      anOrthoDir = std::shared_ptr<GeomAPI_Dir2d>(
-          new GeomAPI_Dir2d(myStart->xy()->decreased(aCenter2d->xy())));
-    }
-
-    // compute parameters of the middle perpendicular
-    std::shared_ptr<GeomAPI_XY> aEndPntCoord = myEnd->xy();
-    std::shared_ptr<GeomAPI_XY> aTempDir = aEndPntCoord->decreased(myStart->xy());
-    std::shared_ptr<GeomAPI_Dir2d> aMidDir(new GeomAPI_Dir2d(-aTempDir->y(), aTempDir->x()));
-    std::shared_ptr<GeomAPI_Pnt2d> aMidPnt(
-        new GeomAPI_Pnt2d(aEndPntCoord->added(myStart->xy())->multiplied(0.5)));
-
-    // compute center of arc by calculating intersection of
-    // orthogonal line and middle perpendicular
-    std::shared_ptr<GeomAPI_Lin2d> anOrthoLine(new GeomAPI_Lin2d(myStart, anOrthoDir));
-    std::shared_ptr<GeomAPI_Lin2d> aMiddleLine(new GeomAPI_Lin2d(aMidPnt, aMidDir));
-    std::shared_ptr<GeomAPI_Pnt2d> aCenter = anOrthoLine->intersect(aMiddleLine);
-    if(aCenter) {
-      myCenter = aCenter;
-    }
-
-    GeomAPI_Circ2d aCircleForArc(myCenter, myStart);
-    double aParameterNew = 0.0;
-    if(aCircleForArc.parameter(myEnd, paramTolerance, aParameterNew)) {
-      if(myParamBefore <= PI / 2.0 && aParameterNew >= PI * 1.5) {
-        if(!boolean(REVERSED_ID())->value()) {
-          boolean(REVERSED_ID())->setValue(true);
-        }
-      } else if(myParamBefore >= PI * 1.5 && aParameterNew <= PI / 2.0) {
-        if(boolean(REVERSED_ID())->value()) {
-          boolean(REVERSED_ID())->setValue(false);
-        }
-      }
-    }
-    myParamBefore = aParameterNew;
-  }
+  } else if(anArcType == ARC_TYPE_BY_CENTER_AND_POINTS())
+    fillByCenterAndTwoPassed();
+  else if(anArcType == ARC_TYPE_BY_THREE_POINTS())
+    fillByThreePassedPoints();
+  else if(anArcType == ARC_TYPE_BY_TANGENT_EDGE())
+    fillByTangentEdge();
 
   double aRadius = 0;
   double anAngle = 0;
@@ -334,17 +184,7 @@ AISObjectPtr SketchPlugin_MacroArc::getAISObject(AISObjectPtr thePrevious)
 
 void SketchPlugin_MacroArc::execute()
 {
-  // Create arc feature.
-  FeaturePtr anArcFeature = sketch()->addFeature(SketchPlugin_Arc::ID());
-  std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-      anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID()))->setValue(myCenter);
-  std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-      anArcFeature->attribute(SketchPlugin_Arc::START_ID()))->setValue(myStart);
-  std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-      anArcFeature->attribute(SketchPlugin_Arc::END_ID()))->setValue(myEnd);
-  anArcFeature->boolean(SketchPlugin_Arc::REVERSED_ID())
-    ->setValue(boolean(REVERSED_ID())->value());
-  anArcFeature->execute();
+  FeaturePtr anArcFeature = createArcFeature();
 
   myCenter.reset();
   myStart.reset();
@@ -392,3 +232,158 @@ void SketchPlugin_MacroArc::execute()
                                          false);
   }
 }
+
+FeaturePtr SketchPlugin_MacroArc::createArcFeature()
+{
+  FeaturePtr anArcFeature = sketch()->addFeature(SketchPlugin_Arc::ID());
+  std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+      anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID()))->setValue(myCenter);
+  std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+      anArcFeature->attribute(SketchPlugin_Arc::START_ID()))->setValue(myStart);
+  std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
+      anArcFeature->attribute(SketchPlugin_Arc::END_ID()))->setValue(myEnd);
+  anArcFeature->boolean(SketchPlugin_Arc::REVERSED_ID())
+                ->setValue(boolean(REVERSED_ID())->value());
+  anArcFeature->boolean(SketchPlugin_Arc::AUXILIARY_ID())
+                ->setValue(boolean(AUXILIARY_ID())->value());
+  anArcFeature->execute();
+
+  return anArcFeature;
+}
+
+void SketchPlugin_MacroArc::fillByCenterAndTwoPassed()
+{
+  AttributePoint2DPtr aCenterPointAttr =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(CENTER_POINT_ID()));
+  if (!aCenterPointAttr->isInitialized())
+      return;
+
+  AttributePoint2DPtr aStartPointAttr =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_POINT_ID()));
+  if (!aStartPointAttr->isInitialized())
+    return;
+
+  myCenter = aCenterPointAttr->pnt();
+  myStart = aStartPointAttr->pnt();
+  myEnd = myStart;
+
+  AttributePoint2DPtr anEndPointAttr =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(END_POINT_ID()));
+  if (!anEndPointAttr->isInitialized())
+    return;
+
+  GeomAPI_Circ2d aCircleForArc(myCenter, myStart);
+
+  // End point should be a projection on circle.
+  bool aWasBlocked = data()->blockSendAttributeUpdated(true);
+  projectPointOnCircle(anEndPointAttr, aCircleForArc);
+  data()->blockSendAttributeUpdated(aWasBlocked, false);
+  myEnd = anEndPointAttr->pnt();
+
+  // update the REVERSED flag
+  recalculateReversedFlagByEnd(aCircleForArc);
+}
+
+void SketchPlugin_MacroArc::recalculateReversedFlagByEnd(const GeomAPI_Circ2d& theCurrentCircular)
+{
+  double aParameterNew = 0.0;
+  if(theCurrentCircular.parameter(myEnd, paramTolerance, aParameterNew)) {
+    if(myParamBefore <= PI / 2.0 && aParameterNew >= PI * 1.5) {
+      boolean(REVERSED_ID())->setValue(true);
+    } else if(myParamBefore >= PI * 1.5 && aParameterNew <= PI / 2.0) {
+      boolean(REVERSED_ID())->setValue(false);
+    }
+  }
+  myParamBefore = aParameterNew;
+}
+
+void SketchPlugin_MacroArc::fillByThreePassedPoints()
+{
+  AttributePoint2DPtr aStartPointAttr =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(START_POINT_ID()));
+  if (!aStartPointAttr->isInitialized())
+    return;
+
+  AttributePoint2DPtr anEndPointAttr =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(END_POINT_ID()));
+  if (!anEndPointAttr->isInitialized())
+    return;
+
+  myStart = aStartPointAttr->pnt();
+  myEnd = anEndPointAttr->pnt();
+
+  AttributePoint2DPtr aPassedPointAttr =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(PASSED_POINT_ID()));
+  if (aPassedPointAttr->isInitialized()) {
+    std::shared_ptr<GeomAPI_Pnt2d> aPassedPnt;
+    std::shared_ptr<GeomAPI_Shape> aTangentCurve;
+    SketchPlugin_Tools::convertRefAttrToPointOrTangentCurve(
+        refattr(PASSED_POINT_REF_ID()), aPassedPointAttr, aTangentCurve, aPassedPnt);
+
+    std::shared_ptr<GeomAPI_Interface> aPassed;
+    if (aTangentCurve)
+      aPassed = aTangentCurve;
+    else
+      aPassed = aPassedPnt;
+
+    std::shared_ptr<GeomAPI_Ax3> anAxis = SketchPlugin_Sketch::plane(sketch());
+    GeomAPI_Circ2d aCircle(myStart, myEnd, aPassed, anAxis);
+    myCenter = aCircle.center();
+
+    recalculateReversedFlagByPassed(aCircle);
+  } else
+    myCenter.reset(new GeomAPI_Pnt2d(myStart->xy()->added(myEnd->xy())->multiplied(0.5)));
+}
+
+void SketchPlugin_MacroArc::recalculateReversedFlagByPassed(
+    const GeomAPI_Circ2d& theCurrentCircular)
+{
+  AttributePoint2DPtr aPassedAttr =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(PASSED_POINT_ID()));
+  std::shared_ptr<GeomAPI_Pnt2d> aPassed = theCurrentCircular.project(aPassedAttr->pnt());
+
+  double aEndParam, aPassedParam;
+  theCurrentCircular.parameter(myEnd, paramTolerance, aEndParam);
+  theCurrentCircular.parameter(aPassed, paramTolerance, aPassedParam);
+
+  if(aPassedParam > aEndParam)
+    boolean(REVERSED_ID())->setValue(true);
+  else
+    boolean(REVERSED_ID())->setValue(false);
+
+  myParamBefore = aEndParam;
+}
+
+void SketchPlugin_MacroArc::fillByTangentEdge()
+{
+  AttributeRefAttrPtr aTangentAttr = refattr(TANGENT_POINT_ID());
+  if (!aTangentAttr->isInitialized())
+    return;
+
+  AttributePoint2DPtr aTangentPointAttr =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aTangentAttr->attr());
+  if (!aTangentPointAttr->isInitialized())
+    return;
+
+  AttributePoint2DPtr anEndPointAttr =
+      std::dynamic_pointer_cast<GeomDataAPI_Point2D>(attribute(END_POINT_ID()));
+  if (!anEndPointAttr->isInitialized())
+    return;
+
+  myStart = aTangentPointAttr->pnt();
+  myEnd = anEndPointAttr->pnt();
+  if (myStart->isEqual(myEnd))
+    return;
+
+  // obtain a shape the tangent point belongs to
+  FeaturePtr aTangentFeature = ModelAPI_Feature::feature(aTangentPointAttr->owner());
+  std::shared_ptr<GeomAPI_Shape> aTangentShape = aTangentFeature->lastResult()->shape();
+
+  std::shared_ptr<GeomAPI_Ax3> anAxis = SketchPlugin_Sketch::plane(sketch());
+  GeomAPI_Circ2d aCircle(myStart, myEnd, aTangentShape, anAxis);
+  myCenter = aCircle.center();
+
+  // rebuild circle to set start point equal to zero parameter
+  aCircle = GeomAPI_Circ2d(myCenter, myStart);
+  recalculateReversedFlagByEnd(aCircle);
+}
index aec30931c7bc33191a98ea2a5ad5b4a1255cfe68..0a191342c251fcb4bd9ccd306bee2d84e839475d 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <GeomAPI_IPresentable.h>
 
+class GeomAPI_Circ2d;
 class GeomAPI_Pnt2d;
 
 /**\class SketchPlugin_MacroArc
@@ -70,16 +71,9 @@ class SketchPlugin_MacroArc: public SketchPlugin_SketchEntity,
   }
 
   /// Start 2D point of the arc
-  inline static const std::string& START_POINT_1_ID()
+  inline static const std::string& START_POINT_ID()
   {
-    static const std::string ID = "start_point_1";
-    return ID;
-  }
-
-  /// Start 2D point of the arc
-  inline static const std::string& START_POINT_2_ID()
-  {
-    static const std::string ID = "start_point_2";
+    static const std::string ID = "start_point";
     return ID;
   }
 
@@ -90,23 +84,9 @@ class SketchPlugin_MacroArc: public SketchPlugin_SketchEntity,
   }
 
   /// End 2D point of the arc
-  inline static const std::string& END_POINT_1_ID()
-  {
-    static const std::string ID = "end_point_1";
-    return ID;
-  }
-
-  /// End 2D point of the arc
-  inline static const std::string& END_POINT_2_ID()
+  inline static const std::string& END_POINT_ID()
   {
-    static const std::string ID = "end_point_2";
-    return ID;
-  }
-
-  /// End 2D point of the arc
-  inline static const std::string& END_POINT_3_ID()
-  {
-    static const std::string ID = "end_point_3";
+    static const std::string ID = "end_point";
     return ID;
   }
 
@@ -191,6 +171,19 @@ class SketchPlugin_MacroArc: public SketchPlugin_SketchEntity,
   /// Use plugin manager for features creation.
   SketchPlugin_MacroArc();
 
+private:
+  /// Set fields for center, start and end points
+  void fillByCenterAndTwoPassed();
+  /// Set fields for center, start and end points by selected passed points
+  void fillByThreePassedPoints();
+  /// Set fields for center, start and end points by selected tangent edge
+  void fillByTangentEdge();
+
+  FeaturePtr createArcFeature();
+
+  void recalculateReversedFlagByEnd(const GeomAPI_Circ2d& theCurrentCircular);
+  void recalculateReversedFlagByPassed(const GeomAPI_Circ2d& theCurrentCircular);
+
 private:
   std::shared_ptr<GeomAPI_Pnt2d> myCenter;
   std::shared_ptr<GeomAPI_Pnt2d> myStart;
index d1bbbd65acf8f8db22b176518eb565b851b3f4e7..7232a6c37fac9462dbdc21e355d865beabbc1c0b 100644 (file)
@@ -85,27 +85,6 @@ void SketchPlugin_MacroCircle::execute()
     createCircleByThreePoints();
 }
 
-static void convertToPointOrTangent(const AttributeRefAttrPtr&      theRefAttr,
-                                    const AttributePtr&             theBaseAttr,
-                                    std::shared_ptr<GeomAPI_Pnt2d>& thePassingPoint,
-                                    std::shared_ptr<GeomAPI_Shape>& theTangentCurve)
-{
-  AttributePtr anAttr = theBaseAttr;
-  if (theRefAttr->isObject()) {
-    FeaturePtr aTgFeature = ModelAPI_Feature::feature(theRefAttr->object());
-    if (aTgFeature) {
-      if (aTgFeature->getKind() != SketchPlugin_Point::ID()) {
-        theTangentCurve = aTgFeature->lastResult()->shape();
-        return;
-      }
-      anAttr = aTgFeature->attribute(SketchPlugin_Point::COORD_ID());
-    }
-  } else
-    anAttr = theRefAttr->attr();
-
-  thePassingPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr)->pnt();
-}
-
 void SketchPlugin_MacroCircle::createCircleByCenterAndPassed()
 {
   // Create circle feature.
@@ -169,7 +148,8 @@ std::shared_ptr<GeomAPI_Circ2d> SketchPlugin_MacroCircle::shapeByCenterAndPassed
       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aCenterAttr)->pnt();
   std::shared_ptr<GeomAPI_Pnt2d> aPassedPoint;
   std::shared_ptr<GeomAPI_Shape> aTangentCurve;
-  convertToPointOrTangent(aPassedRef, aPassedAttr, aPassedPoint, aTangentCurve);
+  SketchPlugin_Tools::convertRefAttrToPointOrTangentCurve(
+      aPassedRef, aPassedAttr, aTangentCurve, aPassedPoint);
 
   // Build a circle
   std::shared_ptr<GeomAPI_Circ2d> aCircle;
@@ -199,7 +179,8 @@ std::shared_ptr<GeomAPI_Circ2d> SketchPlugin_MacroCircle::shapeByThreePoints()
     // calculate circle parameters
     std::shared_ptr<GeomAPI_Pnt2d> aPassedPoint;
     std::shared_ptr<GeomAPI_Shape> aTangentCurve;
-    convertToPointOrTangent(aPassedRef, aPassedAttr, aPassedPoint, aTangentCurve);
+    SketchPlugin_Tools::convertRefAttrToPointOrTangentCurve(
+        aPassedRef, aPassedAttr, aTangentCurve, aPassedPoint);
 
     if (aPassedPoint)
       aPassedEntities[aPntIndex] = aPassedPoint;
@@ -233,7 +214,8 @@ std::shared_ptr<GeomAPI_Circ2d> SketchPlugin_MacroCircle::shapeByTwoPassedPoints
     // calculate circle parameters
     std::shared_ptr<GeomAPI_Pnt2d> aPassedPoint;
     std::shared_ptr<GeomAPI_Shape> aTangentCurve;
-    convertToPointOrTangent(aPassedRef, aPassedAttr, aPassedPoint, aTangentCurve);
+    SketchPlugin_Tools::convertRefAttrToPointOrTangentCurve(
+        aPassedRef, aPassedAttr, aTangentCurve, aPassedPoint);
 
     if (aPassedPoint) {
       aPassedEntities[aPntIndex] = aPassedPoint;
index 5758a6b7d25fb7a2b3563e2ee61b817492db3903..8e3dfabb404b9f881a8a97faec530495a21414b4 100644 (file)
@@ -199,4 +199,26 @@ void createConstraint(SketchPlugin_Feature* theFeature,
     }
   }
 }
+
+void convertRefAttrToPointOrTangentCurve(const AttributeRefAttrPtr&      theRefAttr,
+                                         const AttributePtr&             theDefaultAttr,
+                                         std::shared_ptr<GeomAPI_Shape>& theTangentCurve,
+                                         std::shared_ptr<GeomAPI_Pnt2d>& thePassingPoint)
+{
+  AttributePtr anAttr = theDefaultAttr;
+  if (theRefAttr->isObject()) {
+    FeaturePtr aTgFeature = ModelAPI_Feature::feature(theRefAttr->object());
+    if (aTgFeature) {
+      if (aTgFeature->getKind() != SketchPlugin_Point::ID()) {
+        theTangentCurve = aTgFeature->lastResult()->shape();
+        return;
+      }
+      anAttr = aTgFeature->attribute(SketchPlugin_Point::COORD_ID());
+    }
+  } else
+    anAttr = theRefAttr->attr();
+
+  thePassingPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr)->pnt();
+}
+
 } // namespace SketchPlugin_Tools
index 622b63d68705d6b06e44e28602d5e4e51a0ee905..cecc946fc6b4b00574fd1a5d52d68133af6e74d0 100644 (file)
@@ -11,6 +11,7 @@
 
 #include <ModelAPI_Feature.h>
 #include <ModelAPI_Attribute.h>
+#include <ModelAPI_AttributeRefAttr.h>
 #include <GeomDataAPI_Point2D.h>
 
 class SketchPlugin_Feature;
@@ -51,6 +52,16 @@ void createConstraint(SketchPlugin_Feature* theFeature,
                       const AttributePtr theAttr,
                       const ObjectPtr theObject,
                       const bool theIsCanBeTangent);
+
+/// Creates passing point or tangent curve basing on the given attributes are initialized.
+/// \param[in]  theRefAttr       prefered attribute to be converted
+/// \param[in]  theDefaultAttr   default attribute if theRefAttr is not initialized
+/// \param[out] theTangentCurve  tangent curve if theRefAttr refers to an edge
+/// \param[out] thePassingPoint  passing point if theRefAttr does not refer to an edge
+void convertRefAttrToPointOrTangentCurve(const AttributeRefAttrPtr&      theRefAttr,
+                                         const AttributePtr&             theDefaultAttr,
+                                         std::shared_ptr<GeomAPI_Shape>& theTangentCurve,
+                                         std::shared_ptr<GeomAPI_Pnt2d>& thePassingPoint);
 }; // namespace SketchPlugin_Tools
 
 #endif // SKETCHPLUGIN_TOOLS_H_
\ No newline at end of file
index 7b929019cb77f29024f0d876f4b0699acb66d443..bffe18309ecba4a30db55278cd4f040062c4ed70 100755 (executable)
@@ -14,6 +14,7 @@
 #include "SketchPlugin_ConstraintTangent.h"
 #include "SketchPlugin_Fillet.h"
 #include "SketchPlugin_Line.h"
+#include "SketchPlugin_MacroArc.h"
 #include "SketchPlugin_MacroCircle.h"
 #include "SketchPlugin_Point.h"
 #include "SketchPlugin_Sketch.h"
@@ -1110,11 +1111,12 @@ bool SketchPlugin_CirclePassedPointValidator::isValid(
 
 bool SketchPlugin_ThirdPointValidator::isValid(
     const AttributePtr& theAttribute,
-    const std::list<std::string>&,
+    const std::list<std::string>& theArguments,
     Events_InfoMessage& theError) const
 {
   FeaturePtr anOwner = ModelAPI_Feature::feature(theAttribute->owner());
-  return arePointsNotOnLine(anOwner, theError) && arePointsNotSeparated(anOwner, theError);
+  return arePointsNotOnLine(anOwner, theError) &&
+         arePointsNotSeparated(anOwner, theArguments, theError);
 }
 
 static std::shared_ptr<GeomAPI_Pnt2d> toPoint(const FeaturePtr& theMacroCircle,
@@ -1156,6 +1158,32 @@ static std::shared_ptr<GeomAPI_Pnt2d> toPoint(const FeaturePtr& theMacroCircle,
   return aPoint;
 }
 
+static void threePointsOfFeature(const FeaturePtr& theMacroFeature,
+                                 std::shared_ptr<GeomAPI_Pnt2d> thePoints[3])
+{
+  if (theMacroFeature->getKind() == SketchPlugin_MacroCircle::ID()) {
+    thePoints[0] = toPoint(theMacroFeature,
+          SketchPlugin_MacroCircle::FIRST_POINT_ID(),
+          SketchPlugin_MacroCircle::FIRST_POINT_REF_ID());
+    thePoints[1] = toPoint(theMacroFeature,
+          SketchPlugin_MacroCircle::SECOND_POINT_ID(),
+          SketchPlugin_MacroCircle::SECOND_POINT_REF_ID());
+    thePoints[2] = toPoint(theMacroFeature,
+          SketchPlugin_MacroCircle::THIRD_POINT_ID(),
+          SketchPlugin_MacroCircle::THIRD_POINT_REF_ID());
+  } else if (theMacroFeature->getKind() == SketchPlugin_MacroArc::ID()) {
+    thePoints[0] = toPoint(theMacroFeature,
+          SketchPlugin_MacroArc::START_POINT_ID(),
+          SketchPlugin_MacroArc::START_POINT_REF_ID());
+    thePoints[1] = toPoint(theMacroFeature,
+          SketchPlugin_MacroArc::END_POINT_ID(),
+          SketchPlugin_MacroArc::END_POINT_REF_ID());
+    thePoints[2] = toPoint(theMacroFeature,
+          SketchPlugin_MacroArc::PASSED_POINT_ID(),
+          SketchPlugin_MacroArc::PASSED_POINT_REF_ID());
+  }
+}
+
 static bool isPointsOnLine(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint1,
                            const std::shared_ptr<GeomAPI_Pnt2d>& thePoint2,
                            const std::shared_ptr<GeomAPI_Pnt2d>& thePoint3)
@@ -1196,23 +1224,16 @@ static bool isOnSameSide(const std::shared_ptr<GeomAPI_Circ>& theCircle,
 }
 
 bool SketchPlugin_ThirdPointValidator::arePointsNotOnLine(
-    const FeaturePtr& theMacroCircle,
+    const FeaturePtr& theMacroFeature,
     Events_InfoMessage& theError) const
 {
   static const std::string aErrorPointsOnLine(
       "Selected points are on the same line");
 
-  std::shared_ptr<GeomAPI_Pnt2d> aFirstPoint = toPoint(theMacroCircle,
-        SketchPlugin_MacroCircle::FIRST_POINT_ID(),
-        SketchPlugin_MacroCircle::FIRST_POINT_REF_ID());
-  std::shared_ptr<GeomAPI_Pnt2d> aSecondPoint = toPoint(theMacroCircle,
-        SketchPlugin_MacroCircle::SECOND_POINT_ID(),
-        SketchPlugin_MacroCircle::SECOND_POINT_REF_ID());
-  std::shared_ptr<GeomAPI_Pnt2d> aThirdPoint = toPoint(theMacroCircle,
-        SketchPlugin_MacroCircle::THIRD_POINT_ID(),
-        SketchPlugin_MacroCircle::THIRD_POINT_REF_ID());
-
-  if (isPointsOnLine(aFirstPoint, aSecondPoint, aThirdPoint)) {
+  std::shared_ptr<GeomAPI_Pnt2d> aPoints[3];
+  threePointsOfFeature(theMacroFeature, aPoints);
+
+  if (isPointsOnLine(aPoints[0], aPoints[1], aPoints[2])) {
     theError = aErrorPointsOnLine;
     return false;
   }
@@ -1220,26 +1241,22 @@ bool SketchPlugin_ThirdPointValidator::arePointsNotOnLine(
 }
 
 bool SketchPlugin_ThirdPointValidator::arePointsNotSeparated(
-    const FeaturePtr& theMacroCircle,
+    const FeaturePtr& theMacroFeature,
+    const std::list<std::string>& theArguments,
     Events_InfoMessage& theError) const
 {
   static const std::string aErrorPointsApart(
       "Selected entity is lying between first two points");
 
-  AttributeRefAttrPtr aThirdPointRef =
-      theMacroCircle->refattr(SketchPlugin_MacroCircle::THIRD_POINT_REF_ID());
+  AttributeRefAttrPtr aThirdPointRef = theMacroFeature->refattr(theArguments.front());
   FeaturePtr aRefByThird;
   if (aThirdPointRef->isObject())
     aRefByThird = ModelAPI_Feature::feature(aThirdPointRef->object());
   if (!aRefByThird)
     return true;
 
-  std::shared_ptr<GeomAPI_Pnt2d> aFirstPoint = toPoint(theMacroCircle,
-        SketchPlugin_MacroCircle::FIRST_POINT_ID(),
-        SketchPlugin_MacroCircle::FIRST_POINT_REF_ID());
-  std::shared_ptr<GeomAPI_Pnt2d> aSecondPoint = toPoint(theMacroCircle,
-        SketchPlugin_MacroCircle::SECOND_POINT_ID(),
-        SketchPlugin_MacroCircle::SECOND_POINT_REF_ID());
+  std::shared_ptr<GeomAPI_Pnt2d> aPoints[3];
+  threePointsOfFeature(theMacroFeature, aPoints);
 
   std::shared_ptr<GeomAPI_Edge> aThirdShape =
       std::dynamic_pointer_cast<GeomAPI_Edge>(aRefByThird->lastResult()->shape());
@@ -1247,9 +1264,9 @@ bool SketchPlugin_ThirdPointValidator::arePointsNotSeparated(
     return true;
 
   SketchPlugin_Sketch* aSketch =
-      std::dynamic_pointer_cast<SketchPlugin_Feature>(theMacroCircle)->sketch();
-  std::shared_ptr<GeomAPI_Pnt> aFirstPnt3D = aSketch->to3D(aFirstPoint->x(), aFirstPoint->y());
-  std::shared_ptr<GeomAPI_Pnt> aSecondPnt3D = aSketch->to3D(aSecondPoint->x(), aSecondPoint->y());
+      std::dynamic_pointer_cast<SketchPlugin_Feature>(theMacroFeature)->sketch();
+  std::shared_ptr<GeomAPI_Pnt> aFirstPnt3D = aSketch->to3D(aPoints[0]->x(), aPoints[0]->y());
+  std::shared_ptr<GeomAPI_Pnt> aSecondPnt3D = aSketch->to3D(aPoints[1]->x(), aPoints[1]->y());
 
   bool isOk = true;
   if (aThirdShape->isLine())
index 3dfd9398d231e6d490054359e59f4680ee1dd0c6..441bd1793656215034a1b77db4b79416984035a3 100644 (file)
@@ -344,17 +344,18 @@ class SketchPlugin_ThirdPointValidator : public ModelAPI_AttributeValidator
   //! \param theArguments arguments of the attribute
   //! \param theError error message
   virtual bool isValid(const AttributePtr& theAttribute,
-                       const std::list<std::string>&,
+                       const std::list<std::string>& theArguments,
                        Events_InfoMessage& theError) const;
 
 private:
   //! returns true if three points have not been placed on the same line
-  bool arePointsNotOnLine(const FeaturePtr& theMacroCircle,
+  bool arePointsNotOnLine(const FeaturePtr& theMacroFeature,
                           Events_InfoMessage& theError) const;
 
   //! returns true if the first two points have not been separated
   //! by a feature referred by thrid point
-  bool arePointsNotSeparated(const FeaturePtr& theMacroCircle,
+  bool arePointsNotSeparated(const FeaturePtr& theMacroFeature,
+                             const std::list<std::string>& theArguments,
                              Events_InfoMessage& theError) const;
 };
 
index 646060b45e0e3b5ff455ca04e9bdb49d0d21e9ac..416f478d370ea9460c3ac876fb2fdb1809a90bb4 100644 (file)
                                      accept_expressions="0"
                                      enable_value="enable_by_preferences">
               <validator id="SketchPlugin_DifferentReference" parameters="first_point_ref,second_point_ref,third_point_ref"/>
-              <validator id="SketchPlugin_ThirdPointValidator"/>
+              <validator id="SketchPlugin_ThirdPointValidator" parameters="third_point_ref"/>
             </sketch-2dpoint_selector>
             <validator id="GeomValidators_Different" parameters="first_point_ref,second_point_ref,third_point_ref"/>
           </box>
                                      tooltip="Center of a circle"
                                      accept_expressions="0"
                                      enable_value="enable_by_preferences" />
-            <sketch-2dpoint_selector id="start_point_1"
+            <sketch-2dpoint_selector id="start_point"
                                      reference_attribute="start_point_ref"
                                      title="Start point"
                                      tooltip="Start point"
                                      accept_expressions="0"
                                      enable_value="enable_by_preferences"/>
-            <sketch-2dpoint_selector id="end_point_1"
+            <sketch-2dpoint_selector id="end_point"
                                      reference_attribute="end_point_ref"
                                      title="End point"
                                      tooltip="End point"
                                      accept_expressions="0"
                                      enable_value="enable_by_preferences"/>
-            <validator id="GeomValidators_Different" parameters="center_point,start_point_1,end_point_1"/>
+            <validator id="GeomValidators_Different" parameters="center_point,start_point,end_point"/>
           </box>
           <box id="by_three_points"
                icon="icons/Sketch/arc_3pt_32x32.png"
                title="Three points on arc">
-            <sketch-2dpoint_selector id="start_point_2"
+            <sketch-2dpoint_selector id="start_point"
                                      reference_attribute="start_point_ref"
                                      title="Start point"
                                      tooltip="Start point"
                                      accept_expressions="0"
                                      enable_value="enable_by_preferences"/>
-            <sketch-2dpoint_selector id="end_point_2"
+            <sketch-2dpoint_selector id="end_point"
                                      reference_attribute="end_point_ref"
                                      title="End point"
                                      tooltip="End point"
                                      accept_expressions="0"
-                                     enable_value="enable_by_preferences"/>
+                                     enable_value="enable_by_preferences">
+              <validator id="SketchPlugin_DifferentReference" parameters="start_point_ref,end_point_ref"/>
+            </sketch-2dpoint_selector>
             <sketch-2dpoint_selector id="passed_point"
                                      reference_attribute="passed_point_ref"
                                      title="Passed point"
                                      tooltip="Passed point"
                                      accept_expressions="0"
-                                     enable_value="enable_by_preferences"/>
-            <validator id="GeomValidators_Different" parameters="start_point_2,end_point_2,passed_point"/>
+                                     enable_value="enable_by_preferences">
+              <validator id="SketchPlugin_DifferentReference" parameters="start_point_ref,end_point_ref,passed_point_ref"/>
+              <validator id="SketchPlugin_ThirdPointValidator" parameters="passed_point_ref"/>
+            </sketch-2dpoint_selector>
+            <validator id="GeomValidators_Different" parameters="start_point,end_point,passed_point"/>
           </box>
           <box id="by_tangent_edge"
                icon="icons/Sketch/arc_tang_32x32.png"
                                    shape_types="vertex">
               <validator id="SketchPlugin_ArcTangentPoint"/>
             </sketch_shape_selector>
-            <sketch-2dpoint_selector id="end_point_3"
+            <sketch-2dpoint_selector id="end_point"
                                      reference_attribute="end_point_ref"
                                      title="End point"
                                      tooltip="End point"