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 | |
35 | static const Standard_Integer theStackSize = 20; |
36 | |
37 | //======================================================================= |
38 | //function : TopExp_Explorer |
39 | //purpose : |
40 | //======================================================================= |
41 | |
42 | TopExp_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 | |
55 | TopExp_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 | |
72 | void 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 | |
126 | const 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 | |
148 | void 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 | |
234 | void TopExp_Explorer::ReInit() |
235 | { |
236 | Init(myShape,toFind,toAvoid); |
237 | } |
238 | |
239 | void 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 | |