0024098: Exception Standard_OutOfMemory raised during topological operation.
[occt.git] / src / BOPDS / BOPDS_Iterator.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2012 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 //                         EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 //
7 // The content of this file is subject to the Open CASCADE Technology Public
8 // License Version 6.5 (the "License"). You may not use the content of this file
9 // except in compliance with the License. Please obtain a copy of the License
10 // at http://www.opencascade.org and read it completely before using this file.
11 //
12 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
13 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 //
15 // The Original Code and all software distributed under the License is
16 // distributed on an "AS IS" basis, without warranty of any kind, and the
17 // Initial Developer hereby disclaims all such warranties, including without
18 // limitation, any warranties of merchantability, fitness for a particular
19 // purpose or non-infringement. Please see the License for the specific terms
20 // and conditions governing the rights and limitations under the License.
21
22
23 #include <BOPDS_Iterator.ixx>
24 //
25 #include <Bnd_Box.hxx>
26 //
27 #include <NCollection_BaseAllocator.hxx>
28 #include <NCollection_UBTreeFiller.hxx>
29 //
30 #include <TopoDS.hxx>
31 #include <TopoDS_Vertex.hxx>
32 #include <TopoDS_Shape.hxx>
33 //
34 #include <BOPCol_IndexedDataMapOfShapeBox.hxx>
35 #include <BOPCol_DataMapOfIntegerInteger.hxx>
36 #include <BOPCol_DataMapOfIntegerMapOfInteger.hxx>
37 #include <BOPCol_MapOfInteger.hxx>
38 //
39 #include <BOPDS_BoxBndTree.hxx>
40 #include <BOPDS_IndexRange.hxx>
41 #include <BOPDS_PassKeyBoolean.hxx>
42 #include <BOPDS_MapOfPassKeyBoolean.hxx>
43 #include <BOPDS_Tools.hxx>
44 #include <BOPDS_MapOfPassKeyBoolean.hxx>
45
46
47 //=======================================================================
48 //function : 
49 //purpose  : 
50 //=======================================================================
51   BOPDS_Iterator::BOPDS_Iterator()
52 :
53   myAllocator(NCollection_BaseAllocator::CommonBaseAllocator())
54 {
55   myDS=NULL; 
56   myLength=0;
57   //
58   myLists.SetStartSize(6);
59   myLists.Init();
60 }
61 //=======================================================================
62 //function : 
63 //purpose  : 
64 //=======================================================================
65   BOPDS_Iterator::BOPDS_Iterator(const Handle(NCollection_BaseAllocator)& theAllocator)
66 :
67   myAllocator(theAllocator),
68   myLists(theAllocator)
69 {
70   myDS=NULL; 
71   myLength=0;
72   //
73   myLists.SetStartSize(6);
74   myLists.Init();
75 }
76 //=======================================================================
77 //function : ~
78 //purpose  : 
79 //=======================================================================
80   BOPDS_Iterator::~BOPDS_Iterator()
81 {
82 }
83 //=======================================================================
84 // function: SetDS
85 // purpose: 
86 //=======================================================================
87   void BOPDS_Iterator::SetDS(const BOPDS_PDS& aDS)
88 {
89   myDS=aDS;
90 }
91 //=======================================================================
92 // function: DS
93 // purpose: 
94 //=======================================================================
95   const BOPDS_DS&  BOPDS_Iterator::DS()const
96 {
97   return *myDS;
98 }
99 //=======================================================================
100 // function: ExpectedLength
101 // purpose: 
102 //=======================================================================
103   Standard_Integer BOPDS_Iterator::ExpectedLength() const
104 {
105   return myLength;
106 }
107 //=======================================================================
108 // function: BlockLength
109 // purpose: 
110 //=======================================================================
111   Standard_Integer BOPDS_Iterator::BlockLength() const
112 {
113   Standard_Integer aNbIIs;
114   Standard_Real aCfPredict=.5;
115   
116   aNbIIs=ExpectedLength();
117   
118   if (aNbIIs<=1) {
119     return 1;
120   }
121   //
122   aNbIIs=(Standard_Integer) (aCfPredict*(Standard_Real)aNbIIs);
123   return aNbIIs;
124 }
125 //=======================================================================
126 // function: Initialize
127 // purpose: 
128 //=======================================================================
129   void BOPDS_Iterator::Initialize(const TopAbs_ShapeEnum aType1,
130                                   const TopAbs_ShapeEnum aType2)
131 {
132   Standard_Integer iX;
133   //
134   myLength=0;
135   iX=BOPDS_Tools::TypeToInteger(aType1, aType2);
136   if (iX>=0) {
137     myIterator.Initialize(myLists(iX));
138     myLength=myLists(iX).Extent();
139   }
140 }
141 //=======================================================================
142 // function: More
143 // purpose: 
144 //=======================================================================
145   Standard_Boolean BOPDS_Iterator::More()const
146 {
147   return myIterator.More();
148 }
149 //=======================================================================
150 // function: Next
151 // purpose: 
152 //=======================================================================
153   void BOPDS_Iterator::Next()
154 {
155   myIterator.Next();
156 }
157 //=======================================================================
158 // function: Value
159 // purpose: 
160 //=======================================================================
161   void BOPDS_Iterator::Value(Standard_Integer& theI1,
162                              Standard_Integer& theI2,
163                              Standard_Boolean& theWithSubShape) const
164 {
165   Standard_Integer iT1, iT2, n1, n2;
166   //
167   const BOPDS_PassKeyBoolean& aPKB=myIterator.Value();
168   aPKB.Ids(n1, n2);
169   //
170   iT1=(Standard_Integer)(myDS->ShapeInfo(n1).ShapeType());
171   iT2=(Standard_Integer)(myDS->ShapeInfo(n2).ShapeType());
172   //
173   theI1=n1;
174   theI2=n2;
175   if (iT1<iT2) {
176     theI1=n2;
177     theI2=n1;
178   }
179   //
180   theWithSubShape=aPKB.Flag();
181 }
182
183 //=======================================================================
184 // function: Prepare
185 // purpose: 
186 //=======================================================================
187   void BOPDS_Iterator::Prepare()
188 {
189   Standard_Integer i;
190   //
191   myLength=0;
192   for (i=0; i<6; ++i) {
193     myLists(i).Clear();
194   }
195   //
196   if (myDS==NULL){
197     return;
198   }
199   Intersect();
200 }
201 //=======================================================================
202 // function: Intersect
203 // purpose: 
204 //=======================================================================
205   void BOPDS_Iterator::Intersect()
206 {
207   Standard_Boolean bFlag;
208   Standard_Integer aNb, i, aNbB, aNbR, iTi, iTj;
209   Standard_Integer i1, i2, aNbSD, iX, j, iDS, jB, iR;
210   TopAbs_ShapeEnum aTi, aTj;
211   Handle(NCollection_IncAllocator) aAllocator;
212   //
213   BOPCol_ListIteratorOfListOfInteger aIt;
214   //
215   //-----------------------------------------------------scope_1 f
216   aAllocator=new NCollection_IncAllocator();
217   //
218   BOPCol_DataMapOfShapeInteger aMSI(100, aAllocator);
219   BOPCol_DataMapOfIntegerInteger aMII(100, aAllocator);
220   BOPDS_MapOfPassKeyBoolean aMPKXB(100, aAllocator);
221   BOPCol_IndexedDataMapOfShapeBox aMSB(100, aAllocator);
222   BOPDS_PassKeyBoolean aPKXB; 
223   //
224   BOPDS_BoxBndTreeSelector aSelector;
225   BOPDS_BoxBndTree aBBTree;
226   NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
227   //
228   aNb=myDS->NbSourceShapes();
229   for (i=0; i<aNb; ++i) {
230     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
231     if (aSI.HasBRep()) {
232       const TopoDS_Shape& aS=aSI.Shape();
233       const Bnd_Box& aBoxEx=aSI.Box();
234       aMSI.Bind(aS, i);
235       aMSB.Add(aS, aBoxEx);
236     }
237   }
238   //
239   aNbB=aMSB.Extent();
240   for (i=1; i<=aNbB; ++i) {
241     const TopoDS_Shape& aS=aMSB.FindKey(i);
242     const Bnd_Box& aBoxEx=aMSB(i);
243     //
244     aTreeFiller.Add(i, aBoxEx);
245     //
246     iDS=aMSI.Find(aS);
247     aMII.Bind(i, iDS);
248   }
249   //
250   aTreeFiller.Fill();
251   //
252   aNbR=myDS->NbRanges()-1;
253   for (iR=0; iR<aNbR; ++iR) {
254     const BOPDS_IndexRange& aR=myDS->Range(iR);
255     i1=aR.First();
256     i2=aR.Last();
257     for (i=i1; i<=i2; ++i) {
258       const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
259       //
260       if (!aSI.HasBRep()){
261         continue;
262       }
263       //
264       aTi=aSI.ShapeType();
265       const TopoDS_Shape& aSi=aSI.Shape();
266       const Bnd_Box& aBoxEx=aMSB.FindFromKey(aSi);
267       aSelector.Clear();
268       aSelector.SetBox(aBoxEx);
269       //
270       aNbSD=aBBTree.Select(aSelector);
271       if (!aNbSD){
272         continue;
273       }
274       //
275       const Bnd_Box& aBoxi=myDS->ShapeInfo(i).Box();
276       //
277       const BOPCol_ListOfInteger& aLI=aSelector.Indices();
278       aIt.Initialize(aLI);
279       for (; aIt.More(); aIt.Next()) {
280         jB=aIt.Value();  // box index in MII
281         j=aMII.Find(jB); // DS index
282         if (j>=i1 && j<=i2) {
283           continue;// same range
284         }
285         //
286         const BOPDS_ShapeInfo& aSIj=myDS->ShapeInfo(j);
287         aTj=aSIj.ShapeType();
288         iTi=BOPDS_Tools::TypeToInteger(aTi);
289         iTj=BOPDS_Tools::TypeToInteger(aTj);
290         bFlag=Standard_False;
291         if (iTi<iTj) {
292           bFlag=aSI.HasSubShape(j);
293         } 
294         else if (iTj<iTi) {
295            bFlag=aSIj.HasSubShape(i);
296         }
297         if (bFlag) {
298           continue; 
299         }
300         //
301         aPKXB.SetIds(i, j);
302         if (aMPKXB.Add(aPKXB)) {
303           bFlag=Standard_False;// Bounding boxes are intersected
304           const Bnd_Box& aBoxj=myDS->ShapeInfo(j).Box();
305           if (aBoxi.IsOut(aBoxj)) {
306             bFlag=!bFlag; //Bounding boxes of Sub-shapes are intersected
307           }
308           //
309           iX=BOPDS_Tools::TypeToInteger(aTi, aTj);
310           aPKXB.SetFlag(bFlag);
311           myLists(iX).Append(aPKXB);
312         }// if (aMPKXB.Add(aPKXB)) {
313       }// for (; aIt.More(); aIt.Next()) {
314     }//for (i=i1; i<=i2; ++i) {
315   }//for (iR=1; iR<aNbR; ++iR) {
316   //
317   aMSI.Clear();
318   aMII.Clear();
319   aMPKXB.Clear();
320   aMSB.Clear();
321   //
322   aAllocator.Nullify();
323   //-----------------------------------------------------scope_1 t
324 }