]> OCCT Git - occt.git/commitdiff
0031395: Mesh - BRepMesh produces poor mesh on shape with hidden self-intersections CR31395
authoroan <oan@opencascade.com>
Tue, 27 Dec 2022 12:25:50 +0000 (15:25 +0300)
committeroan <oan@opencascade.com>
Tue, 27 Dec 2022 12:25:50 +0000 (15:25 +0300)
Add parameter UseVertexTolerance to curve tessellator;
Use UseVertexTolerance in case if model healer has failed 5 times at row;
Do not treat 2d loops that fit in 3d tolerance as OK cases.

src/BRepMesh/BRepMesh_CurveTessellator.cxx
src/BRepMesh/BRepMesh_CurveTessellator.hxx
src/BRepMesh/BRepMesh_EdgeDiscret.cxx
src/BRepMesh/BRepMesh_EdgeDiscret.hxx
src/BRepMesh/BRepMesh_FaceChecker.cxx
src/BRepMesh/BRepMesh_ModelHealer.cxx

index ac1784766771704532f2126f9fc7ddbed1f2f5a2..1cb3a141ead3dd52f2af1521cf77e16f7e4d927a 100644 (file)
@@ -36,9 +36,11 @@ IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_CurveTessellator, IMeshTools_CurveTessellato
 BRepMesh_CurveTessellator::BRepMesh_CurveTessellator(
   const IMeshData::IEdgeHandle& theEdge,
   const IMeshTools_Parameters&  theParameters,
-  const Standard_Integer        theMinPointsNb)
+  const Standard_Integer        theMinPointsNb,
+  const Standard_Boolean        isUseVertexTolerance)
   : myDEdge(theEdge),
     myParameters(theParameters),
+    myUseVertexTolerance(isUseVertexTolerance),
     myEdge(theEdge->GetEdge()),
     myCurve(myEdge),
     myMinPointsNb (theMinPointsNb)
@@ -55,9 +57,11 @@ BRepMesh_CurveTessellator::BRepMesh_CurveTessellator (
   const TopAbs_Orientation      theOrientation,
   const IMeshData::IFaceHandle& theFace,
   const IMeshTools_Parameters&  theParameters,
-  const Standard_Integer        theMinPointsNb)
+  const Standard_Integer        theMinPointsNb,
+  const Standard_Boolean        isUseVertexTolerance)
   : myDEdge(theEdge),
     myParameters(theParameters),
+    myUseVertexTolerance(isUseVertexTolerance),
     myEdge(TopoDS::Edge(theEdge->GetEdge().Oriented(theOrientation))),
     myCurve(myEdge, theFace->GetFace()),
     myMinPointsNb (theMinPointsNb)
@@ -225,10 +229,15 @@ Standard_Boolean BRepMesh_CurveTessellator::isInToleranceOfVertex (
   const gp_Pnt&        thePoint,
   const TopoDS_Vertex& theVertex) const
 {
-  const gp_Pnt        aPoint     = BRep_Tool::Pnt(theVertex);
-  const Standard_Real aTolerance = BRep_Tool::Tolerance(theVertex) * 1.1;
+  if (myUseVertexTolerance)
+  {
+    const gp_Pnt        aPoint     = BRep_Tool::Pnt(theVertex);
+    const Standard_Real aTolerance = BRep_Tool::Tolerance(theVertex) * 1.1;
+
+    return (thePoint.SquareDistance (aPoint) < aTolerance * aTolerance);
+  }
 
-  return (thePoint.SquareDistance (aPoint) < aTolerance * aTolerance);
+  return Standard_False;
 }
 
 //=======================================================================
index d9406a842309f94096212a60f858953df1e89535..22b3494ad003fda7eae144ff42cf0b3a797784ef 100644 (file)
@@ -35,7 +35,8 @@ public:
   Standard_EXPORT BRepMesh_CurveTessellator(
     const IMeshData::IEdgeHandle& theEdge,
     const IMeshTools_Parameters&  theParameters,
-    const Standard_Integer        theMinPointsNb = 2);
+    const Standard_Integer        theMinPointsNb = 2,
+    const Standard_Boolean        isUseVertexTolerance = Standard_False);
 
   //! Constructor.
   Standard_EXPORT BRepMesh_CurveTessellator (
@@ -43,7 +44,8 @@ public:
     const TopAbs_Orientation      theOrientation,
     const IMeshData::IFaceHandle& theFace,
     const IMeshTools_Parameters&  theParameters,
-    const Standard_Integer        theMinPointsNb = 2);
+    const Standard_Integer        theMinPointsNb = 2,
+    const Standard_Boolean        isUseVertexTolerance = Standard_False);
 
   //! Destructor.
   Standard_EXPORT virtual ~BRepMesh_CurveTessellator ();
@@ -96,6 +98,7 @@ private:
 
   const IMeshData::IEdgeHandle& myDEdge;
   const IMeshTools_Parameters&  myParameters;
+  Standard_Boolean              myUseVertexTolerance;
   TopoDS_Edge                   myEdge;
   BRepAdaptor_Curve             myCurve;
   Standard_Integer              myMinPointsNb;
