Salome HOME
Correct processing of the fixed arc in PlaneGCS (issue #1280)
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_Arc.cpp
index b9c73ef85ebcac8b00fe9e58b0ad2c7d41caa52d..2725d87904146bf25a72cdd2f73457a47c6bebea 100644 (file)
@@ -382,8 +382,13 @@ static inline void calculatePassedPoint(
       theStartPoint->xy()->decreased(theCenter->xy())));
   std::shared_ptr<GeomAPI_Dir2d> aEndDir(new GeomAPI_Dir2d(
       theEndPoint->xy()->decreased(theCenter->xy())));
-  std::shared_ptr<GeomAPI_Dir2d> aMidDir(new GeomAPI_Dir2d(
-      aStartDir->xy()->added(aEndDir->xy())));
+  std::shared_ptr<GeomAPI_XY> aMidDirXY = aStartDir->xy()->added(aEndDir->xy());
+  if (aMidDirXY->dot(aMidDirXY) < tolerance * tolerance) {
+    // start and end directions are opposite, so middle direction will be orthogonal
+    aMidDirXY->setX(-aStartDir->y());
+    aMidDirXY->setY(aStartDir->x());
+  }
+  std::shared_ptr<GeomAPI_Dir2d> aMidDir(new GeomAPI_Dir2d(aMidDirXY));
   if ((aStartDir->cross(aMidDir) > 0) ^ !theArcReversed)
     aMidDir->reverse();
 
@@ -394,8 +399,6 @@ static inline void calculatePassedPoint(
 
 void SketchPlugin_Arc::updateDependentAttributes()
 {
-  data()->blockSendAttributeUpdated(true);
-
   std::shared_ptr<GeomDataAPI_Point2D> aCenterAttr = std::dynamic_pointer_cast<
       GeomDataAPI_Point2D>(data()->attribute(CENTER_ID()));
   std::shared_ptr<GeomDataAPI_Point2D> aStartAttr = std::dynamic_pointer_cast<
@@ -409,12 +412,19 @@ void SketchPlugin_Arc::updateDependentAttributes()
   AttributeDoublePtr anAngleAttr = std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(
       data()->attribute(ANGLE_ID()));
 
+  if (!aPassedPoint)
+    return;
+
+  data()->blockSendAttributeUpdated(true);
+
   calculatePassedPoint(aCenterAttr->pnt(), aStartAttr->pnt(), anEndAttr->pnt(),
                        isReversed(), aPassedPoint);
-  std::shared_ptr<GeomAPI_Circ2d> aCircle(
-      new GeomAPI_Circ2d(aStartAttr->pnt(), anEndAttr->pnt(), aPassedPoint->pnt()));
-  calculateArcAngleRadius(aCircle, aStartAttr->pnt(), anEndAttr->pnt(), aPassedPoint->pnt(),
-                          anAngleAttr, aRadiusAttr);
+  if (aRadiusAttr && anAngleAttr) {
+    std::shared_ptr<GeomAPI_Circ2d> aCircle(
+        new GeomAPI_Circ2d(aStartAttr->pnt(), anEndAttr->pnt(), aPassedPoint->pnt()));
+    calculateArcAngleRadius(aCircle, aStartAttr->pnt(), anEndAttr->pnt(), aPassedPoint->pnt(),
+                            anAngleAttr, aRadiusAttr);
+  }
   data()->blockSendAttributeUpdated(false);
 }
 
@@ -513,6 +523,8 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID)
   if (theID == CENTER_ID()) {
     if (!isFeatureValid())
       return;
+    if (aCenterAttr->pnt()->distance(aStartAttr->pnt()) < tolerance)
+      return;
     data()->blockSendAttributeUpdated(true);
     // compute and change the arc end point
     std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(