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