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