0025806: Stack overflow during meshing
authoroan <oan@opencascade.com>
Thu, 19 Feb 2015 12:10:25 +0000 (15:10 +0300)
committerbugmaster <bugmaster@opencascade.com>
Thu, 19 Feb 2015 12:11:54 +0000 (15:11 +0300)
Test-case for issue #25806

src/BRepMesh/BRepMesh.hxx
src/BRepMesh/BRepMesh_Delaun.cxx
src/BRepMesh/BRepMesh_Delaun.hxx
tests/bugs/mesh/bug25806 [new file with mode: 0644]

index 139e380..80b2ce0 100644 (file)
@@ -127,6 +127,8 @@ namespace BRepMesh
   typedef NCollection_Handle<DMapOfVertexInteger>                                                   HDMapOfVertexInteger;
   typedef NCollection_Handle<DMapOfIntegerListOfXY>                                                 HDMapOfIntegerListOfXY;
   typedef NCollection_Handle<BRepMesh_VertexTool>                                                   HVertexTool;
+  typedef NCollection_Handle<SequenceOfBndB2d>                                                      HSequenceOfBndB2d;
+  typedef NCollection_Handle<SequenceOfInteger>                                                     HSequenceOfInteger;
 
   //! Other data structures
   typedef std::pair<HArray1OfSegments, HBndBox2dTree>                                               SegmentsTree;
index 1bdb691..6a1581a 100644 (file)
@@ -1701,7 +1701,41 @@ void BRepMesh_Delaun::meshPolygon(BRepMesh::SequenceOfInteger& thePolygon,
     }
   }
 
-  meshSimplePolygon( thePolygon, thePolyBoxes );
+  BRepMesh::SequenceOfInteger* aPolygon1   = &thePolygon;
+  BRepMesh::SequenceOfBndB2d*  aPolyBoxes1 = &thePolyBoxes;
+
+  BRepMesh::HSequenceOfInteger aPolygon2   = new BRepMesh::SequenceOfInteger;
+  BRepMesh::HSequenceOfBndB2d  aPolyBoxes2 = new BRepMesh::SequenceOfBndB2d;
+
+  NCollection_Sequence<BRepMesh::HSequenceOfInteger> aPolyStack;
+  NCollection_Sequence<BRepMesh::HSequenceOfBndB2d>  aPolyBoxStack;
+  for (;;)
+  {
+    decomposeSimplePolygon(*aPolygon1, *aPolyBoxes1, *aPolygon2, *aPolyBoxes2);
+    if (!aPolygon2->IsEmpty())
+    {
+      aPolyStack.Append(aPolygon2);
+      aPolyBoxStack.Append(aPolyBoxes2);
+      
+      aPolygon2   = new BRepMesh::SequenceOfInteger;
+      aPolyBoxes2 = new BRepMesh::SequenceOfBndB2d;
+    }
+
+    if (aPolygon1->IsEmpty())
+    {
+      if (!aPolyStack.IsEmpty() && aPolygon1 == &(*aPolyStack.First()))
+      {
+        aPolyStack.Remove(1);
+        aPolyBoxStack.Remove(1);
+      }
+
+      if (aPolyStack.IsEmpty())
+        return;
+
+      aPolygon1   = &(*aPolyStack.ChangeFirst());
+      aPolyBoxes1 = &(*aPolyBoxStack.ChangeFirst());
+    }
+  }
 }
 
 //=======================================================================
