0031668: Visualization - WebGL sample doesn't work on Emscripten 1.39
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_Area2dBuilder.cxx
1 // Created on: 1995-12-21
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <TopOpeBRepBuild_Area2dBuilder.hxx>
19 #include <TopOpeBRepBuild_Loop.hxx>
20 #include <TopOpeBRepBuild_LoopClassifier.hxx>
21 #include <TopOpeBRepBuild_LoopSet.hxx>
22
23 #ifdef OCCT_DEBUG
24 extern Standard_Boolean TopOpeBRepBuild_GettraceAREA();
25 #endif
26
27 //=======================================================================
28 //function : TopOpeBRepBuild_Area2dBuilder
29 //purpose  : 
30 //=======================================================================
31
32 TopOpeBRepBuild_Area2dBuilder::TopOpeBRepBuild_Area2dBuilder()
33 {
34 }
35
36 //=======================================================================
37 //function : TopOpeBRepBuild_Area2dBuilder
38 //purpose  : 
39 //=======================================================================
40
41 TopOpeBRepBuild_Area2dBuilder::TopOpeBRepBuild_Area2dBuilder
42 (TopOpeBRepBuild_LoopSet& LS, TopOpeBRepBuild_LoopClassifier& LC,
43  const Standard_Boolean ForceClass)
44 {
45   InitAreaBuilder(LS,LC,ForceClass);
46 }
47
48 //=======================================================================
49 //function : InitAreaBuilder
50 //purpose  : 
51 //=======================================================================
52
53 void TopOpeBRepBuild_Area2dBuilder::InitAreaBuilder
54 (TopOpeBRepBuild_LoopSet&        LS,
55  TopOpeBRepBuild_LoopClassifier& LC,
56  const Standard_Boolean ForceClass)
57 {
58   TopAbs_State     state;
59   Standard_Boolean Loopinside;
60   Standard_Boolean loopoutside;
61   
62   TopOpeBRepBuild_ListIteratorOfListOfListOfLoop AreaIter;
63   TopOpeBRepBuild_ListIteratorOfListOfLoop       LoopIter;
64   // boundaryloops : list of boundary loops out of the areas.
65   TopOpeBRepBuild_ListOfLoop                     boundaryloops; 
66   
67   myArea.Clear();          // Clear the list of Area to be built
68   
69   for (LS.InitLoop(); LS.MoreLoop(); LS.NextLoop()) {
70     
71     // process a new loop : L is the new current Loop
72     const Handle(TopOpeBRepBuild_Loop)& L = LS.Loop();
73     Standard_Boolean boundaryL = L->IsShape();
74     
75     // L = shape et ForceClass  : on traite L comme un block
76     // L = shape et !ForceClass : on traite L comme un pur shape
77     // L = !shape               : on traite L comme un block
78     Standard_Boolean traitercommeblock = (!boundaryL) || ForceClass;
79     if ( ! traitercommeblock ) {
80
81       // the loop L is a boundary loop : 
82       // - try to insert it in an existing area, such as L is inside all 
83       //   the block loops. Only block loops of the area are compared. 
84       // - if L could not be inserted, store it in list of boundary loops.
85
86       Loopinside = Standard_False; 
87       for (AreaIter.Initialize(myArea); AreaIter.More(); AreaIter.Next()) {
88         TopOpeBRepBuild_ListOfLoop& aArea = AreaIter.Value();
89         if ( aArea.IsEmpty() ) continue;
90         state = CompareLoopWithListOfLoop(LC,L,aArea,TopOpeBRepBuild_BLOCK );
91         if (state == TopAbs_UNKNOWN) Atomize(state,TopAbs_IN);
92         Loopinside = ( state == TopAbs_IN);
93         if ( Loopinside ) break;
94       } // end of Area scan
95
96       if ( Loopinside ) {
97         TopOpeBRepBuild_ListOfLoop& aArea = AreaIter.Value();
98         ADD_Loop_TO_LISTOFLoop(L,aArea,(void*)("IN, to current area"));
99       }
100       else if ( ! Loopinside ) {
101         ADD_Loop_TO_LISTOFLoop(L,boundaryloops,(void*)("! IN, to boundaryloops"));
102       }
103
104     } // end of boundary loop
105     
106     else { 
107       // the loop L is a block loop
108       // if L is IN theArea :
109       //   - stop area scan, insert L in theArea.
110       //   - remove from the area all the loops outside L
111       //   - make a new area with them, unless they are all boundary
112       //   - if they are all boundary put them back in boundaryLoops
113       // else :
114       //   - create a new area with L.
115       //   - insert boundary loops that are IN the new area
116       //     (and remove them from 'boundaryloops')
117       
118       Loopinside = Standard_False;
119       for (AreaIter.Initialize(myArea); AreaIter.More(); AreaIter.Next() ) {
120         TopOpeBRepBuild_ListOfLoop& aArea = AreaIter.Value();
121         if ( aArea.IsEmpty() ) continue;
122         state = CompareLoopWithListOfLoop(LC,L,aArea,TopOpeBRepBuild_ANYLOOP);
123         if (state == TopAbs_UNKNOWN) Atomize(state,TopAbs_IN);
124         Loopinside = (state == TopAbs_IN);
125         if ( Loopinside ) break;
126       } // end of Area scan
127       
128       if ( Loopinside) {
129         TopOpeBRepBuild_ListOfLoop& aArea = AreaIter.Value();
130         Standard_Boolean allShape = Standard_True;
131         TopOpeBRepBuild_ListOfLoop removedLoops;
132         LoopIter.Initialize(aArea);
133         while (LoopIter.More()) {
134           state = LC.Compare(LoopIter.Value(),L);
135           if (state == TopAbs_UNKNOWN) Atomize(state,TopAbs_IN); // not OUT
136           loopoutside = ( state == TopAbs_OUT );
137           if ( loopoutside ) {
138             const Handle(TopOpeBRepBuild_Loop)& curL = LoopIter.Value();
139             // remove the loop from the area
140             ADD_Loop_TO_LISTOFLoop
141               (curL,removedLoops,(void*)("loopoutside = 1, area = removedLoops"));
142             
143             allShape = allShape && curL->IsShape();
144             REM_Loop_FROM_LISTOFLoop
145               (LoopIter,AreaIter.Value(),(void*)("loop of cur. area, cur. area"));
146           }
147           else {
148             LoopIter.Next();
149           }
150         }
151         // insert the loop in the area
152         ADD_Loop_TO_LISTOFLoop(L,aArea,(void*)("area = current"));
153         if ( ! removedLoops.IsEmpty() ) {
154           if ( allShape ) {
155             ADD_LISTOFLoop_TO_LISTOFLoop
156               (removedLoops,boundaryloops,
157                (void*)("allShape = 1"),(void*)("removedLoops"),(void*)("boundaryloops"));
158           }
159           else {
160             // make a new area with the removed loops
161             TopOpeBRepBuild_ListOfLoop thelist;
162             myArea.Append(thelist);
163             ADD_LISTOFLoop_TO_LISTOFLoop
164               (removedLoops,myArea.Last(),
165                (void*)("allShape = 0"),(void*)("removedLoops"),(void*)("new area"));
166           }
167         }
168       } // Loopinside == True
169       
170       else {
171         Standard_Integer ashapeinside,ablockinside;
172         TopOpeBRepBuild_ListOfLoop thelist1;
173         myArea.Append(thelist1);
174         TopOpeBRepBuild_ListOfLoop& newArea0 = myArea.Last();
175         ADD_Loop_TO_LISTOFLoop(L,newArea0,(void*)("new area"));
176         
177         LoopIter.Initialize(boundaryloops);
178
179
180         while ( LoopIter.More() ) {
181           ashapeinside = ablockinside = Standard_False;
182           const Handle(TopOpeBRepBuild_Loop)& lb = LoopIter.Value();
183           state = LC.Compare(lb,L);
184           if (state == TopAbs_UNKNOWN) Atomize(state,TopAbs_IN);
185           ashapeinside = (state == TopAbs_IN);
186           if (ashapeinside) {
187             state = LC.Compare(L,lb);
188             if (state == TopAbs_UNKNOWN) Atomize(state,TopAbs_IN);
189             ablockinside = (state == TopAbs_IN);
190           }
191           if ( ashapeinside && ablockinside ) {
192             const Handle(TopOpeBRepBuild_Loop)& curL = LoopIter.Value();
193             ADD_Loop_TO_LISTOFLoop
194               (curL,newArea0,(void*)("ashapeinside && ablockinside, new area"));
195
196             REM_Loop_FROM_LISTOFLoop
197               (LoopIter,boundaryloops,(void*)("loop of boundaryloops, boundaryloops"));
198           }
199           else { 
200             LoopIter.Next();
201           }
202         } // end of boundaryloops scan
203       } // Loopinside == False
204     } // end of block loop
205   } // end of LoopSet LS scan
206   
207   if ( ! boundaryloops.IsEmpty() ) {
208     if ( myArea.IsEmpty() )  {
209 #ifdef OCCT_DEBUG
210       if (TopOpeBRepBuild_GettraceAREA())
211         std::cout<<"---"<<std::endl<<"--- purge"<<std::endl<<"---"<<std::endl;
212 #endif
213       TopOpeBRepBuild_ListOfLoop newArea3;
214       newArea3.Append(boundaryloops);
215       myArea.Append(newArea3);
216     }
217   }
218
219   InitArea();
220 }