0028786: Refactoring of the Warning/Error reporting system of Boolean Operations...
[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>
33ba8565 20#include <BOPAlgo_Alerts.hxx>
42cf5bc1 21#include <BOPCol_BoxBndTree.hxx>
22#include <BOPCol_DataMapOfShapeListOfShape.hxx>
23#include <BOPCol_DataMapOfShapeShape.hxx>
24#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
319da2e4 25#include <BOPCol_IndexedDataMapOfShapeShape.hxx>
42cf5bc1 26#include <BOPCol_ListOfInteger.hxx>
27#include <BOPCol_ListOfShape.hxx>
28#include <BOPCol_MapOfOrientedShape.hxx>
29#include <BOPCol_MapOfShape.hxx>
30#include <BOPCol_NCVector.hxx>
31#include <BOPCol_Parallel.hxx>
32#include <BOPTools.hxx>
33#include <BOPTools_AlgoTools.hxx>
34#include <BOPTools_AlgoTools3D.hxx>
35#include <BOPTools_CoupleOfShape.hxx>
36#include <BRep_Builder.hxx>
37#include <BRep_Tool.hxx>
38#include <BRepBndLib.hxx>
39#include <BRepClass3d_SolidClassifier.hxx>
40#include <Geom2d_Curve.hxx>
41#include <Geom_Curve.hxx>
42#include <Geom_Surface.hxx>
4e57c75e 43#include <gp_Dir.hxx>
42cf5bc1 44#include <gp_Pln.hxx>
4e57c75e 45#include <gp_Pnt.hxx>
42cf5bc1 46#include <gp_Pnt2d.hxx>
47#include <gp_Vec.hxx>
48#include <IntTools_Context.hxx>
49#include <NCollection_DataMap.hxx>
42cf5bc1 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
682c9d06 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{
33ba8565 301 GetReport()->Clear();
4e57c75e 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();
33ba8565 321 if (HasErrors()) {
4e57c75e 322 return;
323 }
324 //
36f4947b 325 UserBreak();
326 //
4e57c75e 327 PerformLoops();
33ba8565 328 if (HasErrors()) {
4e57c75e 329 return;
330 }
36f4947b 331 //
332 UserBreak();
333 //
4e57c75e 334 PerformAreas();
33ba8565 335 if (HasErrors()) {
4e57c75e 336 return;
337 }
36f4947b 338 //
339 UserBreak();
340 //
4e57c75e 341 PerformInternalShapes();
33ba8565 342 if (HasErrors()) {
4e57c75e 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{
33ba8565 432 Standard_Integer i, aNbSh;
682c9d06 433 BOPCol_ListIteratorOfListOfShape aIt;
4e57c75e 434 TopoDS_Iterator aItS;
0090ae85 435 Handle(NCollection_BaseAllocator) aAlr;
682c9d06 436 //
682c9d06 437 myLoops.Clear();
4e57c75e 438 //
488e5b9d 439 aAlr=
440 NCollection_BaseAllocator::CommonBaseAllocator();
0090ae85 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();
33ba8565 464 if (aSSp.HasErrors()) {
465 // add warning status
466 {
467 TopoDS_Compound aFacesSp;
468 BRep_Builder().MakeCompound(aFacesSp);
469 BOPCol_ListIteratorOfListOfShape aItLF(aSSp.StartElements());
470 for (; aItLF.More(); aItLF.Next()) {
471 BRep_Builder().Add(aFacesSp, aItLF.Value());
472 }
473 AddWarning (new BOPAlgo_AlertShellSplitterFailed (aFacesSp));
474 }
682c9d06 475 return;
4e57c75e 476 }
477 //
682c9d06 478 const BOPCol_ListOfShape& aLSh=aSSp.Shells();
479 aIt.Initialize (aLSh);
480 for (; aIt.More(); aIt.Next()) {
481 const TopoDS_Shape& aSh=aIt.Value();
482 myLoops.Append(aSh);
483 }
484 //=================================================
4e57c75e 485 //
682c9d06 486 // 2. Post Treatment
682c9d06 487 BRep_Builder aBB;
488 BOPCol_MapOfOrientedShape AddedFacesMap;
489 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap;
4e57c75e 490 BOPCol_MapOfOrientedShape aMP;
682c9d06 491 //
4e57c75e 492 // a. collect all edges that are in loops
493 aIt.Initialize (myLoops);
494 for (; aIt.More(); aIt.Next()) {
495 const TopoDS_Shape& aS=aIt.Value();
496 aItS.Initialize(aS);
497 for (; aItS.More(); aItS.Next()) {
498 const TopoDS_Shape& aF=aItS.Value();
499 aMP.Add(aF);
500 }
501 }
502 //
503 // b. collect all edges that are to avoid
319da2e4 504 aNbSh = myShapesToAvoid.Extent();
505 for (i = 1; i <= aNbSh; ++i) {
506 const TopoDS_Shape& aF = myShapesToAvoid(i);
4e57c75e 507 aMP.Add(aF);
508 }
509 //
510 // c. add all edges that are not processed to myShapesToAvoid
511 aIt.Initialize (myShapes);
512 for (; aIt.More(); aIt.Next()) {
f47b8d2b 513 const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value());
514 if (!myContext->IsInfiniteFace(aF)) {
515 if (!aMP.Contains(aF)) {
516 myShapesToAvoid.Add(aF);
517 }
4e57c75e 518 }
519 }
520 //=================================================
521 //
682c9d06 522 // 3.Internal Shells
4e57c75e 523 myLoopsInternal.Clear();
524 //
525 aEFMap.Clear();
526 AddedFacesMap.Clear();
527 //
319da2e4 528 aNbSh = myShapesToAvoid.Extent();
529 for (i = 1; i <= aNbSh; ++i) {
530 const TopoDS_Shape& aFF = myShapesToAvoid(i);
682c9d06 531 BOPTools::MapShapesAndAncestors(aFF,
1e143abb 532 TopAbs_EDGE, TopAbs_FACE,
533 aEFMap);
4e57c75e 534 }
535 //
319da2e4 536 for (i = 1; i <= aNbSh; ++i) {
537 const TopoDS_Shape& aFF = myShapesToAvoid(i);
4e57c75e 538 if (!AddedFacesMap.Add(aFF)) {
539 continue;
540 }
541 //
542 // make a new shell
0090ae85 543 TopExp_Explorer aExp;
4e57c75e 544 TopoDS_Shell aShell;
545 aBB.MakeShell(aShell);
546 aBB.Add(aShell, aFF);
547 //
0090ae85 548 aItS.Initialize(aShell);
549 for (; aItS.More(); aItS.Next()) {
550 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItS.Value()));
4e57c75e 551 //
0090ae85 552 aExp.Init(aF, TopAbs_EDGE);
553 for (; aExp.More(); aExp.Next()) {
554 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current()));
4e57c75e 555 const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
682c9d06 556 aIt.Initialize(aLF);
557 for (; aIt.More(); aIt.Next()) {
558 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aIt.Value()));
4e57c75e 559 if (AddedFacesMap.Add(aFL)){
560 aBB.Add(aShell, aFL);
561 }
562 }
563 }
564 }
ab860031 565 aShell.Closed (BRep_Tool::IsClosed (aShell));
4e57c75e 566 myLoopsInternal.Append(aShell);
567 }
568}
569//=======================================================================
570//function : PerformAreas
571//purpose :
572//=======================================================================
30ecd5f8 573void BOPAlgo_BuilderSolid::PerformAreas()
4e57c75e 574{
682c9d06 575 Standard_Boolean bIsGrowth, bIsHole;
319da2e4 576 Standard_Integer i, k, aNbInOut, aNbMSH;
4e57c75e 577 BRep_Builder aBB;
682c9d06 578 BOPCol_ListIteratorOfListOfShape aItLS;
4e57c75e 579 BOPCol_ListOfShape aNewSolids, aHoleShells;
319da2e4 580 BOPCol_IndexedDataMapOfShapeShape aInOutMap;
4e57c75e 581 BOPCol_IndexedMapOfShape aMHF;
682c9d06 582 BOPCol_ListIteratorOfListOfInteger aItLI;
583 BOPCol_BoxBndTreeSelector aSelector;
584 BOPCol_BoxBndTree aBBTree;
465d1fba 585 NCollection_UBTreeFiller
586 <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
682c9d06 587 BOPAlgo_DataMapOfIntegerBSSB aDMISB(100);
319da2e4 588 BOPCol_IndexedDataMapOfShapeListOfShape aMSH;
682c9d06 589 BOPAlgo_DataMapIteratorOfDataMapOfIntegerBSSB aItDMISB;
682c9d06 590 //
4e57c75e 591 myAreas.Clear();
592 //
593 // Draft solids [aNewSolids]
682c9d06 594 aItLS.Initialize(myLoops);
595 for (k=0; aItLS.More(); aItLS.Next(), ++k) {
596 TopoDS_Solid aSolid;
597 Bnd_Box aBox;
598 BOPAlgo_BuilderSolid_ShapeBox aSB;
599 //
600 const TopoDS_Shape& aShell = aItLS.Value();
601 aSB.SetShape(aShell);
602 //
603 BRepBndLib::Add(aShell, aBox);
604 bIsHole=Standard_False;
4e57c75e 605 //
682c9d06 606 bIsGrowth=IsGrowthShell(aShell, aMHF);
607 if (bIsGrowth) {
4e57c75e 608 // make a growth solid from a shell
682c9d06 609 aBB.MakeSolid(aSolid);
610 aBB.Add (aSolid, aShell);
4e57c75e 611 //
682c9d06 612 aNewSolids.Append (aSolid);
613 aSB.SetShape(aSolid);
4e57c75e 614 }
615 else{
616 // check if a shell is a hole
4e57c75e 617 bIsHole=IsHole(aShell, myContext);
4e57c75e 618 if (bIsHole) {
619 aHoleShells.Append(aShell);
620 BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF);
1e143abb 621 aSB.SetShape(aShell);
4e57c75e 622 }
623 else {
624 // make a growth solid from a shell
682c9d06 625 aBB.MakeSolid(aSolid);
626 aBB.Add (aSolid, aShell);
4e57c75e 627 //
682c9d06 628 aNewSolids.Append (aSolid);
1e143abb 629 aSB.SetShape(aSolid);
4e57c75e 630 }
631 }
682c9d06 632 //
633 aSB.SetBox(aBox);
634 aSB.SetIsHole(bIsHole);
635 aDMISB.Bind(k, aSB);
636 }
637 //
638 // 2. Prepare TreeFiller
639 aItDMISB.Initialize(aDMISB);
640 for (; aItDMISB.More(); aItDMISB.Next()) {
641 k=aItDMISB.Key();
642 const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
643 //
644 bIsHole=aSB.IsHole();
645 if (bIsHole) {
646 const Bnd_Box& aBox=aSB.Box();
647 aTreeFiller.Add(k, aBox);
648 }
4e57c75e 649 }
650 //
682c9d06 651 // 3. Shake TreeFiller
652 aTreeFiller.Fill();
653 //
654 // 4. Find outer growth shell that is most close
655 // to each hole shell
656 aItDMISB.Initialize(aDMISB);
657 for (; aItDMISB.More(); aItDMISB.Next()) {
658 k=aItDMISB.Key();
659 const BOPAlgo_BuilderSolid_ShapeBox& aSB=aItDMISB.Value();
660 bIsHole=aSB.IsHole();
661 if (bIsHole) {
662 continue;
663 }
664 //
665 const TopoDS_Shape aSolid=aSB.Shape();
666 const Bnd_Box& aBoxSolid=aSB.Box();
4e57c75e 667 //
682c9d06 668 aSelector.Clear();
669 aSelector.SetBox(aBoxSolid);
670 //
bcf50875 671 aBBTree.Select(aSelector);
682c9d06 672 //
673 const BOPCol_ListOfInteger& aLI=aSelector.Indices();
674 //
675 aItLI.Initialize(aLI);
676 for (; aItLI.More(); aItLI.Next()) {
677 k=aItLI.Value();
678 const BOPAlgo_BuilderSolid_ShapeBox& aSBk=aDMISB.Find(k);
679 const TopoDS_Shape& aHole=aSBk.Shape();
4e57c75e 680 //
681 if (!IsInside(aHole, aSolid, myContext)){
682 continue;
683 }
684 //
319da2e4 685 if (aInOutMap.Contains (aHole)){
686 const TopoDS_Shape& aSolidWas = aInOutMap.FindFromKey(aHole);
e83c01bf 687 if (IsInside(aSolid, aSolidWas, myContext)) {
319da2e4 688 aInOutMap.ChangeFromKey(aHole) = aSolid;
4e57c75e 689 }
690 }
691 else{
319da2e4 692 aInOutMap.Add(aHole, aSolid);
4e57c75e 693 }
694 }
319da2e4 695 }//for (i = 1; i <= aNbDMISB; ++i) {
682c9d06 696 //
697 // 5. Map [Solid/Holes] -> aMSH
319da2e4 698 aNbInOut = aInOutMap.Extent();
699 for (i = 1; i <= aNbInOut; ++i) {
700 const TopoDS_Shape& aHole = aInOutMap.FindKey(i);
701 const TopoDS_Shape& aSolid = aInOutMap(i);
4e57c75e 702 //
319da2e4 703 if (aMSH.Contains(aSolid)) {
704 BOPCol_ListOfShape& aLH = aMSH.ChangeFromKey(aSolid);
682c9d06 705 aLH.Append(aHole);
706 }
707 else {
708 BOPCol_ListOfShape aLH;
709 aLH.Append(aHole);
319da2e4 710 aMSH.Add(aSolid, aLH);
4e57c75e 711 }
682c9d06 712 }
4e57c75e 713 //
682c9d06 714 // 6. Add aHoles to Solids
319da2e4 715 aNbMSH = aMSH.Extent();
716 for (i = 1; i <= aNbMSH; ++i) {
717 TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&(aMSH.FindKey(i))));
718 const BOPCol_ListOfShape& aLH = aMSH(i);
4e57c75e 719 //
682c9d06 720 aItLS.Initialize(aLH);
721 for (; aItLS.More(); aItLS.Next()) {
722 const TopoDS_Shape& aHole = aItLS.Value();
4e57c75e 723 aBB.Add (aSolid, aHole);
724 }
725 //
726 // update classifier
682c9d06 727 BRepClass3d_SolidClassifier& aSC=
728 myContext->SolidClassifier(aSolid);
4e57c75e 729 aSC.Load(aSolid);
730 //
731 }
732 //
682c9d06 733 // 7. These aNewSolids are draft solids that
4e57c75e 734 // do not contain any internal shapes
682c9d06 735 aItLS.Initialize(aNewSolids);
736 for ( ; aItLS.More(); aItLS.Next()) {
737 const TopoDS_Shape& aSx=aItLS.Value();
4e57c75e 738 myAreas.Append(aSx);
739 }
4e57c75e 740 // Add holes that outside the solids to myAreas
682c9d06 741 aItLS.Initialize(aHoleShells);
742 for (; aItLS.More(); aItLS.Next()) {
743 const TopoDS_Shape& aHole = aItLS.Value();
319da2e4 744 if (!aInOutMap.Contains(aHole)){
4e57c75e 745 TopoDS_Solid aSolid;
682c9d06 746 //
4e57c75e 747 aBB.MakeSolid(aSolid);
748 aBB.Add (aSolid, aHole);
749 //
750 myAreas.Append(aSolid);
751 }
752 }
753}
754//=======================================================================
755//function : PerformInternalShapes
756//purpose :
757//=======================================================================
30ecd5f8 758void BOPAlgo_BuilderSolid::PerformInternalShapes()
4e57c75e 759{
291fced1 760 if (myAvoidInternalShapes) {
761 return;
762 }
4e57c75e 763 //
764 Standard_Integer aNbFI=myLoopsInternal.Extent();
765 if (!aNbFI) {// nothing to do
766 return;
767 }
768 //
465d1fba 769 Standard_Boolean bIsInternalFace;
bcf50875 770 Standard_Integer k, aNbVFS, aNbSLF, aNbVFP, aNbA;
4e57c75e 771 BRep_Builder aBB;
772 TopoDS_Iterator aIt;
465d1fba 773 TopExp_Explorer aExp;
774 BOPCol_ListIteratorOfListOfShape aItLS;
319da2e4 775 BOPCol_IndexedMapOfShape aMFs;
4e57c75e 776 BOPCol_ListOfShape aLSI;
465d1fba 777 BOPAlgo_VectorOfFaceSolid aVFS;
778 BOPAlgo_VectorOfFacePnt aVFP;
779 BOPCol_ListIteratorOfListOfInteger aItLI;
780 BOPCol_BoxBndTreeSelector aSelector;
781 BOPCol_BoxBndTree aBBTree;
782 NCollection_UBTreeFiller
783 <Standard_Integer, Bnd_Box> aTreeFiller(aBBTree);
784 //
785 aNbA=myAreas.Extent();
4e57c75e 786 //
465d1fba 787 // 1. aVFP
788 aItLS.Initialize(myLoopsInternal);
789 for (; aItLS.More(); aItLS.Next()) {
790 const TopoDS_Shape& aShell=aItLS.Value();
4e57c75e 791 aIt.Initialize(aShell);
792 for (; aIt.More(); aIt.Next()) {
465d1fba 793 const TopoDS_Face& aF=*((TopoDS_Face*)&aIt.Value());
794 //
319da2e4 795 if (!aMFs.Contains(aF)) {
796 aMFs.Add(aF);
797 //
465d1fba 798 gp_Pnt aP;
799 gp_Pnt2d aP2D;
800 //
801 if (aNbA) {
802 BOPTools_AlgoTools3D::PointInFace(aF, aP, aP2D, myContext);
803 }
804 //
805 BOPAlgo_FacePnt& aFP=aVFP.Append1();
806 aFP.SetFace(aF);
807 aFP.SetPnt(aP);
808 }
4e57c75e 809 }
810 }
4e57c75e 811 //
465d1fba 812 if (!aNbA) {
813 // 7b. "Rest" faces treatment
814 TopoDS_Solid aSolid;
815 aBB.MakeSolid(aSolid);
4e57c75e 816 //
465d1fba 817 MakeInternalShells(aMFs, aLSI);
818 //
819 aItLS.Initialize(aLSI);
820 for (; aItLS.More(); aItLS.Next()) {
821 const TopoDS_Shape& aSI=aItLS.Value();
822 aBB.Add (aSolid, aSI);
4e57c75e 823 }
465d1fba 824 myAreas.Append(aSolid);
4e57c75e 825 //
465d1fba 826 return; // =>
827 }//if (!aNbA) {
828 //
829 // 2. Prepare TreeFiller
830 aNbVFP=aVFP.Extent();
831 for(k=0; k<aNbVFP; ++k) {
832 Bnd_Box aBox;
833 //
834 const BOPAlgo_FacePnt& aFP=aVFP(k);
835 const TopoDS_Face& aF=aFP.Face();
836 //
837 BRepBndLib::Add(aF, aBox);
838 aTreeFiller.Add(k, aBox);
839 }
840 //
841 aTreeFiller.Fill();
842 //
843 // 3. Face/Solid candidates: aVFS
844 aItLS.Initialize(myAreas);
845 for (; aItLS.More(); aItLS.Next()) {
846 Bnd_Box aBox;
847 //
848 TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aItLS.Value()));
849 BRepBndLib::Add(aSolid, aBox);
850 //
851 aMFs.Clear();
852 aExp.Init(aSolid, TopAbs_FACE);
853 for (; aExp.More(); aExp.Next()) {
854 const TopoDS_Shape& aFs=aExp.Current();
855 aMFs.Add(aFs);
856 }
857 //
858 aSelector.Clear();
859 aSelector.SetBox(aBox);
860 //
bcf50875 861 aBBTree.Select(aSelector);
465d1fba 862 //
863 const BOPCol_ListOfInteger& aLI=aSelector.Indices();
864 aItLI.Initialize(aLI);
865 for (; aItLI.More(); aItLI.Next()) {
866 k=aItLI.Value();
867 const BOPAlgo_FacePnt& aFP=aVFP(k);
868 const TopoDS_Face& aF=aFP.Face();
869 if (aMFs.Contains(aF)) {
870 continue;
4e57c75e 871 }
465d1fba 872 //
873 const gp_Pnt& aP=aFP.Pnt();
874 //
875 BOPAlgo_FaceSolid& aFS=aVFS.Append1();
876 aFS.SetPnt(aP);
877 aFS.SetFace(aF);
878 aFS.SetSolid(aSolid);
4e57c75e 879 }
465d1fba 880 }
881 //
882 aNbVFS=aVFS.Extent();
883 if (!aNbVFS) {
884 return;
885 }
33ba8565 886 // 4. Refine candidates
465d1fba 887 //=============================================================
888 BOPAlgo_FaceSolidCnt::Perform(myRunParallel, aVFS, myContext);
889 //=============================================================
890 //
891 // 5. Solid/Faces: aMSLF
892 BOPCol_IndexedDataMapOfShapeListOfShape aMSLF;
893 BOPCol_MapOfShape aMFProcessed;
894 //
895 for (k=0; k < aNbVFS; ++k) {
896 const BOPAlgo_FaceSolid& aFS=aVFS(k);
4e57c75e 897 //
465d1fba 898 const TopoDS_Solid& aSolid=aFS.Solid();
899 const TopoDS_Face& aF=aFS.Face();
4e57c75e 900 //
465d1fba 901 bIsInternalFace=aFS.IsInternalFace();
902 if (!bIsInternalFace) {
903 continue;
4e57c75e 904 }
905 //
465d1fba 906 if (aMSLF.Contains(aSolid)) {
907 BOPCol_ListOfShape& aLF=aMSLF.ChangeFromKey(aSolid);
908 aLF.Append(aF);
909 }
910 else {
911 BOPCol_ListOfShape aLF;
912 //
913 aLF.Append(aF);
914 aMSLF.Add(aSolid, aLF);
4e57c75e 915 }
465d1fba 916 }// for (k=0; k < aNbVE; ++k) {
917 //
918 // 6. Update Solids by internal Faces
919 aNbSLF=aMSLF.Extent();
920 for (k=1; k <= aNbSLF; ++k) {
921 const TopoDS_Shape& aSolid=aMSLF.FindKey(k);
922 TopoDS_Shape *pSolid=(TopoDS_Shape*)&aSolid;
4e57c75e 923 //
465d1fba 924 const BOPCol_ListOfShape& aLF=aMSLF(k);
925 //
926 aMFs.Clear();
927 aItLS.Initialize(aLF);
928 for (; aItLS.More(); aItLS.Next()) {
929 const TopoDS_Shape& aF=aItLS.Value();
930 aMFs.Add(aF);
931 aMFProcessed.Add(aF);
4e57c75e 932 }
465d1fba 933 //
934 aLSI.Clear();
935 MakeInternalShells(aMFs, aLSI);
936 //
937 aItLS.Initialize(aLSI);
938 for (; aItLS.More(); aItLS.Next()) {
939 const TopoDS_Shape& aSI=aItLS.Value();
940 aBB.Add (*pSolid, aSI);
941 }
942 }
943 //
944 // 7. "Rest" faces treatment (if there are)
945 aMFs.Clear();
946 for (k=0; k < aNbVFS; ++k) {
947 const BOPAlgo_FaceSolid& aFS=aVFS(k);
948 //
949 const TopoDS_Face& aF=aFS.Face();
950 if (!aMFProcessed.Contains(aF)) {
951 aMFs.Add(aF);
952 }
953 }
954 //
955 aNbFI=aMFs.Extent();
4e57c75e 956 if (aNbFI) {
957 TopoDS_Solid aSolid;
958 aBB.MakeSolid(aSolid);
959 //
465d1fba 960 aLSI.Clear();
961 MakeInternalShells(aMFs, aLSI);
962 //
963 aItLS.Initialize(aLSI);
964 for (; aItLS.More(); aItLS.Next()) {
965 const TopoDS_Shape& aSI=aItLS.Value();
4e57c75e 966 aBB.Add (aSolid, aSI);
967 }
968 myAreas.Append(aSolid);
969 }
970}
4e57c75e 971//=======================================================================
972//function : MakeInternalShells
973//purpose :
974//=======================================================================
319da2e4 975void MakeInternalShells(const BOPCol_IndexedMapOfShape& theMF,
4e57c75e 976 BOPCol_ListOfShape& theShells)
977{
319da2e4 978 Standard_Integer i, aNbF;
4e57c75e 979 BRep_Builder aBB;
319da2e4 980 BOPCol_ListIteratorOfListOfShape aItF;
4e57c75e 981 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
4e57c75e 982 BOPCol_MapOfShape aAddedFacesMap;
983 //
319da2e4 984 aNbF = theMF.Extent();
985 for (i = 1; i <= aNbF; ++i) {
986 TopoDS_Shape aF = theMF(i);
682c9d06 987 BOPTools::MapShapesAndAncestors(aF,
1e143abb 988 TopAbs_EDGE, TopAbs_FACE,
989 aMEF);
4e57c75e 990 }
991 //
319da2e4 992 for (i = 1; i <= aNbF; ++i) {
993 TopoDS_Shape aFF = theMF(i);
4e57c75e 994 if (!aAddedFacesMap.Add(aFF)) {
995 continue;
996 }
997 //
998 // make a new shell
999 TopoDS_Shell aShell;
1000 aBB.MakeShell(aShell);
1001 aFF.Orientation(TopAbs_INTERNAL);
1002 aBB.Add(aShell, aFF);
1003 //
1004 TopoDS_Iterator aItAddedF (aShell);
1005 for (; aItAddedF.More(); aItAddedF.Next()) {
1006 const TopoDS_Shape& aF =aItAddedF.Value();
1007 //
1008 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
1009 for (; aEdgeExp.More(); aEdgeExp.Next()) {
1010 const TopoDS_Shape& aE =aEdgeExp.Current();
1011 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
1012 aItF.Initialize(aLF);
1013 for (; aItF.More(); aItF.Next()) {
1014 TopoDS_Shape aFL=aItF.Value();
1015 if (aAddedFacesMap.Add(aFL)){
1016 aFL.Orientation(TopAbs_INTERNAL);
1017 aBB.Add(aShell, aFL);
1018 }
1019 }
1020 }
1021 }
ab860031 1022 aShell.Closed (BRep_Tool::IsClosed (aShell));
4e57c75e 1023 theShells.Append(aShell);
1024 }
1025}
1026//=======================================================================
1027//function : IsHole
1028//purpose :
1029//=======================================================================
1030Standard_Boolean IsHole(const TopoDS_Shape& theS2,
1e143abb 1031 Handle(IntTools_Context)& theContext)
4e57c75e 1032{
1033 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
1034 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
1035 //
1036 aClsf.PerformInfinitePoint(::RealSmall());
1037 //
1038 return (aClsf.State()==TopAbs_IN);
1039}
1040//=======================================================================
1041//function : IsInside
1042//purpose :
1043//=======================================================================
1044Standard_Boolean IsInside(const TopoDS_Shape& theS1,
1045 const TopoDS_Shape& theS2,
1e143abb 1046 Handle(IntTools_Context)& theContext)
4e57c75e 1047{
1048 TopExp_Explorer aExp;
1049 TopAbs_State aState;
1050 //
1051 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
1052 //
1053 aExp.Init(theS1, TopAbs_FACE);
1054 if (!aExp.More()){
1055 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
1056 aClsf.PerformInfinitePoint(::RealSmall());
1057 aState=aClsf.State();
1058 }
1059 else {
1060 BOPCol_IndexedMapOfShape aBounds;
1061 BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds);
1062 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current()));
92ae0f2f 1063 aState=BOPTools_AlgoTools::ComputeState(aF, *pS2,
1064 Precision::Confusion(),
1e143abb 1065 aBounds, theContext);
4e57c75e 1066 }
1067 return (aState==TopAbs_IN);
1068}
1069//=======================================================================
1070//function : IsGrowthShell
1071//purpose :
1072//=======================================================================
1073Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
1074 const BOPCol_IndexedMapOfShape& theMHF)
1075{
1076 Standard_Boolean bRet;
1077 TopoDS_Iterator aIt;
1078 //
1079 bRet=Standard_False;
1080 if (theMHF.Extent()) {
1081 aIt.Initialize(theShell);
1082 for(; aIt.More(); aIt.Next()) {
1083 const TopoDS_Shape& aF=aIt.Value();
1084 if (theMHF.Contains(aF)) {
1085 return !bRet;
1086 }
1087 }
1088 }
1089 return bRet;
1090}