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