Salome HOME
Issue #262: the updated points of arc now projected back to initial circle
authormpv <mikhail.ponikarov@opencascade.com>
Fri, 28 Nov 2014 08:22:38 +0000 (11:22 +0300)
committermpv <mikhail.ponikarov@opencascade.com>
Fri, 28 Nov 2014 08:22:38 +0000 (11:22 +0300)
src/ModelAPI/ModelAPI_Result.h
src/SketchPlugin/SketchPlugin_Arc.cpp
src/SketchPlugin/SketchPlugin_Arc.h
src/SketchPlugin/Test/TestConstraintRadius.py
src/SketchPlugin/Test/TestSketchArcCircle.py

index 91304744e457755086d2b4a93fb78722b0a24b76..cde5082547158b3d94ef9b179ea229a23c51ee49 100644 (file)
@@ -6,7 +6,7 @@
 #define ModelAPI_Result_H_
 
 #include "ModelAPI_Object.h"
-#include "GeomAPI_Shape.h"
+#include <GeomAPI_Shape.h>
 
 class ModelAPI_Feature;
 
index 9f717bd702ff3279625c7fc1717d464c347d3aaa..0ae869322636f9d64f76240aa5a1bc96fc5fee13 100644 (file)
@@ -23,6 +23,8 @@ const double tolerance = 1e-7;
 SketchPlugin_Arc::SketchPlugin_Arc()
     : SketchPlugin_Feature()
 {
+  myStartUpdate = false;
+  myEndUpdate = false;
 }
 
 void SketchPlugin_Arc::initAttributes()
@@ -42,10 +44,10 @@ void SketchPlugin_Arc::execute()
   if (aSketch && isFeatureValid()) {
     // compute a circle point in 3D view
     std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
-        GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::CENTER_ID()));
+        GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
     // compute the arc start point
     std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
-        GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::START_ID()));
+        GeomDataAPI_Point2D>(data()->attribute(START_ID()));
 
     std::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y()));
     // make a visible point
@@ -59,30 +61,29 @@ void SketchPlugin_Arc::execute()
     // make a visible circle
     std::shared_ptr<GeomDataAPI_Dir> aNDir = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
         aSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
-    bool aHasPlane = aNDir && !(aNDir->x() == 0 && aNDir->y() == 0 && aNDir->z() == 0);
-    if (aHasPlane) {
-      std::shared_ptr<GeomAPI_Dir> aNormal = aNDir->dir();
-      std::shared_ptr<GeomAPI_Pnt> aStartPoint(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
-
-      // compute and change the arc end point
-      std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = std::dynamic_pointer_cast<
-          GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::END_ID()));
-      std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
-          new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
-      std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEndAttr->pnt());
-      if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance)
-        anEndAttr->setValue(aProjection);
-      std::shared_ptr<GeomAPI_Pnt> aEndPoint(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
-
-      std::shared_ptr<GeomAPI_Shape> aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc(
-          aCenter, aStartPoint, aEndPoint, aNormal);
-      if (aCircleShape) {
-        std::shared_ptr<ModelAPI_ResultConstruction> aConstr2 = document()->createConstruction(
-            data(), 1);
-        aConstr2->setShape(aCircleShape);
-        aConstr2->setIsInHistory(false);
-        setResult(aConstr2, 1);
-      }
+    std::shared_ptr<GeomAPI_Dir> aNormal = aNDir->dir();
+    std::shared_ptr<GeomAPI_Pnt> aStartPoint(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
+
+    // compute and change the arc end point
+    std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = std::dynamic_pointer_cast<
+        GeomDataAPI_Point2D>(data()->attribute(END_ID()));
+    /* must be automatically done in attributeChanged
+    std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
+        new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
+    std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEndAttr->pnt());
+    if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance)
+      anEndAttr->setValue(aProjection);
+    */
+    std::shared_ptr<GeomAPI_Pnt> aEndPoint(aSketch->to3D(anEndAttr->x(), anEndAttr->y()));
+
+    std::shared_ptr<GeomAPI_Shape> aCircleShape = GeomAlgoAPI_EdgeBuilder::lineCircleArc(
+        aCenter, aStartPoint, aEndPoint, aNormal);
+    if (aCircleShape) {
+      std::shared_ptr<ModelAPI_ResultConstruction> aConstr2 = document()->createConstruction(
+          data(), 1);
+      aConstr2->setShape(aCircleShape);
+      aConstr2->setIsInHistory(false);
+      setResult(aConstr2, 1);
     }
   }
 }
