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