From 56f67cdaab44ba4bef137e6ad62c41baddbd09ae Mon Sep 17 00:00:00 2001
From: oan <oan@opencascade.com>
Date: Thu, 8 Jul 2021 13:07:05 +0300
Subject: [PATCH] 0032424: [Regression] Mesh - Slow triangulation of a simple
 shape.

Check links produced by splitting of an initial link by the middle point for MinSize requirement.

Conflicts:
	tests/bugs/mesh/bug30008_1
	tests/bugs/moddata_2/bug428
	tests/hlr/poly_hlr/C14
---
 ...Mesh_DelaunayDeflectionControlMeshAlgo.hxx | 54 ++++++++++++++-----
 tests/bugs/iges/buc60820_2                    |  2 +-
 tests/bugs/mesh/bug23513                      |  2 +-
 tests/bugs/mesh/bug27384_2                    |  2 +-
 tests/bugs/mesh/bug30008_1                    |  2 +-
 tests/bugs/mesh/bug31251                      |  4 +-
 tests/bugs/mesh/bug32424                      | 18 +++++++
 tests/bugs/moddata_2/bug428                   |  2 +-
 tests/hlr/poly_hlr/C13                        |  2 +-
 tests/hlr/poly_hlr/C14                        |  2 +-
 tests/hlr/poly_hlr/C4                         |  2 +-
 tests/hlr/poly_hlr/bug23625_2                 |  2 +-
 tests/hlr/poly_hlr/bug23625_3                 |  2 +-
 tests/hlr/poly_hlr/bug27979_3                 |  2 +-
 tests/hlr/poly_hlr/bug27979_5                 |  2 +-
 tests/hlr/poly_hlr/bug27979_7                 |  2 +-
 tests/perf/mesh/bug26889_1                    |  2 +-
 tests/perf/mesh/bug26889_2                    |  2 +-
 tests/perf/mesh/bug26889_3                    |  2 +-
 tests/perf/mesh/bug26965                      |  2 +-
 20 files changed, 78 insertions(+), 32 deletions(-)
 create mode 100644 tests/bugs/mesh/bug32424

diff --git a/src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx b/src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx
index cc496f20ca..5f59ab9c46 100644
--- a/src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx
+++ b/src/BRepMesh/BRepMesh_DelaunayDeflectionControlMeshAlgo.hxx
@@ -34,6 +34,7 @@ public:
   //! Constructor.
   BRepMesh_DelaunayDeflectionControlMeshAlgo()
     : myMaxSqDeflection(-1.),
+      mySqMinSize(-1.),
       myIsAllDegenerated(Standard_False),
       myCircles(NULL)
   {
@@ -77,10 +78,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;
     Message_ProgressScope aPS(theRange, "Iteration", aIterationsNb);
@@ -339,22 +341,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 = 
@@ -365,7 +383,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)
@@ -381,6 +401,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.
@@ -389,8 +417,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);
@@ -422,14 +449,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(
@@ -451,7 +478,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;
           }
@@ -464,6 +491,7 @@ private:
 
 private:
   Standard_Real                         myMaxSqDeflection;
+  Standard_Real                         mySqMinSize;
   Standard_Boolean                      myIsAllDegenerated;
   Handle(IMeshData::MapOfOrientedEdges) myCouplesMap;
   Handle(IMeshData::ListOfPnt2d)        myControlNodes;
diff --git a/tests/bugs/iges/buc60820_2 b/tests/bugs/iges/buc60820_2
index af459d8f62..2ceebe03c0 100755
--- a/tests/bugs/iges/buc60820_2
+++ b/tests/bugs/iges/buc60820_2
@@ -13,6 +13,6 @@ vdisplay result
 vsetdispmode result 1
 vfit
 
-checktrinfo result -tri 244 -nod 237
+checktrinfo result -tri 200 -nod 215
 
 checkview -display result -2d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/mesh/bug23513 b/tests/bugs/mesh/bug23513
