]> SALOME platform Git repositories - modules/shaper.git/commitdiff
Salome HOME
Issue #2390: Revolution become invalid after changing parameter
authorazv <azv@opencascade.com>
Wed, 27 Dec 2017 10:17:49 +0000 (13:17 +0300)
committerazv <azv@opencascade.com>
Wed, 27 Dec 2017 10:17:49 +0000 (13:17 +0300)
Do not use FuzzyValue but set correct tolerances for vertices on circular edges when execute Arc feature.

src/GeomAPI/GeomAPI_Edge.cpp
src/GeomAPI/GeomAPI_Edge.h
src/GeomAlgoAPI/GeomAlgoAPI_SketchBuilder.cpp
src/SketchPlugin/SketchPlugin_Arc.cpp

index 5e72160c5af8b0ce65abf43ac988ae4c9c455325..cf6197337c8ee80f4af7f39fea46cc2cf8dd55d2 100644 (file)
@@ -42,6 +42,7 @@
 #include <gp_Ax1.hxx>
 #include <gp_Pln.hxx>
 #include <gp_Elips.hxx>
+#include <TopExp.hxx>
 
 #include <GCPnts_AbscissaPoint.hxx>
 
@@ -308,3 +309,19 @@ bool GeomAPI_Edge::isDegenerated() const
     return false;
   return BRep_Tool::Degenerated(TopoDS::Edge(aShape));
 }
+
+void GeomAPI_Edge::setFirstPointTolerance(const double theTolerance)
+{
+  TopoDS_Edge anEdge = impl<TopoDS_Edge>();
+  TopoDS_Vertex aVFirst, aVLast;
+  TopExp::Vertices(anEdge, aVFirst, aVLast);
+  BRep_Builder().UpdateVertex(aVFirst, theTolerance);
+}
+
+void GeomAPI_Edge::setLastPointTolerance(const double theTolerance)
+{
+  TopoDS_Edge anEdge = impl<TopoDS_Edge>();
+  TopoDS_Vertex aVFirst, aVLast;
+  TopExp::Vertices(anEdge, aVFirst, aVLast);
+  BRep_Builder().UpdateVertex(aVLast, theTolerance);
+}
index ce0f7b559d18e0f1b9d830af6e6d3d5d94879970..e7d4910f1deb0eda3ea05d810e485b2f4396d4ed 100644 (file)
@@ -104,6 +104,12 @@ public:
   /// Returns true if the edge is degenerated (has no 3D curve)
   GEOMAPI_EXPORT
   bool isDegenerated() const;
+
+  GEOMAPI_EXPORT
+  void setFirstPointTolerance(const double theTolerance);
+
+  GEOMAPI_EXPORT
+  void setLastPointTolerance(const double theTolerance);
 };
 
 //! Pointer on attribute object
index 5916597b6ee32bb0fbf1dde418a01750384d7a7c..a6da1e785e24b70d0a84b515c1afd0b7805fbc94 100644 (file)
@@ -199,8 +199,6 @@ void GeomAlgoAPI_SketchBuilder::createFaces(
   if (theFeatures.empty())
     return;
 
-  static const double kFUZZY_VALUE = 1.e-5; // tolerance to avoid gaps in contours
-
   BRep_Builder aBuilder;
   // Planar face, where the sketch was built
   Handle(Geom_Surface) aPlane(new Geom_Plane(theOrigin->impl<gp_Pnt>(), theNorm->impl<gp_Dir>()));
@@ -220,7 +218,6 @@ void GeomAlgoAPI_SketchBuilder::createFaces(
     if (anEdge.ShapeType() == TopAbs_EDGE)
       aBB.AddArgument(anEdge);
   }
-  aBB.SetFuzzyValue(kFUZZY_VALUE);
   aBB.Perform();
 #ifdef USE_OCCT_720
   if (aBB.HasErrors())
index d8b03f5a83381c3e92f53e2afc36030ab3597a3d..87469bdf9b52768ff0b263869315a1c622e47556 100644 (file)
@@ -119,16 +119,37 @@ void SketchPlugin_Arc::execute()
     aCircleForArc->parameter(anEndAttr->pnt(), paramTolerance, myParamBefore);
   }
 
-  GeomShapePtr anArcShape;
+  bool isReversed = boolean(REVERSED_ID())->value();
+
+  GeomEdgePtr anArcShape;
   if (fabs(myParamBefore - 2.0 * PI) < paramTolerance) {
     anArcShape = GeomAlgoAPI_EdgeBuilder::lineCircle(aCenter, aNormal, aStart->distance(aCenter));
     myParamBefore = 0;
   } else {
-    anArcShape = boolean(REVERSED_ID())->value() ?
+    anArcShape = isReversed ?
       GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, anEnd, aStart, aNormal)
     : GeomAlgoAPI_EdgeBuilder::lineCircleArc(aCenter, aStart, anEnd, aNormal);
   }
 
+  // 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);
+      }
+    }
+  }
+
   std::shared_ptr<ModelAPI_ResultConstruction> aResult = document()->createConstruction(data(), 1);
   aResult->setShape(anArcShape);
   aResult->setIsInHistory(false);