@@ -95,7 +96,7 @@ AISObjectPtr SketchPlugin_Arc::getAISObject(AISObjectPtr thePrevious)
     if (!isFeatureValid()) {
       // compute a circle point in 3D view
       std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
-          GeomDataAPI_Point2D>(data()->attribute(SketchPlugin_Arc::CENTER_ID()));
+          GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
       if (aCenterAttr->isInitialized()) {
         std::shared_ptr<GeomAPI_Pnt> aCenter(aSketch->to3D(aCenterAttr->x(), aCenterAttr->y()));
 
@@ -146,6 +147,8 @@ void SketchPlugin_Arc::move(double theDeltaX, double theDeltaY)
       aData->attribute(SketchPlugin_Arc::CENTER_ID()));
   aPoint1->move(theDeltaX, theDeltaY);
 
+  myStartUpdate = true;
+  myEndUpdate = true;
   std::shared_ptr<GeomDataAPI_Point2D> aPoint2 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
       aData->attribute(SketchPlugin_Arc::START_ID()));
   aPoint2->move(theDeltaX, theDeltaY);
@@ -153,6 +156,8 @@ void SketchPlugin_Arc::move(double theDeltaX, double theDeltaY)
   std::shared_ptr<GeomDataAPI_Point2D> aPoint3 = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
       aData->attribute(SketchPlugin_Arc::END_ID()));
   aPoint3->move(theDeltaX, theDeltaY);
+  myStartUpdate = false;
+  myEndUpdate = false;
 }
 
 double SketchPlugin_Arc::distanceToPoint(const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
@@ -194,3 +199,40 @@ bool SketchPlugin_Arc::isFeatureValid()
 
   return aCenterAttr->isInitialized() && aStartAttr->isInitialized() && anEndAttr->isInitialized();
 }
