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