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