0024495: Crash during performeng boolean operation on attached shape for Windows...
[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//
973c2be1 9// This library is free software; you can redistribute it and / or modify it
10// under the terms of the GNU Lesser General Public version 2.1 as published
11// by the Free Software Foundation, with special exception defined in the file
12// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13// distribution for complete text of the license and disclaimer of any warranty.
4e57c75e 14//
973c2be1 15// Alternatively, this file may be used under the terms of Open CASCADE
16// commercial license or contractual agreement.
4e57c75e 17
18#include <BOPAlgo_BuilderSolid.ixx>
19
20#include <gp_Pnt2d.hxx>
21#include <gp_Pln.hxx>
22#include <gp_Vec.hxx>
23#include <gp_Dir.hxx>
24#include <gp_Pnt.hxx>
25
26#include <Geom_Curve.hxx>
27#include <Geom_Surface.hxx>
28#include <Geom2d_Curve.hxx>
29
30#include <TopAbs.hxx>
31
32#include <TopoDS_Iterator.hxx>
33#include <TopoDS_Face.hxx>
34#include <TopoDS_Shape.hxx>
35#include <TopoDS_Shell.hxx>
36#include <TopoDS_Edge.hxx>
37#include <TopoDS_Solid.hxx>
38#include <TopoDS_Vertex.hxx>
39#include <TopoDS_Compound.hxx>
40
41#include <BRep_Builder.hxx>
42#include <BRep_Tool.hxx>
43#include <BRepTools.hxx>
44#include <BRepClass3d_SolidClassifier.hxx>
45
46#include <TopExp.hxx>
47#include <TopExp_Explorer.hxx>
48//
49#include <BOPTools_AlgoTools.hxx>
50#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
51#include <BOPTools.hxx>
52#include <BOPCol_ListOfShape.hxx>
53#include <BOPCol_MapOfOrientedShape.hxx>
54//
55#include <NCollection_List.hxx>
56//
57#include <BOPCol_DataMapOfShapeShape.hxx>
58#include <BOPCol_DataMapOfShapeListOfShape.hxx>
59#include <BOPInt_Context.hxx>
60#include <BOPTools_CoupleOfShape.hxx>
61#include <BOPCol_MapOfShape.hxx>
62
63static
64 Standard_Boolean IsGrowthShell(const TopoDS_Shape& ,
65 const BOPCol_IndexedMapOfShape& );
66static
67 Standard_Boolean IsHole(const TopoDS_Shape& ,
68 Handle(BOPInt_Context)& );
69static
70 Standard_Boolean IsInside(const TopoDS_Shape& ,
71 const TopoDS_Shape& ,
72 Handle(BOPInt_Context)& );
73static
74 void MakeInternalShells(const BOPCol_MapOfShape& ,
75 BOPCol_ListOfShape& );
76
77static
78 Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell);
79
80//=======================================================================
81//function :
82//purpose :
83//=======================================================================
84 BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid()
85:
86 BOPAlgo_BuilderArea()
87{
88}
89//=======================================================================
90//function :
91//purpose :
92//=======================================================================
30ecd5f8 93BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid(const Handle(NCollection_BaseAllocator)& theAllocator)
4e57c75e 94:
95 BOPAlgo_BuilderArea(theAllocator)
96{
97}
98//=======================================================================
99//function : ~
100//purpose :
101//=======================================================================
30ecd5f8 102BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid()
4e57c75e 103{
104}
105//=======================================================================
30ecd5f8 106//function : SetSolid
107//purpose :
108//=======================================================================
109void BOPAlgo_BuilderSolid::SetSolid(const TopoDS_Solid& aS)
110{
111 mySolid=aS;
112}
113//=======================================================================
114//function : Solid
115//purpose :
116//=======================================================================
117const TopoDS_Solid& BOPAlgo_BuilderSolid::Solid()const
118{
119 return mySolid;
120}
121//=======================================================================
4e57c75e 122//function : Perform
123//purpose :
124//=======================================================================
30ecd5f8 125void BOPAlgo_BuilderSolid::Perform()
4e57c75e 126{
127 myErrorStatus=0;
128 //
129 if (myContext.IsNull()) {
130 //myErrorStatus=11;// Null Context
131 //return;
132 myContext=new BOPInt_Context;
133 }
134 //
135 TopoDS_Compound aC;
136 BRep_Builder aBB;
137 BOPCol_ListIteratorOfListOfShape aIt;
138 //
139 aBB.MakeCompound(aC);
140 aIt.Initialize(myShapes);
141 for(; aIt.More(); aIt.Next()) {
142 const TopoDS_Shape& aF=aIt.Value();
143 aBB.Add(aC, aF);
144 }
145 //
146 //
147 PerformShapesToAvoid();
148 if (myErrorStatus) {
149 return;
150 }
151 //
152 PerformLoops();
153 if (myErrorStatus) {
154 return;
155 }
156 PerformAreas();
157 if (myErrorStatus) {
158 return;
159 }
160 PerformInternalShapes();
161 if (myErrorStatus) {
162 return;
163 }
164}
165//=======================================================================
166//function :PerformShapesToAvoid
167//purpose :
168//=======================================================================
30ecd5f8 169void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
4e57c75e 170{
171 Standard_Boolean bFound;
172 Standard_Integer i, iCnt, aNbE, aNbF;
173 TopAbs_Orientation aOrE;
174 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
175 BOPCol_ListIteratorOfListOfShape aIt;
176 //
177 myShapesToAvoid.Clear();
178 //
179 iCnt=0;
302f96fb 180 for(;;) {
4e57c75e 181 ++iCnt;
182 bFound=Standard_False;
183 //
184 // 1. MEF
185 aMEF.Clear();
186 aIt.Initialize (myShapes);
187 for (; aIt.More(); aIt.Next()) {
188 const TopoDS_Shape& aF=aIt.Value();
189 if (!myShapesToAvoid.Contains(aF)) {
190 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
191 }
4e57c75e 192 }
193 aNbE=aMEF.Extent();
194 //
195 // 2. myFacesToAvoid
196 for (i=1; i<=aNbE; ++i) {
197 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aMEF.FindKey(i)));
198 if (BRep_Tool::Degenerated(aE)) {
199 continue;
200 }
201 //
202 BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
203 aNbF=aLF.Extent();
204 if (!aNbF) {
205 continue;
206 }
207 //
208 aOrE=aE.Orientation();
209 //
210 const TopoDS_Face& aF1=(*(TopoDS_Face*)(&aLF.First()));
211 if (aNbF==1) {
212 if (aOrE==TopAbs_INTERNAL) {
213 continue;
214 }
215 bFound=Standard_True;
216 myShapesToAvoid.Add(aF1);
217 }
218 else if (aNbF==2) {
219 const TopoDS_Face& aF2=(*(TopoDS_Face*)(&aLF.Last()));
220 if (aF2.IsSame(aF1)) {
221 if (BRep_Tool::IsClosed(aE, aF1)) {
222 continue;
223 }
224 //
225 if (aOrE==TopAbs_INTERNAL) {
226 continue;
227 }
228 //
229 bFound=Standard_True;
230 myShapesToAvoid.Add(aF1);
231 myShapesToAvoid.Add(aF2);
232 }
233 }
234 }// for (i=1; i<=aNbE; ++i) {
235 //
236 if (!bFound) {
237 break;
238 }
239 //
240 }//while (1)
241}
242//=======================================================================
243//function : PerformLoops
244//purpose :
245//=======================================================================
30ecd5f8 246void BOPAlgo_BuilderSolid::PerformLoops()
4e57c75e 247{
248 myErrorStatus=0;
249 //
250 myLoops.Clear();
251 //
252 Standard_Integer aNbLF, aNbOff, aNbFP, aNbFA;
253 Standard_Integer i;
254 TopAbs_Orientation anOr;
255 TopoDS_Edge aEL;
256 BRep_Builder aBB;
257 TopoDS_Iterator aItS;
258 //
259 BOPCol_ListIteratorOfListOfShape aItF, aIt;
260 BOPCol_MapIteratorOfMapOfOrientedShape aItM;
261 BOPTools_CoupleOfShape aCSOff;
262 //
263 BOPCol_MapOfOrientedShape AddedFacesMap;
264 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
265 //
266 //=================================================
267 //
268 // 1. Shells Usual
269 //
270 aItF.Initialize (myShapes);
271 for (; aItF.More(); aItF.Next()) {
272 const TopoDS_Shape& aFF = aItF.Value();
273 BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
274 }
275 //
276 aItF.Initialize (myShapes);
277 for (i=1; aItF.More(); aItF.Next(), ++i) {
278 const TopoDS_Shape& aFF = aItF.Value();
279 if (myShapesToAvoid.Contains(aFF)) {
280 continue;
281 }
282 if (!AddedFacesMap.Add(aFF)) {
283 continue;
284 }
285 //
286 // make a new shell
287 TopoDS_Shell aShell;
288 aBB.MakeShell(aShell);
289 aBB.Add(aShell, aFF);
290 //
291 aMEFP.Clear();
292 BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
293 //
294 // loop on faces added to Shell; add their neighbor faces to Shell and so on
295 TopoDS_Iterator aItAddedF (aShell);
296 for (; aItAddedF.More(); aItAddedF.Next()) {
297 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value()));
298 //
299 // loop on edges of aF; find a good neighbor face of aF by aE
300 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
301 for (; aEdgeExp.More(); aEdgeExp.Next()) {
302 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
303 //
304 //1
305 if (aMEFP.Contains(aE)) {
306 const BOPCol_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
307 aNbFP=aLFP.Extent();
308 if (aNbFP>1) {
309 continue;
310 }
311 }
312 //2
313 anOr=aE.Orientation();
314 if (anOr==TopAbs_INTERNAL) {
315 continue;
316 }
317 //3
318 if (BRep_Tool::Degenerated(aE)) {
319 continue;
320 }
321 //
322 // candidate faces list
323 const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
324 aNbLF=aLF.Extent();
325 if (!aNbLF) {
326 continue;
327 }
328 //
329 // try to select one of neighbors
330 // check if a face already added to Shell shares E
331 Standard_Boolean bFound;
332 BOPCol_ListIteratorOfListOfShape aItLF;
333 BOPTools_ListOfCoupleOfShape aLCSOff;
334 //
335 aItLF.Initialize(aLF);
336 for (; aItLF.More(); aItLF.Next()) {
337 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
338 if (myShapesToAvoid.Contains(aFL)) {
339 continue;
340 }
341 if (aF.IsSame(aFL)) {
342 continue;
343 }
344 if (AddedFacesMap.Contains(aFL)){
345 continue;
346 }
347 //
348 bFound=BOPTools_AlgoTools::GetEdgeOff(aE, aFL, aEL);
349 if (!bFound) {
350 continue;
351 }
352 //
353 aCSOff.SetShape1(aEL);
354 aCSOff.SetShape2(aFL);
355 aLCSOff.Append(aCSOff);
356 }//for (; aItLF.More(); aItLF.Next()) {
357 //
358 aNbOff=aLCSOff.Extent();
359 if (!aNbOff){
360 continue;
361 }
362 //
363 TopoDS_Face aSelF;
364 if (aNbOff==1) {
365 aSelF=(*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
366 }
367 else if (aNbOff>1){
368 BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, myContext);
369 }
370 //
371 if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
372 aBB.Add(aShell, aSelF);
373 BOPTools::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
374 }
375 } // for (; aEdgeExp.More(); aEdgeExp.Next()) {
376 } //for (; aItAddedF.More(); aItAddedF.Next()) {
377 //
378 if (IsClosedShell(aShell)) {
379 myLoops.Append(aShell);
380 }
381 } // for (; aItF.More(); aItF.Next()) {
382
383 //
384 // Post Treatment
385 BOPCol_MapOfOrientedShape aMP;
386 //
387 // a. collect all edges that are in loops
388 aIt.Initialize (myLoops);
389 for (; aIt.More(); aIt.Next()) {
390 const TopoDS_Shape& aS=aIt.Value();
391 aItS.Initialize(aS);
392 for (; aItS.More(); aItS.Next()) {
393 const TopoDS_Shape& aF=aItS.Value();
394 aMP.Add(aF);
395 }
396 }
397 //
398 // b. collect all edges that are to avoid
399 aItM.Initialize(myShapesToAvoid);
400 for (; aItM.More(); aItM.Next()) {
401 const TopoDS_Shape& aF=aItM.Key();
402 aMP.Add(aF);
403 }
404 //
405 // c. add all edges that are not processed to myShapesToAvoid
406 aIt.Initialize (myShapes);
407 for (; aIt.More(); aIt.Next()) {
408 const TopoDS_Shape& aF=aIt.Value();
409 if (!aMP.Contains(aF)) {
410 myShapesToAvoid.Add(aF);
411 }
412 }
413 //=================================================
414 //
415 // 2.Internal Shells
416 //
417 myLoopsInternal.Clear();
418 //
419 aEFMap.Clear();
420 AddedFacesMap.Clear();
421 //
422 aNbFA=myShapesToAvoid.Extent();
423 //
424 aItM.Initialize(myShapesToAvoid);
425 for (; aItM.More(); aItM.Next()) {
426 const TopoDS_Shape& aFF=aItM.Key();
427 BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
428 }
429 //
430 aItM.Initialize(myShapesToAvoid);
431 for (; aItM.More(); aItM.Next()) {
432 const TopoDS_Shape& aFF=aItM.Key();
433 if (!AddedFacesMap.Add(aFF)) {
434 continue;
435 }
436 //
437 // make a new shell
438 TopoDS_Shell aShell;
439 aBB.MakeShell(aShell);
440 aBB.Add(aShell, aFF);
441 //
442 TopoDS_Iterator aItAddedF (aShell);
443 for (; aItAddedF.More(); aItAddedF.Next()) {
444 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value()));
445 //
446 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
447 for (; aEdgeExp.More(); aEdgeExp.Next()) {
448 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
449 const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
450 aItF.Initialize(aLF);
451 for (; aItF.More(); aItF.Next()) {
452 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItF.Value()));
453 if (AddedFacesMap.Add(aFL)){
454 aBB.Add(aShell, aFL);
455 }
456 }
457 }
458 }
459 myLoopsInternal.Append(aShell);
460 }
461}
462//=======================================================================
463//function : PerformAreas
464//purpose :
465//=======================================================================
30ecd5f8 466void BOPAlgo_BuilderSolid::PerformAreas()
4e57c75e 467{
468 myErrorStatus=0;
469 //
470 Standard_Boolean bIsGrowthShell, bIsHole;
471 BRep_Builder aBB;
472 TopoDS_Shape anInfinitePointShape;
473 BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
474 BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
475 //
476 BOPCol_ListOfShape aNewSolids, aHoleShells;
477 BOPCol_DataMapOfShapeShape aInOutMap;
478 BOPCol_DataMapOfShapeListOfShape aMSH;
479 BOPCol_IndexedMapOfShape aMHF;
480 //
481 myAreas.Clear();
482 //
483 // Draft solids [aNewSolids]
484 aShellIt.Initialize(myLoops);
485 for ( ; aShellIt.More(); aShellIt.Next()) {
486 const TopoDS_Shape& aShell = aShellIt.Value();
487 //
488 bIsGrowthShell=IsGrowthShell(aShell, aMHF);
489 if (bIsGrowthShell) {
490 // make a growth solid from a shell
491 TopoDS_Solid Solid;
492 aBB.MakeSolid(Solid);
493 aBB.Add (Solid, aShell);
494 //
495 aNewSolids.Append (Solid);
496 }
497 else{
498 // check if a shell is a hole
499 //XX
500 bIsHole=IsHole(aShell, myContext);
501 //XX
502 if (bIsHole) {
503 aHoleShells.Append(aShell);
504 BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF);
505 }
506 else {
507 // make a growth solid from a shell
508 TopoDS_Solid Solid;
509 aBB.MakeSolid(Solid);
510 aBB.Add (Solid, aShell);
511 //
512 aNewSolids.Append (Solid);
513 }
514 }
515 }
516 //
517 // 2. Find outer growth shell that is most close to each hole shell
518 aShellIt.Initialize(aHoleShells);
519 for (; aShellIt.More(); aShellIt.Next()) {
520 const TopoDS_Shape& aHole = aShellIt.Value();
521 //
522 aSolidIt.Initialize(aNewSolids);
523 for ( ; aSolidIt.More(); aSolidIt.Next()) {
524 const TopoDS_Shape& aSolid = aSolidIt.Value();
525 //
526 if (!IsInside(aHole, aSolid, myContext)){
527 continue;
528 }
529 //
530 if ( aInOutMap.IsBound (aHole)){
531 const TopoDS_Shape& aSolid2 = aInOutMap(aHole);
532 if (IsInside(aSolid, aSolid2, myContext)) {
533 aInOutMap.UnBind(aHole);
534 aInOutMap.Bind (aHole, aSolid);
535 }
536 }
537 else{
538 aInOutMap.Bind (aHole, aSolid);
539 }
540 }
541 //
542 // Add aHole to a map Solid/ListOfHoles [aMSH]
543 if (aInOutMap.IsBound(aHole)){
544 const TopoDS_Shape& aSolid=aInOutMap(aHole);
545 if (aMSH.IsBound(aSolid)) {
546 BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
547 aLH.Append(aHole);
548 }
549 else {
550 BOPCol_ListOfShape aLH;
551 aLH.Append(aHole);
552 aMSH.Bind(aSolid, aLH);
553 }
554 //aBB.Add (aSolid, aHole);
555 }
556 }// for (; aShellIt.More(); aShellIt.Next()) {
557 //
558 // 3. Add aHoles to Solids
559 aItMSH.Initialize(aMSH);
560 for (; aItMSH.More(); aItMSH.Next()) {
561 TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&aItMSH.Key()));
562 //
563 const BOPCol_ListOfShape& aLH=aItMSH.Value();
564 aShellIt.Initialize(aLH);
565 for (; aShellIt.More(); aShellIt.Next()) {
566 const TopoDS_Shape& aHole = aShellIt.Value();
567 aBB.Add (aSolid, aHole);
568 }
569 //
570 // update classifier
571 BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid);
572 aSC.Load(aSolid);
573 //
574 }
575 //
576 // These aNewSolids are draft solids that
577 // do not contain any internal shapes
578 //
579 aShellIt.Initialize(aNewSolids);
580 for ( ; aShellIt.More(); aShellIt.Next()) {
581 const TopoDS_Shape& aSx = aShellIt.Value();
582 myAreas.Append(aSx);
583 }
584
585 // Add holes that outside the solids to myAreas
586 aShellIt.Initialize(aHoleShells);
587 for (; aShellIt.More(); aShellIt.Next()) {
588 const TopoDS_Shape& aHole = aShellIt.Value();
589 if (!aInOutMap.IsBound(aHole)){
590 TopoDS_Solid aSolid;
591 aBB.MakeSolid(aSolid);
592 aBB.Add (aSolid, aHole);
593 //
594 myAreas.Append(aSolid);
595 }
596 }
597}
598//=======================================================================
599//function : PerformInternalShapes
600//purpose :
601//=======================================================================
30ecd5f8 602void BOPAlgo_BuilderSolid::PerformInternalShapes()
4e57c75e 603{
604 myErrorStatus=0;
605 //
606 Standard_Integer aNbFI=myLoopsInternal.Extent();
607 if (!aNbFI) {// nothing to do
608 return;
609 }
610 //
611 BRep_Builder aBB;
612 TopoDS_Iterator aIt;
613 BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
614 BOPCol_MapIteratorOfMapOfShape aItMF;
615 //
616 BOPCol_MapOfShape aMF, aMFP, aMFx;
617 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
618 BOPCol_ListOfShape aLSI;
619 //
620 // 1. All internal faces
621 aShellIt.Initialize(myLoopsInternal);
622 for (; aShellIt.More(); aShellIt.Next()) {
623 const TopoDS_Shape& aShell=aShellIt.Value();
624 aIt.Initialize(aShell);
625 for (; aIt.More(); aIt.Next()) {
626 const TopoDS_Shape& aF=aIt.Value();
627 aMF.Add(aF);
628 }
629 }
630 aNbFI=aMF.Extent();
631 //
632 // 2 Process solids
633 aSolidIt.Initialize(myAreas);
634 for ( ; aSolidIt.More(); aSolidIt.Next()) {
635 TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aSolidIt.Value()));
636 //
637 TopExp_Explorer anExpSol(aSolid, TopAbs_FACE);;
638 for (; anExpSol.More(); anExpSol.Next()) {
639 const TopoDS_Shape& aF = anExpSol.Current();
640 TopoDS_Shape aFF=aF;
641 //
642 aFF.Orientation(TopAbs_FORWARD);
643 aMFx.Add(aFF);
644 aFF.Orientation(TopAbs_REVERSED);
645 aMFx.Add(aFF);
646 }
647 aMEF.Clear();
648 BOPTools::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF);
649 //
650 // 2.1 Separate faces to process aMFP
651 aMFP.Clear();
652 aItMF.Initialize(aMF);
653 for (; aItMF.More(); aItMF.Next()) {
654 const TopoDS_Face& aF=(*(TopoDS_Face*)(&aItMF.Key()));
655 if (!aMFx.Contains(aF)) {
656 if (BOPTools_AlgoTools::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext)) {
657 aMFP.Add(aF);
658 }
659 }
660 }
661 aMFx.Clear();
662 //
663 // 2.2 Make Internal Shells
664 aLSI.Clear();
665 MakeInternalShells(aMFP, aLSI);
666 //
667 // 2.3 Add them to aSolid
668 aShellIt.Initialize(aLSI);
669 for (; aShellIt.More(); aShellIt.Next()) {
670 const TopoDS_Shape& aSI=aShellIt.Value();
671 aBB.Add (aSolid, aSI);
672 }
673 //
674 // 2.4 Remove faces aMFP from aMF
675 aItMF.Initialize(aMFP);
676 for (; aItMF.More(); aItMF.Next()) {
677 const TopoDS_Shape& aF=aItMF.Key();
678 aMF.Remove(aF);
679 }
680 //
681 aNbFI=aMF.Extent();
682 if (!aNbFI) {
683 break;
684 }
685 } //for ( ; aSolidIt.More(); aSolidIt.Next()) {
686 if (aNbFI) {
687 TopoDS_Solid aSolid;
688 aBB.MakeSolid(aSolid);
689 //
690 MakeInternalShells(aMF, aLSI);
691 aShellIt.Initialize(aLSI);
692 for (; aShellIt.More(); aShellIt.Next()) {
693 const TopoDS_Shape& aSI=aShellIt.Value();
694 aBB.Add (aSolid, aSI);
695 }
696 myAreas.Append(aSolid);
697 }
698}
699
700//=======================================================================
701//function : MakeInternalShells
702//purpose :
703//=======================================================================
704void MakeInternalShells(const BOPCol_MapOfShape& theMF,
705 BOPCol_ListOfShape& theShells)
706{
707 BOPCol_ListIteratorOfListOfShape aItF;
708 BRep_Builder aBB;
709 //
710 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
711 BOPCol_MapIteratorOfMapOfShape aItM;
712 BOPCol_MapOfShape aAddedFacesMap;
713 //
714 aItM.Initialize(theMF);
715 for (; aItM.More(); aItM.Next()) {
716 const TopoDS_Shape& aF=aItM.Key();
717 BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
718 }
719 //
720 aItM.Initialize(theMF);
721 for (; aItM.More(); aItM.Next()) {
722 TopoDS_Shape aFF=aItM.Key();
723 if (!aAddedFacesMap.Add(aFF)) {
724 continue;
725 }
726 //
727 // make a new shell
728 TopoDS_Shell aShell;
729 aBB.MakeShell(aShell);
730 aFF.Orientation(TopAbs_INTERNAL);
731 aBB.Add(aShell, aFF);
732 //
733 TopoDS_Iterator aItAddedF (aShell);
734 for (; aItAddedF.More(); aItAddedF.Next()) {
735 const TopoDS_Shape& aF =aItAddedF.Value();
736 //
737 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
738 for (; aEdgeExp.More(); aEdgeExp.Next()) {
739 const TopoDS_Shape& aE =aEdgeExp.Current();
740 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
741 aItF.Initialize(aLF);
742 for (; aItF.More(); aItF.Next()) {
743 TopoDS_Shape aFL=aItF.Value();
744 if (aAddedFacesMap.Add(aFL)){
745 aFL.Orientation(TopAbs_INTERNAL);
746 aBB.Add(aShell, aFL);
747 }
748 }
749 }
750 }
751 theShells.Append(aShell);
752 }
753}
754//=======================================================================
755//function : IsHole
756//purpose :
757//=======================================================================
758Standard_Boolean IsHole(const TopoDS_Shape& theS2,
759 Handle(BOPInt_Context)& theContext)
760{
761 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
762 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
763 //
764 aClsf.PerformInfinitePoint(::RealSmall());
765 //
766 return (aClsf.State()==TopAbs_IN);
767}
768//=======================================================================
769//function : IsInside
770//purpose :
771//=======================================================================
772Standard_Boolean IsInside(const TopoDS_Shape& theS1,
773 const TopoDS_Shape& theS2,
774 Handle(BOPInt_Context)& theContext)
775{
776 TopExp_Explorer aExp;
777 TopAbs_State aState;
778 //
779 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
780 //
781 aExp.Init(theS1, TopAbs_FACE);
782 if (!aExp.More()){
783 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
784 aClsf.PerformInfinitePoint(::RealSmall());
785 aState=aClsf.State();
786 }
787 else {
788 BOPCol_IndexedMapOfShape aBounds;
789 BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds);
790 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current()));
791 aState=BOPTools_AlgoTools::ComputeState(aF, *pS2, 1.e-14, aBounds, theContext);
792 }
793 return (aState==TopAbs_IN);
794}
795//=======================================================================
796//function : IsGrowthShell
797//purpose :
798//=======================================================================
799Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
800 const BOPCol_IndexedMapOfShape& theMHF)
801{
802 Standard_Boolean bRet;
803 TopoDS_Iterator aIt;
804 //
805 bRet=Standard_False;
806 if (theMHF.Extent()) {
807 aIt.Initialize(theShell);
808 for(; aIt.More(); aIt.Next()) {
809 const TopoDS_Shape& aF=aIt.Value();
810 if (theMHF.Contains(aF)) {
811 return !bRet;
812 }
813 }
814 }
815 return bRet;
816}
817//=======================================================================
818//function : IsClosedShell
819//purpose :
820//=======================================================================
821Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
822{
823 Standard_Integer aNbE;
824 Standard_Boolean bRet;
825 TopoDS_Iterator aIt;
826 TopExp_Explorer aExp;
827 //
828 BOPCol_MapOfShape aM;
829 //
830 bRet=Standard_False;
831 aIt.Initialize(theShell);
832 for(; aIt.More(); aIt.Next()) {
833 const TopoDS_Face& aF=(*(TopoDS_Face*)(&aIt.Value()));
834 aExp.Init(aF, TopAbs_EDGE);
835 for (; aExp.More(); aExp.Next()) {
836 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
837 if (BRep_Tool::Degenerated(aE)) {
838 continue;
839 }
840 //
841 if (aE.Orientation()==TopAbs_INTERNAL) {
842 continue;
843 }
844 if (!aM.Add(aE)) {
845 aM.Remove(aE);
846 }
847 }
848 }
849 //
850 aNbE=aM.Extent();
851 if (!aNbE) {
852 bRet=!bRet;
853 }
854 return bRet;
855}