1 // Created on: 1993-01-18
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and / or modify it
9 // under the terms of the GNU Lesser General Public version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 #define No_Standard_NoMoreObject
18 #define No_Standard_NoSuchObject
20 #include <TopExp_Explorer.ixx>
21 #include <TopoDS_Iterator.hxx>
23 #include <Standard.hxx>
24 #include <Standard_NoMoreObject.hxx>
25 #include <Standard_NoSuchObject.hxx>
27 // macro to compare two types of shapes
28 // always True if the first one is SHAPE
29 #define SAMETYPE(x,y) ((x) == (y))
30 #define AVOID(x,y) (((x) == TopAbs_SHAPE) ? Standard_False : (x) == (y))
31 #define LESSCOMPLEX(x,y) ((x) > (y))
33 static const Standard_Integer theStackSize = 20;
35 //=======================================================================
36 //function : TopExp_Explorer
38 //=======================================================================
40 TopExp_Explorer::TopExp_Explorer() :
41 myStack(0L),myTop(-1),hasMore(Standard_False)
43 myStack = (TopoDS_Iterator*)Standard::Allocate(theStackSize*sizeof(TopoDS_Iterator));
44 mySizeOfStack = theStackSize;
48 //=======================================================================
49 //function : TopExp_Explorer
51 //=======================================================================
53 TopExp_Explorer::TopExp_Explorer(const TopoDS_Shape& S,
54 const TopAbs_ShapeEnum ToFind,
55 const TopAbs_ShapeEnum ToAvoid):
56 myStack(0L),myTop(-1),hasMore(Standard_False)
59 myStack = (TopoDS_Iterator*)Standard::Allocate(theStackSize*sizeof(TopoDS_Iterator));
60 mySizeOfStack = theStackSize;
61 Init(S,ToFind,ToAvoid);
65 //=======================================================================
68 //=======================================================================
70 void TopExp_Explorer::Init(const TopoDS_Shape& S,
71 const TopAbs_ShapeEnum ToFind,
72 const TopAbs_ShapeEnum ToAvoid)
75 for(int i=0;i<= myTop; i++)
76 myStack[i].~TopoDS_Iterator();
85 hasMore = Standard_False;
90 // for SOLID, FACE, EDGE ignores the initial orientation
91 TopAbs_ShapeEnum T = myShape.ShapeType();
92 if ((T == TopAbs_SOLID) || (T == TopAbs_FACE) || (T == TopAbs_EDGE))
93 myShape.Orientation(TopAbs_FORWARD);
96 if (toFind == TopAbs_SHAPE)
97 hasMore = Standard_False;
100 TopAbs_ShapeEnum ty = S.ShapeType();
102 if (LESSCOMPLEX(ty,toFind)) {
103 // the first Shape is less complex, nothing to find
104 hasMore = Standard_False;
106 else if (!SAMETYPE(ty,toFind)) {
107 // type is more complex search inside
108 hasMore = Standard_True;
113 hasMore = Standard_True;
119 //=======================================================================
122 //=======================================================================
124 const TopoDS_Shape& TopExp_Explorer::Current()const
126 Standard_NoSuchObject_Raise_if(!hasMore,"TopExp_Explorer::Current");
128 const TopoDS_Shape& S = myStack[myTop].Value();
136 //=======================================================================
139 //=======================================================================
142 #pragma warning(push)
143 #pragma warning(disable: 4291) // to avoid warning when using new(buffer) syntax
146 void TopExp_Explorer::Next()
148 Standard_Integer NewSize;
149 TopoDS_Shape ShapTop;
151 Standard_NoMoreObject_Raise_if(!hasMore,"TopExp_Explorer::Next");
154 // empty stack. Entering the initial shape.
155 ty = myShape.ShapeType();
157 if (SAMETYPE(toFind,ty)) {
158 // already visited once
159 hasMore = Standard_False;
162 else if (AVOID(toAvoid,ty)) {
163 // avoid the top-level
164 hasMore = Standard_False;
168 // push and try to find
169 if(++myTop >= mySizeOfStack) {
170 NewSize = mySizeOfStack + theStackSize;
171 TopExp_Stack newStack = (TopoDS_Iterator*)Standard::Allocate(NewSize*sizeof(TopoDS_Iterator));
173 for ( i =0; i < myTop; i++) {
174 new (&newStack[i]) TopoDS_Iterator(myStack[i]);
175 myStack[i].~TopoDS_Iterator();
177 Standard::Free(myStack);
178 mySizeOfStack = NewSize;
181 new (&myStack[myTop]) TopoDS_Iterator(myShape);
184 else myStack[myTop].Next();
187 if (myStack[myTop].More()) {
188 ShapTop = myStack[myTop].Value();
189 ty = ShapTop.ShapeType();
190 if (SAMETYPE(toFind,ty)) {
191 hasMore = Standard_True;
194 else if (LESSCOMPLEX(toFind,ty) && !AVOID(toAvoid,ty)) {
195 if(++myTop >= mySizeOfStack) {
196 NewSize = mySizeOfStack + theStackSize;
197 TopExp_Stack newStack = (TopoDS_Iterator*)Standard::Allocate(NewSize*sizeof(TopoDS_Iterator));
199 for (i =0; i < myTop; i++) {
200 new (&newStack[i]) TopoDS_Iterator(myStack[i]);
201 myStack[i].~TopoDS_Iterator();
203 Standard::Free(myStack);
204 mySizeOfStack = NewSize;
207 new (&myStack[myTop]) TopoDS_Iterator(ShapTop);
210 myStack[myTop].Next();
214 myStack[myTop].~TopoDS_Iterator();
217 myStack[myTop].Next();
220 hasMore = Standard_False;
227 //=======================================================================
230 //=======================================================================
232 void TopExp_Explorer::ReInit()
234 Init(myShape,toFind,toAvoid);
237 void TopExp_Explorer::Destroy()
241 for(int i=0;i<= myTop; i++)myStack[i].~TopoDS_Iterator();
242 Standard::Free(myStack);