-// Created on: 1993-01-18
-// Created by: Remi LEQUETTE
// Copyright (c) 1993-1999 Matra Datavision
-// Copyright (c) 1999-2014 OPEN CASCADE SAS
+// Copyright (c) 1999-2025 OPEN CASCADE SAS
//
// This file is part of Open CASCADE Technology software library.
//
// Alternatively, this file may be used under the terms of Open CASCADE
// commercial license or contractual agreement.
-#define No_Standard_NoMoreObject
-#define No_Standard_NoSuchObject
-
#include <TopExp_Explorer.hxx>
-#include <Standard_NoMoreObject.hxx>
-#include <Standard_NoSuchObject.hxx>
-#include <TopAbs.hxx>
+namespace
+{
+//! Returns true if the given type matches the type to find.
+inline Standard_Boolean isSameType(const TopAbs_ShapeEnum theType,
+ const TopAbs_ShapeEnum toFind) noexcept
+{
+ return toFind == theType;
+}
-// macro to compare two types of shapes
-// always True if the first one is SHAPE
-#define SAMETYPE(x, y) ((x) == (y))
-#define AVOID(x, y) (((x) == TopAbs_SHAPE) ? Standard_False : (x) == (y))
-#define LESSCOMPLEX(x, y) ((x) > (y))
+//! Returns true if the given type should be avoided.
+inline Standard_Boolean shouldAvoid(const TopAbs_ShapeEnum theType,
+ const TopAbs_ShapeEnum toAvoid) noexcept
+{
+ return toAvoid != TopAbs_SHAPE && toAvoid == theType;
+}
-static const Standard_Integer theStackSize = 20;
+//! Returns true if the given type is more complex than the type to find.
+inline Standard_Boolean isMoreComplex(const TopAbs_ShapeEnum theType,
+ const TopAbs_ShapeEnum toFind) noexcept
+{
+ return toFind > theType;
+}
+} // namespace
//=================================================================================================
-TopExp_Explorer::TopExp_Explorer()
- : myStack(0L),
- myTop(-1),
- mySizeOfStack(theStackSize),
+TopExp_Explorer::TopExp_Explorer() noexcept
+ : myStack(20),
toFind(TopAbs_SHAPE),
toAvoid(TopAbs_SHAPE),
hasMore(Standard_False)
{
- myStack = (TopoDS_Iterator*)Standard::Allocate(theStackSize * sizeof(TopoDS_Iterator));
}
//=================================================================================================
-TopExp_Explorer::TopExp_Explorer(const TopoDS_Shape& theS,
- const TopAbs_ShapeEnum theToFind,
- const TopAbs_ShapeEnum theToAvoid)
- : myStack(0L),
- myTop(-1),
- mySizeOfStack(theStackSize),
- toFind(theToFind),
- toAvoid(theToAvoid),
+TopExp_Explorer::TopExp_Explorer(const TopoDS_Shape& S,
+ const TopAbs_ShapeEnum ToFind,
+ const TopAbs_ShapeEnum ToAvoid)
+ : myStack(20),
+ toFind(ToFind),
+ toAvoid(ToAvoid),
hasMore(Standard_False)
{
- myStack = (TopoDS_Iterator*)Standard::Allocate(theStackSize * sizeof(TopoDS_Iterator));
+ Init(S, ToFind, ToAvoid);
+}
- Init(theS, theToFind, theToAvoid);
+//=================================================================================================
+
+TopExp_Explorer::~TopExp_Explorer()
+{
+ Clear();
}
//=================================================================================================
return;
}
-#if 0
- // for SOLID, FACE, EDGE ignores the initial orientation
- TopAbs_ShapeEnum T = myShape.ShapeType();
- if ((T == TopAbs_SOLID) || (T == TopAbs_FACE) || (T == TopAbs_EDGE))
- myShape.Orientation(TopAbs_FORWARD);
-#endif
-
if (toFind == TopAbs_SHAPE)
hasMore = Standard_False;
-
else
{
TopAbs_ShapeEnum ty = S.ShapeType();
- if (LESSCOMPLEX(ty, toFind))
+ if (ty > toFind)
{
- // the first Shape is less complex, nothing to find
hasMore = Standard_False;
}
- else if (!SAMETYPE(ty, toFind))
+ else if (!isSameType(ty, toFind))
{
- // type is more complex search inside
hasMore = Standard_True;
Next();
}
else
{
- // type is found
hasMore = Standard_True;
}
}
//=================================================================================================
-const TopoDS_Shape& TopExp_Explorer::Current() const
-{
- Standard_NoSuchObject_Raise_if(!hasMore, "TopExp_Explorer::Current");
- if (myTop >= 0)
- {
- const TopoDS_Shape& S = myStack[myTop].Value();
- return S;
- }
- else
- return myShape;
-}
-
-//=================================================================================================
-
void TopExp_Explorer::Next()
{
- Standard_Integer NewSize;
- TopoDS_Shape ShapTop;
- TopAbs_ShapeEnum ty;
- Standard_NoMoreObject_Raise_if(!hasMore, "TopExp_Explorer::Next");
-
- if (myTop < 0)
+ if (myStack.IsEmpty())
{
- // empty stack. Entering the initial shape.
- ty = myShape.ShapeType();
+ TopAbs_ShapeEnum ty = myShape.ShapeType();
- if (SAMETYPE(toFind, ty))
+ if (isSameType(ty, toFind))
{
- // already visited once
hasMore = Standard_False;
return;
}
- else if (AVOID(toAvoid, ty))
+ else if (shouldAvoid(ty, toAvoid))
{
- // avoid the top-level
hasMore = Standard_False;
return;
}
else
{
- // push and try to find
- if (++myTop >= mySizeOfStack)
- {
- NewSize = mySizeOfStack + theStackSize;
- TopExp_Stack newStack =
- (TopoDS_Iterator*)Standard::Allocate(NewSize * sizeof(TopoDS_Iterator));
- Standard_Integer i;
- for (i = 0; i < myTop; i++)
- {
- new (&newStack[i]) TopoDS_Iterator(myStack[i]);
- myStack[i].~TopoDS_Iterator();
- }
- Standard::Free(myStack);
- mySizeOfStack = NewSize;
- myStack = newStack;
- }
- new (&myStack[myTop]) TopoDS_Iterator(myShape);
+ myStack.Append(TopoDS_Iterator(myShape));
}
}
else
- myStack[myTop].Next();
+ myStack.ChangeLast().Next();
for (;;)
{
- if (myStack[myTop].More())
+ TopoDS_Iterator& aTopIter = myStack.ChangeLast();
+
+ if (aTopIter.More())
{
- ShapTop = myStack[myTop].Value();
- ty = ShapTop.ShapeType();
- if (SAMETYPE(toFind, ty))
+ const TopoDS_Shape& aShapTop = aTopIter.Value();
+ const TopAbs_ShapeEnum ty = aShapTop.ShapeType();
+
+ if (isSameType(ty, toFind))
{
hasMore = Standard_True;
return;
}
- else if (LESSCOMPLEX(toFind, ty) && !AVOID(toAvoid, ty))
+ else if (isMoreComplex(ty, toFind) && !shouldAvoid(ty, toAvoid))
{
- if (++myTop >= mySizeOfStack)
- {
- NewSize = mySizeOfStack + theStackSize;
- TopExp_Stack newStack =
- (TopoDS_Iterator*)Standard::Allocate(NewSize * sizeof(TopoDS_Iterator));
- Standard_Integer i;
- for (i = 0; i < myTop; i++)
- {
- new (&newStack[i]) TopoDS_Iterator(myStack[i]);
- myStack[i].~TopoDS_Iterator();
- }
- Standard::Free(myStack);
- mySizeOfStack = NewSize;
- myStack = newStack;
- }
- new (&myStack[myTop]) TopoDS_Iterator(ShapTop);
+ myStack.Append(TopoDS_Iterator(aShapTop));
+ // aTopIter reference is now invalid after Append
}
else
{
- myStack[myTop].Next();
+ aTopIter.Next();
}
}
else
{
- myStack[myTop].~TopoDS_Iterator();
- myTop--;
- if (myTop < 0)
+ myStack.EraseLast();
+ if (myStack.IsEmpty())
break;
- myStack[myTop].Next();
+ myStack.ChangeLast().Next();
}
}
hasMore = Standard_False;
//=================================================================================================
-void TopExp_Explorer::ReInit()
+const TopoDS_Shape& TopExp_Explorer::Current() const noexcept
{
- Init(myShape, toFind, toAvoid);
+ return myStack.IsEmpty() ? myShape : myStack.Last().Value();
}
//=================================================================================================
-TopExp_Explorer::~TopExp_Explorer()
+Standard_Integer TopExp_Explorer::Depth() const noexcept
{
- Clear();
- if (myStack)
- {
- Standard::Free(myStack);
- }
- mySizeOfStack = 0;
- myStack = 0L;
+ return myStack.Length();
}
//=================================================================================================
void TopExp_Explorer::Clear()
{
hasMore = Standard_False;
- for (int i = 0; i <= myTop; ++i)
- {
- myStack[i].~TopoDS_Iterator();
- }
- myTop = -1;
+ myStack.Clear();
}
#ifndef _TopExp_Explorer_HeaderFile
#define _TopExp_Explorer_HeaderFile
-#include <TopExp_Stack.hxx>
+#include <NCollection_Vector.hxx>
+#include <TopAbs.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shape.hxx>
DEFINE_STANDARD_ALLOC
//! Creates an empty explorer, becomes useful after Init.
- Standard_EXPORT TopExp_Explorer();
+ Standard_EXPORT TopExp_Explorer() noexcept;
//! Creates an Explorer on the Shape <S>.
//!
const TopAbs_ShapeEnum ToAvoid = TopAbs_SHAPE);
//! Returns True if there are more shapes in the exploration.
- Standard_Boolean More() const { return hasMore; }
+ Standard_Boolean More() const noexcept { return hasMore; }
//! Moves to the next Shape in the exploration.
- //! Exceptions
- //! Standard_NoMoreObject if there are no more shapes to explore.
Standard_EXPORT void Next();
//! Returns the current shape in the exploration.
- //! Exceptions
- //! Standard_NoSuchObject if this explorer has no more shapes to explore.
- const TopoDS_Shape& Value() const { return Current(); }
+ const TopoDS_Shape& Value() const noexcept { return Current(); }
//! Returns the current shape in the exploration.
- //! Exceptions
- //! Standard_NoSuchObject if this explorer has no more shapes to explore.
- Standard_EXPORT const TopoDS_Shape& Current() const;
+ Standard_EXPORT const TopoDS_Shape& Current() const noexcept;
//! Reinitialize the exploration with the original arguments.
- Standard_EXPORT void ReInit();
+ void ReInit() { Init(myShape, toFind, toAvoid); }
//! Return explored shape.
- const TopoDS_Shape& ExploredShape() const { return myShape; }
+ const TopoDS_Shape& ExploredShape() const noexcept { return myShape; }
//! Returns the current depth of the exploration. 0 is
//! the shape to explore itself.
- Standard_Integer Depth() const { return myTop; }
+ Standard_EXPORT Standard_Integer Depth() const noexcept;
- //! Clears the content of the explorer. It will return
- //! False on More().
+ //! Clears the content of the explorer.
Standard_EXPORT void Clear();
//! Destructor.
Standard_EXPORT ~TopExp_Explorer();
private:
- TopExp_Stack myStack;
- TopoDS_Shape myShape;
- Standard_Integer myTop;
- Standard_Integer mySizeOfStack;
- TopAbs_ShapeEnum toFind;
- TopAbs_ShapeEnum toAvoid;
- Standard_Boolean hasMore;
+ NCollection_Vector<TopoDS_Iterator> myStack;
+ TopoDS_Shape myShape;
+ TopAbs_ShapeEnum toFind;
+ TopAbs_ShapeEnum toAvoid;
+ Standard_Boolean hasMore;
};
#endif // _TopExp_Explorer_HeaderFile