0024187: Wrong result of COMMON operation.
[occt.git] / src / BOPAlgo / BOPAlgo_Tools.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2012 OPEN CASCADE SAS
3 //
4 // The content of this file is subject to the Open CASCADE Technology Public
5 // License Version 6.5 (the "License"). You may not use the content of this file
6 // except in compliance with the License. Please obtain a copy of the License
7 // at http://www.opencascade.org and read it completely before using this file.
8 //
9 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
10 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
11 //
12 // The Original Code and all software distributed under the License is
13 // distributed on an "AS IS" basis, without warranty of any kind, and the
14 // Initial Developer hereby disclaims all such warranties, including without
15 // limitation, any warranties of merchantability, fitness for a particular
16 // purpose or non-infringement. Please see the License for the specific terms
17 // and conditions governing the rights and limitations under the License.
18
19 #include <BOPAlgo_Tools.ixx>
20 #include <BOPDS_DS.hxx>
21 #include <BOPDS_MapOfPaveBlock.hxx>
22 #include <BOPDS_IndexedMapOfPaveBlock.hxx>
23 #include <BOPDS_CommonBlock.hxx>
24 #include <BOPDS_DataMapOfPaveBlockListOfPaveBlock.hxx>
25 #include <BOPCol_IndexedMapOfInteger.hxx>
26
27 //=======================================================================
28 //function : MakeBlocksCnx
29 //purpose  : 
30 //=======================================================================
31   void BOPAlgo_Tools::MakeBlocksCnx(const BOPCol_IndexedDataMapOfIntegerListOfInteger& aMILI,
32                                     BOPCol_DataMapOfIntegerListOfInteger& aMBlocks,
33                                     Handle(NCollection_BaseAllocator)& aAllocator)
34 {
35   Standard_Integer aNbV, nV, aNbVS, nVP, nVx, aNbVP, aNbEC, k, i, j;
36   BOPCol_ListIteratorOfListOfInteger aItLI;
37   //
38   BOPCol_MapOfInteger aMVS(100, aAllocator);
39   BOPCol_IndexedMapOfInteger aMEC(100, aAllocator);
40   BOPCol_IndexedMapOfInteger aMVP(100, aAllocator);
41   BOPCol_IndexedMapOfInteger aMVAdd(100, aAllocator);
42   //
43   aNbV=aMILI.Extent();
44   //
45   for (k=0,i=1; i<=aNbV; ++i) {
46     aNbVS=aMVS.Extent();
47     if (aNbVS==aNbV) {
48       break;
49     }
50     //
51     nV = aMILI.FindKey(i);
52     if (aMVS.Contains(nV)){
53       continue;
54     }
55     aMVS.Add(nV);
56     //
57     aMEC.Clear();
58     aMVP.Clear();
59     aMVAdd.Clear();
60     //
61     aMVP.Add(nV);
62     for(;;) {
63       aNbVP=aMVP.Extent();
64       for (j=1; j<=aNbVP; ++j) {
65         nVP=aMVP(j);
66         const BOPCol_ListOfInteger& aLV=aMILI.FindFromKey(nVP);
67         aItLI.Initialize(aLV);
68         for (; aItLI.More(); aItLI.Next()) {
69           nVx=aItLI.Value();
70           if (aMEC.Contains(nVx)) {
71             continue;
72           }
73           //
74           aMVS.Add(nVx);
75           aMEC.Add(nVx);
76           aMVAdd.Add(nVx);
77         }
78       }
79       //
80       aNbVP=aMVAdd.Extent();
81       if (!aNbVP) {
82         break; // from while(1)
83       }
84       //
85       aMVP.Clear();
86       for (j=1; j<=aNbVP; ++j) {
87         aMVP.Add(aMVAdd(j));
88       }
89       aMVAdd.Clear();
90     }//while(1) {
91     //
92     BOPCol_ListOfInteger aLIx(aAllocator);
93     //
94     aNbEC = aMEC.Extent();
95     for (j=1; j<=aNbEC; ++j) {
96       nVx=aMEC(j);
97       aLIx.Append(nVx);
98     }
99     //
100     aMBlocks.Bind(k, aLIx);
101     ++k;
102   }//for (k=0,i=1; i<=aNbV; ++i)
103   aMVAdd.Clear();
104   aMVP.Clear();
105   aMEC.Clear();
106   aMVS.Clear();
107 }
108 //=======================================================================
109 //function : FillMap
110 //purpose  : 
111 //=======================================================================
112   void BOPAlgo_Tools::FillMap(const Standard_Integer n1,
113                               const Standard_Integer n2,
114                               BOPCol_IndexedDataMapOfIntegerListOfInteger& aMILI,
115                               Handle(NCollection_BaseAllocator)& aAllocator)
116 {
117   if (aMILI.Contains(n1)) {
118     BOPCol_ListOfInteger& aLI=aMILI.ChangeFromKey(n1);
119     aLI.Append(n2);
120   }
121   else {
122     BOPCol_ListOfInteger aLI(aAllocator);
123     aLI.Append(n2);
124     aMILI.Add(n1, aLI);
125   }
126   if (aMILI.Contains(n2)) {
127     BOPCol_ListOfInteger& aLI=aMILI.ChangeFromKey(n2);
128     aLI.Append(n1);
129   }
130   else {
131     BOPCol_ListOfInteger aLI(aAllocator);
132     aLI.Append(n1);
133     aMILI.Add(n2, aLI);
134   }
135 }
136 //=======================================================================
137 //function : FillMap
138 //purpose  : 
139 //=======================================================================
140   void BOPAlgo_Tools::FillMap(const Handle(BOPDS_PaveBlock)& aPB1,
141                               const Handle(BOPDS_PaveBlock)& aPB2,
142                               BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock& aMPBLPB,
143                               Handle(NCollection_BaseAllocator)& aAllocator)
144 {
145   if (aMPBLPB.Contains(aPB1)) {
146     BOPDS_ListOfPaveBlock& aLPB=aMPBLPB.ChangeFromKey(aPB1);
147     aLPB.Append(aPB2);
148   }
149   else {
150     BOPDS_ListOfPaveBlock aLPB(aAllocator);
151     aLPB.Append(aPB2);
152     aMPBLPB.Add(aPB1, aLPB);
153   }
154   if (aMPBLPB.Contains(aPB2)) {
155     BOPDS_ListOfPaveBlock& aLPB=aMPBLPB.ChangeFromKey(aPB2);
156     aLPB.Append(aPB1);
157   }
158   else {
159     BOPDS_ListOfPaveBlock aLPB(aAllocator);
160     aLPB.Append(aPB1);
161     aMPBLPB.Add(aPB2, aLPB);
162   }
163 }
164 //=======================================================================
165 //function : FillMap
166 //purpose  : 
167 //=======================================================================
168   void BOPAlgo_Tools::FillMap(const Handle(BOPDS_PaveBlock)& aPB,
169                               const Standard_Integer nF,
170                               BOPDS_IndexedDataMapOfPaveBlockListOfInteger& aMPBLI,
171                               Handle(NCollection_BaseAllocator)& aAllocator)
172 {
173   if (aMPBLI.Contains(aPB)) {
174     BOPCol_ListOfInteger& aLI=aMPBLI.ChangeFromKey(aPB);
175     aLI.Append(nF);
176   }
177   else {
178     BOPCol_ListOfInteger aLI(aAllocator);
179     aLI.Append(nF);
180     aMPBLI.Add(aPB, aLI);
181   }
182 }
183 //=======================================================================
184 //function : MakeBlocks
185 //purpose  : 
186 //=======================================================================
187   void BOPAlgo_Tools::MakeBlocks(const BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock& aMILI,
188                                  BOPDS_DataMapOfIntegerListOfPaveBlock& aMBlocks,
189                                  Handle(NCollection_BaseAllocator)& aAllocator)
190 {
191   Standard_Integer aNbV,  aNbVS, aNbVP, aNbEC, k, i, j;
192   BOPDS_ListIteratorOfListOfPaveBlock aItLI;
193   //
194   BOPDS_MapOfPaveBlock aMVS(100, aAllocator);
195   BOPDS_IndexedMapOfPaveBlock aMEC(100, aAllocator);
196   BOPDS_IndexedMapOfPaveBlock aMVP(100, aAllocator);
197   BOPDS_IndexedMapOfPaveBlock aMVAdd(100, aAllocator);
198   //
199   aNbV=aMILI.Extent();
200   //
201   for (k=0, i=1; i<=aNbV; ++i) {
202     aNbVS=aMVS.Extent();
203     if (aNbVS==aNbV) {
204       break;
205     }
206     //
207     const Handle(BOPDS_PaveBlock)& nV=aMILI.FindKey(i);
208     if (aMVS.Contains(nV)){
209       continue;
210     }
211     aMVS.Add(nV);
212     //
213     aMEC.Clear();
214     aMVP.Clear();
215     aMVAdd.Clear();
216     //
217     aMVP.Add(nV);
218     for(;;) {
219       aNbVP=aMVP.Extent();
220       for (j=1; j<=aNbVP; ++j) {
221         const Handle(BOPDS_PaveBlock)& nVP=aMVP(j);
222         const BOPDS_ListOfPaveBlock& aLV=aMILI.FindFromKey(nVP);
223         aItLI.Initialize(aLV);
224         for (; aItLI.More(); aItLI.Next()) {
225           const Handle(BOPDS_PaveBlock)& nVx=aItLI.Value();
226           if (aMEC.Contains(nVx)) {
227             continue;
228           }
229           //
230           aMVS.Add(nVx);
231           aMEC.Add(nVx);
232           aMVAdd.Add(nVx);
233         }
234       }
235       //
236       aNbVP=aMVAdd.Extent();
237       if (!aNbVP) {
238         break; // from while(1)
239       }
240       //
241       aMVP.Clear();
242       for (j=1; j<=aNbVP; ++j) {
243         aMVP.Add(aMVAdd(j));
244       }
245       aMVAdd.Clear();
246     }//while(1) {
247     //
248     BOPDS_ListOfPaveBlock aLIx(aAllocator);
249     //
250     aNbEC = aMEC.Extent();
251     for (j=1; j<=aNbEC; ++j) {
252       const Handle(BOPDS_PaveBlock)& nVx=aMEC(j);
253       aLIx.Append(nVx);
254     }
255     //
256     aMBlocks.Bind(k, aLIx);
257     ++k;
258   }//for (k=0, i=1; i<=aNbV; ++i)
259   aMVAdd.Clear();
260   aMVP.Clear();
261   aMEC.Clear();
262   aMVS.Clear();
263 }
264 //=======================================================================
265 //function : PerformCommonBlocks
266 //purpose  : 
267 //=======================================================================
268   void BOPAlgo_Tools::PerformCommonBlocks(BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock& aMPBLPB,
269                                           Handle(NCollection_BaseAllocator)& aAllocator,
270                                           BOPDS_PDS& pDS)
271 {
272   Standard_Integer aNbCB;
273   //
274   aNbCB=aMPBLPB.Extent();
275   if (!aNbCB) {
276     return;
277   }
278   //
279   Standard_Integer aNbPB, aNbBlocks, k;
280   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
281   Handle(BOPDS_CommonBlock) aCB;
282   BOPDS_DataMapOfIntegerListOfPaveBlock aMBlocks(100, aAllocator);
283   //
284   BOPAlgo_Tools::MakeBlocks(aMPBLPB, aMBlocks, aAllocator);
285   //
286   aNbBlocks = aMBlocks.Extent();
287   for (k=0; k<aNbBlocks; ++k) {
288     const BOPDS_ListOfPaveBlock& aLPB=aMBlocks.Find(k);
289     aNbPB=aLPB.Extent();
290     if (aNbPB>1) {
291       aCB=new BOPDS_CommonBlock;
292       //
293       aItLPB.Initialize(aLPB);
294       for (; aItLPB.More(); aItLPB.Next()) {
295         const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
296         aCB->AddPaveBlock(aPBx);
297       }
298       //
299       aItLPB.Initialize(aLPB);
300       for (; aItLPB.More(); aItLPB.Next()) {
301         const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
302         pDS->SetCommonBlock(aPBx, aCB);
303       }
304     }//if (aNbPB>1) {
305   }
306 }
307 //=======================================================================
308 //function : PerformCommonBlocks
309 //purpose  : 
310 //=======================================================================
311   void BOPAlgo_Tools::PerformCommonBlocks(const BOPDS_IndexedDataMapOfPaveBlockListOfInteger& aMPBLI,
312                                           Handle(NCollection_BaseAllocator)& ,//aAllocator
313                                           BOPDS_PDS& pDS)
314 {
315   Standard_Integer nF, i, aNb;
316   BOPCol_ListIteratorOfListOfInteger aItLI;
317   Handle(BOPDS_PaveBlock) aPB;
318   Handle(BOPDS_CommonBlock) aCB;
319   //
320   aNb=aMPBLI.Extent();
321   for (i=1; i<=aNb; ++i) {
322     aPB=aMPBLI.FindKey(i);
323     if (pDS->IsCommonBlock(aPB)) {
324       aCB=pDS->CommonBlock(aPB);
325     }
326     else {
327       aCB=new BOPDS_CommonBlock;
328       aCB->AddPaveBlock(aPB);
329     }
330     //
331     const BOPCol_ListOfInteger& aLI=aMPBLI.FindFromKey(aPB);
332     aItLI.Initialize(aLI);
333     for (; aItLI.More(); aItLI.Next()) {
334       nF=aItLI.Value();
335       aCB->AddFace(nF);
336     }
337     pDS->SetCommonBlock(aPB, aCB);
338   }
339 }