0026627: [Regression] Shape Healing hangs as of OCC 6.8.0
authorabv <abv@opencascade.com>
Mon, 7 Sep 2015 04:14:41 +0000 (07:14 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 10 Sep 2015 13:40:29 +0000 (16:40 +0300)
Check for orientation of the solid corrected to ensure that cycle always finishes.

Test case added: bugs modalg_6 bug26627
Tests boolean volumemaker A3, B5, B7 corrected (improvements)

src/BRepClass3d/BRepClass3d_SClassifier.cxx
tests/boolean/volumemaker/A3
tests/boolean/volumemaker/B5
tests/boolean/volumemaker/B7
tests/bugs/modalg_6/bug26627 [new file with mode: 0644]

index 860db3b..07833c1 100644 (file)
@@ -33,6 +33,8 @@
 #include <TopoDS.hxx>
 #include <TopoDS_Face.hxx>
 
+#include <vector>
+
 // modified by NIZHNY-MKK  Mon Jun 21 15:13:40 2004
 static
   Standard_Boolean FaceNormal (const TopoDS_Face& aF,
@@ -103,72 +105,76 @@ void BRepClass3d_SClassifier::PerformInfinitePoint(BRepClass3d_SolidExplorer& aS
   myFace.Nullify();
   myState=2;
 
-  aSE.InitShell();
-  if (aSE.MoreShell())
+  // Collect faces in sequence to iterate
+  std::vector<TopoDS_Face> aFaces;
+  for (aSE.InitShell(); aSE.MoreShell(); aSE.NextShell())
   {
-    aSE.InitFace();
-    if (aSE.MoreFace())
+    for (aSE.InitFace(); aSE.MoreFace(); aSE.NextFace())
     {
-      TopoDS_Face aF = aSE.CurrentFace();
+      aFaces.push_back (aSE.CurrentFace());
+    }
+  }
+
+  // iteratively try up to 10 probing points from each face
+  const int NB_MAX_POINTS_PER_FACE = 10;
+  for (int itry = 0; itry < NB_MAX_POINTS_PER_FACE; itry++)
+  {
+    for (std::vector<TopoDS_Face>::iterator iFace = aFaces.begin(); iFace != aFaces.end(); ++iFace)
+    {
+      TopoDS_Face aF = *iFace;
+
       TopAbs_State aState = TopAbs_OUT;
       IntCurveSurface_TransitionOnCurve aTransition = IntCurveSurface_Tangent;
-      TopoDS_Face MinFace = aF;
-      for (;;)
-      {
-        aParam = 0.1 + 0.8 * aRandomGenerator.NextReal(); // random number in range [0.1, 0.9]
-        bFound = aSE.FindAPointInTheFace(aF, aPoint, aU, aV, aParam);
-        if (!bFound)
-          return;
 
-        if (!FaceNormal(aF, aU, aV, aDN))
-          continue;
-        gp_Lin aLin(aPoint, -aDN);
-        Standard_Real parmin = RealLast();
-        for (aSE.InitShell();aSE.MoreShell();aSE.NextShell()) { 
-          if (aSE.RejectShell(aLin) == Standard_False) { 
-            for (aSE.InitFace();aSE.MoreFace(); aSE.NextFace()) {
-              if (aSE.RejectFace(aLin) == Standard_False) { 
-                TopoDS_Shape aLocalShape = aSE.CurrentFace();
-                TopoDS_Face CurFace = TopoDS::Face(aLocalShape);
-                IntCurvesFace_Intersector& Intersector3d = aSE.Intersector(CurFace);
-                Intersector3d.Perform(aLin,-RealLast(),parmin); 
-                
-                if(Intersector3d.IsDone()) {
-                  if(Intersector3d.NbPnt()) { 
-                    Standard_Integer imin = 1;
-                    for (Standard_Integer i = 2; i <= Intersector3d.NbPnt(); i++)
-                      if (Intersector3d.WParameter(i) < Intersector3d.WParameter(imin))
-                        imin = i;
-                    parmin = Intersector3d.WParameter(imin);
-                    aState = Intersector3d.State(imin);
-                    aTransition = Intersector3d.Transition(imin);
-                    MinFace = CurFace;
-                  }
+      aParam = 0.1 + 0.8 * aRandomGenerator.NextReal(); // random number in range [0.1, 0.9]
+      bFound = aSE.FindAPointInTheFace(aF, aPoint, aU, aV, aParam);
+      if (!bFound || !FaceNormal(aF, aU, aV, aDN))
+        continue;
+
+      gp_Lin aLin(aPoint, -aDN);
+      Standard_Real parmin = RealLast();
+      for (aSE.InitShell();aSE.MoreShell();aSE.NextShell()) { 
+        if (aSE.RejectShell(aLin) == Standard_False) { 
+          for (aSE.InitFace();aSE.MoreFace(); aSE.NextFace()) {
+            if (aSE.RejectFace(aLin) == Standard_False) { 
+              TopoDS_Shape aLocalShape = aSE.CurrentFace();
+              TopoDS_Face CurFace = TopoDS::Face(aLocalShape);
+              IntCurvesFace_Intersector& Intersector3d = aSE.Intersector(CurFace);
+              Intersector3d.Perform(aLin,-RealLast(),parmin); 
+
+              if(Intersector3d.IsDone()) {
+                if(Intersector3d.NbPnt()) { 
+                  Standard_Integer imin = 1;
+                  for (Standard_Integer i = 2; i <= Intersector3d.NbPnt(); i++)
+                    if (Intersector3d.WParameter(i) < Intersector3d.WParameter(imin))
+                      imin = i;
+                  parmin = Intersector3d.WParameter(imin);
+                  aState = Intersector3d.State(imin);
+                  aTransition = Intersector3d.Transition(imin);
                 }
               }
             }
           }
-          else
-            myState = 1;
-        } //end of loop on the whole solid
+        }
+        else
+          myState = 1;
+      } //end of loop on the whole solid
         
-        if (aState == TopAbs_IN)
-        {
-          if (aTransition == IntCurveSurface_Out) { 
-            //-- The line is going from inside the solid to outside 
-            //-- the solid.
-            myState = 3; //-- IN --
-            return;
-          }
-          else if (aTransition == IntCurveSurface_In) { 
-            myState = 4; //-- OUT --
-            return;
-          }
+      if (aState == TopAbs_IN)
+      {
+        if (aTransition == IntCurveSurface_Out) { 
+          //-- The line is going from inside the solid to outside 
+          //-- the solid.
+          myState = 3; //-- IN --
+          return;
+        }
+        else if (aTransition == IntCurveSurface_In) { 
+          myState = 4; //-- OUT --
+          return;
         }
-        aF = MinFace;
       }
-    } //if (aSE.MoreFace())
-  } //if (aSE.MoreShell())
+    } // iteration by faces
+  } // iteration by points
 }
 
 //=======================================================================
index a665eec..9aeac52 100644 (file)
@@ -2,7 +2,6 @@
 # plane unstable
 
 puts "TODO OCC26020 ALL: Error: bopcheck failed"
-puts "TODO OCC26020 ALL: Faulty shapes in variables faulty_1 to faulty_"
 
 # planar face 
 plane pln_f1 0 -870 -1.3877787807814457e-014 0 1 1.1102230246251565e-016
@@ -37,5 +36,5 @@ mkface f6 pln_f6 -1000000 1000000 -1000000 1000000
 # make volume operation 
 mkvolume result f1 f2 f3 f4 f5 f6
 
-set square 2.4e+013
+set square 1183220.
 
index 64f6809..06903f3 100644 (file)
@@ -1,8 +1,6 @@
 # test script on make volume operation
 # plane
 
-puts "TODO OCC26020 ALL: Error: bopcheck failed"
-
 # planar face 
 plane pln_f1 2949.26242211 -890 552.5 1.110223024625157e-016 -1 1.1102230246251563e-016
 erase pln_f1
@@ -36,5 +34,4 @@ mkface f6 pln_f6 -1000000 1000000 -1000000 1000000
 # make volume operation 
 mkvolume result f1 f2 f3 f4 f5 f6
 
-set square 2.4e+013
-
+set square 12400.
index 795efc4..a6e9633 100644 (file)
@@ -1,8 +1,7 @@
 # test script on make volume operation
 # plane
 
-puts "TODO ?OCC26020 ALL: Faulty shapes in variables faulty_1 to faulty_"
-puts "TODO ?OCC26020 ALL: Error: bopcheck failed"
+puts "TODO OCC26020 ALL: Error: bopcheck failed"
 
 # planar face 
 plane pln_f1 18.855982726712998 17.500000000800412 0 -0.96152394764524818 -0.27472112788189063 0
@@ -52,4 +51,4 @@ mkface f9 pln_f9 -1000000 1000000 -1000000 1000000
 # make volume operation 
 mkvolume result f1 f2 f3 f4 f5 f6 f7 f8 f9
 
-set square 2.75501e+013
+set square 1.3412e+013
diff --git a/tests/bugs/modalg_6/bug26627 b/tests/bugs/modalg_6/bug26627
new file mode 100644 (file)
index 0000000..b33ce91
--- /dev/null
@@ -0,0 +1,19 @@
+puts "##################################################"
+puts "0026627: Shape Healing hangs as of OCC 6.8.0"
+puts "##################################################"
+
+# load and check shape
+restore [locate_data_file bug26627_fixed.brep] a
+tolerance a
+checkshape a
+
+# call fixshape -- it should finish in fraction of second
+cpulimit 10
+fixshape result a 1e-6
+
+# result should have positive volume
+if { [regexp {Mass\s*:\s*([0-9.e+-]*)} [vprops result] dummy volume] } {
+  checkreal "Volume of the solid" $volume 4332.63 0.1 0.
+} else {
+  puts "Error: cannot get volume of result!"
+}