1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-08-09 13:22:24 +03:00

0031378: Modeling algorithms - brep incremental mesh is frozen during STEP file loading

Refactoring of BRepMesh_Delaun::isBoundToFrontier() to unwind the recursion loop.
This commit is contained in:
oan
2020-03-12 17:37:09 +03:00
committed by bugmaster
parent 87c7d55469
commit c9125b6232
3 changed files with 59 additions and 40 deletions

View File

@@ -34,6 +34,7 @@
#include <NCollection_Vector.hxx> #include <NCollection_Vector.hxx>
#include <algorithm> #include <algorithm>
#include <stack>
const Standard_Real AngDeviation1Deg = M_PI/180.; const Standard_Real AngDeviation1Deg = M_PI/180.;
const Standard_Real AngDeviation90Deg = 90 * AngDeviation1Deg; const Standard_Real AngDeviation90Deg = 90 * AngDeviation1Deg;
@@ -652,28 +653,30 @@ void BRepMesh_Delaun::insertInternalEdges()
//======================================================================= //=======================================================================
//function : isBoundToFrontier //function : isBoundToFrontier
//purpose : Goes through the neighbour triangles around the given node //purpose :
// started from the given link, returns TRUE if some triangle
// has a bounding frontier edge or FALSE elsewhere.
// Stop link is used to prevent cycles.
// Previous element Id is used to identify next neighbor element.
//======================================================================= //=======================================================================
Standard_Boolean BRepMesh_Delaun::isBoundToFrontier( Standard_Boolean BRepMesh_Delaun::isBoundToFrontier(
const Standard_Integer theRefNodeId, const Standard_Integer theRefNodeId,
const Standard_Integer theRefLinkId, const Standard_Integer theRefLinkId)
const Standard_Integer theStopLinkId,
const Standard_Integer thePrevElementId)
{ {
const BRepMesh_PairOfIndex& aPair = std::stack<Standard_Integer> aLinkStack;
myMeshData->ElementsConnectedTo( theRefLinkId ); TColStd_PackedMapOfInteger aVisitedLinks;
aLinkStack.push (theRefLinkId);
while (!aLinkStack.empty ())
{
const Standard_Integer aCurrentLinkId = aLinkStack.top ();
aLinkStack.pop ();
const BRepMesh_PairOfIndex& aPair = myMeshData->ElementsConnectedTo (aCurrentLinkId);
if (aPair.IsEmpty ()) if (aPair.IsEmpty ())
return Standard_False; return Standard_False;
Standard_Integer aNbElements = aPair.Extent(); const Standard_Integer aNbElements = aPair.Extent ();
for (Standard_Integer anElemIt = 1; anElemIt <= aNbElements; ++anElemIt) for (Standard_Integer anElemIt = 1; anElemIt <= aNbElements; ++anElemIt)
{ {
const Standard_Integer aTriId = aPair.Index (anElemIt); const Standard_Integer aTriId = aPair.Index (anElemIt);
if ( aTriId < 0 || aTriId == thePrevElementId ) if (aTriId < 0)
continue; continue;
const BRepMesh_Triangle& aElement = GetTriangle (aTriId); const BRepMesh_Triangle& aElement = GetTriangle (aTriId);
@@ -682,12 +685,9 @@ Standard_Boolean BRepMesh_Delaun::isBoundToFrontier(
for (Standard_Integer anEdgeIt = 0; anEdgeIt < 3; ++anEdgeIt) for (Standard_Integer anEdgeIt = 0; anEdgeIt < 3; ++anEdgeIt)
{ {
const Standard_Integer anEdgeId = anEdges[anEdgeIt]; const Standard_Integer anEdgeId = anEdges[anEdgeIt];
if ( anEdgeId == theRefLinkId ) if (anEdgeId == aCurrentLinkId)
continue; continue;
if ( anEdgeId == theStopLinkId )
return Standard_False;
const BRepMesh_Edge& anEdge = GetEdge (anEdgeId); const BRepMesh_Edge& anEdge = GetEdge (anEdgeId);
if (anEdge.FirstNode () != theRefNodeId && if (anEdge.FirstNode () != theRefNodeId &&
anEdge.LastNode () != theRefNodeId) anEdge.LastNode () != theRefNodeId)
@@ -698,7 +698,11 @@ Standard_Boolean BRepMesh_Delaun::isBoundToFrontier(
if (anEdge.Movability () != BRepMesh_Free) if (anEdge.Movability () != BRepMesh_Free)
return Standard_True; return Standard_True;
return isBoundToFrontier( theRefNodeId, anEdgeId, theStopLinkId, aTriId ); if (aVisitedLinks.Add (anEdgeId))
{
aLinkStack.push (anEdgeId);
}
}
} }
} }
@@ -792,8 +796,7 @@ void BRepMesh_Delaun::cleanupMesh()
for ( Standard_Integer aLinkNodeIt = 0; aLinkNodeIt < 2; ++aLinkNodeIt ) for ( Standard_Integer aLinkNodeIt = 0; aLinkNodeIt < 2; ++aLinkNodeIt )
{ {
isConnected[aLinkNodeIt] = isBoundToFrontier( ( aLinkNodeIt == 0 ) ? isConnected[aLinkNodeIt] = isBoundToFrontier( ( aLinkNodeIt == 0 ) ?
anEdge.FirstNode() : anEdge.LastNode(), anEdge.FirstNode() : anEdge.LastNode(), aFreeEdgeId);
aFreeEdgeId, aFreeEdgeId, -1);
} }
if ( !isConnected[0] || !isConnected[1] ) if ( !isConnected[0] || !isConnected[1] )

View File

@@ -292,12 +292,8 @@ private:
//! Goes through the neighbour triangles around the given node started //! Goes through the neighbour triangles around the given node started
//! from the given link, returns TRUE if some triangle has a bounding //! from the given link, returns TRUE if some triangle has a bounding
//! frontier edge or FALSE elsewhere. //! frontier edge or FALSE elsewhere.
//! Stop link is used to prevent cycles.
//! Previous element Id is used to identify next neighbor element.
Standard_Boolean isBoundToFrontier (const Standard_Integer theRefNodeId, Standard_Boolean isBoundToFrontier (const Standard_Integer theRefNodeId,
const Standard_Integer theRefLinkId, const Standard_Integer theRefLinkId);
const Standard_Integer theStopLinkId,
const Standard_Integer thePrevElementId);
//! Remove internal triangles from the given polygon. //! Remove internal triangles from the given polygon.
void cleanupPolygon (const IMeshData::SequenceOfInteger& thePolygon, void cleanupPolygon (const IMeshData::SequenceOfInteger& thePolygon,

20
tests/bugs/mesh/bug31378 Normal file
View File

@@ -0,0 +1,20 @@
puts "======="
puts "0031378: Modeling algorithms - brep incremental mesh is frozen during STEP file loading"
puts "======="
puts ""
pload ALL
ReadStep D [locate_data_file bug31378_lego-FP.stp]
XGetOneShape result D
incmesh result 1.7 -parallel
vinit
vdefaults -autoTriang 0
vsetdispmode 1
vdisplay result
vfit
checktrinfo result -tri
checkview -screenshot -3d -path ${imagedir}/${test_image}.png