0022972: Eliminate macro definitions that has compiler-provided analogs (WNT and...
[occt.git] / src / TopExp / TopExp_Explorer.cxx
CommitLineData
b311480e 1// Created on: 1993-01-18
2// Created by: Remi LEQUETTE
3// Copyright (c) 1993-1999 Matra Datavision
973c2be1 4// Copyright (c) 1999-2014 OPEN CASCADE SAS
b311480e 5//
973c2be1 6// This file is part of Open CASCADE Technology software library.
b311480e 7//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 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.
b311480e 13//
973c2be1 14// Alternatively, this file may be used under the terms of Open CASCADE
15// commercial license or contractual agreement.
7fd59977 16
17#define No_Standard_NoMoreObject
18#define No_Standard_NoSuchObject
19
42cf5bc1 20
7fd59977 21#include <Standard.hxx>
22#include <Standard_NoMoreObject.hxx>
23#include <Standard_NoSuchObject.hxx>
42cf5bc1 24#include <TopAbs.hxx>
25#include <TopExp_Explorer.hxx>
26#include <TopoDS_Iterator.hxx>
27#include <TopoDS_Shape.hxx>
7fd59977 28
29// macro to compare two types of shapes
30// always True if the first one is SHAPE
31#define SAMETYPE(x,y) ((x) == (y))
32#define AVOID(x,y) (((x) == TopAbs_SHAPE) ? Standard_False : (x) == (y))
33#define LESSCOMPLEX(x,y) ((x) > (y))
34
35static const Standard_Integer theStackSize = 20;
36
37//=======================================================================
38//function : TopExp_Explorer
39//purpose :
40//=======================================================================
41
42TopExp_Explorer::TopExp_Explorer() :
43 myStack(0L),myTop(-1),hasMore(Standard_False)
44{
45 myStack = (TopoDS_Iterator*)Standard::Allocate(theStackSize*sizeof(TopoDS_Iterator));
46 mySizeOfStack = theStackSize;
47}
48
49
50//=======================================================================
51//function : TopExp_Explorer
52//purpose :
53//=======================================================================
54
55TopExp_Explorer::TopExp_Explorer(const TopoDS_Shape& S,
56 const TopAbs_ShapeEnum ToFind,
57 const TopAbs_ShapeEnum ToAvoid):
58 myStack(0L),myTop(-1),hasMore(Standard_False)
59
60{
61 myStack = (TopoDS_Iterator*)Standard::Allocate(theStackSize*sizeof(TopoDS_Iterator));
62 mySizeOfStack = theStackSize;
63 Init(S,ToFind,ToAvoid);
64}
65
66
67//=======================================================================
68//function : Init
69//purpose :
70//=======================================================================
71
72void TopExp_Explorer::Init(const TopoDS_Shape& S,
73 const TopAbs_ShapeEnum ToFind,
74 const TopAbs_ShapeEnum ToAvoid)
75{
76 if(myTop >=0) {
77 for(int i=0;i<= myTop; i++)
78 myStack[i].~TopoDS_Iterator();
79 }
80
81 myTop = -1;
82 myShape = S;
83 toFind = ToFind;
84 toAvoid = ToAvoid;
85
86 if (S.IsNull()) {
87 hasMore = Standard_False;
88 return;
89 }
90
91#if 0
92 // for SOLID, FACE, EDGE ignores the initial orientation
93 TopAbs_ShapeEnum T = myShape.ShapeType();
94 if ((T == TopAbs_SOLID) || (T == TopAbs_FACE) || (T == TopAbs_EDGE))
95 myShape.Orientation(TopAbs_FORWARD);
96#endif
97
98 if (toFind == TopAbs_SHAPE)
99 hasMore = Standard_False;
100
101 else {
102 TopAbs_ShapeEnum ty = S.ShapeType();
103
104 if (LESSCOMPLEX(ty,toFind)) {
105 // the first Shape is less complex, nothing to find
106 hasMore = Standard_False;
107 }
108 else if (!SAMETYPE(ty,toFind)) {
109 // type is more complex search inside
110 hasMore = Standard_True;
111 Next();
112 }
113 else {
114 // type is found
115 hasMore = Standard_True;
116 }
117 }
118}
119
120
121//=======================================================================
122//function : Current
123//purpose :
124//=======================================================================
125
126const TopoDS_Shape& TopExp_Explorer::Current()const
127{
128 Standard_NoSuchObject_Raise_if(!hasMore,"TopExp_Explorer::Current");
129 if (myTop >= 0) {
130 const TopoDS_Shape& S = myStack[myTop].Value();
131 return S;
132 }
133 else
134 return myShape;
135}
136
137
138//=======================================================================
139//function : Next
140//purpose :
141//=======================================================================
142
57c28b61 143#ifdef _MSC_VER
7fd59977 144#pragma warning(push)
145#pragma warning(disable: 4291) // to avoid warning when using new(buffer) syntax
146#endif
147
148void TopExp_Explorer::Next()
149{
150 Standard_Integer NewSize;
151 TopoDS_Shape ShapTop;
152 TopAbs_ShapeEnum ty;
153 Standard_NoMoreObject_Raise_if(!hasMore,"TopExp_Explorer::Next");
154
155 if (myTop < 0) {
156 // empty stack. Entering the initial shape.
157 ty = myShape.ShapeType();
158
159 if (SAMETYPE(toFind,ty)) {
160 // already visited once
161 hasMore = Standard_False;
162 return;
163 }
164 else if (AVOID(toAvoid,ty)) {
165 // avoid the top-level
166 hasMore = Standard_False;
167 return;
168 }
169 else {
170 // push and try to find
171 if(++myTop >= mySizeOfStack) {
172 NewSize = mySizeOfStack + theStackSize;
173 TopExp_Stack newStack = (TopoDS_Iterator*)Standard::Allocate(NewSize*sizeof(TopoDS_Iterator));
174 Standard_Integer i;
175 for ( i =0; i < myTop; i++) {
176 new (&newStack[i]) TopoDS_Iterator(myStack[i]);
177 myStack[i].~TopoDS_Iterator();
178 }
547702a1 179 Standard::Free(myStack);
7fd59977 180 mySizeOfStack = NewSize;
181 myStack = newStack;
182 }
183 new (&myStack[myTop]) TopoDS_Iterator(myShape);
184 }
185 }
186 else myStack[myTop].Next();
187
188 for (;;) {
189 if (myStack[myTop].More()) {
190 ShapTop = myStack[myTop].Value();
191 ty = ShapTop.ShapeType();
192 if (SAMETYPE(toFind,ty)) {
193 hasMore = Standard_True;
194 return;
195 }
196 else if (LESSCOMPLEX(toFind,ty) && !AVOID(toAvoid,ty)) {
197 if(++myTop >= mySizeOfStack) {
198 NewSize = mySizeOfStack + theStackSize;
199 TopExp_Stack newStack = (TopoDS_Iterator*)Standard::Allocate(NewSize*sizeof(TopoDS_Iterator));
200 Standard_Integer i;
201 for (i =0; i < myTop; i++) {
202 new (&newStack[i]) TopoDS_Iterator(myStack[i]);
203 myStack[i].~TopoDS_Iterator();
204 }
547702a1 205 Standard::Free(myStack);
7fd59977 206 mySizeOfStack = NewSize;
207 myStack = newStack;
208 }
209 new (&myStack[myTop]) TopoDS_Iterator(ShapTop);
210 }
211 else {
212 myStack[myTop].Next();
213 }
214 }
215 else {
216 myStack[myTop].~TopoDS_Iterator();
217 myTop--;
218 if(myTop < 0) break;
219 myStack[myTop].Next();
220 }
221 }
222 hasMore = Standard_False;
223}
224
57c28b61 225#ifdef _MSC_VER
7fd59977 226#pragma warning(pop)
227#endif
228
229//=======================================================================
230//function : ReInit
231//purpose :
232//=======================================================================
233
234void TopExp_Explorer::ReInit()
235{
236 Init(myShape,toFind,toAvoid);
237}
238
239void TopExp_Explorer::Destroy()
240{
241 if (myStack)
242 {
243 for(int i=0;i<= myTop; i++)myStack[i].~TopoDS_Iterator();
547702a1 244 Standard::Free(myStack);
7fd59977 245 }
246 mySizeOfStack = 0;
247 myStack = 0L;
248}
249