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