b311480e |
1 | // Created on: 1995-12-21 |
2 | // Created by: Jean Yves LEBEY |
3 | // Copyright (c) 1995-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 | // " Voyager, c'est bien utile, ca fait travailler l'imagination. |
18 | // Tout le reste n'est que deceptions et fatigues. Notre voyage |
19 | // a nous est entierement imaginaire. Voila sa force. " |
20 | // Celine |
21 | // Voyage au bout de la nuit |
22 | |
7fd59977 |
23 | #include <Standard_DomainError.hxx> |
24 | #include <TopAbs.hxx> |
42cf5bc1 |
25 | #include <TopOpeBRepBuild_AreaBuilder.hxx> |
26 | #include <TopOpeBRepBuild_Loop.hxx> |
27 | #include <TopOpeBRepBuild_LoopClassifier.hxx> |
28 | #include <TopOpeBRepBuild_LoopSet.hxx> |
7fd59977 |
29 | |
7fd59977 |
30 | //======================================================================= |
31 | //function : TopOpeBRepBuild_AreaBuilder |
32 | //purpose : |
33 | //======================================================================= |
34 | |
35 | TopOpeBRepBuild_AreaBuilder::TopOpeBRepBuild_AreaBuilder() : |
36 | myUNKNOWNRaise(Standard_False) // no raise if UNKNOWN state found |
37 | { |
38 | } |
39 | |
40 | //======================================================================= |
41 | //function : TopOpeBRepBuild_AreaBuilder |
42 | //purpose : |
43 | //======================================================================= |
44 | |
45 | TopOpeBRepBuild_AreaBuilder::TopOpeBRepBuild_AreaBuilder |
46 | (TopOpeBRepBuild_LoopSet& LS, |
47 | TopOpeBRepBuild_LoopClassifier& LC, |
48 | const Standard_Boolean ForceClass) : |
49 | myUNKNOWNRaise(Standard_False) // no raise if UNKNOWN state found |
50 | { |
51 | InitAreaBuilder(LS,LC,ForceClass); |
52 | } |
53 | |
e6f550da |
54 | TopOpeBRepBuild_AreaBuilder::~TopOpeBRepBuild_AreaBuilder() |
7fd59977 |
55 | {} |
56 | |
57 | //======================================================================= |
58 | //function : CompareLoopWithListOfLoop |
59 | //purpose : Compare position of the Loop <L> with the Area <LOL> |
60 | // using the Loop Classifier <LC>. |
61 | // According to <whattotest>, Loops of <LOL> are selected or not |
62 | // during <LOL> exploration. |
63 | //result : TopAbs_OUT if <LOL> is empty |
64 | // TopAbs_UNKNOWN if position undefined |
65 | // TopAbs_IN if <L> is inside all the selected Loops of <LOL> |
66 | // TopAbs_OUT if <L> is outside one of the selected Loops of <LOL> |
67 | // TopAbs_ON if <L> is on one of the selected Loops of <LOL> |
68 | //======================================================================= |
69 | TopAbs_State TopOpeBRepBuild_AreaBuilder::CompareLoopWithListOfLoop |
70 | (TopOpeBRepBuild_LoopClassifier &LC, |
71 | const Handle(TopOpeBRepBuild_Loop)& L, |
72 | const TopOpeBRepBuild_ListOfLoop &LOL, |
73 | const TopOpeBRepBuild_LoopEnum what) const |
74 | { |
75 | TopAbs_State state = TopAbs_UNKNOWN; |
76 | Standard_Boolean totest; // L must or not be tested |
77 | TopOpeBRepBuild_ListIteratorOfListOfLoop LoopIter; |
78 | |
79 | if ( LOL.IsEmpty() ) return TopAbs_OUT; |
80 | |
81 | for ( LoopIter.Initialize(LOL); LoopIter.More(); LoopIter.Next() ) { |
82 | const Handle(TopOpeBRepBuild_Loop)& curL = LoopIter.Value(); |
83 | switch ( what ) { |
84 | case TopOpeBRepBuild_ANYLOOP : totest = Standard_True;break; |
85 | case TopOpeBRepBuild_BOUNDARY : totest = curL->IsShape();break; |
86 | case TopOpeBRepBuild_BLOCK : totest = !curL->IsShape();break; |
87 | default : totest = Standard_False; |
88 | } |
89 | if ( totest ) { |
90 | state = LC.Compare(L,curL); |
91 | if (state == TopAbs_OUT) |
92 | // <L> is out of at least one Loop of <LOL> : stop to explore |
93 | break; |
94 | } |
95 | } |
96 | |
97 | return state; |
98 | } |
99 | |
100 | //======================================================================= |
101 | //function : Atomize |
102 | //purpose : myUNKNOWNRaise = True --> raise if <state> = UNKNOWN |
103 | // myUNKNOWNRaise = False--> assign a new value <newstate> to <state> |
104 | //======================================================================= |
105 | |
106 | void TopOpeBRepBuild_AreaBuilder::Atomize(TopAbs_State& state, |
107 | const TopAbs_State newstate) const |
108 | { |
109 | if (myUNKNOWNRaise) { |
110 | Standard_DomainError_Raise_if((state == TopAbs_UNKNOWN), |
111 | "AreaBuilder : Position Unknown"); |
112 | } |
113 | else { |
7fd59977 |
114 | state = newstate; |
115 | } |
116 | } |
117 | |
118 | |
119 | //======================================================================= |
120 | //function : InitAreaBuilder |
121 | //purpose : |
122 | //======================================================================= |
123 | |
124 | void TopOpeBRepBuild_AreaBuilder::InitAreaBuilder |
125 | (TopOpeBRepBuild_LoopSet& LS, |
126 | TopOpeBRepBuild_LoopClassifier& LC, |
127 | const Standard_Boolean ForceClass) |
128 | { |
129 | TopAbs_State state; |
130 | Standard_Boolean Loopinside; |
131 | Standard_Boolean loopoutside; |
132 | |
133 | TopOpeBRepBuild_ListIteratorOfListOfListOfLoop AreaIter; |
134 | TopOpeBRepBuild_ListIteratorOfListOfLoop LoopIter; |
135 | // boundaryloops : list of boundary loops out of the areas. |
136 | TopOpeBRepBuild_ListOfLoop boundaryloops; |
137 | |
138 | myArea.Clear(); // Clear the list of Area to be built |
139 | |
140 | for (LS.InitLoop(); LS.MoreLoop(); LS.NextLoop()) { |
141 | |
142 | // process a new loop : L is the new current Loop |
143 | const Handle(TopOpeBRepBuild_Loop)& L = LS.Loop(); |
144 | Standard_Boolean boundaryL = L->IsShape(); |
145 | |
146 | // L = Shape et ForceClass : on traite L comme un block |
147 | // L = Shape et !ForceClass : on traite L comme un pur Shape |
148 | // L = !Shape : on traite L comme un block |
149 | Standard_Boolean traitercommeblock = (!boundaryL) || ForceClass; |
150 | if ( ! traitercommeblock ) { |
151 | |
152 | // the loop L is a boundary loop : |
153 | // - try to insert it in an existing area, such as L is inside all |
154 | // the block loops. Only block loops of the area are compared. |
155 | // - if L could not be inserted, store it in list of boundary loops. |
156 | |
157 | Loopinside = Standard_False; |
158 | for (AreaIter.Initialize(myArea); AreaIter.More(); AreaIter.Next()) { |
159 | TopOpeBRepBuild_ListOfLoop& aArea = AreaIter.Value(); |
160 | if ( aArea.IsEmpty() ) continue; |
161 | state = CompareLoopWithListOfLoop(LC,L,aArea,TopOpeBRepBuild_BLOCK ); |
162 | if (state == TopAbs_UNKNOWN) Atomize(state,TopAbs_IN); |
163 | Loopinside = ( state == TopAbs_IN); |
164 | if ( Loopinside ) break; |
165 | } // end of Area scan |
166 | |
167 | if ( Loopinside ) { |
168 | TopOpeBRepBuild_ListOfLoop& aArea = AreaIter.Value(); |
169 | ADD_Loop_TO_LISTOFLoop(L,aArea,(void*)("IN, to current area")); |
170 | } |
171 | else if ( ! Loopinside ) { |
172 | ADD_Loop_TO_LISTOFLoop(L,boundaryloops,(void*)("! IN, to boundaryloops")); |
173 | } |
174 | |
175 | } // end of boundary loop |
176 | |
177 | else { |
178 | // the loop L is a block loop |
179 | // if L is IN theArea : |
180 | // - stop area scan, insert L in theArea. |
181 | // - remove from the area all the loops outside L |
182 | // - make a new area with them, unless they are all boundary |
183 | // - if they are all boundary put them back in boundaryLoops |
184 | // else : |
185 | // - create a new area with L. |
186 | // - insert boundary loops that are IN the new area |
187 | // (and remove them from 'boundaryloops') |
188 | |
189 | Loopinside = Standard_False; |
190 | for (AreaIter.Initialize(myArea); AreaIter.More(); AreaIter.Next() ) { |
191 | TopOpeBRepBuild_ListOfLoop& aArea = AreaIter.Value(); |
192 | if ( aArea.IsEmpty() ) continue; |
193 | state = CompareLoopWithListOfLoop(LC,L,aArea,TopOpeBRepBuild_ANYLOOP); |
194 | if (state == TopAbs_UNKNOWN) Atomize(state,TopAbs_IN); |
195 | Loopinside = (state == TopAbs_IN); |
196 | if ( Loopinside ) break; |
197 | } // end of Area scan |
198 | |
199 | if ( Loopinside) { |
200 | TopOpeBRepBuild_ListOfLoop& aArea = AreaIter.Value(); |
201 | Standard_Boolean allShape = Standard_True; |
202 | TopOpeBRepBuild_ListOfLoop removedLoops; |
203 | LoopIter.Initialize(aArea); |
204 | while (LoopIter.More()) { |
205 | state = LC.Compare(LoopIter.Value(),L); |
206 | if (state == TopAbs_UNKNOWN) Atomize(state,TopAbs_IN); // not OUT |
207 | loopoutside = ( state == TopAbs_OUT ); |
208 | if ( loopoutside ) { |
209 | const Handle(TopOpeBRepBuild_Loop)& curL = LoopIter.Value(); |
210 | // remove the loop from the area |
211 | ADD_Loop_TO_LISTOFLoop |
212 | (curL,removedLoops,(void*)("loopoutside = 1, area = removedLoops")); |
213 | |
214 | allShape = allShape && curL->IsShape(); |
215 | REM_Loop_FROM_LISTOFLoop |
216 | (LoopIter,AreaIter.Value(),(void*)("loop of cur. area, cur. area")); |
217 | } |
218 | else { |
219 | LoopIter.Next(); |
220 | } |
221 | } |
222 | // insert the loop in the area |
223 | ADD_Loop_TO_LISTOFLoop(L,aArea,(void*)("area = current")); |
224 | if ( ! removedLoops.IsEmpty() ) { |
225 | if ( allShape ) { |
226 | ADD_LISTOFLoop_TO_LISTOFLoop |
227 | (removedLoops,boundaryloops, |
228 | (void*)("allShape = 1"),(void*)("removedLoops"),(void*)("boundaryloops")); |
229 | } |
230 | else { |
231 | // make a new area with the removed loops |
232 | TopOpeBRepBuild_ListOfLoop thelist; |
233 | myArea.Append(thelist); |
234 | ADD_LISTOFLoop_TO_LISTOFLoop |
235 | (removedLoops,myArea.Last(), |
236 | (void*)("allShape = 0"),(void*)("removedLoops"),(void*)("new area")); |
237 | } |
238 | } |
239 | } // Loopinside == True |
240 | |
241 | else { |
242 | Standard_Integer ashapeinside,ablockinside; |
243 | TopOpeBRepBuild_ListOfLoop thelist1; |
244 | myArea.Append(thelist1); |
245 | TopOpeBRepBuild_ListOfLoop& newArea0 = myArea.Last(); |
246 | ADD_Loop_TO_LISTOFLoop(L,newArea0,(void*)("new area")); |
247 | |
248 | LoopIter.Initialize(boundaryloops); |
249 | while ( LoopIter.More() ) { |
250 | ashapeinside = ablockinside = Standard_False; |
251 | state = LC.Compare(LoopIter.Value(),L); |
252 | if (state == TopAbs_UNKNOWN) Atomize(state,TopAbs_IN); |
253 | ashapeinside = (state == TopAbs_IN); |
254 | if (ashapeinside) { |
255 | state = LC.Compare(L,LoopIter.Value()); |
256 | if (state == TopAbs_UNKNOWN) Atomize(state,TopAbs_IN); |
257 | ablockinside = (state == TopAbs_IN); |
258 | } |
259 | if ( ashapeinside && ablockinside ) { |
260 | const Handle(TopOpeBRepBuild_Loop)& curL = LoopIter.Value(); |
261 | ADD_Loop_TO_LISTOFLoop |
262 | (curL,newArea0,(void*)("ashapeinside && ablockinside, new area")); |
263 | |
264 | REM_Loop_FROM_LISTOFLoop |
265 | (LoopIter,boundaryloops,(void*)("loop of boundaryloops, boundaryloops")); |
266 | } |
267 | else { |
268 | LoopIter.Next(); |
269 | } |
270 | } // end of boundaryloops scan |
271 | } // Loopinside == False |
272 | } // end of block loop |
273 | } // end of LoopSet LS scan |
274 | |
275 | InitArea(); |
276 | } |
277 | |
278 | //======================================================================= |
279 | //function : InitArea |
280 | //purpose : |
281 | //======================================================================= |
282 | |
283 | Standard_Integer TopOpeBRepBuild_AreaBuilder::InitArea() |
284 | { |
285 | myAreaIterator.Initialize(myArea); |
286 | InitLoop(); |
287 | Standard_Integer n = myArea.Extent(); |
288 | return n; |
289 | } |
290 | |
291 | //======================================================================= |
292 | //function : MoreArea |
293 | //purpose : |
294 | //======================================================================= |
295 | |
296 | Standard_Boolean TopOpeBRepBuild_AreaBuilder::MoreArea() const |
297 | { |
298 | Standard_Boolean b = myAreaIterator.More(); |
299 | return b; |
300 | } |
301 | |
302 | //======================================================================= |
303 | //Function : NextArea |
304 | //Purpose : |
305 | //======================================================================= |
306 | |
307 | void TopOpeBRepBuild_AreaBuilder::NextArea() |
308 | { |
309 | myAreaIterator.Next(); |
310 | InitLoop(); |
311 | } |
312 | |
313 | //======================================================================= |
314 | //function : InitLoop |
315 | //purpose : |
316 | //======================================================================= |
317 | |
318 | Standard_Integer TopOpeBRepBuild_AreaBuilder::InitLoop() |
319 | { |
320 | Standard_Integer n = 0; |
321 | if (myAreaIterator.More()) { |
322 | const TopOpeBRepBuild_ListOfLoop& LAL = myAreaIterator.Value(); |
323 | myLoopIterator.Initialize(LAL); |
324 | n = LAL.Extent(); |
325 | } |
326 | else { // Create an empty ListIteratorOfListOfLoop |
327 | myLoopIterator = TopOpeBRepBuild_ListIteratorOfListOfLoop(); |
328 | } |
329 | return n; |
330 | } |
331 | |
332 | //======================================================================= |
333 | //function : MoreLoop |
334 | //purpose : |
335 | //======================================================================= |
336 | |
337 | Standard_Boolean TopOpeBRepBuild_AreaBuilder::MoreLoop() const |
338 | { |
339 | Standard_Boolean b = myLoopIterator.More(); |
340 | return b; |
341 | } |
342 | |
343 | //======================================================================= |
344 | //function : NextLoop |
345 | //purpose : |
346 | //======================================================================= |
347 | |
348 | void TopOpeBRepBuild_AreaBuilder::NextLoop() |
349 | { |
350 | myLoopIterator.Next(); |
351 | } |
352 | |
353 | //======================================================================= |
354 | //function : Loop |
355 | //purpose : |
356 | //======================================================================= |
357 | |
358 | const Handle(TopOpeBRepBuild_Loop)& TopOpeBRepBuild_AreaBuilder::Loop() const |
359 | { |
360 | const Handle(TopOpeBRepBuild_Loop)& L = myLoopIterator.Value(); |
361 | return L; |
362 | } |
363 | |
364 | //======================================================================= |
365 | //function : ADD_Loop_TO_LISTOFLoop |
366 | //purpose : |
367 | //======================================================================= |
368 | |
369 | void TopOpeBRepBuild_AreaBuilder::ADD_Loop_TO_LISTOFLoop |
370 | (const Handle(TopOpeBRepBuild_Loop)& L, |
371 | TopOpeBRepBuild_ListOfLoop& LOL, |
372 | const Standard_Address /*ss*/) const |
373 | { |
374 | LOL.Append(L); |
375 | } |
376 | |
377 | //======================================================================= |
378 | //function : REM_Loop_FROM_LISTOFLoop |
379 | //purpose : |
380 | //======================================================================= |
381 | |
382 | void TopOpeBRepBuild_AreaBuilder::REM_Loop_FROM_LISTOFLoop |
383 | (TopOpeBRepBuild_ListIteratorOfListOfLoop& ITA, |
384 | TopOpeBRepBuild_ListOfLoop& A, |
385 | const Standard_Address /*ss*/) const |
386 | { |
387 | A.Remove(ITA); |
388 | } |
389 | |
390 | //======================================================================= |
391 | //function : ADD_LISTOFLoop_TO_LISTOFLoop |
392 | //purpose : |
393 | //======================================================================= |
394 | |
395 | void TopOpeBRepBuild_AreaBuilder::ADD_LISTOFLoop_TO_LISTOFLoop |
396 | (TopOpeBRepBuild_ListOfLoop& A1, |
397 | TopOpeBRepBuild_ListOfLoop& A2, |
398 | const Standard_Address /*ss*/, |
399 | const Standard_Address /*ss1*/, |
400 | const Standard_Address /*ss2*/) const |
401 | { |
402 | A2.Append(A1); |
403 | } |