0024624: Lost word in license statement in source files
[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
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
33static const Standard_Integer theStackSize = 20;
34
35//=======================================================================
36//function : TopExp_Explorer
37//purpose :
38//=======================================================================
39
40TopExp_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
53TopExp_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
70void 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
124const 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
146void 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 }
547702a1 177 Standard::Free(myStack);
7fd59977 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 }
547702a1 203 Standard::Free(myStack);
7fd59977 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
232void TopExp_Explorer::ReInit()
233{
234 Init(myShape,toFind,toAvoid);
235}
236
237void TopExp_Explorer::Destroy()
238{
239 if (myStack)
240 {
241 for(int i=0;i<= myTop; i++)myStack[i].~TopoDS_Iterator();
547702a1 242 Standard::Free(myStack);
7fd59977 243 }
244 mySizeOfStack = 0;
245 myStack = 0L;
246}
247