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 | |
7fd59977 |
17 | |
7fd59977 |
18 | #include <Standard_DomainError.hxx> |
7fd59977 |
19 | #include <TopAbs.hxx> |
42cf5bc1 |
20 | #include <TopAbs_Orientation.hxx> |
21 | #include <TopAbs_ShapeEnum.hxx> |
22 | #include <TopOpeBRepBuild_Area1dBuilder.hxx> |
23 | #include <TopOpeBRepBuild_Loop.hxx> |
24 | #include <TopOpeBRepBuild_LoopClassifier.hxx> |
25 | #include <TopOpeBRepBuild_LoopEnum.hxx> |
26 | #include <TopOpeBRepBuild_LoopSet.hxx> |
27 | #include <TopOpeBRepBuild_Pave.hxx> |
28 | #include <TopOpeBRepBuild_PaveClassifier.hxx> |
29 | #include <TopOpeBRepBuild_PaveSet.hxx> |
7fd59977 |
30 | |
0797d9d3 |
31 | #ifdef OCCT_DEBUG |
1d0a9d4d |
32 | extern Standard_Boolean TopOpeBRepBuild_GettraceAREA(); |
7fd59977 |
33 | #endif |
34 | |
35 | //======================================================================= |
36 | //function : DumpList |
37 | //purpose : |
38 | //======================================================================= |
39 | |
0797d9d3 |
40 | #ifdef OCCT_DEBUG |
7fd59977 |
41 | void TopOpeBRepBuild_Area1dBuilder::DumpList(const TopOpeBRepBuild_ListOfLoop& LOL) |
42 | { |
7fd59977 |
43 | Standard_Integer iLOL; |
44 | TopOpeBRepBuild_ListIteratorOfListOfLoop itLOL; |
45 | for (iLOL = 0, itLOL.Initialize(LOL); itLOL.More(); iLOL++, itLOL.Next()) { |
46 | if (iLOL) cout<<" "; |
47 | else cout<<"DUMP_AREA : "; |
48 | const Handle(TopOpeBRepBuild_Loop)& L = itLOL.Value(); |
49 | L->Dump();cout<<endl; |
50 | } |
498ce76b |
51 | #else |
52 | void TopOpeBRepBuild_Area1dBuilder::DumpList(const TopOpeBRepBuild_ListOfLoop&) |
53 | { |
7fd59977 |
54 | #endif |
55 | } |
56 | |
57 | //======================================================================= |
58 | //function : TopOpeBRepBuild_Area1dBuilder |
59 | //purpose : |
60 | //======================================================================= |
61 | |
62 | TopOpeBRepBuild_Area1dBuilder::TopOpeBRepBuild_Area1dBuilder() |
63 | { |
64 | } |
65 | |
66 | //======================================================================= |
67 | //function : TopOpeBRepBuild_Area1dBuilder |
68 | //purpose : |
69 | //======================================================================= |
70 | |
71 | TopOpeBRepBuild_Area1dBuilder::TopOpeBRepBuild_Area1dBuilder |
72 | (TopOpeBRepBuild_PaveSet& LS, |
73 | TopOpeBRepBuild_PaveClassifier& LC, |
74 | const Standard_Boolean ForceClass) |
75 | { |
76 | InitAreaBuilder(LS,LC,ForceClass); |
77 | } |
78 | |
79 | //======================================================================= |
80 | //function : InitAreaBuilder |
81 | //purpose : |
82 | //======================================================================= |
83 | |
84 | void TopOpeBRepBuild_Area1dBuilder::InitAreaBuilder |
85 | (TopOpeBRepBuild_LoopSet& LS, |
86 | TopOpeBRepBuild_LoopClassifier& LC, |
87 | const Standard_Boolean ForceClass) |
88 | { |
89 | TopAbs_State state; |
90 | Standard_Boolean Loopinside; |
91 | Standard_Boolean loopoutside; |
92 | |
93 | TopOpeBRepBuild_ListIteratorOfListOfListOfLoop AreaIter; |
94 | TopOpeBRepBuild_ListIteratorOfListOfLoop LoopIter; |
95 | // boundaryloops : list of boundary loops out of the areas. |
96 | TopOpeBRepBuild_ListOfLoop boundaryloops; |
97 | |
98 | myArea.Clear(); // Clear the list of Area to be built |
99 | |
100 | for (LS.InitLoop(); LS.MoreLoop(); LS.NextLoop()) { |
101 | |
102 | // process a new loop : L is the new current Loop |
103 | const Handle(TopOpeBRepBuild_Loop)& L = LS.Loop(); |
104 | Standard_Boolean boundaryL = L->IsShape(); |
105 | |
0797d9d3 |
106 | #ifdef OCCT_DEBUG |
7fd59977 |
107 | if (TopOpeBRepBuild_GettraceAREA()) { |
108 | cout<<"++++ new loop : "; L->Dump(); |
109 | if (boundaryL) cout<<" is bound"; else cout<<" is not bound"; |
110 | cout<<endl; |
111 | } |
112 | #endif |
113 | |
114 | |
115 | // L = shape et ForceClass : on traite L comme un block |
116 | // L = shape et !ForceClass : on traite L comme un pur shape |
117 | // L = !shape : on traite L comme un block |
118 | Standard_Boolean traitercommeblock = !boundaryL || ForceClass; |
119 | if ( ! traitercommeblock ) { |
120 | |
121 | // the loop L is a boundary loop : |
122 | // - try to insert it in an existing area, such as L is inside all |
123 | // the block loops. Only block loops of the area are compared. |
124 | // - if L could not be inserted, store it in list of boundary loops. |
125 | |
126 | Loopinside = Standard_False; |
127 | for (AreaIter.Initialize(myArea); AreaIter.More(); AreaIter.Next()) { |
128 | TopOpeBRepBuild_ListOfLoop& aArea = AreaIter.Value(); |
129 | if ( aArea.IsEmpty() ) continue; |
130 | state = CompareLoopWithListOfLoop(LC,L,aArea,TopOpeBRepBuild_BLOCK); |
131 | if (state == TopAbs_UNKNOWN) Atomize(state,TopAbs_IN); |
132 | Loopinside = ( state == TopAbs_IN); |
133 | if ( Loopinside ) break; |
134 | } // end of Area scan |
135 | |
136 | if ( Loopinside ) { |
137 | TopOpeBRepBuild_ListOfLoop& aArea = AreaIter.Value(); |
138 | ADD_Loop_TO_LISTOFLoop(L,aArea,(void*)("IN, to current area")); |
139 | } |
140 | else if ( ! Loopinside ) { |
141 | ADD_Loop_TO_LISTOFLoop(L,boundaryloops,(void*)("! IN, to boundaryloops")); |
142 | } |
143 | |
144 | } // end of boundary loop |
145 | |
146 | else { |
147 | // the loop L is a block loop |
148 | // if L is IN theArea : |
149 | // - stop area scan, insert L in theArea. |
150 | // - remove from the area all the loops outside L |
151 | // - make a new area with them, unless they are all boundary |
152 | // - if they are all boundary put them back in boundaryLoops |
153 | // else : |
154 | // - create a new area with L. |
155 | // - insert boundary loops that are IN the new area |
156 | // (and remove them from 'boundaryloops') |
157 | |
158 | Loopinside = Standard_False; |
159 | for (AreaIter.Initialize(myArea); AreaIter.More(); AreaIter.Next() ) { |
160 | TopOpeBRepBuild_ListOfLoop& aArea = AreaIter.Value(); |
161 | if ( aArea.IsEmpty() ) continue; |
162 | state = CompareLoopWithListOfLoop(LC,L,aArea,TopOpeBRepBuild_ANYLOOP); |
163 | if (state == TopAbs_UNKNOWN) Atomize(state,TopAbs_IN); |
164 | Loopinside = (state == TopAbs_IN); |
165 | if ( Loopinside ) break; |
166 | } // end of Area scan |
167 | |
168 | if ( Loopinside) { |
169 | TopOpeBRepBuild_ListOfLoop& aArea = AreaIter.Value(); |
170 | Standard_Boolean allShape = Standard_True; |
171 | TopOpeBRepBuild_ListOfLoop removedLoops; |
172 | LoopIter.Initialize(aArea); |
173 | while (LoopIter.More()) { |
174 | state = LC.Compare(LoopIter.Value(),L); |
175 | if (state == TopAbs_UNKNOWN) Atomize(state,TopAbs_IN); // not OUT |
176 | loopoutside = ( state == TopAbs_OUT ); |
177 | if ( loopoutside ) { |
178 | const Handle(TopOpeBRepBuild_Loop)& curL = LoopIter.Value(); |
179 | // remove the loop from the area |
180 | ADD_Loop_TO_LISTOFLoop |
181 | (curL,removedLoops,(void*)("loopoutside = 1, area = removedLoops")); |
182 | |
183 | allShape = allShape && curL->IsShape(); |
184 | REM_Loop_FROM_LISTOFLoop |
185 | (LoopIter,AreaIter.Value(),(void*)("loop of cur. area, cur. area")); |
186 | } |
187 | else { |
188 | LoopIter.Next(); |
189 | } |
190 | } |
191 | // insert the loop in the area |
192 | ADD_Loop_TO_LISTOFLoop(L,aArea,(void*)("area = current")); |
193 | if ( ! removedLoops.IsEmpty() ) { |
194 | if ( allShape ) { |
195 | ADD_LISTOFLoop_TO_LISTOFLoop |
196 | (removedLoops,boundaryloops, |
197 | (void*)("allShape = 1"),(void*)("removedLoops"),(void*)("boundaryloops")); |
198 | } |
199 | else { |
200 | // make a new area with the removed loops |
201 | TopOpeBRepBuild_ListOfLoop thelist; |
202 | myArea.Append(thelist); |
203 | ADD_LISTOFLoop_TO_LISTOFLoop |
204 | (removedLoops,myArea.Last(), |
205 | (void*)("allShape = 0"),(void*)("removedLoops"),(void*)("new area")); |
206 | } |
207 | } |
208 | } // Loopinside == True |
209 | |
210 | else { |
211 | Standard_Integer ashapeinside,ablockinside; |
212 | TopOpeBRepBuild_ListOfLoop thelist1; |
213 | myArea.Append(thelist1); |
214 | TopOpeBRepBuild_ListOfLoop& newArea0 = myArea.Last(); |
215 | ADD_Loop_TO_LISTOFLoop(L,newArea0,(void*)("new area")); |
216 | |
217 | LoopIter.Initialize(boundaryloops); |
218 | while ( LoopIter.More() ) { |
219 | ashapeinside = ablockinside = Standard_False; |
220 | state = LC.Compare(LoopIter.Value(),L); |
221 | if (state == TopAbs_UNKNOWN) Atomize(state,TopAbs_IN); |
222 | ashapeinside = (state == TopAbs_IN); |
223 | if (ashapeinside) { |
224 | state = LC.Compare(L,LoopIter.Value()); |
225 | if (state == TopAbs_UNKNOWN) Atomize(state,TopAbs_IN); |
226 | ablockinside = (state == TopAbs_IN); |
227 | } |
228 | if ( ashapeinside && ablockinside ) { |
229 | const Handle(TopOpeBRepBuild_Loop)& curL = LoopIter.Value(); |
230 | ADD_Loop_TO_LISTOFLoop |
231 | (curL,newArea0,(void*)("ashapeinside && ablockinside, new area")); |
232 | |
233 | REM_Loop_FROM_LISTOFLoop |
234 | (LoopIter,boundaryloops,(void*)("loop of boundaryloops, boundaryloops")); |
235 | } |
236 | else { |
237 | LoopIter.Next(); |
238 | } |
239 | } // end of boundaryloops scan |
240 | } // Loopinside == False |
241 | } // end of block loop |
242 | } // end of LoopSet LS scan |
243 | |
0797d9d3 |
244 | #ifdef OCCT_DEBUG |
7fd59977 |
245 | if (TopOpeBRepBuild_GettraceAREA()) { |
246 | if ( ! myArea.IsEmpty() ) { |
247 | cout<<"------- Areas -------"<<endl; |
248 | for (AreaIter.Initialize(myArea);AreaIter.More();AreaIter.Next()) |
249 | DumpList(AreaIter.Value()); |
250 | cout<<"---------------------"<<endl; |
251 | } |
252 | } |
253 | #endif |
254 | |
255 | InitArea(); |
256 | } |
257 | |
258 | //======================================================================= |
259 | //function : ADD_Loop_TO_LISTOFLoop |
260 | //purpose : |
261 | //======================================================================= |
262 | |
263 | void TopOpeBRepBuild_Area1dBuilder::ADD_Loop_TO_LISTOFLoop |
264 | (const Handle(TopOpeBRepBuild_Loop)& L, |
265 | TopOpeBRepBuild_ListOfLoop& LOL, |
498ce76b |
266 | const Standard_Address |
0797d9d3 |
267 | #ifdef OCCT_DEBUG |
498ce76b |
268 | ss |
7fd59977 |
269 | #endif |
498ce76b |
270 | ) const |
271 | { |
7fd59977 |
272 | LOL.Append(L); |
273 | |
0797d9d3 |
274 | #ifdef OCCT_DEBUG |
7fd59977 |
275 | if (TopOpeBRepBuild_GettraceAREA()) { |
276 | cout<<"--------------------- add area loop to area : "; |
277 | L->Dump(); cout<<endl; |
498ce76b |
278 | if (ss != NULL) cout<<(char*)ss<<endl; |
7fd59977 |
279 | DumpList(LOL); |
280 | cout<<"---------------------"<<endl; |
281 | } |
282 | #endif |
283 | } |
284 | |
285 | //======================================================================= |
286 | //function : REM_Loop_FROM_LISTOFLoop |
287 | //purpose : |
288 | //======================================================================= |
289 | |
290 | void TopOpeBRepBuild_Area1dBuilder::REM_Loop_FROM_LISTOFLoop |
291 | (TopOpeBRepBuild_ListIteratorOfListOfLoop& ITA, |
292 | TopOpeBRepBuild_ListOfLoop& A, |
0797d9d3 |
293 | #ifdef OCCT_DEBUG |
7fd59977 |
294 | const Standard_Address ss) const |
295 | { |
7fd59977 |
296 | char* s = (char*)ss; |
498ce76b |
297 | #else |
298 | const Standard_Address) const |
299 | { |
7fd59977 |
300 | #endif |
301 | |
0797d9d3 |
302 | #ifdef OCCT_DEBUG |
7fd59977 |
303 | if (TopOpeBRepBuild_GettraceAREA()) { |
304 | if (ITA.More()) { |
305 | cout<<"--------------------- remove area loop from area : "; |
306 | ITA.Value()->Dump(); cout<<endl; |
307 | if (s != NULL) cout<<s<<endl; |
308 | } |
309 | } |
310 | #endif |
311 | |
312 | A.Remove(ITA); |
313 | |
0797d9d3 |
314 | #ifdef OCCT_DEBUG |
7fd59977 |
315 | if (TopOpeBRepBuild_GettraceAREA()) { |
316 | DumpList(A); |
317 | cout<<"---------------------"<<endl; |
318 | } |
319 | #endif |
320 | } |
321 | |
322 | //======================================================================= |
323 | //function : ADD_LISTOFLoop_TO_LISTOFLoop |
324 | //purpose : |
325 | //======================================================================= |
326 | |
327 | void TopOpeBRepBuild_Area1dBuilder::ADD_LISTOFLoop_TO_LISTOFLoop |
328 | (TopOpeBRepBuild_ListOfLoop& A1, |
329 | TopOpeBRepBuild_ListOfLoop& A2, |
0797d9d3 |
330 | #ifdef OCCT_DEBUG |
7fd59977 |
331 | const Standard_Address ss, |
332 | const Standard_Address ss1, |
333 | const Standard_Address ss2) const |
498ce76b |
334 | #else |
335 | const Standard_Address, |
336 | const Standard_Address, |
337 | const Standard_Address) const |
338 | #endif |
7fd59977 |
339 | { |
0797d9d3 |
340 | #ifdef OCCT_DEBUG |
7fd59977 |
341 | char* s = (char*)ss; |
342 | char* s1 = (char*)ss1; |
343 | char* s2 = (char*)ss2; |
344 | |
345 | if (TopOpeBRepBuild_GettraceAREA()) { |
346 | cout<<"--------------------- add area 1 to area 2 : "; |
347 | if (s != NULL) cout<<s; cout<<endl; |
348 | cout<<"1 : "; if (s1 != NULL) cout<<s1; cout<<endl; |
349 | DumpList(A1); |
350 | } |
351 | #endif |
352 | |
353 | A2.Append(A1); |
354 | |
0797d9d3 |
355 | #ifdef OCCT_DEBUG |
7fd59977 |
356 | if (TopOpeBRepBuild_GettraceAREA()) { |
357 | cout<<"2 : "; if (s2 != NULL) cout<<s2; cout<<endl; |
358 | DumpList(A2); |
359 | cout<<"---------------------"<<endl; |
360 | } |
361 | #endif |
362 | } |
363 | |
364 | |
365 | |
366 | |
367 | |
368 | |
369 | |
370 | |
371 | |