0025242: Wrong result of cut operation.
[occt.git] / src / BOPDS / BOPDS_Iterator.cxx
CommitLineData
4e57c75e 1// Created by: Peter KURNEV
973c2be1 2// Copyright (c) 2010-2014 OPEN CASCADE SAS
4e57c75e 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//
973c2be1 7// This file is part of Open CASCADE Technology software library.
4e57c75e 8//
d5f74e42 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
973c2be1 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.
4e57c75e 14//
973c2be1 15// Alternatively, this file may be used under the terms of Open CASCADE
16// commercial license or contractual agreement.
4e57c75e 17
18#include <BOPDS_Iterator.ixx>
19//
20#include <Bnd_Box.hxx>
21//
ddf2fe8e 22#include <NCollection_IncAllocator.hxx>
4e57c75e 23#include <NCollection_UBTreeFiller.hxx>
24//
4e57c75e 25#include <TopoDS_Shape.hxx>
26//
a2098360 27#include <BOPCol_NCVector.hxx>
28#include <BOPCol_TBB.hxx>
db8e4b9a 29#include <BOPCol_BoxBndTree.hxx>
a2098360 30//
4e57c75e 31#include <BOPDS_IndexRange.hxx>
32#include <BOPDS_PassKeyBoolean.hxx>
33#include <BOPDS_MapOfPassKeyBoolean.hxx>
34#include <BOPDS_Tools.hxx>
a2098360 35
36/////////////////////////////////////////////////////////////////////////
37//=======================================================================
38//class : BOPDS_TreeSelector
39//purpose :
40//=======================================================================
41class 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//=======================================================================
72typedef BOPCol_NCVector <BOPDS_TSR> BOPDS_VectorOfTSR;
73typedef BOPCol_TBBFunctor <BOPDS_TSR,BOPDS_VectorOfTSR> BOPDS_TSRFunctor;
74typedef BOPCol_TBBCnt <BOPDS_TSRFunctor, BOPDS_VectorOfTSR> BOPDS_TSRCnt;
75/////////////////////////////////////////////////////////////////////////
4e57c75e 76
77
78//=======================================================================
79//function :
80//purpose :
81//=======================================================================
ceaa5e27 82BOPDS_Iterator::BOPDS_Iterator()
4e57c75e 83:
a2098360 84 myAllocator(NCollection_BaseAllocator::CommonBaseAllocator()),
85 myRunParallel(Standard_False)
4e57c75e 86{
87 myDS=NULL;
88 myLength=0;
89 //
ceaa5e27 90 myLists.SetStartSize(BOPDS_DS::NbInterfTypes());
4e57c75e 91 myLists.Init();
92}
93//=======================================================================
94//function :
95//purpose :
96//=======================================================================
ceaa5e27 97BOPDS_Iterator::BOPDS_Iterator
98 (const Handle(NCollection_BaseAllocator)& theAllocator)
4e57c75e 99:
100 myAllocator(theAllocator),
a2098360 101 myLists(theAllocator),
102 myRunParallel(Standard_False)
4e57c75e 103{
104 myDS=NULL;
105 myLength=0;
106 //
ceaa5e27 107 myLists.SetStartSize(BOPDS_DS::NbInterfTypes());
4e57c75e 108 myLists.Init();
109}
110//=======================================================================
111//function : ~
112//purpose :
113//=======================================================================
ceaa5e27 114BOPDS_Iterator::~BOPDS_Iterator()
4e57c75e 115{
116}
117//=======================================================================
a2098360 118//function : SetRunParallel
119//purpose :
120//=======================================================================
121void BOPDS_Iterator::SetRunParallel(const Standard_Boolean theFlag)
122{
123 myRunParallel=theFlag;
124}
125//=======================================================================
126//function : RunParallel
127//purpose :
128//=======================================================================
129Standard_Boolean BOPDS_Iterator::RunParallel()const
130{
131 return myRunParallel;
132}
133//=======================================================================
4e57c75e 134// function: SetDS
135// purpose:
136//=======================================================================
ceaa5e27 137void BOPDS_Iterator::SetDS(const BOPDS_PDS& aDS)
4e57c75e 138{
139 myDS=aDS;
140}
141//=======================================================================
142// function: DS
143// purpose:
144//=======================================================================
ceaa5e27 145const BOPDS_DS& BOPDS_Iterator::DS()const
4e57c75e 146{
147 return *myDS;
148}
149//=======================================================================
150// function: ExpectedLength
151// purpose:
152//=======================================================================
ceaa5e27 153Standard_Integer BOPDS_Iterator::ExpectedLength() const
4e57c75e 154{
155 return myLength;
156}
157//=======================================================================
158// function: BlockLength
159// purpose:
160//=======================================================================
ceaa5e27 161Standard_Integer BOPDS_Iterator::BlockLength() const
4e57c75e 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//=======================================================================
ceaa5e27 179void BOPDS_Iterator::Initialize(const TopAbs_ShapeEnum aType1,
a2098360 180 const TopAbs_ShapeEnum aType2)
4e57c75e 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//=======================================================================
ceaa5e27 195Standard_Boolean BOPDS_Iterator::More()const
4e57c75e 196{
197 return myIterator.More();
198}
199//=======================================================================
200// function: Next
201// purpose:
202//=======================================================================
ceaa5e27 203void BOPDS_Iterator::Next()
4e57c75e 204{
205 myIterator.Next();
206}
207//=======================================================================
208// function: Value
209// purpose:
210//=======================================================================
a2098360 211void BOPDS_Iterator::Value
212 (Standard_Integer& theI1,
213 Standard_Integer& theI2,
214 Standard_Boolean& theWithSubShape) const
4e57c75e 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}
4e57c75e 233//=======================================================================
234// function: Prepare
235// purpose:
236//=======================================================================
ceaa5e27 237void BOPDS_Iterator::Prepare()
4e57c75e 238{
ceaa5e27 239 Standard_Integer i, aNbInterfTypes;
4e57c75e 240 //
ceaa5e27 241 aNbInterfTypes=BOPDS_DS::NbInterfTypes();
4e57c75e 242 myLength=0;
ceaa5e27 243 for (i=0; i<aNbInterfTypes; ++i) {
4e57c75e 244 myLists(i).Clear();
245 }
246 //
247 if (myDS==NULL){
248 return;
249 }
250 Intersect();
251}
a2098360 252//
4e57c75e 253//=======================================================================
254// function: Intersect
255// purpose:
256//=======================================================================
ceaa5e27 257void BOPDS_Iterator::Intersect()
4e57c75e 258{
259 Standard_Boolean bFlag;
a2098360 260 Standard_Integer aNb, i, aNbR, iTi, iTj;
261 Standard_Integer i1, i2, aNbSD, iX, j, iR;
4e57c75e 262 TopAbs_ShapeEnum aTi, aTj;
263 Handle(NCollection_IncAllocator) aAllocator;
4e57c75e 264 BOPCol_ListIteratorOfListOfInteger aIt;
265 //
266 //-----------------------------------------------------scope_1 f
267 aAllocator=new NCollection_IncAllocator();
268 //
4e57c75e 269 BOPDS_MapOfPassKeyBoolean aMPKXB(100, aAllocator);
4e57c75e 270 BOPDS_PassKeyBoolean aPKXB;
271 //
db8e4b9a 272 BOPCol_BoxBndTreeSelector aSelector;
273 BOPCol_BoxBndTree aBBTree;
4e57c75e 274 NCollection_UBTreeFiller <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
275 //
276 aNb=myDS->NbSourceShapes();
a2098360 277 BOPDS_VectorOfTSR aVTSR(aNb, aAllocator);
278 //
4e57c75e 279 for (i=0; i<aNb; ++i) {
280 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
955b3e71 281 bFlag=aSI.IsInterfering();
a2098360 282 //
283 BOPDS_TSR& aTSR=aVTSR.Append1();
284 //
285 aTSR.SetHasBRep(bFlag);
286 if (!bFlag) {
287 continue;
4e57c75e 288 }
4e57c75e 289 //
a2098360 290 const Bnd_Box& aBoxEx=aSI.Box();
291 aTSR.SetTree(aBBTree);
292 aTSR.SetBox(aBoxEx);
4e57c75e 293 //
a2098360 294 aTreeFiller.Add(i, aBoxEx);
4e57c75e 295 }
296 //
297 aTreeFiller.Fill();
298 //
a2098360 299 //===========================================
300 BOPDS_TSRCnt::Perform(myRunParallel, aVTSR);
301 //===========================================
302 //
4e57c75e 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 //
955b3e71 311 if (!aSI.IsInterfering()){
a2098360 312 continue;
4e57c75e 313 }
314 //
315 aTi=aSI.ShapeType();
a2098360 316 const Bnd_Box& aBoxi=aSI.Box();
4e57c75e 317 //
a2098360 318 BOPDS_TSR& aTSRi=aVTSR(i);
319 const BOPCol_ListOfInteger& aLI=aTSRi.Indices();
320 aNbSD=aLI.Extent();
4e57c75e 321 if (!aNbSD){
a2098360 322 continue;
4e57c75e 323 }
324 //
4e57c75e 325 aIt.Initialize(aLI);
326 for (; aIt.More(); aIt.Next()) {
a2098360 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)) {
4e57c75e 360 }// for (; aIt.More(); aIt.Next()) {
361 }//for (i=i1; i<=i2; ++i) {
362 }//for (iR=1; iR<aNbR; ++iR) {
363 //
4e57c75e 364 aMPKXB.Clear();
a2098360 365 aVTSR.Clear();
4e57c75e 366 aAllocator.Nullify();
367 //-----------------------------------------------------scope_1 t
368}