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