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