Modeling Data - Fixed possible issue with Explorer (#1195)

Add tests for TopExp_Explorer nested iteration and reinitialization
This commit is contained in:
Pasukhin Dmitry
2026-04-07 18:14:35 +01:00
committed by GitHub
parent 0ebbbedb23
commit cf0c71b982
2 changed files with 55 additions and 3 deletions

View File

@@ -131,6 +131,57 @@ TEST(TopExp_Test, CommonVertex)
EXPECT_TRUE(isFound) << "Should find at least one pair of adjacent edges in a box";
}
TEST(TopExp_Test, Explorer_NestedFaceEdge_Terminates)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
// Reproduce the pattern from issue #1194: nested TopExp_Explorer
// iterating edges within faces must terminate.
int aTotalEdgeRefs = 0;
int aFaceCount = 0;
for (TopExp_Explorer aFaceExp(aBox, TopAbs_FACE); aFaceExp.More(); aFaceExp.Next())
{
++aFaceCount;
int anEdgeCount = 0;
for (TopExp_Explorer anEdgeExp(TopoDS::Face(aFaceExp.Current()), TopAbs_EDGE); anEdgeExp.More();
anEdgeExp.Next())
{
ASSERT_FALSE(anEdgeExp.Current().IsNull());
++anEdgeCount;
// Guard against infinite loop
ASSERT_LT(anEdgeCount, 100) << "Edge iteration appears infinite on face " << aFaceCount;
}
EXPECT_EQ(anEdgeCount, 4) << "Each box face should reference exactly 4 edges";
aTotalEdgeRefs += anEdgeCount;
}
EXPECT_EQ(aFaceCount, 6);
EXPECT_EQ(aTotalEdgeRefs, 24) << "6 faces * 4 edges each = 24 edge references";
}
TEST(TopExp_Test, Explorer_ReInit_Terminates)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);
const TopoDS_Shape& aBox = aBoxMaker.Shape();
ASSERT_TRUE(aBoxMaker.IsDone());
// Test that re-initializing an explorer (Clear + Init cycle) works correctly.
TopExp_Explorer anExp;
for (TopExp_Explorer aFaceExp(aBox, TopAbs_FACE); aFaceExp.More(); aFaceExp.Next())
{
const TopoDS_Face& aFace = TopoDS::Face(aFaceExp.Current());
anExp.Init(aFace, TopAbs_EDGE);
int anEdgeCount = 0;
for (; anExp.More(); anExp.Next())
{
++anEdgeCount;
ASSERT_LT(anEdgeCount, 100) << "Edge iteration appears infinite (reused explorer)";
}
EXPECT_EQ(anEdgeCount, 4);
}
}
TEST(TopExp_Test, MapShapesAndAncestors)
{
BRepPrimAPI_MakeBox aBoxMaker(10.0, 20.0, 30.0);

View File

@@ -182,9 +182,10 @@ int TopExp_Explorer::Depth() const noexcept
void TopExp_Explorer::Clear()
{
// Shrink to 0 - NCollection_LocalArray destroys all live elements.
if (myStack.Size() > 0)
myStack.Reallocate(0);
// Reset live iterators to release shape references immediately,
// but keep the array allocation to avoid Reallocate(0)/Reallocate(N) cycles.
for (int i = myStackTop; i >= 0; --i)
myStack[i] = TopoDS_Iterator();
myStackTop = -1;
hasMore = false;
}