@@ -1746,18 +1780,21 @@ inline Standard_Boolean BRepMesh_Delaun::meshElementaryPolygon(
 
 //=======================================================================
 //function : meshSimplePolygon
-//purpose  : Triangulatiion of a closed simple polygon (polygon without 
-//           glued edges and loops) described by the list of indexes of 
-//           its edges in the structure.
-//           (negative index means reversed edge)
+//purpose  : 
 //=======================================================================
-void BRepMesh_Delaun::meshSimplePolygon(BRepMesh::SequenceOfInteger& thePolygon,
-                                        BRepMesh::SequenceOfBndB2d&  thePolyBoxes )
+void BRepMesh_Delaun::decomposeSimplePolygon(
+  BRepMesh::SequenceOfInteger& thePolygon,
+  BRepMesh::SequenceOfBndB2d&  thePolyBoxes,
+  BRepMesh::SequenceOfInteger& thePolygonCut,
+  BRepMesh::SequenceOfBndB2d&  thePolyBoxesCut)
 {
   // Check is the given polygon elementary
   if ( meshElementaryPolygon( thePolygon ) )
+  {
+    thePolygon.Clear();
+    thePolyBoxes.Clear();
     return;
-
+  }
 
   // Polygon contains more than 3 links
   Standard_Integer aFirstEdgeInfo = thePolygon(1);
@@ -1774,7 +1811,11 @@ void BRepMesh_Delaun::meshSimplePolygon(BRepMesh::SequenceOfInteger& thePolygon,
 
   Standard_Real aRefEdgeLen = aRefEdgeDir.Magnitude();
   if ( aRefEdgeLen < Precision )
+  {
+    thePolygon.Clear();
+    thePolyBoxes.Clear();
     return;
+  }
 
   aRefEdgeDir /= aRefEdgeLen;
 
@@ -1865,7 +1906,11 @@ void BRepMesh_Delaun::meshSimplePolygon(BRepMesh::SequenceOfInteger& thePolygon,
   }
 
   if ( aUsedLinkId == 0 )
+  {
+    thePolygon.Clear();
+    thePolyBoxes.Clear();
     return;
+  }
 
 
   BRepMesh_Edge aNewEdges[2] = {
@@ -1893,19 +1938,14 @@ void BRepMesh_Delaun::meshSimplePolygon(BRepMesh::SequenceOfInteger& thePolygon,
   // polygon.
   if ( aUsedLinkId < aPolyLen )
   {
-    BRepMesh::SequenceOfInteger aRightPolygon;
-    thePolygon.Split( aUsedLinkId, aRightPolygon );
-    aRightPolygon.Prepend( -aNewEdgesInfo[2] );
-
-    BRepMesh::SequenceOfBndB2d aRightPolyBoxes;
-    thePolyBoxes.Split( aUsedLinkId, aRightPolyBoxes );
+    thePolygon.Split(aUsedLinkId, thePolygonCut);
+    thePolygonCut.Prepend( -aNewEdgesInfo[2] );
+    thePolyBoxes.Split(aUsedLinkId, thePolyBoxesCut);
 
     Bnd_B2d aBox;
     aBox.Add( aRefVertices[0] );
     aBox.Add( aRefVertices[2] );
-    aRightPolyBoxes.Prepend( aBox );
-
-    meshSimplePolygon( aRightPolygon, aRightPolyBoxes );
+    thePolyBoxesCut.Prepend( aBox );
   }
   else
   {
@@ -1922,8 +1962,6 @@ void BRepMesh_Delaun::meshSimplePolygon(BRepMesh::SequenceOfInteger& thePolygon,
     aBox.Add( aRefVertices[2] );
 
     thePolyBoxes.SetValue( 1, aBox );
-
-    meshSimplePolygon( thePolygon, thePolyBoxes );
   }
 }
 
index 527f2ea..b3f7765 100755 (executable)
@@ -196,11 +196,20 @@ private:
                     BRepMesh::SequenceOfBndB2d&  thePolyBoxes,
                     BRepMesh::HMapOfInteger      theSkipped = NULL);
 
-  //! Triangulatiion of a closed simple polygon (polygon without glued edges and loops)
-  //! described by the list of indexes of its edges in the structure.
-  //! (negative index means reversed edge)
-  void meshSimplePolygon (BRepMesh::SequenceOfInteger& thePolygon,
-                          BRepMesh::SequenceOfBndB2d&  thePolyBoxes);
+  //! Decomposes the given closed simple polygon (polygon without glued edges 
+  //! and loops) on two simpler ones by adding new link at the most thin part 
+  //! in respect to end point of the first link.
+  //! In case if source polygon consists of three links, creates new triangle 
+  //! and clears source container.
+  //! @param thePolygon source polygon to be decomposed (first part of decomposition).
+  //! @param thePolyBoxes bounding boxes corresponded to source polygon's links.
+  //! @param thePolygonCut product of decomposition of source polygon (second part of decomposition).
+  //! @param thePolyBoxesCut bounding boxes corresponded to resulting polygon's links.
+  void decomposeSimplePolygon (
+    BRepMesh::SequenceOfInteger& thePolygon,
+    BRepMesh::SequenceOfBndB2d&  thePolyBoxes,
+    BRepMesh::SequenceOfInteger& thePolygonCut,
+    BRepMesh::SequenceOfBndB2d&  thePolyBoxesCut);
 
   //! Triangulation of closed polygon containing only three edges.
   inline Standard_Boolean meshElementaryPolygon (const BRepMesh::SequenceOfInteger& thePolygon);
diff --git a/tests/bugs/mesh/bug25806 b/tests/bugs/mesh/bug25806
new file mode 100644 (file)
index 0000000..30000a2
--- /dev/null
@@ -0,0 +1,14 @@
+puts "========"
+puts "OCC25806"
+puts "========"
+puts ""
+#################################
+# Stack overflow during meshing
+#################################
+
+restore [locate_data_file OCC25806_shape_1040739_1.brep] a
+set bug_info [incmesh a 0.001]
+if {[lindex $bug_info 6] != "NoError"} {
+  puts "ERROR: OCC25806 is reproduced. Errors during meshing."
+}
+