0031144: Shape Healing - ShapeAnalysis::OuterWire() infinite loop on solid obtained...
authorabv <abv@opencascade.com>
Tue, 12 Nov 2019 16:10:14 +0000 (19:10 +0300)
committerbugmaster <bugmaster@opencascade.com>
Fri, 15 Nov 2019 13:37:25 +0000 (16:37 +0300)
Implementation of ShapeAnalysis::OuterWire() is revised to avoid infinite cycle if face contains internal vertex.

src/ShapeAnalysis/ShapeAnalysis.cxx
tests/bugs/mesh/bug31144 [new file with mode: 0644]

index fdc65a7..3efe42d 100644 (file)
@@ -241,9 +241,10 @@ Standard_Boolean ShapeAnalysis::IsOuterBound(const TopoDS_Face& face)
 
 //=======================================================================
 //function : OuterBound
-//purpose  : replacement of bad BRepTools::OuterBound()
+//purpose  : replacement of bad BRepTools::OuterBound(), to be merged
+// - skips internal vertices in face, if any, without exception
+// - returns positively oriented wire rather than greater one
 //=======================================================================
-//:n3
 
 TopoDS_Wire ShapeAnalysis::OuterWire(const TopoDS_Face& face) 
 {
@@ -251,21 +252,26 @@ TopoDS_Wire ShapeAnalysis::OuterWire(const TopoDS_Face& face)
   F.Orientation(TopAbs_FORWARD);
 
   BRep_Builder B;
-  TopoDS_Wire W;
-  TopoDS_Iterator exp (F, Standard_False);
-  while ( exp.More() ) {
-    if(exp.Value().ShapeType() != TopAbs_WIRE)
+  TopoDS_Iterator anIt (F, Standard_False);
+  while (anIt.More())
+  {
+    TopoDS_Shape aWire = anIt.Value();
+    anIt.Next();
+
+    // skip possible internal vertices in face
+    if (aWire.ShapeType() != TopAbs_WIRE)
       continue;
-    W = TopoDS::Wire ( exp.Value() );
-    exp.Next();
-    if ( ! exp.More() ) return W;
-    //szv#4:S4163:12Mar99 SGI warns
-    TopoDS_Shape sh = F.EmptyCopied();
-    TopoDS_Face fc = TopoDS::Face( sh );
-    B.Add ( fc, W );
-    if ( ShapeAnalysis::IsOuterBound ( fc ) ) return W;
+
+    // if current wire is the last one, return it without analysis
+    if (! anIt.More())
+      return TopoDS::Wire (aWire);
+
+    TopoDS_Shape aTestFace = F.EmptyCopied();
+    B.Add (aTestFace, aWire);
+    if (ShapeAnalysis::IsOuterBound (TopoDS::Face (aTestFace)))
+      return TopoDS::Wire (aWire);
   }
-  return W;
+  return TopoDS_Wire();
 }
 
 //=======================================================================
diff --git a/tests/bugs/mesh/bug31144 b/tests/bugs/mesh/bug31144
new file mode 100644 (file)
index 0000000..31f40af
--- /dev/null
@@ -0,0 +1,17 @@
+puts "======="
+puts "0031144: Shape Healing - ShapeAnalysis::OuterWire() infinite loop on solid obtained from IFC"
+puts "======="
+puts ""
+puts "REQUIRED ALL: Meshing statuses: Failure"
+
+cpulimit 10
+
+restore [locate_data_file bug31144.brep] a
+
+checkshape a
+tolerance a
+
+puts "Note: incmesh is called because this is the only known way to call problematic method"
+incmesh a 1.
+
+trinfo a
\ No newline at end of file