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