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