0025242: Wrong result of cut operation.
[occt.git] / src / BOPDS / BOPDS_Iterator.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 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 // This file is part of Open CASCADE Technology software library.
8 //
9 // This library is free software; you can redistribute it and/or modify it under
10 // the terms of the GNU Lesser General Public License version 2.1 as published
11 // by the Free Software Foundation, with special exception defined in the file
12 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 // distribution for complete text of the license and disclaimer of any warranty.
14 //
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
17
18 #include <BOPDS_Iterator.ixx>
19 //
20 #include <Bnd_Box.hxx>
21 //
22 #include <NCollection_IncAllocator.hxx>
23 #include <NCollection_UBTreeFiller.hxx>
24 //
25 #include <TopoDS_Shape.hxx>
26 //
27 #include <BOPCol_NCVector.hxx>
28 #include <BOPCol_TBB.hxx>
29 #include <BOPCol_BoxBndTree.hxx>
30 //
31 #include <BOPDS_IndexRange.hxx>
32 #include <BOPDS_PassKeyBoolean.hxx>
33 #include <BOPDS_MapOfPassKeyBoolean.hxx>
34 #include <BOPDS_Tools.hxx>
35
36 /////////////////////////////////////////////////////////////////////////
37 //=======================================================================
38 //class    : BOPDS_TreeSelector
39 //purpose  : 
40 //=======================================================================
41 class BOPDS_TSR : public BOPCol_BoxBndTreeSelector{
42  public:
43   BOPDS_TSR() : 
44     BOPCol_BoxBndTreeSelector(), 
45     myHasBRep(Standard_False), 
46     myTree(NULL) {
47   }
48   //
49   virtual ~BOPDS_TSR() {
50   }
51   //
52   void SetHasBRep(const Standard_Boolean bFlag) {
53     myHasBRep=bFlag;
54   }
55   //
56   void SetTree(BOPCol_BoxBndTree& aTree) {
57     myTree=&aTree;
58   }
59   //
60   void Perform() {
61     if (myHasBRep) {
62       myTree->Select(*this);
63     }
64   }
65   //
66  protected:
67   Standard_Boolean myHasBRep;
68   BOPCol_BoxBndTree *myTree;
69 };
70 //
71 //=======================================================================
72 typedef BOPCol_NCVector <BOPDS_TSR> BOPDS_VectorOfTSR; 
73 typedef BOPCol_TBBFunctor <BOPDS_TSR,BOPDS_VectorOfTSR> BOPDS_TSRFunctor;
74 typedef BOPCol_TBBCnt <BOPDS_TSRFunctor, BOPDS_VectorOfTSR> BOPDS_TSRCnt;
75 /////////////////////////////////////////////////////////////////////////
76
77
78 //=======================================================================
79 //function : 
80 //purpose  : 
81 //=======================================================================
82 BOPDS_Iterator::BOPDS_Iterator()
83 :
84   myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
85   myRunParallel(Standard_False)
86 {
87   myDS=NULL; 
88   myLength=0;
89   //
90   myLists.SetStartSize(BOPDS_DS::NbInterfTypes());
91   myLists.Init();
92 }
93 //=======================================================================
94 //function : 
95 //purpose  : 
96 //=======================================================================
97 BOPDS_Iterator::BOPDS_Iterator
98   (const Handle(NCollection_BaseAllocator)& theAllocator)
99 :
100   myAllocator(theAllocator),
101   myLists(theAllocator),
102   myRunParallel(Standard_False)
103 {
104   myDS=NULL; 
105   myLength=0;
106   //
107   myLists.SetStartSize(BOPDS_DS::NbInterfTypes());
108   myLists.Init();
109 }
110 //=======================================================================
111 //function : ~
112 //purpose  : 
113 //=======================================================================
114 BOPDS_Iterator::~BOPDS_Iterator()
115 {
116 }
117 //=======================================================================
118 //function : SetRunParallel
119 //purpose  : 
120 //=======================================================================
121 void BOPDS_Iterator::SetRunParallel(const Standard_Boolean theFlag)
122 {
123   myRunParallel=theFlag;
124 }
125 //=======================================================================
126 //function : RunParallel
127 //purpose  : 
128 //=======================================================================
129 Standard_Boolean BOPDS_Iterator::RunParallel()const
130 {
131   return myRunParallel;
132 }
133 //=======================================================================
134 // function: SetDS
135 // purpose: 
136 //=======================================================================
137 void BOPDS_Iterator::SetDS(const BOPDS_PDS& aDS)
138 {
139   myDS=aDS;
140 }
141 //=======================================================================
142 // function: DS
143 // purpose: 
144 //=======================================================================
145 const BOPDS_DS&  BOPDS_Iterator::DS()const
146 {
147   return *myDS;
148 }
149 //=======================================================================
150 // function: ExpectedLength
151 // purpose: 
152 //=======================================================================
153 Standard_Integer BOPDS_Iterator::ExpectedLength() const
154 {
155   return myLength;
156 }
157 //=======================================================================
158 // function: BlockLength
159 // purpose: 
160 //=======================================================================
161 Standard_Integer BOPDS_Iterator::BlockLength() const
162 {
163   Standard_Integer aNbIIs;
164   Standard_Real aCfPredict=.5;
165   
166   aNbIIs=ExpectedLength();
167   
168   if (aNbIIs<=1) {
169     return 1;
170   }
171   //
172   aNbIIs=(Standard_Integer) (aCfPredict*(Standard_Real)aNbIIs);
173   return aNbIIs;
174 }
175 //=======================================================================
176 // function: Initialize
177 // purpose: 
178 //=======================================================================
179 void BOPDS_Iterator::Initialize(const TopAbs_ShapeEnum aType1,
180     const TopAbs_ShapeEnum aType2)
181 {
182   Standard_Integer iX;
183   //
184   myLength=0;
185   iX=BOPDS_Tools::TypeToInteger(aType1, aType2);
186   if (iX>=0) {
187     myIterator.Initialize(myLists(iX));
188     myLength=myLists(iX).Extent();
189   }
190 }
191 //=======================================================================
192 // function: More
193 // purpose: 
194 //=======================================================================
195 Standard_Boolean BOPDS_Iterator::More()const
196 {
197   return myIterator.More();
198 }
199 //=======================================================================
200 // function: Next
201 // purpose: 
202 //=======================================================================
203 void BOPDS_Iterator::Next()
204 {
205   myIterator.Next();
206 }
207 //=======================================================================
208 // function: Value
209 // purpose: 
210 //=======================================================================
211 void BOPDS_Iterator::Value
212   (Standard_Integer& theI1,
213    Standard_Integer& theI2,
214    Standard_Boolean& theWithSubShape) const
215 {
216   Standard_Integer iT1, iT2, n1, n2;
217   //
218   const BOPDS_PassKeyBoolean& aPKB=myIterator.Value();
219   aPKB.Ids(n1, n2);
220   //
221   iT1=(Standard_Integer)(myDS->ShapeInfo(n1).ShapeType());
222   iT2=(Standard_Integer)(myDS->ShapeInfo(n2).ShapeType());
223   //
224   theI1=n1;
225   theI2=n2;
226   if (iT1<iT2) {
227     theI1=n2;
228     theI2=n1;
229   }
230   //
231   theWithSubShape=aPKB.Flag();
232 }
233 //=======================================================================
234 // function: Prepare
235 // purpose: 
236 //=======================================================================
237 void BOPDS_Iterator::Prepare()
238 {
239   Standard_Integer i, aNbInterfTypes;
240   //
241   aNbInterfTypes=BOPDS_DS::NbInterfTypes();
242   myLength=0;
243   for (i=0; i<aNbInterfTypes; ++i) {
244     myLists(i).Clear();
245   }
246   //
247   if (myDS==NULL){
248     return;
249   }
250   Intersect();
251 }
252 //
253 //=======================================================================
254 // function: Intersect
255 // purpose: 
256 //=======================================================================
257 void BOPDS_Iterator::Intersect()
258 {
259   Standard_Boolean bFlag;
260   Standard_Integer aNb, i, aNbR, iTi, iTj;
261   Standard_Integer i1, i2, aNbSD, iX, j, iR;
262   TopAbs_ShapeEnum aTi, aTj;
263   Handle(NCollection_IncAllocator) aAllocator;
264   BOPCol_ListIteratorOfListOfInteger aIt;
265   //
266   //-----------------------------------------------------scope_1 f
267   aAllocator=new NCollection_IncAllocator();
268   //
269   BOPDS_MapOfPassKeyBoolean aMPKXB(100, aAllocator);
270   BOPDS_PassKeyBoolean aPKXB; 
271   //
272   BOPCol_BoxBndTreeSelector aSelector;
273   BOPCol_BoxBndTree aBBTree;
274   NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
275   //
276   aNb=myDS->NbSourceShapes();
277   BOPDS_VectorOfTSR aVTSR(aNb, aAllocator);
278   //
279   for (i=0; i<aNb; ++i) {
280     const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
281     bFlag=aSI.IsInterfering();
282     //
283     BOPDS_TSR& aTSR=aVTSR.Append1();
284     //
285     aTSR.SetHasBRep(bFlag);
286     if (!bFlag) {
287       continue;
288     }
289     //
290     const Bnd_Box& aBoxEx=aSI.Box();
291     aTSR.SetTree(aBBTree);
292     aTSR.SetBox(aBoxEx);
293     //
294     aTreeFiller.Add(i, aBoxEx);
295   }
296   //
297   aTreeFiller.Fill();
298   //
299   //===========================================
300   BOPDS_TSRCnt::Perform(myRunParallel, aVTSR);
301   //===========================================
302   //
303   aNbR=myDS->NbRanges()-1;
304   for (iR=0; iR<aNbR; ++iR) {
305     const BOPDS_IndexRange& aR=myDS->Range(iR);
306     i1=aR.First();
307     i2=aR.Last();
308     for (i=i1; i<=i2; ++i) {
309       const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
310       //
311       if (!aSI.IsInterfering()){
312         continue;
313       }
314       //
315       aTi=aSI.ShapeType();
316       const Bnd_Box& aBoxi=aSI.Box();
317       //
318       BOPDS_TSR& aTSRi=aVTSR(i);
319       const BOPCol_ListOfInteger& aLI=aTSRi.Indices();
320       aNbSD=aLI.Extent();
321       if (!aNbSD){
322         continue;
323       }
324       //
325       aIt.Initialize(aLI);
326       for (; aIt.More(); aIt.Next()) {
327         j=aIt.Value(); // DS index
328         if (j>=i1 && j<=i2) {
329           continue;// same range
330         }
331         //
332         const BOPDS_ShapeInfo& aSIj=myDS->ShapeInfo(j);
333         aTj=aSIj.ShapeType();
334         iTi=BOPDS_Tools::TypeToInteger(aTi);
335         iTj=BOPDS_Tools::TypeToInteger(aTj);
336         //
337         bFlag=Standard_False;
338         if (iTi<iTj) {
339           bFlag=aSI.HasSubShape(j);
340         } 
341         else if (iTj<iTi) {
342           bFlag=aSIj.HasSubShape(i);
343         }
344         if (bFlag) {
345           continue; 
346         }
347         //
348         aPKXB.SetIds(i, j);
349         if (aMPKXB.Add(aPKXB)) {
350           bFlag=Standard_False;// Bounding boxes are intersected
351           const Bnd_Box& aBoxj=aSIj.Box();
352           if (aBoxi.IsOut(aBoxj)) {
353             bFlag=!bFlag; //Bounding boxes of Sub-shapes are intersected
354           }
355           //
356           iX=BOPDS_Tools::TypeToInteger(aTi, aTj);
357           aPKXB.SetFlag(bFlag);
358           myLists(iX).Append(aPKXB);
359         }// if (aMPKXB.Add(aPKXB)) {
360       }// for (; aIt.More(); aIt.Next()) {
361     }//for (i=i1; i<=i2; ++i) {
362   }//for (iR=1; iR<aNbR; ++iR) {
363   //
364   aMPKXB.Clear();
365   aVTSR.Clear();
366   aAllocator.Nullify();
367   //-----------------------------------------------------scope_1 t
368 }