index 31c7963c5983f4d42d546aaf946d4bd7a68e4c97..efbaa5a5f291c4742eb335feab484aa7d9768e27 100644 (file)
@@ -64,11 +64,12 @@ Handle(IMeshTools_CurveTessellator) BRepMesh_EdgeDiscret::CreateEdgeTessellator(
   const TopAbs_Orientation      theOrientation,
   const IMeshData::IFaceHandle& theDFace,
   const IMeshTools_Parameters&  theParameters,
-  const Standard_Integer        theMinPointsNb)
+  const Standard_Integer        theMinPointsNb,
+  const Standard_Boolean        isUseVertexTolerance)
 {
   return theDEdge->GetSameParam() ? 
-    new BRepMesh_CurveTessellator(theDEdge, theParameters, theMinPointsNb) :
-    new BRepMesh_CurveTessellator(theDEdge, theOrientation, theDFace, theParameters, theMinPointsNb);
+    new BRepMesh_CurveTessellator(theDEdge, theParameters, theMinPointsNb, isUseVertexTolerance) :
+    new BRepMesh_CurveTessellator(theDEdge, theOrientation, theDFace, theParameters, theMinPointsNb, isUseVertexTolerance);
 }
 
 //=======================================================================
index 89b67eda394ed0b213f2e09372c1cc9e2c03b852..27747c820ff2678e320e858470efa19ba526ad61 100644 (file)
@@ -47,7 +47,8 @@ public:
     const TopAbs_Orientation      theOrientation,
     const IMeshData::IFaceHandle& theDFace,
     const IMeshTools_Parameters&  theParameters,
-    const Standard_Integer        theMinPointsNb = 2);
+    const Standard_Integer        theMinPointsNb = 2,
+    const Standard_Boolean        isUseVertexTolerance = Standard_False);
 
   //! Creates instance of tessellation extractor.
   Standard_EXPORT static Handle(IMeshTools_CurveTessellator) CreateEdgeTessellationExtractor(
index b78238d692857d6fc3910d8cd37f3e7fda43eddc..5ea498ecbf14f148961580ccdd411d494cfd1c40 100644 (file)
@@ -267,7 +267,7 @@ void BRepMesh_FaceChecker::perform(const Standard_Integer theWireIndex) const
   Handle(IMeshData::MapOfIEdgePtr)& aIntersections = myWiresIntersectingEdges->ChangeValue(theWireIndex);
 
   // TODO: Tolerance is set to twice value of face deflection in order to fit regressions.
-  BndBox2dTreeSelector aSelector(2 * myDFace->GetDeflection());
+  BndBox2dTreeSelector aSelector(2 * Precision::PConfusion()/*myDFace->GetDeflection()*/);
   for (Standard_Integer aWireIt = theWireIndex; aWireIt < myDFace->WiresNb(); ++aWireIt)
   {
     const Handle(IMeshData::BndBox2dTree)& aBndBoxTree2 = myWiresBndBoxTree->Value(aWireIt);
index 4c2eed209ac8e31e36cdf9bb5faadfd98c585e77..1285f95769ede17a19adccc1af1b48aa4e1d49e9 100644 (file)
@@ -41,11 +41,19 @@ namespace
   {
   public:
     //! Constructor.
-    EdgeAmplifier(const IMeshTools_Parameters& theParameters)
-      : myParameters(theParameters)
+    EdgeAmplifier(const IMeshTools_Parameters& theParameters,
+                  const Standard_Boolean       isUseVertexTolerance = Standard_False)
+      : myParameters        (theParameters),
+        myUseVertexTolerance(isUseVertexTolerance)
     {
     }
 
+    //! Take vertex tolerance into account.
+    void SetUseVertexTolerance(const Standard_Boolean isUseVertexTolerance)
+    {
+      myUseVertexTolerance = isUseVertexTolerance;
+    }
+
     //! Main operator.
     void operator()(const IMeshData::IEdgePtr& theDEdge) const
     {
@@ -75,7 +83,7 @@ namespace
       Handle(IMeshTools_CurveTessellator) aTessellator =
         BRepMesh_EdgeDiscret::CreateEdgeTessellator(
           aDEdge, aPCurve->GetOrientation(), aDFace,
-          myParameters, aPointsNb);
+          myParameters, aPointsNb, myUseVertexTolerance);
 
       BRepMesh_EdgeDiscret::Tessellate3d(aDEdge, aTessellator, Standard_False);
       BRepMesh_EdgeDiscret::Tessellate2d(aDEdge, Standard_False);
@@ -89,6 +97,7 @@ namespace
 
   private:
     const IMeshTools_Parameters& myParameters;
+    Standard_Boolean             myUseVertexTolerance;
   };
 
   //! Returns True if some of two vertcies is same with reference one.
@@ -190,12 +199,14 @@ void BRepMesh_ModelHealer::amplifyEdges()
     new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
 
   Standard_Integer aAmpIt = 0;
-  const Standard_Real aIterNb = 5;
+  const Standard_Integer aIterNb = 6;
   IMeshData::MapOfIEdgePtr aEdgesToUpdate(1, aTmpAlloc);
   EdgeAmplifier anEdgeAmplifier (myParameters);
 
   while (aAmpIt++ < aIterNb && popEdgesToUpdate(aEdgesToUpdate))
   {
+    anEdgeAmplifier.SetUseVertexTolerance (aAmpIt == aIterNb);
+
     // Try to update discretization by decreasing deflection of problematic edges.
     OSD_Parallel::ForEach(aEdgesToUpdate.cbegin(), aEdgesToUpdate.cend(),
                           anEdgeAmplifier,