index ab612f14f3..fa1c1aa12f 100644
--- a/tests/bugs/mesh/bug23513
+++ b/tests/bugs/mesh/bug23513
@@ -12,7 +12,7 @@ vfit
  
 checkview -screenshot -3d -path ${imagedir}/${test_image}.png
 
-checktrinfo result -tri 323820 -nod 161951 -defl 0.00096399964870812682
+checktrinfo result -tri 62936 -nod 31509 -defl 0.00096399964870812682
 
 set log [tricheck result]
 if { [llength $log] != 0 } {
diff --git a/tests/bugs/mesh/bug27384_2 b/tests/bugs/mesh/bug27384_2
index 84ab562c6a..e80517c6e0 100644
--- a/tests/bugs/mesh/bug27384_2
+++ b/tests/bugs/mesh/bug27384_2
@@ -17,7 +17,7 @@ vdefaults -autoTriang 0
 vdisplay result
 vfit
 
-set rel_tol 0.035439456401028344
+set rel_tol 0.6928018366802983
 set max_rel_tol_diff 0.001
 set area_eps 1
 
diff --git a/tests/bugs/mesh/bug30008_1 b/tests/bugs/mesh/bug30008_1
index 1beebc5f40..1143910dad 100644
--- a/tests/bugs/mesh/bug30008_1
+++ b/tests/bugs/mesh/bug30008_1
@@ -12,6 +12,6 @@ vdisplay result
 vviewparams -scale 8.46292 -proj 0.653203 -0.644806 0.396926 -up -0.0109833 0.51609 0.856464 -at 347.559 1026.89 219.262 -eye 2080.75 -684.022 1272.45
 
 tricheck result
-checktrinfo result -tri 11826 -nod 7310 -defl 7.6167024939147652
+checktrinfo result -tri 6978 -nod 4890 -defl 7.6167024939147652
 
 checkview -screenshot -3d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/mesh/bug31251 b/tests/bugs/mesh/bug31251
index 242d2e13e1..2ef84b14eb 100644
--- a/tests/bugs/mesh/bug31251
+++ b/tests/bugs/mesh/bug31251
@@ -15,7 +15,7 @@ vdefaults -autoTriang 0
 
 tclean result
 incmesh result 0.004 -a 14
-checktrinfo result -tri 70560 -nod 39946 -defl 0.22962869401103247
+checktrinfo result -tri 70556 -nod 39944 -defl 0.22962869401103247
 
 vdisplay result -redisplay
 vfit
@@ -23,7 +23,7 @@ checkview -screenshot -3d -path ${imagedir}/${test_image}_default.png
 
 tclean result
 incmesh result 0.004 -a 14 -force_face_def
-checktrinfo result -tri 292560 -nod 150946 -defl 0.04579460790575135
+checktrinfo result -tri 292556 -nod 150944 -defl 0.04579460790575135
 
 vdisplay result -redisplay
 vfit
diff --git a/tests/bugs/mesh/bug32424 b/tests/bugs/mesh/bug32424
new file mode 100644
index 0000000000..f5e12302e1
--- /dev/null
+++ b/tests/bugs/mesh/bug32424
@@ -0,0 +1,18 @@
+puts "======="
+puts "0032424: Mesh - Slow triangulation of a simple shape."
+puts "======="
+puts ""
+cpulimit 3
+
+restore [locate_data_file bug32424.brep] result
+
+incmesh result 0.17 -a 20
+
+checktrinfo result -tri 16168 -nod 8206
+
+vinit
+vdefaults -autoTriang 0
+vsetdispmode 1
+vdisplay result
+vfit
+checkview -screenshot -3d -path ${imagedir}/${test_image}.png
diff --git a/tests/bugs/moddata_2/bug428 b/tests/bugs/moddata_2/bug428
index 7140f02607..c1a4c9d0df 100755
--- a/tests/bugs/moddata_2/bug428
+++ b/tests/bugs/moddata_2/bug428
@@ -19,5 +19,5 @@ isos result 0
 triangles result
 fit
 
-checktrinfo result -tri 10924 -nod 7869
+checktrinfo result -tri 7863 -nod 6342
 checkview -screenshot -2d -path ${imagedir}/${test_image}_axo.png
diff --git a/tests/hlr/poly_hlr/C13 b/tests/hlr/poly_hlr/C13
index 255ff26e64..3b9c705210 100644
--- a/tests/hlr/poly_hlr/C13
+++ b/tests/hlr/poly_hlr/C13
@@ -1,5 +1,5 @@
 set viewname "vright"
-set length 9547.11
+set length 9546.99
 
 testreadstep [locate_data_file bug27341_Assembly_ABS_1_CAD.stp] a
 COMPUTE_HLR $viewname $algotype
diff --git a/tests/hlr/poly_hlr/C14 b/tests/hlr/poly_hlr/C14
index 857e487132..5fde7169f6 100644
--- a/tests/hlr/poly_hlr/C14
+++ b/tests/hlr/poly_hlr/C14
@@ -1,4 +1,4 @@
-puts "TODO OCC30286 ALL: Error : The length of result shape is 5496.05, expected 5934.34"
+puts "TODO OCC30286 ALL: Error : The length of result shape is 5499.*, expected 5934.34"
 
 set viewname "vright"
 set length 5934.34
diff --git a/tests/hlr/poly_hlr/C4 b/tests/hlr/poly_hlr/C4
index 38b7efc966..be7953c784 100644
--- a/tests/hlr/poly_hlr/C4
+++ b/tests/hlr/poly_hlr/C4
@@ -1,4 +1,4 @@
-puts "TODO OCC30286 ALL: Error : The length of result shape is 2707.33, expected 2765.47"
+puts "TODO OCC30286 ALL: Error : The length of result shape is 2705.91, expected 2765.47"
 
 set viewname "vright"
 set length 2765.47
diff --git a/tests/hlr/poly_hlr/bug23625_2 b/tests/hlr/poly_hlr/bug23625_2
index 568c972e7a..10b31c6352 100644
--- a/tests/hlr/poly_hlr/bug23625_2
+++ b/tests/hlr/poly_hlr/bug23625_2
@@ -4,7 +4,7 @@ puts "============"
 puts ""
 
 set viewname "vfront"
-set length 28991.6
+set length 29113.3
 
 restore [locate_data_file bug23625_a2.brep] a
 COMPUTE_HLR $viewname $algotype
diff --git a/tests/hlr/poly_hlr/bug23625_3 b/tests/hlr/poly_hlr/bug23625_3
index 697e06a396..264015f5c8 100644
--- a/tests/hlr/poly_hlr/bug23625_3
+++ b/tests/hlr/poly_hlr/bug23625_3
@@ -4,7 +4,7 @@ puts "============"
 puts ""
 
 set viewname "vtop"
-set length 19620.9
+set length 19604.4
 
 restore [locate_data_file bug23625_a3.brep] a
 COMPUTE_HLR $viewname $algotype
diff --git a/tests/hlr/poly_hlr/bug27979_3 b/tests/hlr/poly_hlr/bug27979_3
index 022d82b732..865d4d5064 100644
--- a/tests/hlr/poly_hlr/bug27979_3
+++ b/tests/hlr/poly_hlr/bug27979_3
@@ -1,4 +1,4 @@
-puts "TODO OCC30286 ALL: Error : The length of result shape is 4.6692, expected 4."
+puts "TODO OCC30286 ALL: Error : The length of result shape is 4.*, expected 4."
 
 puts "========================================================================"
 puts "OCC27979: Parasolid converted BREP shows weird lines on hidden line Algo"
diff --git a/tests/hlr/poly_hlr/bug27979_5 b/tests/hlr/poly_hlr/bug27979_5
index 052c5adc78..5b324fcf4e 100644
--- a/tests/hlr/poly_hlr/bug27979_5
+++ b/tests/hlr/poly_hlr/bug27979_5
@@ -1,4 +1,4 @@
-puts "TODO OCC30286 ALL: Error : The length of result shape is 4.15911, expected 4."
+puts "TODO OCC30286 ALL: Error : The length of result shape is 4.*, expected 4."
 
 puts "========================================================================"
 puts "OCC27979: Parasolid converted BREP shows weird lines on hidden line Algo"
diff --git a/tests/hlr/poly_hlr/bug27979_7 b/tests/hlr/poly_hlr/bug27979_7
index a59e3a80cd..0a25d5b417 100644
--- a/tests/hlr/poly_hlr/bug27979_7
+++ b/tests/hlr/poly_hlr/bug27979_7
@@ -1,4 +1,4 @@
-puts "TODO OCC30286 ALL: Error : The length of result shape is 3.2349, expected 3."
+puts "TODO OCC30286 ALL: Error : The length of result shape is 3.*, expected 3."
 
 puts "========================================================================"
 puts "OCC27979: Parasolid converted BREP shows weird lines on hidden line Algo"
diff --git a/tests/perf/mesh/bug26889_1 b/tests/perf/mesh/bug26889_1
index 4413cc1d50..10b03c6a37 100644
--- a/tests/perf/mesh/bug26889_1
+++ b/tests/perf/mesh/bug26889_1
@@ -11,7 +11,7 @@ dchrono t restart
 incmesh a_1 0.01 1
 dchrono t stop counter incmesh
 
-checktrinfo a_1 -tri 743149 -nod 372395 -defl 0.081028355715069861
+checktrinfo a_1 -tri 525271 -nod 263456 -defl 0.081028355715069861
 
 set log [tricheck a_1]
 if { [llength $log] != 0 } {
diff --git a/tests/perf/mesh/bug26889_2 b/tests/perf/mesh/bug26889_2
index 658c263eda..878f636c12 100644
--- a/tests/perf/mesh/bug26889_2
+++ b/tests/perf/mesh/bug26889_2
@@ -11,7 +11,7 @@ dchrono t restart
 incmesh a_1 0.1 1
 dchrono t stop counter incmesh
 
-checktrinfo a_1 -tri 182273 -nod 91484 -defl 0.11671770612283024
+checktrinfo a_1 -tri 68779 -nod 34737 -defl 0.11671770612283024
 
 set log [tricheck a_1]
 if { [llength $log] != 0 } {
diff --git a/tests/perf/mesh/bug26889_3 b/tests/perf/mesh/bug26889_3
index 7810bcc210..d4525bb9b3 100644
--- a/tests/perf/mesh/bug26889_3
+++ b/tests/perf/mesh/bug26889_3
@@ -11,7 +11,7 @@ dchrono t restart
 incmesh a_1 1.0 1
 dchrono t stop counter incmesh
 
-checktrinfo a_1 -tri 73119 -nod 36828 -defl 1.0
+checktrinfo a_1 -tri 12469 -nod 6503 -defl 1.0
 
 set log [tricheck a_1]
 if { [llength $log] != 0 } {
diff --git a/tests/perf/mesh/bug26965 b/tests/perf/mesh/bug26965
index 0b08bbfac6..8203f5ed54 100644
--- a/tests/perf/mesh/bug26965
+++ b/tests/perf/mesh/bug26965
@@ -16,4 +16,4 @@ dchrono h
 vfit
 checkview -screenshot -3d -path ${imagedir}/${test_image}.png
 
-checktrinfo a -tri 217070 -nod 108740 -defl 0.098772787476728782
\ No newline at end of file
+checktrinfo a -tri 14764 -nod 7587 -defl 0.098772787476728782
\ No newline at end of file