0024495: Crash during performeng boolean operation on attached shape for Windows...
[occt.git] / src / BOPAlgo / BOPAlgo_Tools.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and / or modify it
7 // under the terms of the GNU Lesser General Public version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <BOPAlgo_Tools.ixx>
16 #include <BOPDS_DS.hxx>
17 #include <BOPDS_MapOfPaveBlock.hxx>
18 #include <BOPDS_IndexedMapOfPaveBlock.hxx>
19 #include <BOPDS_CommonBlock.hxx>
20 #include <BOPDS_DataMapOfPaveBlockListOfPaveBlock.hxx>
21 #include <BOPCol_IndexedMapOfInteger.hxx>
22
23 //=======================================================================
24 //function : MakeBlocksCnx
25 //purpose  : 
26 //=======================================================================
27   void BOPAlgo_Tools::MakeBlocksCnx(const BOPCol_IndexedDataMapOfIntegerListOfInteger& aMILI,
28                                     BOPCol_DataMapOfIntegerListOfInteger& aMBlocks,
29                                     Handle(NCollection_BaseAllocator)& aAllocator)
30 {
31   Standard_Integer aNbV, nV, aNbVS, nVP, nVx, aNbVP, aNbEC, k, i, j;
32   BOPCol_ListIteratorOfListOfInteger aItLI;
33   //
34   BOPCol_MapOfInteger aMVS(100, aAllocator);
35   BOPCol_IndexedMapOfInteger aMEC(100, aAllocator);
36   BOPCol_IndexedMapOfInteger aMVP(100, aAllocator);
37   BOPCol_IndexedMapOfInteger aMVAdd(100, aAllocator);
38   //
39   aNbV=aMILI.Extent();
40   //
41   for (k=0,i=1; i<=aNbV; ++i) {
42     aNbVS=aMVS.Extent();
43     if (aNbVS==aNbV) {
44       break;
45     }
46     //
47     nV = aMILI.FindKey(i);
48     if (aMVS.Contains(nV)){
49       continue;
50     }
51     aMVS.Add(nV);
52     //
53     aMEC.Clear();
54     aMVP.Clear();
55     aMVAdd.Clear();
56     //
57     aMVP.Add(nV);
58     for(;;) {
59       aNbVP=aMVP.Extent();
60       for (j=1; j<=aNbVP; ++j) {
61         nVP=aMVP(j);
62         const BOPCol_ListOfInteger& aLV=aMILI.FindFromKey(nVP);
63         aItLI.Initialize(aLV);
64         for (; aItLI.More(); aItLI.Next()) {
65           nVx=aItLI.Value();
66           if (aMEC.Contains(nVx)) {
67             continue;
68           }
69           //
70           aMVS.Add(nVx);
71           aMEC.Add(nVx);
72           aMVAdd.Add(nVx);
73         }
74       }
75       //
76       aNbVP=aMVAdd.Extent();
77       if (!aNbVP) {
78         break; // from while(1)
79       }
80       //
81       aMVP.Clear();
82       for (j=1; j<=aNbVP; ++j) {
83         aMVP.Add(aMVAdd(j));
84       }
85       aMVAdd.Clear();
86     }//while(1) {
87     //
88     BOPCol_ListOfInteger aLIx(aAllocator);
89     //
90     aNbEC = aMEC.Extent();
91     for (j=1; j<=aNbEC; ++j) {
92       nVx=aMEC(j);
93       aLIx.Append(nVx);
94     }
95     //
96     aMBlocks.Bind(k, aLIx);
97     ++k;
98   }//for (k=0,i=1; i<=aNbV; ++i)
99   aMVAdd.Clear();
100   aMVP.Clear();
101   aMEC.Clear();
102   aMVS.Clear();
103 }
104 //=======================================================================
105 //function : FillMap
106 //purpose  : 
107 //=======================================================================
108   void BOPAlgo_Tools::FillMap(const Standard_Integer n1,
109                               const Standard_Integer n2,
110                               BOPCol_IndexedDataMapOfIntegerListOfInteger& aMILI,
111                               Handle(NCollection_BaseAllocator)& aAllocator)
112 {
113   if (aMILI.Contains(n1)) {
114     BOPCol_ListOfInteger& aLI=aMILI.ChangeFromKey(n1);
115     aLI.Append(n2);
116   }
117   else {
118     BOPCol_ListOfInteger aLI(aAllocator);
119     aLI.Append(n2);
120     aMILI.Add(n1, aLI);
121   }
122   if (aMILI.Contains(n2)) {
123     BOPCol_ListOfInteger& aLI=aMILI.ChangeFromKey(n2);
124     aLI.Append(n1);
125   }
126   else {
127     BOPCol_ListOfInteger aLI(aAllocator);
128     aLI.Append(n1);
129     aMILI.Add(n2, aLI);
130   }
131 }
132 //=======================================================================
133 //function : FillMap
134 //purpose  : 
135 //=======================================================================
136   void BOPAlgo_Tools::FillMap(const Handle(BOPDS_PaveBlock)& aPB1,
137                               const Handle(BOPDS_PaveBlock)& aPB2,
138                               BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock& aMPBLPB,
139                               Handle(NCollection_BaseAllocator)& aAllocator)
140 {
141   if (aMPBLPB.Contains(aPB1)) {
142     BOPDS_ListOfPaveBlock& aLPB=aMPBLPB.ChangeFromKey(aPB1);
143     aLPB.Append(aPB2);
144   }
145   else {
146     BOPDS_ListOfPaveBlock aLPB(aAllocator);
147     aLPB.Append(aPB2);
148     aMPBLPB.Add(aPB1, aLPB);
149   }
150   if (aMPBLPB.Contains(aPB2)) {
151     BOPDS_ListOfPaveBlock& aLPB=aMPBLPB.ChangeFromKey(aPB2);
152     aLPB.Append(aPB1);
153   }
154   else {
155     BOPDS_ListOfPaveBlock aLPB(aAllocator);
156     aLPB.Append(aPB1);
157     aMPBLPB.Add(aPB2, aLPB);
158   }
159 }
160 //=======================================================================
161 //function : FillMap
162 //purpose  : 
163 //=======================================================================
164   void BOPAlgo_Tools::FillMap(const Handle(BOPDS_PaveBlock)& aPB,
165                               const Standard_Integer nF,
166                               BOPDS_IndexedDataMapOfPaveBlockListOfInteger& aMPBLI,
167                               Handle(NCollection_BaseAllocator)& aAllocator)
168 {
169   if (aMPBLI.Contains(aPB)) {
170     BOPCol_ListOfInteger& aLI=aMPBLI.ChangeFromKey(aPB);
171     aLI.Append(nF);
172   }
173   else {
174     BOPCol_ListOfInteger aLI(aAllocator);
175     aLI.Append(nF);
176     aMPBLI.Add(aPB, aLI);
177   }
178 }
179 //=======================================================================
180 //function : MakeBlocks
181 //purpose  : 
182 //=======================================================================
183   void BOPAlgo_Tools::MakeBlocks(const BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock& aMILI,
184                                  BOPDS_DataMapOfIntegerListOfPaveBlock& aMBlocks,
185                                  Handle(NCollection_BaseAllocator)& aAllocator)
186 {
187   Standard_Integer aNbV,  aNbVS, aNbVP, aNbEC, k, i, j;
188   BOPDS_ListIteratorOfListOfPaveBlock aItLI;
189   //
190   BOPDS_MapOfPaveBlock aMVS(100, aAllocator);
191   BOPDS_IndexedMapOfPaveBlock aMEC(100, aAllocator);
192   BOPDS_IndexedMapOfPaveBlock aMVP(100, aAllocator);
193   BOPDS_IndexedMapOfPaveBlock aMVAdd(100, aAllocator);
194   //
195   aNbV=aMILI.Extent();
196   //
197   for (k=0, i=1; i<=aNbV; ++i) {
198     aNbVS=aMVS.Extent();
199     if (aNbVS==aNbV) {
200       break;
201     }
202     //
203     const Handle(BOPDS_PaveBlock)& nV=aMILI.FindKey(i);
204     if (aMVS.Contains(nV)){
205       continue;
206     }
207     aMVS.Add(nV);
208     //
209     aMEC.Clear();
210     aMVP.Clear();
211     aMVAdd.Clear();
212     //
213     aMVP.Add(nV);
214     for(;;) {
215       aNbVP=aMVP.Extent();
216       for (j=1; j<=aNbVP; ++j) {
217         const Handle(BOPDS_PaveBlock)& nVP=aMVP(j);
218         const BOPDS_ListOfPaveBlock& aLV=aMILI.FindFromKey(nVP);
219         aItLI.Initialize(aLV);
220         for (; aItLI.More(); aItLI.Next()) {
221           const Handle(BOPDS_PaveBlock)& nVx=aItLI.Value();
222           if (aMEC.Contains(nVx)) {
223             continue;
224           }
225           //
226           aMVS.Add(nVx);
227           aMEC.Add(nVx);
228           aMVAdd.Add(nVx);
229         }
230       }
231       //
232       aNbVP=aMVAdd.Extent();
233       if (!aNbVP) {
234         break; // from while(1)
235       }
236       //
237       aMVP.Clear();
238       for (j=1; j<=aNbVP; ++j) {
239         aMVP.Add(aMVAdd(j));
240       }
241       aMVAdd.Clear();
242     }//while(1) {
243     //
244     BOPDS_ListOfPaveBlock aLIx(aAllocator);
245     //
246     aNbEC = aMEC.Extent();
247     for (j=1; j<=aNbEC; ++j) {
248       const Handle(BOPDS_PaveBlock)& nVx=aMEC(j);
249       aLIx.Append(nVx);
250     }
251     //
252     aMBlocks.Bind(k, aLIx);
253     ++k;
254   }//for (k=0, i=1; i<=aNbV; ++i)
255   aMVAdd.Clear();
256   aMVP.Clear();
257   aMEC.Clear();
258   aMVS.Clear();
259 }
260 //=======================================================================
261 //function : PerformCommonBlocks
262 //purpose  : 
263 //=======================================================================
264   void BOPAlgo_Tools::PerformCommonBlocks(BOPDS_IndexedDataMapOfPaveBlockListOfPaveBlock& aMPBLPB,
265                                           Handle(NCollection_BaseAllocator)& aAllocator,
266                                           BOPDS_PDS& pDS)
267 {
268   Standard_Integer aNbCB;
269   //
270   aNbCB=aMPBLPB.Extent();
271   if (!aNbCB) {
272     return;
273   }
274   //
275   Standard_Integer aNbPB, aNbBlocks, k;
276   BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
277   Handle(BOPDS_CommonBlock) aCB;
278   BOPDS_DataMapOfIntegerListOfPaveBlock aMBlocks(100, aAllocator);
279   //
280   BOPAlgo_Tools::MakeBlocks(aMPBLPB, aMBlocks, aAllocator);
281   //
282   aNbBlocks = aMBlocks.Extent();
283   for (k=0; k<aNbBlocks; ++k) {
284     const BOPDS_ListOfPaveBlock& aLPB=aMBlocks.Find(k);
285     aNbPB=aLPB.Extent();
286     if (aNbPB>1) {
287       aCB=new BOPDS_CommonBlock;
288       //
289       aItLPB.Initialize(aLPB);
290       for (; aItLPB.More(); aItLPB.Next()) {
291         const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
292         aCB->AddPaveBlock(aPBx);
293       }
294       //
295       aItLPB.Initialize(aLPB);
296       for (; aItLPB.More(); aItLPB.Next()) {
297         const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
298         pDS->SetCommonBlock(aPBx, aCB);
299       }
300     }//if (aNbPB>1) {
301   }
302 }
303 //=======================================================================
304 //function : PerformCommonBlocks
305 //purpose  : 
306 //=======================================================================
307   void BOPAlgo_Tools::PerformCommonBlocks(const BOPDS_IndexedDataMapOfPaveBlockListOfInteger& aMPBLI,
308                                           Handle(NCollection_BaseAllocator)& ,//aAllocator
309                                           BOPDS_PDS& pDS)
310 {
311   Standard_Integer nF, i, aNb;
312   BOPCol_ListIteratorOfListOfInteger aItLI;
313   Handle(BOPDS_PaveBlock) aPB;
314   Handle(BOPDS_CommonBlock) aCB;
315   //
316   aNb=aMPBLI.Extent();
317   for (i=1; i<=aNb; ++i) {
318     aPB=aMPBLI.FindKey(i);
319     if (pDS->IsCommonBlock(aPB)) {
320       aCB=pDS->CommonBlock(aPB);
321     }
322     else {
323       aCB=new BOPDS_CommonBlock;
324       aCB->AddPaveBlock(aPB);
325     }
326     //
327     const BOPCol_ListOfInteger& aLI=aMPBLI.FindFromKey(aPB);
328     aItLI.Initialize(aLI);
329     for (; aItLI.More(); aItLI.Next()) {
330       nF=aItLI.Value();
331       aCB->AddFace(nF);
332     }
333     pDS->SetCommonBlock(aPB, aCB);
334   }
335 }