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:
@@ -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] )
|
||||||
|
@@ -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
20
tests/bugs/mesh/bug31378
Normal 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
|
Reference in New Issue
Block a user