Salome HOME
Issue #1739: Naming on faces not correct
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_Arc.cpp
index b4666ebca7f75e60b967030702ee6b60b2976fa5..07c4d3ee5649abb0ab136380105425b5a471c4a3 100644 (file)
@@ -145,20 +145,8 @@ void SketchPlugin_Arc::execute()
     AttributeBooleanPtr isInversed =
         std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(attribute(INVERSED_ID()));
 
-    std::shared_ptr<GeomAPI_Dir> anXDir(new GeomAPI_Dir(aStartPoint->xyz()->decreased(aCenter->xyz())));
-    std::shared_ptr<GeomAPI_Ax2> anAx2(new GeomAPI_Ax2(aCenter, aNormal, anXDir));
-    std::shared_ptr<GeomAPI_Circ> aCirc(new GeomAPI_Circ(anAx2, aCenter->distance(aStartPoint)));
-    double aParameterNew = 0.0;
-    if(aCirc->parameter(aEndPoint, paramTolerance, aParameterNew)) {
-      if(0 <= myParamBefore && myParamBefore <= PI / 2.0
-        && PI * 1.5 <= aParameterNew && aParameterNew <= PI * 2.0) {
-          isInversed->setValue(true);
-      } else if(PI * 1.5 <= myParamBefore && myParamBefore <= PI * 2.0
-        && 0 <= aParameterNew && aParameterNew <= PI / 2.0) {
-          isInversed->setValue(false);
-      }
-    }
-    myParamBefore = aParameterNew;
+    // compute end parameter
+    aCircleForArc->parameter(anEndAttr->pnt(), paramTolerance, myParamBefore);
 
     std::shared_ptr<GeomAPI_Shape> aCircleShape;
     if(!isInversed->value()) {
@@ -208,26 +196,30 @@ AISObjectPtr SketchPlugin_Arc::getAISObject(AISObjectPtr thePrevious)
             std::shared_ptr<GeomAPI_Pnt> aStartPoint(aSketch->to3D(aStartAttr->x(), aStartAttr->y()));
             std::shared_ptr<GeomAPI_Pnt> aEndPoint = aStartPoint;
             if (aTypeAttr && aTypeAttr->isInitialized() &&
-                aTypeAttr->value() == ARC_TYPE_THREE_POINTS() && aEndAttr->isInitialized() &&
-                aEndAttr->pnt()->distance(aStartAttr->pnt()) > tolerance) {
-              aEndPoint = aSketch->to3D(aEndAttr->x(), aEndAttr->y());
-              std::shared_ptr<GeomDataAPI_Point2D> aPassedAttr = 
-                std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(PASSED_POINT_ID()));
-              if (!aPassedAttr->isInitialized()) { // calculate the appropriate center for the presentation
-                // check that center is bad for the current start and end and must be recomputed
-                std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(new GeomAPI_Circ2d(
-                  aCenterAttr->pnt(), aStartAttr->pnt()));
-                std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(aEndAttr->pnt());
-                if (!aProjection.get() || aEndAttr->pnt()->distance(aProjection) > tolerance) {
-                  std::shared_ptr<GeomAPI_XY> aDir = 
-                    aEndAttr->pnt()->xy()->decreased(aStartAttr->pnt()->xy())->multiplied(0.5);
-                  double x = aDir->x();
-                  double y = aDir->y();
-                  aDir->setX(x - y);
-                  aDir->setY(y + x);
-                  std::shared_ptr<GeomAPI_XY> aCenterXY = aStartAttr->pnt()->xy()->added(aDir);
-                  aCenter = aSketch->to3D(aCenterXY->x(), aCenterXY->y());
+                aTypeAttr->value() == ARC_TYPE_THREE_POINTS()) {
+              if (aEndAttr->isInitialized() && // 
+                  aEndAttr->pnt()->distance(aStartAttr->pnt()) > tolerance) {
+                aEndPoint = aSketch->to3D(aEndAttr->x(), aEndAttr->y());
+                std::shared_ptr<GeomDataAPI_Point2D> aPassedAttr = 
+                  std::dynamic_pointer_cast<GeomDataAPI_Point2D>(data()->attribute(PASSED_POINT_ID()));
+                if (!aPassedAttr->isInitialized()) { // calculate the appropriate center for the presentation
+                  // check that center is bad for the current start and end and must be recomputed
+                  std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(new GeomAPI_Circ2d(
+                    aCenterAttr->pnt(), aStartAttr->pnt()));
+                  std::shared_ptr<GeomAPI_Pnt2d> aProjection = aCircleForArc->project(aEndAttr->pnt());
+                  if (!aProjection.get() || aEndAttr->pnt()->distance(aProjection) > tolerance) {
+                    std::shared_ptr<GeomAPI_XY> aDir = 
+                      aEndAttr->pnt()->xy()->decreased(aStartAttr->pnt()->xy())->multiplied(0.5);
+                    double x = aDir->x();
+                    double y = aDir->y();
+                    aDir->setX(x - y);
+                    aDir->setY(y + x);
+                    std::shared_ptr<GeomAPI_XY> aCenterXY = aStartAttr->pnt()->xy()->added(aDir);
+                    aCenter = aSketch->to3D(aCenterXY->x(), aCenterXY->y());
+                  }
                 }
+              } else { // issue #1695: don't display circle if initialized only start point
+                return AISObjectPtr();
               }
             }
             AttributeBooleanPtr isInversed =
@@ -361,6 +353,8 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID)
         double aStartAngle, aEndAngle;
         anEdge->getRange(aStartAngle, aEndAngle);
         data()->real(ANGLE_ID())->setValue(aEndAngle - aStartAngle);
+        myParamBefore = aEndAngle;
+        adjustPeriod(myParamBefore);
       }
     }
     return;
@@ -503,6 +497,19 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID)
       if (!anAngleAttr->isInitialized() || fabs(aNewAngle - anAngleAttr->value()) > tolerance)
         anAngleAttr->setValue(aNewAngle);
     }
+
+    // calculate arc aperture and change the Inversed flag if needed
+    AttributeBooleanPtr isInversed =
+        std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(attribute(INVERSED_ID()));
+    double aParameterNew = aEndParam - aStartParam;
+    if (0 <= myParamBefore && myParamBefore <= PI / 2.0 &&
+        PI * 1.5 <= aParameterNew && aParameterNew <= PI * 2.0)
+      isInversed->setValue(true);
+    else if (PI * 1.5 <= myParamBefore && myParamBefore <= PI * 2.0 &&
+             0 <= aParameterNew && aParameterNew <= PI / 2.0)
+      isInversed->setValue(false);
+    myParamBefore = aParameterNew;
+
     // do not need to inform that other parameters were changed in this basis mode: these arguments
     // change is enough
     data()->blockSendAttributeUpdated(false, false);