0024510: Remove unused local variables
[occt.git] / src / BOPAlgo / BOPAlgo_BuilderSolid.cxx
1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
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 //
7 // This file is part of Open CASCADE Technology software library.
8 //
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.
14 //
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
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
63 static
64   Standard_Boolean IsGrowthShell(const TopoDS_Shape& ,
65                                  const BOPCol_IndexedMapOfShape& );
66 static
67   Standard_Boolean IsHole(const TopoDS_Shape& ,
68                           Handle(BOPInt_Context)& );
69 static
70   Standard_Boolean IsInside(const TopoDS_Shape& ,
71                             const TopoDS_Shape& ,
72                             Handle(BOPInt_Context)& );
73 static
74   void MakeInternalShells(const BOPCol_MapOfShape& ,
75                           BOPCol_ListOfShape& );
76
77 static
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 //=======================================================================
93 BOPAlgo_BuilderSolid::BOPAlgo_BuilderSolid(const Handle(NCollection_BaseAllocator)& theAllocator)
94 :
95   BOPAlgo_BuilderArea(theAllocator)
96 {
97 }
98 //=======================================================================
99 //function : ~
100 //purpose  : 
101 //=======================================================================
102 BOPAlgo_BuilderSolid::~BOPAlgo_BuilderSolid()
103 {
104 }
105 //=======================================================================
106 //function : SetSolid 
107 //purpose  : 
108 //=======================================================================
109 void BOPAlgo_BuilderSolid::SetSolid(const TopoDS_Solid& aS)
110 {
111   mySolid=aS;
112 }
113 //=======================================================================
114 //function : Solid 
115 //purpose  : 
116 //=======================================================================
117 const TopoDS_Solid& BOPAlgo_BuilderSolid::Solid()const
118 {
119   return mySolid;
120 }
121 //=======================================================================
122 //function : Perform
123 //purpose  : 
124 //=======================================================================
125 void BOPAlgo_BuilderSolid::Perform()
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 //=======================================================================
169 void BOPAlgo_BuilderSolid::PerformShapesToAvoid()
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;
180   for(;;) {
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       }
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 //=======================================================================
246 void BOPAlgo_BuilderSolid::PerformLoops()
247 {
248   myErrorStatus=0;
249   //
250   myLoops.Clear();
251   //
252   Standard_Integer aNbLF, aNbOff, aNbFP;
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   aItM.Initialize(myShapesToAvoid);
423   for (; aItM.More(); aItM.Next()) {
424     const TopoDS_Shape& aFF=aItM.Key();
425     BOPTools::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
426   }
427   //
428   aItM.Initialize(myShapesToAvoid);
429   for (; aItM.More(); aItM.Next()) {
430     const TopoDS_Shape& aFF=aItM.Key();
431     if (!AddedFacesMap.Add(aFF)) {
432       continue;
433     }
434     //
435     // make a new shell
436     TopoDS_Shell aShell;
437     aBB.MakeShell(aShell);
438     aBB.Add(aShell, aFF);
439     //
440     TopoDS_Iterator aItAddedF (aShell);
441     for (; aItAddedF.More(); aItAddedF.Next()) {
442       const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItAddedF.Value()));
443       //
444       TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
445       for (; aEdgeExp.More(); aEdgeExp.Next()) {
446         const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aEdgeExp.Current()));
447         const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
448         aItF.Initialize(aLF);
449         for (; aItF.More(); aItF.Next()) { 
450           const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItF.Value()));
451           if (AddedFacesMap.Add(aFL)){
452             aBB.Add(aShell, aFL);
453           }
454         }
455       }
456     }
457     myLoopsInternal.Append(aShell);
458   }
459 }
460 //=======================================================================
461 //function : PerformAreas
462 //purpose  : 
463 //=======================================================================
464 void BOPAlgo_BuilderSolid::PerformAreas()
465 {
466   myErrorStatus=0;
467   //
468   Standard_Boolean bIsGrowthShell, bIsHole;
469   BRep_Builder aBB; 
470   TopoDS_Shape anInfinitePointShape;
471   BOPCol_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
472   BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
473   //
474   BOPCol_ListOfShape aNewSolids, aHoleShells; 
475   BOPCol_DataMapOfShapeShape aInOutMap;
476   BOPCol_DataMapOfShapeListOfShape aMSH;
477   BOPCol_IndexedMapOfShape aMHF;
478   //
479   myAreas.Clear();
480   //
481   //  Draft solids [aNewSolids]
482   aShellIt.Initialize(myLoops);
483   for ( ; aShellIt.More(); aShellIt.Next()) {
484     const TopoDS_Shape& aShell = aShellIt.Value();
485     //
486     bIsGrowthShell=IsGrowthShell(aShell, aMHF);
487     if (bIsGrowthShell) {
488       // make a growth solid from a shell
489       TopoDS_Solid Solid;
490       aBB.MakeSolid(Solid);
491       aBB.Add (Solid, aShell);
492       //
493       aNewSolids.Append (Solid);
494     }
495     else{
496       // check if a shell is a hole
497       //XX
498       bIsHole=IsHole(aShell, myContext);
499       //XX
500       if (bIsHole) {
501         aHoleShells.Append(aShell);
502         BOPTools::MapShapes(aShell, TopAbs_FACE, aMHF);
503       }
504       else {
505         // make a growth solid from a shell
506         TopoDS_Solid Solid;
507         aBB.MakeSolid(Solid);
508         aBB.Add (Solid, aShell);
509         //
510         aNewSolids.Append (Solid);
511       }
512     }
513   }
514   //
515   // 2. Find outer growth shell that is most close to each hole shell
516   aShellIt.Initialize(aHoleShells);
517   for (; aShellIt.More(); aShellIt.Next()) {
518     const TopoDS_Shape& aHole = aShellIt.Value();
519     //
520     aSolidIt.Initialize(aNewSolids);
521     for ( ; aSolidIt.More(); aSolidIt.Next())    {
522       const TopoDS_Shape& aSolid = aSolidIt.Value();
523       //
524       if (!IsInside(aHole, aSolid, myContext)){
525         continue;
526       }
527       //
528       if ( aInOutMap.IsBound (aHole)){
529         const TopoDS_Shape& aSolid2 = aInOutMap(aHole);
530         if (IsInside(aSolid, aSolid2, myContext)) {
531           aInOutMap.UnBind(aHole);
532           aInOutMap.Bind (aHole, aSolid);
533         }
534       }
535       else{
536         aInOutMap.Bind (aHole, aSolid);
537       }
538     }
539     //
540     // Add aHole to a map Solid/ListOfHoles [aMSH]
541     if (aInOutMap.IsBound(aHole)){
542       const TopoDS_Shape& aSolid=aInOutMap(aHole);
543       if (aMSH.IsBound(aSolid)) {
544         BOPCol_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
545         aLH.Append(aHole);
546       }
547       else {
548         BOPCol_ListOfShape aLH;
549         aLH.Append(aHole);
550         aMSH.Bind(aSolid, aLH);
551       }
552       //aBB.Add (aSolid, aHole);
553     }
554   }// for (; aShellIt.More(); aShellIt.Next()) {
555   //
556   // 3. Add aHoles to Solids
557   aItMSH.Initialize(aMSH);
558   for (; aItMSH.More(); aItMSH.Next()) {
559     TopoDS_Solid aSolid=(*(TopoDS_Solid*)(&aItMSH.Key()));
560     //
561     const BOPCol_ListOfShape& aLH=aItMSH.Value();
562     aShellIt.Initialize(aLH);
563     for (; aShellIt.More(); aShellIt.Next()) {
564       const TopoDS_Shape& aHole = aShellIt.Value();
565       aBB.Add (aSolid, aHole);
566     }
567     //
568     // update classifier
569     BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid);
570     aSC.Load(aSolid);
571     //
572   }
573   //
574   // These aNewSolids are draft solids that 
575   // do not contain any internal shapes
576   //
577   aShellIt.Initialize(aNewSolids);
578   for ( ; aShellIt.More(); aShellIt.Next()) {
579     const TopoDS_Shape& aSx = aShellIt.Value();
580     myAreas.Append(aSx);
581   }
582
583   // Add holes that outside the solids to myAreas
584   aShellIt.Initialize(aHoleShells);
585   for (; aShellIt.More(); aShellIt.Next()) {
586     const TopoDS_Shape& aHole = aShellIt.Value();
587     if (!aInOutMap.IsBound(aHole)){
588       TopoDS_Solid aSolid;
589       aBB.MakeSolid(aSolid);
590       aBB.Add (aSolid, aHole);
591       //
592       myAreas.Append(aSolid);
593     }
594   }
595 }
596 //=======================================================================
597 //function : PerformInternalShapes
598 //purpose  : 
599 //=======================================================================
600 void BOPAlgo_BuilderSolid::PerformInternalShapes()
601 {
602   myErrorStatus=0;
603   //
604   Standard_Integer aNbFI=myLoopsInternal.Extent();
605   if (!aNbFI) {// nothing to do
606     return;
607   }
608   // 
609   BRep_Builder aBB;
610   TopoDS_Iterator aIt;
611   BOPCol_ListIteratorOfListOfShape aShellIt, aSolidIt;
612   BOPCol_MapIteratorOfMapOfShape aItMF;
613   //
614   BOPCol_MapOfShape aMF, aMFP, aMFx;
615   BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
616   BOPCol_ListOfShape aLSI;
617   //
618   // 1. All internal faces
619   aShellIt.Initialize(myLoopsInternal);
620   for (; aShellIt.More(); aShellIt.Next()) {
621     const TopoDS_Shape& aShell=aShellIt.Value();
622     aIt.Initialize(aShell);
623     for (; aIt.More(); aIt.Next()) {
624       const TopoDS_Shape& aF=aIt.Value();
625       aMF.Add(aF);
626     }
627   }
628   aNbFI=aMF.Extent();
629   //
630   // 2 Process solids
631   aSolidIt.Initialize(myAreas);
632   for ( ; aSolidIt.More(); aSolidIt.Next()) {
633     TopoDS_Solid& aSolid=(*(TopoDS_Solid*)(&aSolidIt.Value()));
634     //
635     TopExp_Explorer anExpSol(aSolid, TopAbs_FACE);;
636     for (; anExpSol.More(); anExpSol.Next()) {
637       const TopoDS_Shape& aF = anExpSol.Current();
638       TopoDS_Shape aFF=aF;
639       //
640       aFF.Orientation(TopAbs_FORWARD);
641       aMFx.Add(aFF);
642       aFF.Orientation(TopAbs_REVERSED);
643       aMFx.Add(aFF);
644     }
645     aMEF.Clear();
646     BOPTools::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF);
647     //
648     // 2.1 Separate faces to process aMFP
649     aMFP.Clear();
650     aItMF.Initialize(aMF);
651     for (; aItMF.More(); aItMF.Next()) {
652       const TopoDS_Face& aF=(*(TopoDS_Face*)(&aItMF.Key()));
653       if (!aMFx.Contains(aF)) {
654         if (BOPTools_AlgoTools::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext)) {
655           aMFP.Add(aF);
656         }
657       }
658     }
659     aMFx.Clear();
660     //
661     // 2.2 Make Internal Shells
662     aLSI.Clear();
663     MakeInternalShells(aMFP, aLSI);
664     //
665     // 2.3 Add them to aSolid
666     aShellIt.Initialize(aLSI);
667     for (; aShellIt.More(); aShellIt.Next()) {
668       const TopoDS_Shape& aSI=aShellIt.Value();
669       aBB.Add (aSolid, aSI);
670     }
671     //
672     // 2.4 Remove faces aMFP from aMF
673     aItMF.Initialize(aMFP);
674     for (; aItMF.More(); aItMF.Next()) {
675       const TopoDS_Shape& aF=aItMF.Key();
676       aMF.Remove(aF);
677     }
678     //
679     aNbFI=aMF.Extent();
680     if (!aNbFI) {
681       break;
682     }
683   } //for ( ; aSolidIt.More(); aSolidIt.Next()) {
684   if (aNbFI) {
685     TopoDS_Solid aSolid;
686     aBB.MakeSolid(aSolid);
687     //
688     MakeInternalShells(aMF, aLSI);
689     aShellIt.Initialize(aLSI);
690     for (; aShellIt.More(); aShellIt.Next()) {
691       const TopoDS_Shape& aSI=aShellIt.Value();
692       aBB.Add (aSolid, aSI);
693     }
694     myAreas.Append(aSolid);
695   }
696 }
697
698 //=======================================================================
699 //function : MakeInternalShells
700 //purpose  : 
701 //=======================================================================
702 void MakeInternalShells(const BOPCol_MapOfShape& theMF,
703                         BOPCol_ListOfShape& theShells)
704 {
705   BOPCol_ListIteratorOfListOfShape aItF;
706   BRep_Builder aBB;
707   //
708   BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
709   BOPCol_MapIteratorOfMapOfShape aItM;
710   BOPCol_MapOfShape aAddedFacesMap;
711   //
712   aItM.Initialize(theMF);
713   for (; aItM.More(); aItM.Next()) {
714     const TopoDS_Shape& aF=aItM.Key();
715     BOPTools::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
716   }
717   //
718   aItM.Initialize(theMF);
719   for (; aItM.More(); aItM.Next()) {
720     TopoDS_Shape aFF=aItM.Key();
721     if (!aAddedFacesMap.Add(aFF)) {
722       continue;
723     }
724     //
725     // make a new shell
726     TopoDS_Shell aShell;
727     aBB.MakeShell(aShell);    
728     aFF.Orientation(TopAbs_INTERNAL);
729     aBB.Add(aShell, aFF);
730     //
731     TopoDS_Iterator aItAddedF (aShell);
732     for (; aItAddedF.More(); aItAddedF.Next()) {
733       const TopoDS_Shape& aF =aItAddedF.Value();
734       //
735       TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
736       for (; aEdgeExp.More(); aEdgeExp.Next()) {
737         const TopoDS_Shape& aE =aEdgeExp.Current();
738         const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
739         aItF.Initialize(aLF);
740         for (; aItF.More(); aItF.Next()) { 
741           TopoDS_Shape aFL=aItF.Value();
742           if (aAddedFacesMap.Add(aFL)){
743             aFL.Orientation(TopAbs_INTERNAL);
744             aBB.Add(aShell, aFL);
745           }
746         }
747       }
748     }
749     theShells.Append(aShell);
750   }
751 }
752 //=======================================================================
753 //function : IsHole
754 //purpose  : 
755 //=======================================================================
756 Standard_Boolean IsHole(const TopoDS_Shape& theS2,
757                         Handle(BOPInt_Context)& theContext)
758 {
759   TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
760   BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
761   //
762   aClsf.PerformInfinitePoint(::RealSmall());
763   //
764   return (aClsf.State()==TopAbs_IN);
765 }
766 //=======================================================================
767 //function : IsInside
768 //purpose  : 
769 //=======================================================================
770 Standard_Boolean IsInside(const TopoDS_Shape& theS1,
771                           const TopoDS_Shape& theS2,
772                           Handle(BOPInt_Context)& theContext)
773 {
774   TopExp_Explorer aExp;
775   TopAbs_State aState;
776   //
777   TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
778   //
779   aExp.Init(theS1, TopAbs_FACE);
780   if (!aExp.More()){
781     BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
782     aClsf.PerformInfinitePoint(::RealSmall());
783     aState=aClsf.State();
784   }
785   else {
786     BOPCol_IndexedMapOfShape aBounds;
787     BOPTools::MapShapes(*pS2, TopAbs_EDGE, aBounds);
788     const TopoDS_Face& aF = (*(TopoDS_Face*)(&aExp.Current()));
789     aState=BOPTools_AlgoTools::ComputeState(aF, *pS2, 1.e-14, aBounds, theContext);
790   }
791   return (aState==TopAbs_IN);
792 }
793 //=======================================================================
794 //function : IsGrowthShell
795 //purpose  : 
796 //=======================================================================
797 Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
798                                const BOPCol_IndexedMapOfShape& theMHF)
799 {
800   Standard_Boolean bRet;
801   TopoDS_Iterator aIt;
802   // 
803   bRet=Standard_False;
804   if (theMHF.Extent()) {
805     aIt.Initialize(theShell);
806     for(; aIt.More(); aIt.Next()) {
807       const TopoDS_Shape& aF=aIt.Value();
808       if (theMHF.Contains(aF)) {
809         return !bRet;
810       }
811     }
812   }
813   return bRet;
814 }
815 //=======================================================================
816 //function : IsClosedShell
817 //purpose  : 
818 //=======================================================================
819 Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
820 {
821   Standard_Integer aNbE;
822   Standard_Boolean bRet;
823   TopoDS_Iterator aIt;
824   TopExp_Explorer aExp;
825   //
826   BOPCol_MapOfShape aM;
827   // 
828   bRet=Standard_False;
829   aIt.Initialize(theShell);
830   for(; aIt.More(); aIt.Next()) {
831     const TopoDS_Face& aF=(*(TopoDS_Face*)(&aIt.Value()));
832     aExp.Init(aF, TopAbs_EDGE);
833     for (; aExp.More(); aExp.Next()) {
834       const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
835       if (BRep_Tool::Degenerated(aE)) {
836         continue;
837       }
838       //
839       if (aE.Orientation()==TopAbs_INTERNAL) {
840         continue;
841       }
842       if (!aM.Add(aE)) {
843         aM.Remove(aE);
844       }
845     }
846   }
847   //
848   aNbE=aM.Extent();
849   if (!aNbE) {
850     bRet=!bRet;
851   }
852   return bRet;
853 }