]> OCCT Git - occt-copy.git/commitdiff
0032424: [Regression] Mesh - Slow triangulation of a simple shape. CR740-SALOME-PATCH-1
authorrnv <rnv@opencascade.com>
Thu, 22 Jul 2021 10:33:11 +0000 (13:33 +0300)
committerrnv <rnv@opencascade.com>
Thu, 22 Jul 2021 10:33:11 +0000 (13:33 +0300)
src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx

index 04f4708d661dd3b9b38a62245eabaa43de540e78..85e37ebaf167dc110bfb3b85a3382f496caa1b95 100644 (file)
@@ -34,7 +34,9 @@ public:
   //! Constructor.
   BRepMesh_DelaunayDeflectionControlMeshAlgo()
     : myMaxSqDeflection(-1.),
-      myIsAllDegenerated(Standard_False)
+      mySqMinSize(-1.),
+      myIsAllDegenerated(Standard_False),
+      myCircles(NULL)
   {
   }
 
@@ -65,10 +67,11 @@ protected:
     Handle(NCollection_IncAllocator) aTmpAlloc =
       new NCollection_IncAllocator(IMeshData::MEMORY_BLOCK_SIZE_HUGE);
 
+    mySqMinSize    = this->getParameters().MinSize * this->getParameters().MinSize;
     myCouplesMap   = new IMeshData::MapOfOrientedEdges(3 * this->getStructure()->ElementsOfDomain().Extent(), aTmpAlloc);
     myControlNodes = new IMeshData::ListOfPnt2d(aTmpAlloc);
     myCircles      = &theMesher.Circles();
-
+    
     const Standard_Integer aIterationsNb = 11;
     Standard_Boolean isInserted = Standard_True;
     for (Standard_Integer aPass = 1; aPass <= aIterationsNb && isInserted && !myIsAllDegenerated; ++aPass)
@@ -318,22 +321,38 @@ private:
         if (!usePoint (aMidPnt2d, LineDeviation (theNodesInfo[i].Point, 
                                                  theNodesInfo[j].Point)))
         {
-          if (!checkLinkEndsForAngularDeviation(theNodesInfo[i], 
-                                                theNodesInfo[j],
-                                                aMidPnt2d))
+          if (!rejectSplitLinksForMinSize (theNodesInfo[i],
+                                           theNodesInfo[j],
+                                           aMidPnt2d))
           {
-            myControlNodes->Append(aMidPnt2d);
+            if (!checkLinkEndsForAngularDeviation (theNodesInfo[i],
+                                                   theNodesInfo[j],
+                                                   aMidPnt2d))
+            {
+              myControlNodes->Append(aMidPnt2d);
+            }
           }
         }
       }
     }
   }
 
+  //! Checks that two links produced as the result of a split of 
+  //! the given link by the middle point fit MinSize requirement.
+  Standard_Boolean rejectSplitLinksForMinSize (const TriangleNodeInfo& theNodeInfo1,
+                                               const TriangleNodeInfo& theNodeInfo2,
+                                               const gp_XY&            theMidPoint)
+  {
+    const gp_Pnt aPnt = getPoint3d (theMidPoint);
+    return ((theNodeInfo1.Point - aPnt.XYZ()).SquareModulus() < mySqMinSize ||
+            (theNodeInfo2.Point - aPnt.XYZ()).SquareModulus() < mySqMinSize);
+  }
+
   //! Checks the given point (located between the given nodes)
   //! for specified angular deviation.
   Standard_Boolean checkLinkEndsForAngularDeviation(const TriangleNodeInfo& theNodeInfo1,
                                                     const TriangleNodeInfo& theNodeInfo2,
-                                                    const gp_XY& /*theMidPoint*/)
+                                                    const gp_XY&          /*theMidPoint*/)
   {
     gp_Dir aNorm1, aNorm2;
     const Handle(Geom_Surface)& aSurf = 
@@ -344,7 +363,9 @@ private:
     {
       Standard_Real anAngle = aNorm1.Angle(aNorm2);
       if (anAngle > this->getParameters().AngleInterior)
+      {
         return Standard_False;
+      }
     }
 #if 0
     else if (GeomLib::NormEstim(aSurf, theMidPoint, Precision::Confusion(), aNorm1) != 0)
@@ -360,6 +381,14 @@ private:
     return Standard_True;
   }
 
+  //! Returns 3d point corresponding to the given one in 2d space.
+  gp_Pnt getPoint3d (const gp_XY& thePnt2d)
+  {
+    gp_Pnt aPnt;
+    this->getDFace()->GetSurface()->D0(thePnt2d.X(), thePnt2d.Y(), aPnt);
+    return aPnt;
+  }
+
   //! Computes deflection of the given point and caches it for
   //! insertion in case if it overflows deflection.
   //! @return True if point has been cached for insertion.
@@ -368,8 +397,7 @@ private:
     const gp_XY&             thePnt2d,
     const DeflectionFunctor& theDeflectionFunctor)
   {
-    gp_Pnt aPnt;
-    this->getDFace()->GetSurface()->D0(thePnt2d.X(), thePnt2d.Y(), aPnt);
+    const gp_Pnt aPnt = getPoint3d (thePnt2d);
     if (!checkDeflectionOfPointAndUpdateCache(thePnt2d, aPnt, theDeflectionFunctor.SquareDeviation(aPnt)))
     {
       myControlNodes->Append(thePnt2d);
@@ -401,14 +429,14 @@ private:
     return rejectByMinSize(thePnt2d, thePnt3d);
   }
 
-  //! Checks the given node for 
+  //! Checks distance between the given node and nodes of triangles 
+  //! shot by it for MinSize criteria.
+  //! This check is expected to roughly estimate and prevent 
+  //! generation of triangles with sides smaller than MinSize.
   Standard_Boolean rejectByMinSize(
     const gp_XY&  thePnt2d,
     const gp_Pnt& thePnt3d)
   {
-    const Standard_Real aSqMinSize = 
-      this->getParameters().MinSize * this->getParameters().MinSize;
-
     IMeshData::MapOfInteger aUsedNodes;
     IMeshData::ListOfInteger& aCirclesList =
       const_cast<BRepMesh_CircleTool&>(*myCircles).Select(
@@ -430,7 +458,7 @@ private:
           const BRepMesh_Vertex& aVertex = this->getStructure()->GetNode(aNodes[i]);
           const gp_Pnt& aPoint = this->getNodesMap()->Value(aVertex.Location3d());
 
-          if (thePnt3d.SquareDistance(aPoint) < aSqMinSize)
+          if (thePnt3d.SquareDistance(aPoint) < mySqMinSize)
           {
             return Standard_True;
           }
@@ -443,6 +471,7 @@ private:
 
 private:
   Standard_Real                         myMaxSqDeflection;
+  Standard_Real                         mySqMinSize;
   Standard_Boolean                      myIsAllDegenerated;
   Handle(IMeshData::MapOfOrientedEdges) myCouplesMap;
   Handle(IMeshData::ListOfPnt2d)        myControlNodes;