Salome HOME
updated copyright message
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_Arc.cpp
index ca7579d8664f8f285ba30f85a1d09b63b1c3d0e4..0eb84450c4e5dbbbf75634280721b4d011754fde 100644 (file)
@@ -1,8 +1,21 @@
-// Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
-
-// File:        SketchPlugin_Arc.cpp
-// Created:     26 Apr 2014
-// Author:      Artem ZHIDKOV
+// Copyright (C) 2014-2023  CEA, EDF
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
 
 #include "SketchPlugin_Arc.h"
 #include "SketchPlugin_Sketch.h"
 #include <GeomAlgoAPI_EdgeBuilder.h>
 #include <GeomAlgoAPI_CompoundBuilder.h>
 // for sqrt on Linux
-#include <math.h>
+#include <cmath>
 
-const double tolerance = 1e-7;
-const double paramTolerance = 1.e-4;
-const double PI = 3.141592653589793238463;
+static const double tolerance = 1e-7;
+static const double paramTolerance = 1.e-4;
+static const double PI = 3.141592653589793238463;
 
 
 SketchPlugin_Arc::SketchPlugin_Arc()
@@ -99,50 +112,47 @@ void SketchPlugin_Arc::execute()
       aSketch->data()->attribute(SketchPlugin_Sketch::NORM_ID()));
   std::shared_ptr<GeomAPI_Dir> aNormal(new GeomAPI_Dir(aNDir->x(), aNDir->y(), aNDir->z()));
 
-  GeomShapePtr anArcShape = boolean(REVERSED_ID())->value() ?
-      GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, anEnd, aStart, aNormal)
-    : GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, aStart, anEnd, aNormal);
-
   if (myParamBefore == 0) { // parameter has not been calculate yet
     std::shared_ptr<GeomAPI_Circ2d> aCircleForArc(
         new GeomAPI_Circ2d(aCenterAttr->pnt(), aStartAttr->pnt()));
     aCircleForArc->parameter(anEndAttr->pnt(), paramTolerance, myParamBefore);
   }
 
-  std::shared_ptr<ModelAPI_ResultConstruction> aResult = document()->createConstruction(data(), 1);
-  aResult->setShape(anArcShape);
-  aResult->setIsInHistory(false);
-  setResult(aResult, 1);
-}
-
-void SketchPlugin_Arc::move(double theDeltaX, double theDeltaY)
-{
-  std::shared_ptr<ModelAPI_Data> aData = data();
-  if(!aData->isValid()) {
-    return;
-  }
-
-  bool aWasBlocked = aData->blockSendAttributeUpdated(true);
-
-  std::shared_ptr<GeomDataAPI_Point2D> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-      attribute(CENTER_ID()));
-  if(aCenter->isInitialized()) {
-    aCenter->move(theDeltaX, theDeltaY);
-  }
+  bool isReversed = boolean(REVERSED_ID())->value();
 
-  std::shared_ptr<GeomDataAPI_Point2D> aStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-      attribute(START_ID()));
-  if(aStart->isInitialized()) {
-    aStart->move(theDeltaX, theDeltaY);
+  GeomEdgePtr anArcShape;
+  if (fabs(myParamBefore - 2.0 * PI) < paramTolerance) {
+    anArcShape = GeomAlgoAPI_EdgeBuilder::lineCircle(aCenter, aNormal, aStart->distance(aCenter));
+    myParamBefore = 0;
+  } else {
+    anArcShape = isReversed ?
+      GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, anEnd, aStart, aNormal)
+    : GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, aStart, anEnd, aNormal);
   }
 
-  std::shared_ptr<GeomDataAPI_Point2D> anEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
-      attribute(END_ID()));
-  if(anEnd->isInitialized()) {
-    anEnd->move(theDeltaX, theDeltaY);
+  // calculate tolerances for start and end points of the arc and set them to the result shape
+  // (this is done to fix gaps which appear because of inaccurate computation of arcs in PlaneGCS,
+  // which leads to difference in SketchPlugin_Arc attributes and boundary points of result shape)
+  if (anArcShape) {
+    for (int ind = 0; ind < 2; ++ind) {
+      bool isFirst = ind == 0;
+      GeomPointPtr anArcBndPoint = isFirst == isReversed ? anEnd : aStart;
+      GeomPointPtr aShapePoint = isFirst ? anArcShape->firstPoint() : anArcShape->lastPoint();
+      double aDistance = anArcBndPoint->distance(aShapePoint);
+      // avoid setting too high tolerance because it may be caused by incomplete update of an arc
+      if (aDistance > tolerance && aDistance < 100. * tolerance) {
+        if (isFirst)
+          anArcShape->setFirstPointTolerance(aDistance);
+        else
+          anArcShape->setLastPointTolerance(aDistance);
+      }
+    }
   }
 
-  aData->blockSendAttributeUpdated(aWasBlocked);
+  std::shared_ptr<ModelAPI_ResultConstruction> aResult = document()->createConstruction(data(), 1);
+  aResult->setShape(anArcShape);
+  aResult->setIsInHistory(false);
+  setResult(aResult, 1);
 }
 
 bool SketchPlugin_Arc::isFixed()
@@ -245,6 +255,9 @@ void SketchPlugin_Arc::attributeChanged(const std::string& theID)
         }
         data()->blockSendAttributeUpdated(aWasBlocked, false);
       }
+      if (fabs(aParameterNew) < paramTolerance ||
+          fabs(aParameterNew - 2.0 * PI) < paramTolerance)
+        aParameterNew = 2.0 * PI;
       myParamBefore = aParameterNew;
     }
   }