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