mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-05-10 09:30:48 +08:00
Foundation Classes - Performance improvements for TopExp package (#831)
- Replaced raw pointer-based stack (`TopExp_Stack`) with `NCollection_Vector<TopoDS_Iterator>` - Mark some methods noexcept - Removed `myTop` field
This commit is contained in:
@@ -6,5 +6,4 @@ set(OCCT_TopExp_FILES
|
||||
TopExp.hxx
|
||||
TopExp_Explorer.cxx
|
||||
TopExp_Explorer.hxx
|
||||
TopExp_Stack.hxx
|
||||
)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
// 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.
|
||||
//
|
||||
@@ -14,51 +12,60 @@
|
||||
// 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();
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@@ -79,34 +86,23 @@ void TopExp_Explorer::Init(const TopoDS_Shape& S,
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -114,110 +110,60 @@ void TopExp_Explorer::Init(const TopoDS_Shape& S,
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
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;
|
||||
@@ -225,22 +171,16 @@ void TopExp_Explorer::Next()
|
||||
|
||||
//=================================================================================================
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
//=================================================================================================
|
||||
@@ -248,9 +188,5 @@ TopExp_Explorer::~TopExp_Explorer()
|
||||
void TopExp_Explorer::Clear()
|
||||
{
|
||||
hasMore = Standard_False;
|
||||
for (int i = 0; i <= myTop; ++i)
|
||||
{
|
||||
myStack[i].~TopoDS_Iterator();
|
||||
}
|
||||
myTop = -1;
|
||||
myStack.Clear();
|
||||
}
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
#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>
|
||||
|
||||
@@ -84,7 +85,7 @@ public:
|
||||
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>.
|
||||
//!
|
||||
@@ -110,48 +111,39 @@ public:
|
||||
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
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
// Created on: 1990-12-20
|
||||
// Created by: Remi Lequette
|
||||
// Copyright (c) 1990-1999 Matra Datavision
|
||||
// Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
//
|
||||
// This file is part of Open CASCADE Technology software library.
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or modify it under
|
||||
// the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
// by the Free Software Foundation, with special exception defined in the file
|
||||
// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
// distribution for complete text of the license and disclaimer of any warranty.
|
||||
//
|
||||
// Alternatively, this file may be used under the terms of Open CASCADE
|
||||
// commercial license or contractual agreement.
|
||||
|
||||
#ifndef _TopExp_Stack_HeaderFile
|
||||
#define _TopExp_Stack_HeaderFile
|
||||
|
||||
class TopoDS_Iterator;
|
||||
typedef TopoDS_Iterator* TopExp_Stack;
|
||||
|
||||
#endif // _TopExp_Stack_HeaderFile
|
||||
Reference in New Issue
Block a user