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