0026567: Exception in Boolean intersection command
[occt.git] / src / BOPAlgo / BOPAlgo_BuilderSolid.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.
465d1fba 17//
42cf5bc1 18#include <BOPAlgo_BuilderSolid.hxx>
19#include <BOPAlgo_ShellSplitter.hxx>
20#include <BOPCol_BoxBndTree.hxx>
21#include <BOPCol_DataMapOfShapeListOfShape.hxx>
22#include <BOPCol_DataMapOfShapeShape.hxx>
23#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
319da2e4 24#include <BOPCol_IndexedDataMapOfShapeShape.hxx>
42cf5bc1 25#include <BOPCol_ListOfInteger.hxx>
26#include <BOPCol_ListOfShape.hxx>
27#include <BOPCol_MapOfOrientedShape.hxx>
28#include <BOPCol_MapOfShape.hxx>
29#include <BOPCol_NCVector.hxx>
30#include <BOPCol_Parallel.hxx>
31#include <BOPTools.hxx>
32#include <BOPTools_AlgoTools.hxx>
33#include <BOPTools_AlgoTools3D.hxx>
34#include <BOPTools_CoupleOfShape.hxx>
35#include <BRep_Builder.hxx>
36#include <BRep_Tool.hxx>
37#include <BRepBndLib.hxx>
38#include <BRepClass3d_SolidClassifier.hxx>
39#include <Geom2d_Curve.hxx>
40#include <Geom_Curve.hxx>
41#include <Geom_Surface.hxx>
4e57c75e 42#include <gp_Dir.hxx>
42cf5bc1 43#include <gp_Pln.hxx>
4e57c75e 44#include <gp_Pnt.hxx>
42cf5bc1 45#include <gp_Pnt2d.hxx>
46#include <gp_Vec.hxx>
47#include <IntTools_Context.hxx>
48#include <NCollection_DataMap.hxx>
49#include <NCollection_IncAllocator.hxx>
50#include <NCollection_List.hxx>
51#include <NCollection_UBTreeFiller.hxx>
682c9d06 52#include <TColStd_MapIntegerHasher.hxx>
4e57c75e 53#include <TopAbs.hxx>
42cf5bc1 54#include <TopExp.hxx>
55#include <TopExp_Explorer.hxx>
56#include <TopoDS_Compound.hxx>
57#include <TopoDS_Edge.hxx>
4e57c75e 58#include <TopoDS_Face.hxx>
42cf5bc1 59#include <TopoDS_Iterator.hxx>
4e57c75e 60#include <TopoDS_Shape.hxx>
61#include <TopoDS_Shell.hxx>
4e57c75e 62#include <TopoDS_Solid.hxx>
63#include <TopoDS_Vertex.hxx>
4e57c75e 64
42cf5bc1 65//
4e57c75e 66static
67 Standard_Boolean IsGrowthShell(const TopoDS_Shape& ,
68 const BOPCol_IndexedMapOfShape& );
69static
70 Standard_Boolean IsHole(const TopoDS_Shape& ,
1e143abb 71 Handle(IntTools_Context)& );
4e57c75e 72static
73 Standard_Boolean IsInside(const TopoDS_Shape& ,
74 const TopoDS_Shape& ,
1e143abb 75 Handle(IntTools_Context)& );
4e57c75e 76static
319da2e4 77 void MakeInternalShells(const BOPCol_IndexedMapOfShape& ,
4e57c75e 78 BOPCol_ListOfShape& );
79
682c9d06 80//=======================================================================
81//class : BOPAlgo_BuilderSolid_ShapeBox
82//purpose : Auxiliary class
83//=======================================================================
84class BOPAlgo_BuilderSolid_ShapeBox {
85 public:
86 BOPAlgo_BuilderSolid_ShapeBox() {
87 myIsHole=Standard_False;
88 };
89 //
90 ~BOPAlgo_BuilderSolid_ShapeBox() {
91 };
92 //
93 void SetShape(const TopoDS_Shape& aS) {
94 myShape=aS;
95 };
96 //
97 const TopoDS_Shape& Shape()const {
98 return myShape;
99 };
100 //
101 void SetBox(const Bnd_Box& aBox) {
102 myBox=aBox;
103 };
104 //
105 const Bnd_Box& Box()const {
106 return myBox;
107 };
108 //
109 void SetIsHole(const Standard_Boolean bFlag) {
110 myIsHole=bFlag;
111 };
112 //
113 Standard_Boolean IsHole()const {
114 return myIsHole;
115 };
116 //
117 protected:
118 Standard_Boolean myIsHole;
119 TopoDS_Shape myShape;
120 Bnd_Box myBox;
121};
122//
465d1fba 123typedef NCollection_DataMap
124 <Standard_Integer,
125 BOPAlgo_BuilderSolid_ShapeBox,
126 TColStd_MapIntegerHasher> BOPAlgo_DataMapOfIntegerBSSB;
682c9d06 127//
465d1fba 128typedef BOPAlgo_DataMapOfIntegerBSSB::Iterator
682c9d06 129 BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB;
130//
4e57c75e 131//=======================================================================
465d1fba 132//function : BOPAlgo_FacePnt
133//purpose :
134//=======================================================================
135class BOPAlgo_FacePnt {
136 public:
137 BOPAlgo_FacePnt() {
138 }
139 //
140 virtual ~BOPAlgo_FacePnt() {
141 }
142 //
143 void SetFace(const TopoDS_Face& aFace) {
144 myFace=aFace;
145 }
146 //
147 const TopoDS_Face& Face()const {
148 return myFace;
149 }
150 //
151 void SetPnt(const gp_Pnt& aPnt) {
152 myPnt=aPnt;
153 }
154 //
155 const gp_Pnt& Pnt()const {
156 return myPnt;
157 }
158 //
159 protected:
160 gp_Pnt myPnt;
161 TopoDS_Face myFace;
162};
163//
164typedef BOPCol_NCVector
165 <BOPAlgo_FacePnt> BOPAlgo_VectorOfFacePnt;
166//
167//=======================================================================
168//function : BOPAlgo_FaceSolid
169//purpose :
170//=======================================================================
171class BOPAlgo_FaceSolid : public BOPAlgo_Algo {
172 public:
173 DEFINE_STANDARD_ALLOC
174
175 BOPAlgo_FaceSolid() :
176 myIsInternalFace(Standard_False) {
177 }
178 //
179 virtual ~BOPAlgo_FaceSolid() {
180 }
181 //
182 void SetFace(const TopoDS_Face& aFace) {
183 myFace=aFace;
184 }
185 //
186 const TopoDS_Face& Face()const {
187 return myFace;
188 }
189 //
190 void SetSolid(const TopoDS_Solid& aSolid) {
191 mySolid=aSolid;
192 }
193 //
194 const TopoDS_Solid& Solid()const {
195 return mySolid;
196 }
197 //
198 void SetPnt(const gp_Pnt& aPnt) {
199 myPnt=aPnt;
200 }
201 //
202 const gp_Pnt& Pnt()const {
203 return myPnt;
204 }
205 void SetContext(const Handle(IntTools_Context)& aContext) {
206 myContext=aContext;
207 }
208 //
209 const Handle(IntTools_Context)& Context()const {
210 return myContext;
211 }
212 //
213 Standard_Boolean IsInternalFace() const {
214 return myIsInternalFace;
215 }
216 //
217 virtual void Perform () {
218 TopAbs_State aState;
219 //
220 BOPAlgo_Algo::UserBreak();
221 //
92ae0f2f 222 aState=BOPTools_AlgoTools::ComputeState(myPnt, mySolid,
223 Precision::Confusion(),
224 myContext);
465d1fba 225 //
226 myIsInternalFace=(aState==TopAbs_IN);
227 }
228 //
229 protected:
230 Standard_Boolean myIsInternalFace;
231 gp_Pnt myPnt;
232 TopoDS_Face myFace;
233 TopoDS_Solid mySolid;
234 Handle(IntTools_Context) myContext;
235};
236//=======================================================================
237typedef BOPCol_NCVector
238 <BOPAlgo_FaceSolid> BOPAlgo_VectorOfFaceSolid;
239//
c7b59798 240typedef BOPCol_ContextFunctor
465d1fba 241 <BOPAlgo_FaceSolid,
242 BOPAlgo_VectorOfFaceSolid,
243 Handle(IntTools_Context),
244 IntTools_Context> BOPAlgo_FaceSolidFunctor;
245//
c7b59798 246typedef BOPCol_ContextCnt
465d1fba 247 <BOPAlgo_FaceSolidFunctor,
248 BOPAlgo_VectorOfFaceSolid,
249 Handle(IntTools_Context)> BOPAlgo_FaceSolidCnt;
250//
251//=======================================================================
465d1fba 252
465d1fba 253//=======================================================================
4e57c75e 254//function :
255//purpose :
256//=======================================================================
682c9d06 257BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid()
4e57c75e 258:
259 BOPAlgo_BuilderArea()
260{
261}
262//=======================================================================
263//function :
264//purpose :
265//=======================================================================
682c9d06 266BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid
267 (const Handle(NCollection_BaseAllocator)& theAllocator)
4e57c75e 268:
269 BOPAlgo_BuilderArea(theAllocator)
270{
271}
272//=======================================================================
273//function : ~
274//purpose :
275//=======================================================================
30ecd5f8 276BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid()
4e57c75e 277{
278}
279//=======================================================================
30ecd5f8 280//function : SetSolid
281//purpose :
282//=======================================================================
283void BOPAlgo_BuilderSolid::SetSolid(const TopoDS_Solid& aS)
284{
285 mySolid=aS;
286}
287//=======================================================================
288//function : Solid
289//purpose :
290//=======================================================================
291const TopoDS_Solid& BOPAlgo_BuilderSolid::Solid()const
292{
293 return mySolid;
294}
295//=======================================================================
4e57c75e 296//function : Perform
297//purpose :
298//=======================================================================
30ecd5f8 299void BOPAlgo_BuilderSolid::Perform()
4e57c75e 300{
301 myErrorStatus=0;
302 //
303 if (myContext.IsNull()) {
1e143abb 304 myContext=new IntTools_Context;
4e57c75e 305 }
306 //
307 TopoDS_Compound aC;
308 BRep_Builder aBB;
309 BOPCol_ListIteratorOfListOfShape aIt;
310 //
311 aBB.MakeCompound(aC);
312 aIt.Initialize(myShapes);
313 for(; aIt.More(); aIt.Next()) {
314 const TopoDS_Shape& aF=aIt.Value();
315 aBB.Add(aC, aF);
316 }
317 //
36f4947b 318 UserBreak();
4e57c75e 319 //
320 PerformShapesToAvoid();
321 if (myErrorStatus) {
322 return;
323 }
324 //
36f4947b 325 UserBreak();
326 //
4e57c75e 327 PerformLoops();
328 if (myErrorStatus) {
329 return;
330 }
36f4947b 331 //
332 UserBreak();
333 //
4e57c75e 334 PerformAreas();
335 if (myErrorStatus) {
336 return;
337 }
36f4947b 338 //
339 UserBreak();
340 //
4e57c75e 341 PerformInternalShapes();
342 if (myErrorStatus) {
343 return;
344 }
345}
346//=======================================================================
347//function :PerformShapesToAvoid
348//purpose :
349//=======================================================================
30ecd5f8 350void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
4e57c75e 351{
352 Standard_Boolean bFound;
353 Standard_Integer i, iCnt, aNbE, aNbF;
354 TopAbs_Orientation aOrE;
355 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
356 BOPCol_ListIteratorOfListOfShape aIt;
357 //
358 myShapesToAvoid.Clear();
359 //
360 iCnt=0;
302f96fb 361 for(;;) {
4e57c75e 362 ++iCnt;
363 bFound=Standard_False;
364 //
365 // 1. MEF
366 aMEF.Clear();
367 aIt.Initialize (myShapes);
368 for (; aIt.More(); aIt.Next()) {
369 const TopoDS_Shape& aF=aIt.Value();
370 if (!myShapesToAvoid.Contains(aF)) {
465d1fba 371 BOPTools::MapShapesAndAncestors(aF,
372 TopAbs_EDGE,
373 TopAbs_FACE,
374 aMEF);
4e57c75e 375 }
4e57c75e 376 }
377 aNbE=aMEF.Extent();
378 //
379 // 2. myFacesToAvoid
380 for (i=1; i<=aNbE; ++i) {
381 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aMEF.FindKey(i)));
382 if (BRep_Tool::Degenerated(aE)) {
383 continue;
384 }
385 //
386 BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
387 aNbF=aLF.Extent();
388 if (!aNbF) {
389 continue;
390 }
391 //
392 aOrE=aE.Orientation();
393 //
394 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
395 if (aNbF==1) {
396 if (aOrE==TopAbs_INTERNAL) {
397 continue;
398 }
399 bFound=Standard_True;
400 myShapesToAvoid.Add(aF1);
401 }
402 else if (aNbF==2) {
403 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
404 if (aF2.IsSame(aF1)) {
405 if (BRep_Tool::IsClosed(aE, aF1)) {
406 continue;
407 }
408 //
409 if (aOrE==TopAbs_INTERNAL) {
410 continue;
411 }
412 //
413 bFound=Standard_True;
414 myShapesToAvoid.Add(aF1);
415 myShapesToAvoid.Add(aF2);
416 }
417 }
418 }// for (i=1; i<=aNbE; ++i) {
419 //
420 if (!bFound) {
421 break;
422 }
423 //
682c9d06 424 }//for(;;) {
4e57c75e 425}
426//=======================================================================
427//function : PerformLoops
428//purpose :
429//=======================================================================
30ecd5f8 430void BOPAlgo_BuilderSolid::PerformLoops()
4e57c75e 431{
319da2e4 432 Standard_Integer iErr, i, aNbSh;
682c9d06 433 BOPCol_ListIteratorOfListOfShape aIt;
4e57c75e 434 TopoDS_Iterator aItS;
0090ae85 435 Handle(NCollection_BaseAllocator) aAlr;
682c9d06 436 //
437 myErrorStatus=0;
438 myLoops.Clear();
4e57c75e 439 //
0090ae85 440 aAlr=new NCollection_IncAllocator();
441 BOPAlgo_ShellSplitter aSSp(aAlr);
442 //
4e57c75e 443 // 1. Shells Usual
682c9d06 444 aIt.Initialize (myShapes);
445 for (; aIt.More(); aIt.Next()) {
f47b8d2b 446 const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value());
447 if (myContext->IsInfiniteFace(aF)) {
448 TopoDS_Shell aSh;
449 BRep_Builder aBB;
450 //
451 aBB.MakeShell(aSh);
452 aBB.Add(aSh, aF);
453 myLoops.Append(aSh);
454 continue;
455 }
456 //
682c9d06 457 if (!myShapesToAvoid.Contains(aF)) {
458 aSSp.AddStartElement(aF);
459 }
460 }
4e57c75e 461 //
682c9d06 462 aSSp.SetRunParallel(myRunParallel);
463 aSSp.Perform();
464 iErr=aSSp.ErrorStatus();
465 if (iErr) {
466 return;
4e57c75e 467 }
468 //
682c9d06 469 const BOPCol_ListOfShape& aLSh=aSSp.Shells();
470 aIt.Initialize (aLSh);
471 for (; aIt.More(); aIt.Next()) {
472 const TopoDS_Shape& aSh=aIt.Value();
473 myLoops.Append(aSh);
474 }
475 //=================================================
4e57c75e 476 //
682c9d06 477 // 2. Post Treatment
682c9d06 478 BRep_Builder aBB;
479 BOPCol_MapOfOrientedShape AddedFacesMap;
480 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
4e57c75e 481 BOPCol_MapOfOrientedShape aMP;
682c9d06 482 //
4e57c75e 483 // a. collect all edges that are in loops
484 aIt.Initialize (myLoops);
485 for (; aIt.More(); aIt.Next()) {
486 const TopoDS_Shape& aS=aIt.Value();
487 aItS.Initialize(aS);
488 for (; aItS.More(); aItS.Next()) {
489 const TopoDS_Shape& aF=aItS.Value();
490 aMP.Add(aF);
491 }
492 }
493 //
494 // b. collect all edges that are to avoid
319da2e4 495 aNbSh = myShapesToAvoid.Extent();
496 for (i = 1; i <= aNbSh; ++i) {
497 const TopoDS_Shape& aF = myShapesToAvoid(i);
4e57c75e 498 aMP.Add(aF);
499 }
500 //
501 // c. add all edges that are not processed to myShapesToAvoid
502 aIt.Initialize (myShapes);
503 for (; aIt.More(); aIt.Next()) {
f47b8d2b 504 const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value());
505 if (!myContext->IsInfiniteFace(aF)) {
506 if (!aMP.Contains(aF)) {
507 myShapesToAvoid.Add(aF);
508 }
4e57c75e 509 }
510 }
511 //=================================================
512 //
682c9d06 513 // 3.Internal Shells
4e57c75e 514 myLoopsInternal.Clear();
515 //
516 aEFMap.Clear();
517 AddedFacesMap.Clear();
518 //
319da2e4 519 aNbSh = myShapesToAvoid.Extent();
520 for (i = 1; i <= aNbSh; ++i) {
521 const TopoDS_Shape& aFF = myShapesToAvoid(i);
682c9d06 522 BOPTools::MapShapesAndAncestors(aFF,
1e143abb 523 TopAbs_EDGE, TopAbs_FACE,
524 aEFMap);
4e57c75e 525 }
526 //
319da2e4 527 for (i = 1; i <= aNbSh; ++i) {
528 const TopoDS_Shape& aFF = myShapesToAvoid(i);
4e57c75e 529 if (!AddedFacesMap.Add(aFF)) {
530 continue;
531 }
532 //
533 // make a new shell
0090ae85 534 TopExp_Explorer aExp;
4e57c75e 535 TopoDS_Shell aShell;
536 aBB.MakeShell(aShell);
537 aBB.Add(aShell, aFF);
538 //
0090ae85 539 aItS.Initialize(aShell);
540 for (; aItS.More(); aItS.Next()) {
541 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItS.Value()));
4e57c75e 542 //
0090ae85 543 aExp.Init(aF, TopAbs_EDGE);
544 for (; aExp.More(); aExp.Next()) {
545 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current()));
4e57c75e 546 const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
682c9d06 547 aIt.Initialize(aLF);
548 for (; aIt.More(); aIt.Next()) {
549 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aIt.Value()));
4e57c75e 550 if (AddedFacesMap.Add(aFL)){
551 aBB.Add(aShell, aFL);
552 }
553 }
554 }
555 }
ab860031 556 aShell.Closed (BRep_Tool::IsClosed (aShell));
4e57c75e 557 myLoopsInternal.Append(aShell);
558 }
559}
560//=======================================================================
561//function : PerformAreas
562//purpose :
563//=======================================================================
30ecd5f8 564void BOPAlgo_BuilderSolid::PerformAreas()
4e57c75e 565{
682c9d06 566 Standard_Boolean bIsGrowth, bIsHole;
319da2e4 567 Standard_Integer i, k, aNbInOut, aNbMSH;
4e57c75e 568 BRep_Builder aBB;
682c9d06 569 BOPCol_ListIteratorOfListOfShape aItLS;
4e57c75e 570 BOPCol_ListOfShape aNewSolids, aHoleShells;
319da2e4 571 BOPCol_IndexedDataMapOfShapeShape aInOutMap;
4e57c75e 572 BOPCol_IndexedMapOfShape aMHF;
682c9d06 573 BOPCol_ListIteratorOfListOfInteger aItLI;
574 BOPCol_BoxBndTreeSelector aSelector;
575 BOPCol_BoxBndTree aBBTree;
465d1fba 576 NCollection_UBTreeFiller
577 <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
682c9d06 578 BOPAlgo_DataMapOfIntegerBSSB aDMISB(100);
319da2e4 579 BOPCol_IndexedDataMapOfShapeListOfShape aMSH;
682c9d06 580 BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB aItDMISB;
682c9d06 581 //
582 myErrorStatus=0;
4e57c75e 583 //
584 myAreas.Clear();
585 //
586 // Draft solids [aNewSolids]
682c9d06 587 aItLS.Initialize(myLoops);
588 for (k=0; aItLS.More(); aItLS.Next(), ++k) {
589 TopoDS_Solid aSolid;
590 Bnd_Box aBox;
591 BOPAlgo_BuilderSolid_ShapeBox aSB;
592 //
593 const TopoDS_Shape& aShell = aItLS.Value();
594 aSB.SetShape(aShell);
595 //
596 BRepBndLib::Add(aShell, aBox);
597 bIsHole=Standard_False;
4e57c75e 598 //
682c9d06 599 bIsGrowth=IsGrowthShell(aShell, aMHF);
600 if (bIsGrowth) {
4e57c75e 601 // make a growth solid from a shell
682c9d06 602 aBB.MakeSolid(aSolid);
603 aBB.Add (aSolid, aShell);
4e57c75e 604 //
682c9d06 605 aNewSolids.Append (aSolid);
606 aSB.SetShape(aSolid);
4e57c75e 607 }
608 else{
609 // check if a shell is a hole
4e57c75e 610 bIsHole=IsHole(aShell, myContext);
4e57c75e 611 if (bIsHole) {
612 aHoleShells.Append(aShell);
613 BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF);
1e143abb 614 aSB.SetShape(aShell);
4e57c75e 615 }
616 else {
617 // make a growth solid from a shell
682c9d06 618 aBB.MakeSolid(aSolid);
619 aBB.Add (aSolid, aShell);
4e57c75e 620 //
682c9d06 621 aNewSolids.Append (aSolid);
1e143abb 622 aSB.SetShape(aSolid);
4e57c75e 623 }
624 }
682c9d06 625 //
626 aSB.SetBox(aBox);
627 aSB.SetIsHole(bIsHole);
628 aDMISB.Bind(k, aSB);
629 }
630 //
631 // 2. Prepare TreeFiller
632 aItDMISB.Initialize(aDMISB);
633 for (; aItDMISB.More(); aItDMISB.Next()) {
634 k=aItDMISB.Key();
635 const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
636 //
637 bIsHole=aSB.IsHole();
638 if (bIsHole) {
639 const Bnd_Box& aBox=aSB.Box();
640 aTreeFiller.Add(k, aBox);
641 }
4e57c75e 642 }
643 //
682c9d06 644 // 3. Shake TreeFiller
645 aTreeFiller.Fill();
646 //
647 // 4. Find outer growth shell that is most close
648 // to each hole shell
649 aItDMISB.Initialize(aDMISB);
650 for (; aItDMISB.More(); aItDMISB.Next()) {
651 k=aItDMISB.Key();
652 const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
653 bIsHole=aSB.IsHole();
654 if (bIsHole) {
655 continue;
656 }
657 //
658 const TopoDS_Shape aSolid=aSB.Shape();
659 const Bnd_Box& aBoxSolid=aSB.Box();
4e57c75e 660 //
682c9d06 661 aSelector.Clear();
662 aSelector.SetBox(aBoxSolid);
663 //
bcf50875 664 aBBTree.Select(aSelector);
682c9d06 665 //
666 const BOPCol_ListOfInteger& aLI=aSelector.Indices();
667 //
668 aItLI.Initialize(aLI);
669 for (; aItLI.More(); aItLI.Next()) {
670 k=aItLI.Value();
671 const BOPAlgo_BuilderSolid_ShapeBox& aSBk=aDMISB.Find(k);
672 const TopoDS_Shape& aHole=aSBk.Shape();
4e57c75e 673 //
674 if (!IsInside(aHole, aSolid, myContext)){
675 continue;
676 }
677 //
319da2e4 678 if (aInOutMap.Contains (aHole)){
679 const TopoDS_Shape& aSolidWas = aInOutMap.FindFromKey(aHole);
e83c01bf 680 if (IsInside(aSolid, aSolidWas, myContext)) {
319da2e4 681 aInOutMap.ChangeFromKey(aHole) = aSolid;
4e57c75e 682 }
683 }
684 else{
319da2e4 685 aInOutMap.Add(aHole, aSolid);
4e57c75e 686 }
687 }
319da2e4 688 }//for (i = 1; i <= aNbDMISB; ++i) {
682c9d06 689 //
690 // 5. Map [Solid/Holes] -> aMSH
319da2e4 691 aNbInOut = aInOutMap.Extent();
692 for (i = 1; i <= aNbInOut; ++i) {
693 const TopoDS_Shape& aHole = aInOutMap.FindKey(i);
694 const TopoDS_Shape& aSolid = aInOutMap(i);
4e57c75e 695 //
319da2e4 696 if (aMSH.Contains(aSolid)) {
697 BOPCol_ListOfShape& aLH = aMSH.ChangeFromKey(aSolid);
682c9d06 698 aLH.Append(aHole);
699 }
700 else {
701 BOPCol_ListOfShape aLH;
702 aLH.Append(aHole);
319da2e4 703 aMSH.Add(aSolid, aLH);
4e57c75e 704 }
682c9d06 705 }
4e57c75e 706 //
682c9d06 707 // 6. Add aHoles to Solids
319da2e4 708 aNbMSH = aMSH.Extent();
709 for (i = 1; i <= aNbMSH; ++i) {
710 TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&(aMSH.FindKey(i))));
711 const BOPCol_ListOfShape& aLH = aMSH(i);
4e57c75e 712 //
682c9d06 713 aItLS.Initialize(aLH);
714 for (; aItLS.More(); aItLS.Next()) {
715 const TopoDS_Shape& aHole = aItLS.Value();
4e57c75e 716 aBB.Add (aSolid, aHole);
717 }
718 //
719 // update classifier
682c9d06 720 BRepClass3d_SolidClassifier& aSC=
721 myContext->SolidClassifier(aSolid);
4e57c75e 722 aSC.Load(aSolid);
723 //
724 }
725 //
682c9d06 726 // 7. These aNewSolids are draft solids that
4e57c75e 727 // do not contain any internal shapes
682c9d06 728 aItLS.Initialize(aNewSolids);
729 for ( ; aItLS.More(); aItLS.Next()) {
730 const TopoDS_Shape& aSx=aItLS.Value();
4e57c75e 731 myAreas.Append(aSx);
732 }
4e57c75e 733 // Add holes that outside the solids to myAreas
682c9d06 734 aItLS.Initialize(aHoleShells);
735 for (; aItLS.More(); aItLS.Next()) {
736 const TopoDS_Shape& aHole = aItLS.Value();
319da2e4 737 if (!aInOutMap.Contains(aHole)){
4e57c75e 738 TopoDS_Solid aSolid;
682c9d06 739 //
4e57c75e 740 aBB.MakeSolid(aSolid);
741 aBB.Add (aSolid, aHole);
742 //
743 myAreas.Append(aSolid);
744 }
745 }
746}
747//=======================================================================
748//function : PerformInternalShapes
749//purpose :
750//=======================================================================
30ecd5f8 751void BOPAlgo_BuilderSolid::PerformInternalShapes()
4e57c75e 752{
753 myErrorStatus=0;
754 //
755 Standard_Integer aNbFI=myLoopsInternal.Extent();
756 if (!aNbFI) {// nothing to do
757 return;
758 }
759 //
465d1fba 760 Standard_Boolean bIsInternalFace;
bcf50875 761 Standard_Integer k, aNbVFS, aNbSLF, aNbVFP, aNbA;
4e57c75e 762 BRep_Builder aBB;
763 TopoDS_Iterator aIt;
465d1fba 764 TopExp_Explorer aExp;
765 BOPCol_ListIteratorOfListOfShape aItLS;
319da2e4 766 BOPCol_IndexedMapOfShape aMFs;
4e57c75e 767 BOPCol_ListOfShape aLSI;
465d1fba 768 BOPAlgo_VectorOfFaceSolid aVFS;
769 BOPAlgo_VectorOfFacePnt aVFP;
770 BOPCol_ListIteratorOfListOfInteger aItLI;
771 BOPCol_BoxBndTreeSelector aSelector;
772 BOPCol_BoxBndTree aBBTree;
773 NCollection_UBTreeFiller
774 <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
775 //
776 aNbA=myAreas.Extent();
4e57c75e 777 //
465d1fba 778 // 1. aVFP
779 aItLS.Initialize(myLoopsInternal);
780 for (; aItLS.More(); aItLS.Next()) {
781 const TopoDS_Shape& aShell=aItLS.Value();
4e57c75e 782 aIt.Initialize(aShell);
783 for (; aIt.More(); aIt.Next()) {
465d1fba 784 const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value());
785 //
319da2e4 786 if (!aMFs.Contains(aF)) {
787 aMFs.Add(aF);
788 //
465d1fba 789 gp_Pnt aP;
790 gp_Pnt2d aP2D;
791 //
792 if (aNbA) {
793 BOPTools_AlgoTools3D::PointInFace(aF, aP, aP2D, myContext);
794 }
795 //
796 BOPAlgo_FacePnt& aFP=aVFP.Append1();
797 aFP.SetFace(aF);
798 aFP.SetPnt(aP);
799 }
4e57c75e 800 }
801 }
4e57c75e 802 //
465d1fba 803 if (!aNbA) {
804 // 7b. "Rest" faces treatment
805 TopoDS_Solid aSolid;
806 aBB.MakeSolid(aSolid);
4e57c75e 807 //
465d1fba 808 MakeInternalShells(aMFs, aLSI);
809 //
810 aItLS.Initialize(aLSI);
811 for (; aItLS.More(); aItLS.Next()) {
812 const TopoDS_Shape& aSI=aItLS.Value();
813 aBB.Add (aSolid, aSI);
4e57c75e 814 }
465d1fba 815 myAreas.Append(aSolid);
4e57c75e 816 //
465d1fba 817 return; // =>
818 }//if (!aNbA) {
819 //
820 // 2. Prepare TreeFiller
821 aNbVFP=aVFP.Extent();
822 for(k=0; k<aNbVFP; ++k) {
823 Bnd_Box aBox;
824 //
825 const BOPAlgo_FacePnt& aFP=aVFP(k);
826 const TopoDS_Face& aF=aFP.Face();
827 //
828 BRepBndLib::Add(aF, aBox);
829 aTreeFiller.Add(k, aBox);
830 }
831 //
832 aTreeFiller.Fill();
833 //
834 // 3. Face/Solid candidates: aVFS
835 aItLS.Initialize(myAreas);
836 for (; aItLS.More(); aItLS.Next()) {
837 Bnd_Box aBox;
838 //
839 TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aItLS.Value()));
840 BRepBndLib::Add(aSolid, aBox);
841 //
842 aMFs.Clear();
843 aExp.Init(aSolid, TopAbs_FACE);
844 for (; aExp.More(); aExp.Next()) {
845 const TopoDS_Shape& aFs=aExp.Current();
846 aMFs.Add(aFs);
847 }
848 //
849 aSelector.Clear();
850 aSelector.SetBox(aBox);
851 //
bcf50875 852 aBBTree.Select(aSelector);
465d1fba 853 //
854 const BOPCol_ListOfInteger& aLI=aSelector.Indices();
855 aItLI.Initialize(aLI);
856 for (; aItLI.More(); aItLI.Next()) {
857 k=aItLI.Value();
858 const BOPAlgo_FacePnt& aFP=aVFP(k);
859 const TopoDS_Face& aF=aFP.Face();
860 if (aMFs.Contains(aF)) {
861 continue;
4e57c75e 862 }
465d1fba 863 //
864 const gp_Pnt& aP=aFP.Pnt();
865 //
866 BOPAlgo_FaceSolid& aFS=aVFS.Append1();
867 aFS.SetPnt(aP);
868 aFS.SetFace(aF);
869 aFS.SetSolid(aSolid);
4e57c75e 870 }
465d1fba 871 }
872 //
873 aNbVFS=aVFS.Extent();
874 if (!aNbVFS) {
875 return;
876 }
877 // 4. Refine candidares
878 //=============================================================
879 BOPAlgo_FaceSolidCnt::Perform(myRunParallel, aVFS, myContext);
880 //=============================================================
881 //
882 // 5. Solid/Faces: aMSLF
883 BOPCol_IndexedDataMapOfShapeListOfShape aMSLF;
884 BOPCol_MapOfShape aMFProcessed;
885 //
886 for (k=0; k < aNbVFS; ++k) {
887 const BOPAlgo_FaceSolid& aFS=aVFS(k);
4e57c75e 888 //
465d1fba 889 const TopoDS_Solid& aSolid=aFS.Solid();
890 const TopoDS_Face& aF=aFS.Face();
4e57c75e 891 //
465d1fba 892 bIsInternalFace=aFS.IsInternalFace();
893 if (!bIsInternalFace) {
894 continue;
4e57c75e 895 }
896 //
465d1fba 897 if (aMSLF.Contains(aSolid)) {
898 BOPCol_ListOfShape& aLF=aMSLF.ChangeFromKey(aSolid);
899 aLF.Append(aF);
900 }
901 else {
902 BOPCol_ListOfShape aLF;
903 //
904 aLF.Append(aF);
905 aMSLF.Add(aSolid, aLF);
4e57c75e 906 }
465d1fba 907 }// for (k=0; k < aNbVE; ++k) {
908 //
909 // 6. Update Solids by internal Faces
910 aNbSLF=aMSLF.Extent();
911 for (k=1; k <= aNbSLF; ++k) {
912 const TopoDS_Shape& aSolid=aMSLF.FindKey(k);
913 TopoDS_Shape *pSolid=(TopoDS_Shape*)&aSolid;
4e57c75e 914 //
465d1fba 915 const BOPCol_ListOfShape& aLF=aMSLF(k);
916 //
917 aMFs.Clear();
918 aItLS.Initialize(aLF);
919 for (; aItLS.More(); aItLS.Next()) {
920 const TopoDS_Shape& aF=aItLS.Value();
921 aMFs.Add(aF);
922 aMFProcessed.Add(aF);
4e57c75e 923 }
465d1fba 924 //
925 aLSI.Clear();
926 MakeInternalShells(aMFs, aLSI);
927 //
928 aItLS.Initialize(aLSI);
929 for (; aItLS.More(); aItLS.Next()) {
930 const TopoDS_Shape& aSI=aItLS.Value();
931 aBB.Add (*pSolid, aSI);
932 }
933 }
934 //
935 // 7. "Rest" faces treatment (if there are)
936 aMFs.Clear();
937 for (k=0; k < aNbVFS; ++k) {
938 const BOPAlgo_FaceSolid& aFS=aVFS(k);
939 //
940 const TopoDS_Face& aF=aFS.Face();
941 if (!aMFProcessed.Contains(aF)) {
942 aMFs.Add(aF);
943 }
944 }
945 //
946 aNbFI=aMFs.Extent();
4e57c75e 947 if (aNbFI) {
948 TopoDS_Solid aSolid;
949 aBB.MakeSolid(aSolid);
950 //
465d1fba 951 aLSI.Clear();
952 MakeInternalShells(aMFs, aLSI);
953 //
954 aItLS.Initialize(aLSI);
955 for (; aItLS.More(); aItLS.Next()) {
956 const TopoDS_Shape& aSI=aItLS.Value();
4e57c75e 957 aBB.Add (aSolid, aSI);
958 }
959 myAreas.Append(aSolid);
960 }
961}
4e57c75e 962//=======================================================================
963//function : MakeInternalShells
964//purpose :
965//=======================================================================
319da2e4 966void MakeInternalShells(const BOPCol_IndexedMapOfShape& theMF,
4e57c75e 967 BOPCol_ListOfShape& theShells)
968{
319da2e4 969 Standard_Integer i, aNbF;
4e57c75e 970 BRep_Builder aBB;
319da2e4 971 BOPCol_ListIteratorOfListOfShape aItF;
4e57c75e 972 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
4e57c75e 973 BOPCol_MapOfShape aAddedFacesMap;
974 //
319da2e4 975 aNbF = theMF.Extent();
976 for (i = 1; i <= aNbF; ++i) {
977 TopoDS_Shape aF = theMF(i);
682c9d06 978 BOPTools::MapShapesAndAncestors(aF,
1e143abb 979 TopAbs_EDGE, TopAbs_FACE,
980 aMEF);
4e57c75e 981 }
982 //
319da2e4 983 for (i = 1; i <= aNbF; ++i) {
984 TopoDS_Shape aFF = theMF(i);
4e57c75e 985 if (!aAddedFacesMap.Add(aFF)) {
986 continue;
987 }
988 //
989 // make a new shell
990 TopoDS_Shell aShell;
991 aBB.MakeShell(aShell);
992 aFF.Orientation(TopAbs_INTERNAL);
993 aBB.Add(aShell, aFF);
994 //
995 TopoDS_Iterator aItAddedF (aShell);
996 for (; aItAddedF.More(); aItAddedF.Next()) {
997 const TopoDS_Shape& aF =aItAddedF.Value();
998 //
999 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
1000 for (; aEdgeExp.More(); aEdgeExp.Next()) {
1001 const TopoDS_Shape& aE =aEdgeExp.Current();
1002 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
1003 aItF.Initialize(aLF);
1004 for (; aItF.More(); aItF.Next()) {
1005 TopoDS_Shape aFL=aItF.Value();
1006 if (aAddedFacesMap.Add(aFL)){
1007 aFL.Orientation(TopAbs_INTERNAL);
1008 aBB.Add(aShell, aFL);
1009 }
1010 }
1011 }
1012 }
ab860031 1013 aShell.Closed (BRep_Tool::IsClosed (aShell));
4e57c75e 1014 theShells.Append(aShell);
1015 }
1016}
1017//=======================================================================
1018//function : IsHole
1019//purpose :
1020//=======================================================================
1021Standard_Boolean IsHole(const TopoDS_Shape& theS2,
1e143abb 1022 Handle(IntTools_Context)& theContext)
4e57c75e 1023{
1024 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
1025 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
1026 //
1027 aClsf.PerformInfinitePoint(::RealSmall());
1028 //
1029 return (aClsf.State()==TopAbs_IN);
1030}
1031//=======================================================================
1032//function : IsInside
1033//purpose :
1034//=======================================================================
1035Standard_Boolean IsInside(const TopoDS_Shape& theS1,
1036 const TopoDS_Shape& theS2,
1e143abb 1037 Handle(IntTools_Context)& theContext)
4e57c75e 1038{
1039 TopExp_Explorer aExp;
1040 TopAbs_State aState;
1041 //
1042 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
1043 //
1044 aExp.Init(theS1, TopAbs_FACE);
1045 if (!aExp.More()){
1046 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
1047 aClsf.PerformInfinitePoint(::RealSmall());
1048 aState=aClsf.State();
1049 }
1050 else {
1051 BOPCol_IndexedMapOfShape aBounds;
1052 BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds);
1053 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current()));
92ae0f2f 1054 aState=BOPTools_AlgoTools::ComputeState(aF, *pS2,
1055 Precision::Confusion(),
1e143abb 1056 aBounds, theContext);
4e57c75e 1057 }
1058 return (aState==TopAbs_IN);
1059}
1060//=======================================================================
1061//function : IsGrowthShell
1062//purpose :
1063//=======================================================================
1064Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
1065 const BOPCol_IndexedMapOfShape& theMHF)
1066{
1067 Standard_Boolean bRet;
1068 TopoDS_Iterator aIt;
1069 //
1070 bRet=Standard_False;
1071 if (theMHF.Extent()) {
1072 aIt.Initialize(theShell);
1073 for(; aIt.More(); aIt.Next()) {
1074 const TopoDS_Shape& aF=aIt.Value();
1075 if (theMHF.Contains(aF)) {
1076 return !bRet;
1077 }
1078 }
1079 }
1080 return bRet;
1081}