diff --git a/src/BRepMesh/BRepMesh.hxx b/src/BRepMesh/BRepMesh.hxx index 139e3804b0..80b2ce0420 100644 --- a/src/BRepMesh/BRepMesh.hxx +++ b/src/BRepMesh/BRepMesh.hxx @@ -127,6 +127,8 @@ namespace BRepMesh typedef NCollection_Handle HDMapOfVertexInteger; typedef NCollection_Handle HDMapOfIntegerListOfXY; typedef NCollection_Handle HVertexTool; + typedef NCollection_Handle HSequenceOfBndB2d; + typedef NCollection_Handle HSequenceOfInteger; //! Other data structures typedef std::pair SegmentsTree; diff --git a/src/BRepMesh/BRepMesh_Delaun.cxx b/src/BRepMesh/BRepMesh_Delaun.cxx index 1bdb69164a..6a1581a63d 100644 --- a/src/BRepMesh/BRepMesh_Delaun.cxx +++ b/src/BRepMesh/BRepMesh_Delaun.cxx @@ -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 aPolyStack; + NCollection_Sequence 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 ); } } diff --git a/src/BRepMesh/BRepMesh_Delaun.hxx b/src/BRepMesh/BRepMesh_Delaun.hxx index 527f2eab5c..b3f7765c22 100755 --- a/src/BRepMesh/BRepMesh_Delaun.hxx +++ b/src/BRepMesh/BRepMesh_Delaun.hxx @@ -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 index 0000000000..30000a2cf9 --- /dev/null +++ b/tests/bugs/mesh/bug25806 @@ -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." +} +