+
+void SketchPlugin_Arc::attributeChanged(const std::string& theID)
+{
+  std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
+      GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
+  if (!aCenterAttr->isInitialized())
+    return;
+  std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
+      GeomDataAPI_Point2D>(data()->attribute(START_ID()));
+  if (!aStartAttr->isInitialized())
+    return;
+  std::shared_ptr<GeomDataAPI_Point2D> anEndAttr = std::dynamic_pointer_cast<
+      GeomDataAPI_Point2D>(data()->attribute(END_ID()));
+  if (!anEndAttr->isInitialized())
+    return;
+
+  // update the points in accordance to the changed point changes
+  if (theID == END_ID() && !myEndUpdate) {
+    myEndUpdate = true;
+    // compute and change the arc end point
+    std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
+        new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
+    std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEndAttr->pnt());
+    if (aProjection && anEndAttr->pnt()->distance(aProjection) > tolerance)
+      anEndAttr->setValue(aProjection);
+    myEndUpdate = false;
+  } else if (theID == START_ID() && !myStartUpdate) {
+    myStartUpdate = true;
+    // compute and change the arc end point
+    std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
+        new GeomAPI_Circ2d(aCenterAttr->pnt(), anEndAttr->pnt()));
+    std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(aStartAttr->pnt());
+    if (aProjection && aStartAttr->pnt()->distance(aProjection) > tolerance)
+      aStartAttr->setValue(aProjection);
+    myStartUpdate = false;
+  }
+}
index 3958adbd743a464b3614b0e8df0b25e967e63a5d..e03da285aa83cccf9990578f81e7cc0674f662f7 100644 (file)
  */
 class SketchPlugin_Arc : public SketchPlugin_Feature, public GeomAPI_IPresentable
 {
+  /// to avoid cyclic dependencies in automatic updates: they mean that 
+  /// update is performed right now and automatic updates are not needed
+  bool myStartUpdate, myEndUpdate;
+
  public:
   /// Arc feature kind
   inline static const std::string& ID()
@@ -62,6 +66,10 @@ class SketchPlugin_Arc : public SketchPlugin_Feature, public GeomAPI_IPresentabl
   /// Request for initialization of data model of the feature: adding all attributes
   SKETCHPLUGIN_EXPORT virtual void initAttributes();
 
+  /// Called on change of any argument-attribute of this object
+  /// \param theID identifier of changed attribute
+  SKETCHPLUGIN_EXPORT virtual void attributeChanged(const std::string& theID);
+
   /// Returns the AIS preview
   virtual AISObjectPtr getAISObject(AISObjectPtr thePrevious);
 
index afe60ba4f4971bb09d57c0ea3e9d08f63e28533e..cc71a412ff7b5cc2904f46584ffebbc896614d14 100644 (file)
@@ -107,12 +107,13 @@ assert (anArcPrevEndPointX == 50.)
 assert (anArcPrevEndPointY == 0.)
 # Move one point of the arc
 aSession.startOperation()
-anArcStartPoint.setValue(0., 60)
+anArcStartPoint.setValue(0, 60)
 aSession.finishOperation()
 assert (anArcCentr.x() == 10.)
 assert (anArcCentr.y() == 10.)
-assert (anArcEndPoint.x() != anArcPrevEndPointX)
-assert (anArcEndPoint.y() != anArcPrevEndPointY)
+# MPV: it just projects back to the circle the moved start point
+#assert (anArcEndPoint.x() != anArcPrevEndPointX)
+#assert (anArcEndPoint.y() != anArcPrevEndPointY)
 #=========================================================================
 # 4. Move the centr or the point of the arc
 # 5. Check radius is the same
index 8ce7a3186b3bef32c439dceab06b871ab1098e45..c59725e218a969c2fe77015a48e7cc1edd79edba 100644 (file)
@@ -86,31 +86,33 @@ assert (anArcEndPoint.y() == 0.0)
 # 1. Move whole arc
 # 2. Change the start point
 #=========================================================================
-aSession.startOperation()
-deltaX, deltaY = 5., 10.
-anArcCentr.setValue(anArcCentr.x() + deltaX, anArcCentr.y() + deltaY)
-anArcStartPoint.setValue(
-    anArcStartPoint.x() + deltaX, anArcStartPoint.y() + deltaY)
-anArcEndPoint.setValue(anArcEndPoint.x() + deltaX, anArcEndPoint.y() + deltaY)
-aSession.finishOperation()
-assert (anArcCentr.x() == 15)
-assert (anArcCentr.y() == 20)
-assert (anArcStartPoint.x() == 5)
-assert (anArcStartPoint.y() == 60)
-assert (anArcEndPoint.x() == 55)
-assert (anArcEndPoint.y() == 10)
-# Change the start point
-aSession.startOperation()
-anArcStartPoint.setValue(anArcStartPoint.x() + deltaX, anArcStartPoint.y())
-aPrevEndPointX = anArcEndPoint.x()
-aPrevEndPointY = anArcEndPoint.y()
-aSession.finishOperation()
-assert (anArcCentr.x() == 15)
-assert (anArcCentr.y() == 20)
-assert (anArcStartPoint.x() == 10)
-assert (anArcStartPoint.y() == 60)
-assert (anArcEndPoint.x() != aPrevEndPointX)
-assert (anArcEndPoint.y() != aPrevEndPointY)
+
+# MPV: movement now is done little bit in different way, just move points causes changing them
+#  back t okeep the radius unchanged (projection back to the initial circle)
+#aSession.startOperation()
+#deltaX, deltaY = 5., 10.
+#anArcCentr.setValue(anArcCentr.x() + deltaX, anArcCentr.y() + deltaY)
+#anArcStartPoint.setValue(
+#    anArcStartPoint.x() + deltaX, anArcStartPoint.y() + deltaY)
+#anArcEndPoint.setValue(anArcEndPoint.x() + deltaX, anArcEndPoint.y() + deltaY)
+#aSession.finishOperation()
+#assert (anArcCentr.y() == 20)
+#assert (anArcStartPoint.x() == 5)
+#assert (anArcStartPoint.y() == 60)
+#assert (anArcEndPoint.x() == 55)
+#assert (anArcEndPoint.y() == 10)
+## Change the start point
+#aSession.startOperation()
+#anArcStartPoint.setValue(anArcStartPoint.x() + deltaX, anArcStartPoint.y())
+#aPrevEndPointX = anArcEndPoint.x()
+#aPrevEndPointY = anArcEndPoint.y()
+#aSession.finishOperation()
+#assert (anArcCentr.x() == 15)
+#assert (anArcCentr.y() == 20)
+#assert (anArcStartPoint.x() == 10)
+#assert (anArcStartPoint.y() == 60)
+#assert (anArcEndPoint.x() != aPrevEndPointX)
+#assert (anArcEndPoint.y() != aPrevEndPointY)
 #=========================================================================
 # Check results of the Arc
 #=========================================================================