0024530: TKMesh - remove unused package IntPoly
[occt.git] / src / TopExp / TopExp_Explorer.cxx
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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17 #define No_Standard_NoMoreObject
18 #define No_Standard_NoSuchObject
19
20 #include <TopExp_Explorer.ixx>
21 #include <TopoDS_Iterator.hxx>
22 #include <TopAbs.hxx>
23 #include <Standard.hxx>
24 #include <Standard_NoMoreObject.hxx>
25 #include <Standard_NoSuchObject.hxx>
26
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))
32
33 static const Standard_Integer theStackSize = 20;
34
35 //=======================================================================
36 //function : TopExp_Explorer
37 //purpose  : 
38 //=======================================================================
39
40 TopExp_Explorer::TopExp_Explorer() :
41     myStack(0L),myTop(-1),hasMore(Standard_False)
42 {
43   myStack = (TopoDS_Iterator*)Standard::Allocate(theStackSize*sizeof(TopoDS_Iterator));
44   mySizeOfStack = theStackSize;
45 }
46
47
48 //=======================================================================
49 //function : TopExp_Explorer
50 //purpose  : 
51 //=======================================================================
52
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)
57
58 {
59   myStack = (TopoDS_Iterator*)Standard::Allocate(theStackSize*sizeof(TopoDS_Iterator));
60   mySizeOfStack = theStackSize;
61   Init(S,ToFind,ToAvoid);
62 }
63
64
65 //=======================================================================
66 //function : Init
67 //purpose  : 
68 //=======================================================================
69
70 void  TopExp_Explorer::Init(const TopoDS_Shape& S, 
71                             const TopAbs_ShapeEnum ToFind, 
72                             const TopAbs_ShapeEnum ToAvoid)
73 {
74   if(myTop >=0) {
75     for(int i=0;i<= myTop; i++)
76       myStack[i].~TopoDS_Iterator();
77   }
78   
79   myTop   = -1;
80   myShape = S;
81   toFind  = ToFind;
82   toAvoid = ToAvoid;
83
84   if (S.IsNull()) {
85      hasMore = Standard_False;
86      return;
87   }
88
89 #if 0
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);
94 #endif
95
96   if (toFind == TopAbs_SHAPE)
97     hasMore = Standard_False;
98
99   else {
100     TopAbs_ShapeEnum ty = S.ShapeType();
101
102     if (LESSCOMPLEX(ty,toFind)) {
103       // the first Shape is less complex, nothing to find
104       hasMore = Standard_False;
105     }
106     else if (!SAMETYPE(ty,toFind)) {
107       // type is more complex search inside
108       hasMore = Standard_True;
109       Next();
110     }
111     else {
112       // type is found
113       hasMore = Standard_True;
114     }
115   }
116 }
117
118
119 //=======================================================================
120 //function : Current
121 //purpose  : 
122 //=======================================================================
123
124 const TopoDS_Shape&  TopExp_Explorer::Current()const 
125 {
126   Standard_NoSuchObject_Raise_if(!hasMore,"TopExp_Explorer::Current");
127   if (myTop >= 0) {
128     const TopoDS_Shape& S = myStack[myTop].Value();
129     return S;
130   }
131   else
132     return myShape;
133 }
134
135
136 //=======================================================================
137 //function : Next
138 //purpose  : 
139 //=======================================================================
140
141 #ifdef WNT
142 #pragma warning(push)
143 #pragma warning(disable: 4291) // to avoid warning when using new(buffer) syntax
144 #endif
145
146 void  TopExp_Explorer::Next()
147 {
148   Standard_Integer NewSize;
149   TopoDS_Shape ShapTop;
150   TopAbs_ShapeEnum ty;
151   Standard_NoMoreObject_Raise_if(!hasMore,"TopExp_Explorer::Next");
152
153   if (myTop < 0) {
154     // empty stack. Entering the initial shape.
155     ty = myShape.ShapeType();
156
157     if (SAMETYPE(toFind,ty)) {
158       // already visited once
159       hasMore = Standard_False;
160       return;
161     }
162     else if (AVOID(toAvoid,ty)) {
163       // avoid the top-level
164       hasMore = Standard_False;
165       return;
166     }
167     else {
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));
172         Standard_Integer i;
173         for ( i =0; i < myTop; i++) {
174           new (&newStack[i]) TopoDS_Iterator(myStack[i]);
175           myStack[i].~TopoDS_Iterator();
176         }
177         Standard::Free(myStack);
178         mySizeOfStack = NewSize;
179         myStack = newStack;
180       }
181       new (&myStack[myTop]) TopoDS_Iterator(myShape);
182     }
183   }
184   else myStack[myTop].Next();
185
186   for (;;) {
187     if (myStack[myTop].More()) {
188       ShapTop = myStack[myTop].Value();
189       ty = ShapTop.ShapeType();
190       if (SAMETYPE(toFind,ty)) {
191         hasMore = Standard_True;
192         return;
193       }
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));
198           Standard_Integer i;
199           for (i =0; i < myTop; i++) {
200             new (&newStack[i]) TopoDS_Iterator(myStack[i]);
201             myStack[i].~TopoDS_Iterator();
202           }
203           Standard::Free(myStack);
204           mySizeOfStack = NewSize;
205           myStack = newStack;
206         }
207         new (&myStack[myTop]) TopoDS_Iterator(ShapTop);
208       }
209       else {
210         myStack[myTop].Next();
211       }
212     }
213     else {
214       myStack[myTop].~TopoDS_Iterator();
215       myTop--;
216       if(myTop < 0) break;
217       myStack[myTop].Next();
218     }
219   }
220   hasMore = Standard_False;
221 }
222
223 #ifdef WNT
224 #pragma warning(pop)
225 #endif
226
227 //=======================================================================
228 //function : ReInit
229 //purpose  : 
230 //=======================================================================
231
232 void  TopExp_Explorer::ReInit()
233 {
234   Init(myShape,toFind,toAvoid);
235 }
236
237 void  TopExp_Explorer::Destroy()
238 {
239   if (myStack) 
240     {
241       for(int i=0;i<= myTop; i++)myStack[i].~TopoDS_Iterator();
242       Standard::Free(myStack);
243     }
244   mySizeOfStack = 0;
245   myStack = 0L;
246 }
247