Salome HOME
Issue #2024: Redesign of circle and arc of circle
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_Arc.cpp
index e752c7be1f45e5a92b2b6cb08a3b8a623173cea3..9ebf16eb34205e343f114a511be0a5eb0e9ba60f 100644 (file)
@@ -192,13 +192,52 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID)
         aCirc->parameter(anEdge->lastPoint(), paramTolerance, anEndParam);
         aWasBlocked = data()->blockSendAttributeUpdated(true);
         if(aStartParam < aMidParam && aMidParam < anEndParam) {
-          setReversed(true);
-        } else {
           setReversed(false);
+        } else {
+          setReversed(true);
         }
         data()->blockSendAttributeUpdated(aWasBlocked, false);
       }
     }
+  } else if(theID == CENTER_ID() || theID == START_ID() || theID == END_ID()) {
+    if(!aCenterAttr->isInitialized()
+      || !aStartAttr->isInitialized()
+      || !anEndAttr->isInitialized()) {
+      return;
+    }
+    std::shared_ptr<GeomAPI_Pnt2d> aCenter = aCenterAttr->pnt();
+    std::shared_ptr<GeomAPI_Pnt2d> aStart = aStartAttr->pnt();
+    std::shared_ptr<GeomAPI_Pnt2d> anEnd = anEndAttr->pnt();
+    double aRadius = aCenter->distance(aStart);
+    if (aRadius < tolerance)
+      return;
+    std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(new GeomAPI_Circ2d(aCenter, aStart));
+
+    bool aWasBlocked = data()->blockSendAttributeUpdated(true);
+    // The Arc end point is projected
+    // on the circle formed by center and start points
+    std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(anEnd);
+    if (aProjection && anEnd->distance(aProjection) > tolerance) {
+      anEndAttr->setValue(aProjection);
+      anEnd = aProjection;
+    }
+    data()->blockSendAttributeUpdated(aWasBlocked, false);
+
+    double aParameterNew = 0.0;
+    if(aCircleForArc->parameter(anEnd, paramTolerance, aParameterNew)) {
+      bool aWasBlocked = data()->blockSendAttributeUpdated(true);
+      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);
+        }
+      }
+      data()->blockSendAttributeUpdated(aWasBlocked, false);
+    }
+    myParamBefore = aParameterNew;
   }
 
   double aRadius = 0;