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