1
0
mirror of https://git.dev.opencascade.org/repos/occt.git synced 2025-04-10 18:51:21 +03:00
occt/src/TopExp/TopExp_Explorer.cxx
akz 57c28b6122 0022972: Eliminate macro definitions that has compiler-provided analogs (WNT and so on)
1) Macro definition WNT replaced by _WIN32 and _MSC_VER for platform and compiler detection accordingly.
2) Macro definition LIN replaced by __linux__ macro.
3) Macro definition DEB replaced by OCCT_DEBUG macro.
2015-09-24 14:13:06 +03:00

250 lines
6.5 KiB
C++

// Created on: 1993-01-18
// Created by: Remi LEQUETTE
// Copyright (c) 1993-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.
#define No_Standard_NoMoreObject
#define No_Standard_NoSuchObject
#include <Standard.hxx>
#include <Standard_NoMoreObject.hxx>
#include <Standard_NoSuchObject.hxx>
#include <TopAbs.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopoDS_Shape.hxx>
// 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))
static const Standard_Integer theStackSize = 20;
//=======================================================================
//function : TopExp_Explorer
//purpose :
//=======================================================================
TopExp_Explorer::TopExp_Explorer() :
myStack(0L),myTop(-1),hasMore(Standard_False)
{
myStack = (TopoDS_Iterator*)Standard::Allocate(theStackSize*sizeof(TopoDS_Iterator));
mySizeOfStack = theStackSize;
}
//=======================================================================
//function : TopExp_Explorer
//purpose :
//=======================================================================
TopExp_Explorer::TopExp_Explorer(const TopoDS_Shape& S,
const TopAbs_ShapeEnum ToFind,
const TopAbs_ShapeEnum ToAvoid):
myStack(0L),myTop(-1),hasMore(Standard_False)
{
myStack = (TopoDS_Iterator*)Standard::Allocate(theStackSize*sizeof(TopoDS_Iterator));
mySizeOfStack = theStackSize;
Init(S,ToFind,ToAvoid);
}
//=======================================================================
//function : Init
//purpose :
//=======================================================================
void TopExp_Explorer::Init(const TopoDS_Shape& S,
const TopAbs_ShapeEnum ToFind,
const TopAbs_ShapeEnum ToAvoid)
{
if(myTop >=0) {
for(int i=0;i<= myTop; i++)
myStack[i].~TopoDS_Iterator();
}
myTop = -1;
myShape = S;
toFind = ToFind;
toAvoid = ToAvoid;
if (S.IsNull()) {
hasMore = Standard_False;
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)) {
// the first Shape is less complex, nothing to find
hasMore = Standard_False;
}
else if (!SAMETYPE(ty,toFind)) {
// type is more complex search inside
hasMore = Standard_True;
Next();
}
else {
// type is found
hasMore = Standard_True;
}
}
}
//=======================================================================
//function : Current
//purpose :
//=======================================================================
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;
}
//=======================================================================
//function : Next
//purpose :
//=======================================================================
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4291) // to avoid warning when using new(buffer) syntax
#endif
void TopExp_Explorer::Next()
{
Standard_Integer NewSize;
TopoDS_Shape ShapTop;
TopAbs_ShapeEnum ty;
Standard_NoMoreObject_Raise_if(!hasMore,"TopExp_Explorer::Next");
if (myTop < 0) {
// empty stack. Entering the initial shape.
ty = myShape.ShapeType();
if (SAMETYPE(toFind,ty)) {
// already visited once
hasMore = Standard_False;
return;
}
else if (AVOID(toAvoid,ty)) {
// 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);
}
}
else myStack[myTop].Next();
for (;;) {
if (myStack[myTop].More()) {
ShapTop = myStack[myTop].Value();
ty = ShapTop.ShapeType();
if (SAMETYPE(toFind,ty)) {
hasMore = Standard_True;
return;
}
else if (LESSCOMPLEX(toFind,ty) && !AVOID(toAvoid,ty)) {
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);
}
else {
myStack[myTop].Next();
}
}
else {
myStack[myTop].~TopoDS_Iterator();
myTop--;
if(myTop < 0) break;
myStack[myTop].Next();
}
}
hasMore = Standard_False;
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif
//=======================================================================
//function : ReInit
//purpose :
//=======================================================================
void TopExp_Explorer::ReInit()
{
Init(myShape,toFind,toAvoid);
}
void TopExp_Explorer::Destroy()
{
if (myStack)
{
for(int i=0;i<= myTop; i++)myStack[i].~TopoDS_Iterator();
Standard::Free(myStack);
}
mySizeOfStack = 0;
myStack = 0L;
}