Salome HOME
Merge from BR_Dev_For_4_0 branch (from tag mergeto_BR_QT4_Dev_17Jan08)
[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
97
98 //=======================================================================
99 //function : 
100 //purpose  : 
101 //=======================================================================
102   GEOMAlgo_BuilderSolid::GEOMAlgo_BuilderSolid()
103 :
104   GEOMAlgo_BuilderArea()
105 {
106 }
107 //=======================================================================
108 //function : ~
109 //purpose  : 
110 //=======================================================================
111   GEOMAlgo_BuilderSolid::~GEOMAlgo_BuilderSolid()
112 {
113 }
114 //=======================================================================
115 //function : Perform
116 //purpose  : 
117 //=======================================================================
118   void GEOMAlgo_BuilderSolid::Perform()
119 {
120   myErrorStatus=0;
121   //
122   //
123   TopoDS_Compound aC;
124   BRep_Builder aBB;
125   TopTools_ListIteratorOfListOfShape aIt;
126   
127   aBB.MakeCompound(aC);
128   aIt.Initialize(myShapes);
129   for(; aIt.More(); aIt.Next()) {
130     const TopoDS_Shape& aF=aIt.Value();
131     aBB.Add(aC, aF);
132   }
133   //
134   //
135   if (myContext==NULL) {
136     myErrorStatus=11;// Null Context
137     return;
138   }
139   //
140   PerformShapesToAvoid();
141   if (myErrorStatus) {
142     return;
143   }
144   //
145   PerformLoops();
146   if (myErrorStatus) {
147     return;
148   }
149   PerformAreas();
150   if (myErrorStatus) {
151     return;
152   }
153   PerformInternalShapes();
154   if (myErrorStatus) {
155     return;
156   }
157 }
158 //=======================================================================
159 //function :PerformShapesToAvoid
160 //purpose  : 
161 //=======================================================================
162   void GEOMAlgo_BuilderSolid::PerformShapesToAvoid()
163 {
164   Standard_Boolean bFound;
165   Standard_Integer i, iCnt, aNbE, aNbF;
166   TopAbs_Orientation aOrE;
167   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
168   TopTools_ListIteratorOfListOfShape aIt;
169   //
170   myShapesToAvoid.Clear();
171   //
172   iCnt=0;
173   while (1) {
174     ++iCnt;
175     bFound=Standard_False;
176     //
177     // 1. MEF
178     aMEF.Clear();
179     aIt.Initialize (myShapes);
180     for (; aIt.More(); aIt.Next()) {
181       const TopoDS_Shape& aF=aIt.Value();
182       if (!myShapesToAvoid.Contains(aF)) {
183         TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
184       }
185       else {
186         int a=0;
187       }
188     }
189     aNbE=aMEF.Extent();
190     //
191     // 2. myFacesToAvoid
192     for (i=1; i<=aNbE; ++i) {
193       const TopoDS_Edge& aE=TopoDS::Edge(aMEF.FindKey(i));
194       if (BRep_Tool::Degenerated(aE)) {
195         continue;
196       }
197       //
198       TopTools_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
199       //
200       aNbF=aLF.Extent();
201       if (!aNbF) {
202         continue;
203       }
204       //
205       aOrE=aE.Orientation();
206       //
207       const TopoDS_Face& aF1=TopoDS::Face(aLF.First());
208       if (aNbF==1) {
209         if (aOrE==TopAbs_INTERNAL) {
210           continue;
211         }
212         bFound=Standard_True;
213         myShapesToAvoid.Add(aF1);
214       }
215       else if (aNbF==2) {
216         const TopoDS_Face& aF2=TopoDS::Face(aLF.Last());
217         if (aF2.IsSame(aF1)) {
218           if (BRep_Tool::IsClosed(aE, aF1)) {
219             continue;
220           }
221           //
222           if (aOrE==TopAbs_INTERNAL) {
223             continue;
224           }
225           //
226           bFound=Standard_True;
227           myShapesToAvoid.Add(aF1);
228           myShapesToAvoid.Add(aF2);
229         }
230       }
231     }// for (i=1; i<=aNbE; ++i) {
232     //
233     if (!bFound) {
234       break;
235     }
236     //
237   }//while (1) 
238 }  
239 //=======================================================================
240 //function : PerformLoops
241 //purpose  : 
242 //=======================================================================
243   void GEOMAlgo_BuilderSolid::PerformLoops()
244 {
245   myErrorStatus=0;
246   //
247   myLoops.Clear();
248   //
249   Standard_Integer aNbLF, aNbOff, aNbFP;
250   TopAbs_Orientation anOr;
251   TopoDS_Edge aEL;
252   BRep_Builder aBB;
253   NMTTools_CoupleOfShape aCSOff;
254   TopTools_MapOfOrientedShape AddedFacesMap;
255   TopTools_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
256   TopTools_ListIteratorOfListOfShape aItF;
257   //
258   //=================================================
259   //
260   // 1. Shells Usual
261   //
262   aItF.Initialize (myShapes);
263   for (; aItF.More(); aItF.Next()) {
264     const TopoDS_Shape& aFF = aItF.Value();
265     TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
266   }
267   //
268   aItF.Initialize (myShapes);
269   for (; aItF.More(); aItF.Next()) {
270     const TopoDS_Shape& aFF = aItF.Value();
271     if (myShapesToAvoid.Contains(aFF)) {
272       continue;
273     }
274     if (!AddedFacesMap.Add(aFF)) {
275       continue;
276     }
277     //
278     // make a new shell
279     TopoDS_Shell aShell;
280     aBB.MakeShell(aShell);
281     aBB.Add(aShell, aFF);
282     //
283     aMEFP.Clear();
284     TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
285     //
286     // loop on faces added to Shell; add their neighbor faces to Shell and so on
287     TopoDS_Iterator aItAddedF (aShell);
288     for (; aItAddedF.More(); aItAddedF.Next()) {
289       const TopoDS_Face& aF = TopoDS::Face(aItAddedF.Value());
290       //
291       // loop on edges of aF; find a good neighbor face of aF by aE
292       TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
293       for (; aEdgeExp.More(); aEdgeExp.Next()) {
294         const TopoDS_Edge& aE = TopoDS::Edge(aEdgeExp.Current());
295         //
296         //1
297         if (aMEFP.Contains(aE)) {
298           const TopTools_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
299           aNbFP=aLFP.Extent();
300           if (aNbFP>1) { 
301             continue;
302           }
303         }
304         //2
305         anOr=aE.Orientation();
306         if (anOr==TopAbs_INTERNAL) {
307           continue;
308         }
309         //3
310         if (BRep_Tool::Degenerated(aE)) {
311           continue;
312         }
313         //
314         // candidate faces list
315         const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE);
316         aNbLF=aLF.Extent();
317         if (!aNbLF) {
318           continue;
319         }
320         //
321         // try to select one of neighbors
322         // check if a face already added to Shell shares E
323         Standard_Boolean bFound;
324         TopTools_ListIteratorOfListOfShape aItLF;
325         NMTTools_ListOfCoupleOfShape aLCSOff;
326         //
327         aItLF.Initialize(aLF);
328         for (; aItLF.More(); aItLF.Next()) { 
329           const TopoDS_Face& aFL=TopoDS::Face(aItLF.Value());
330           if (myShapesToAvoid.Contains(aFL)) {
331             continue;
332           }
333           if (aF.IsSame(aFL)) {
334             continue;
335           } 
336           if (AddedFacesMap.Contains(aFL)){
337             continue;
338           }
339           //
340           bFound=GEOMAlgo_Tools3D::GetEdgeOff(aE, aFL, aEL);
341           if (!bFound) {
342             continue;
343           }
344           //
345           aCSOff.SetShape1(aEL);
346           aCSOff.SetShape2(aFL);
347           aLCSOff.Append(aCSOff);
348         }//for (; aItLF.More(); aItLF.Next()) { 
349         //
350         aNbOff=aLCSOff.Extent();
351         if (!aNbOff){
352           continue;
353         }
354         //
355         TopoDS_Face aSelF;
356         if (aNbOff==1) {
357           aSelF=TopoDS::Face(aLCSOff.First().Shape2());
358         }
359         else if (aNbOff>1){
360           GEOMAlgo_Tools3D::GetFaceOff(aE, aF, aLCSOff, aSelF);
361         }
362         //
363         if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) { 
364           aBB.Add(aShell, aSelF);
365           TopExp::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
366         }
367       } // for (; aEdgeExp.More(); aEdgeExp.Next()) { 
368     } //for (; aItAddedF.More(); aItAddedF.Next()) {
369     myLoops.Append(aShell);
370   } // for (; aItF.More(); aItF.Next()) {
371   //=================================================
372   //
373   // 2.Internal Shells
374   //
375   myLoopsInternal.Clear();
376   //
377   Standard_Integer aNbFA;
378   TopTools_MapIteratorOfMapOfOrientedShape aItM;
379   //
380   aEFMap.Clear();
381   AddedFacesMap.Clear();
382   //
383   aNbFA=myShapesToAvoid.Extent();
384   //
385   aItM.Initialize(myShapesToAvoid);
386   for (; aItM.More(); aItM.Next()) {
387     const TopoDS_Shape& aFF=aItM.Key();
388     TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
389   }
390   //
391   aItM.Initialize(myShapesToAvoid);
392   for (; aItM.More(); aItM.Next()) {
393     const TopoDS_Shape& aFF=aItM.Key();
394     if (!AddedFacesMap.Add(aFF)) {
395       continue;
396     }
397     //
398     // make a new shell
399     TopoDS_Shell aShell;
400     aBB.MakeShell(aShell);
401     aBB.Add(aShell, aFF);
402     //
403     TopoDS_Iterator aItAddedF (aShell);
404     for (; aItAddedF.More(); aItAddedF.Next()) {
405       const TopoDS_Face& aF = TopoDS::Face(aItAddedF.Value());
406       //
407       TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
408       for (; aEdgeExp.More(); aEdgeExp.Next()) {
409         const TopoDS_Edge& aE = TopoDS::Edge(aEdgeExp.Current());
410         const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE);
411         aItF.Initialize(aLF);
412         for (; aItF.More(); aItF.Next()) { 
413           const TopoDS_Face& aFL=TopoDS::Face(aItF.Value());
414           if (AddedFacesMap.Add(aFL)){
415             aBB.Add(aShell, aFL);
416           }
417         }
418       }
419     }
420     myLoopsInternal.Append(aShell);
421   }
422 }
423 //=======================================================================
424 //function : PerformAreas
425 //purpose  : 
426 //=======================================================================
427   void GEOMAlgo_BuilderSolid::PerformAreas()
428 {
429   myErrorStatus=0;
430   //
431   Standard_Boolean bIsGrowthShell, bIsHole;
432   TopTools_ListOfShape aNewSolids, aHoleShells; 
433   TopoDS_Shape anInfinitePointShape;
434   TopTools_DataMapOfShapeShape aInOutMap;
435   TopTools_DataMapOfShapeListOfShape aMSH;
436   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
437   TopTools_ListIteratorOfListOfShape aShellIt, aSolidIt;
438   TopTools_IndexedMapOfShape aMHF;
439   BRep_Builder aBB;
440   //
441   myAreas.Clear();
442   //
443   //  Draft solids [aNewSolids]
444   aShellIt.Initialize(myLoops);
445   for ( ; aShellIt.More(); aShellIt.Next()) {
446     const TopoDS_Shape& aShell = aShellIt.Value();
447     //
448     bIsGrowthShell=IsGrowthShell(aShell, aMHF);
449     if (bIsGrowthShell) {
450       // make a growth solid from a shell
451       TopoDS_Solid Solid;
452       aBB.MakeSolid(Solid);
453       aBB.Add (Solid, aShell);
454       //
455       aNewSolids.Append (Solid);
456     }
457     else{
458       // check if a shell is a hole
459       //XX
460       bIsHole=IsHole(aShell, myContext);
461       //bIsHole=GEOMAlgo_BuilderTools::IsHole(aShell);
462       //XX
463       if (bIsHole) {
464         aHoleShells.Append(aShell);
465         TopExp::MapShapes(aShell, TopAbs_FACE, aMHF);
466       }
467       else {
468         // make a growth solid from a shell
469         TopoDS_Solid Solid;
470         aBB.MakeSolid(Solid);
471         aBB.Add (Solid, aShell);
472         //
473         aNewSolids.Append (Solid);
474       }
475     }
476   }
477   //
478   // 2. Find outer growth shell that is most close to each hole shell
479   aShellIt.Initialize(aHoleShells);
480   for (; aShellIt.More(); aShellIt.Next()) {
481     const TopoDS_Shape& aHole = aShellIt.Value();
482     //
483     aSolidIt.Initialize(aNewSolids);
484     for ( ; aSolidIt.More(); aSolidIt.Next())    {
485       const TopoDS_Shape& aSolid = aSolidIt.Value();
486       //
487       if (!IsInside(aHole, aSolid, myContext)){
488         continue;
489       }
490       //
491       if ( aInOutMap.IsBound (aHole)){
492         const TopoDS_Shape& aSolid2 = aInOutMap(aHole);
493         if (IsInside(aSolid, aSolid2, myContext)) {
494           aInOutMap.UnBind(aHole);
495           aInOutMap.Bind (aHole, aSolid);
496         }
497       }
498       else{
499         aInOutMap.Bind (aHole, aSolid);
500       }
501     }
502     //
503     // Add aHole to a map Solid/ListOfHoles [aMSH]
504     if (aInOutMap.IsBound(aHole)){
505       const TopoDS_Shape& aSolid=aInOutMap(aHole);
506       if (aMSH.IsBound(aSolid)) {
507         TopTools_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
508         aLH.Append(aHole);
509       }
510       else {
511         TopTools_ListOfShape aLH;
512         aLH.Append(aHole);
513         aMSH.Bind(aSolid, aLH);
514       }
515       //aBB.Add (aSolid, aHole);
516     }
517   }// for (; aShellIt.More(); aShellIt.Next()) {
518   //
519   // 3. Add aHoles to Solids
520   aItMSH.Initialize(aMSH);
521   for (; aItMSH.More(); aItMSH.Next()) {
522     TopoDS_Solid aSolid=TopoDS::Solid(aItMSH.Key());
523     //
524     const TopTools_ListOfShape& aLH=aItMSH.Value();
525     aShellIt.Initialize(aLH);
526     for (; aShellIt.More(); aShellIt.Next()) {
527       const TopoDS_Shape& aHole = aShellIt.Value();
528       aBB.Add (aSolid, aHole);
529     }
530     //
531     // update classifier
532     BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid);
533     aSC.Load(aSolid);
534     //
535   }
536   //
537   // These aNewSolids are draft solids that 
538   // do not contain any internal shapes
539   //
540   myAreas.Append(aNewSolids);
541 }
542 //=======================================================================
543 //function : PerformInternalShapes
544 //purpose  : 
545 //=======================================================================
546   void GEOMAlgo_BuilderSolid::PerformInternalShapes()
547 {
548   myErrorStatus=0;
549   //
550   Standard_Integer aNbFI=myLoopsInternal.Extent();
551   if (!aNbFI) {// nothing to do
552     return;
553   }
554   // 
555   BRep_Builder aBB;
556   TopTools_ListIteratorOfListOfShape aShellIt, aSolidIt;
557   TopoDS_Iterator aIt; 
558   TopTools_MapOfShape aMF, aMFP;
559   TopTools_MapIteratorOfMapOfShape aItMF;
560   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
561   TopTools_ListOfShape aLSI;
562   //
563   // 1. All internal faces
564   aShellIt.Initialize(myLoopsInternal);
565   for (; aShellIt.More(); aShellIt.Next()) {
566     const TopoDS_Shape& aShell=aShellIt.Value();
567     aIt.Initialize(aShell);
568     for (; aIt.More(); aIt.Next()) {
569       const TopoDS_Shape& aF=aIt.Value();
570       aMF.Add(aF);
571     }
572   }
573   aNbFI=aMF.Extent();
574   //
575   // 2 Process solids
576   aSolidIt.Initialize(myAreas);
577   for ( ; aSolidIt.More(); aSolidIt.Next()) {
578     TopoDS_Solid& aSolid=TopoDS::Solid(aSolidIt.Value());
579     //
580     aMEF.Clear();
581     TopExp::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF);
582     //
583     // 2.1 Separate faces to process aMFP
584     aMFP.Clear();
585     aItMF.Initialize(aMF);
586     for (; aItMF.More(); aItMF.Next()) {
587       const TopoDS_Face& aF=TopoDS::Face(aItMF.Key());
588       if (GEOMAlgo_Tools3D::IsInternalFace(aF, aSolid, aMEF, 1.e-14, *myContext)) {
589         aMFP.Add(aF);
590       }
591     }
592     //
593     // 2.2 Make Internal Shells
594     aLSI.Clear();
595     MakeInternalShells(aMFP, aLSI);
596     //
597     // 2.3 Add them to aSolid
598     aShellIt.Initialize(aLSI);
599     for (; aShellIt.More(); aShellIt.Next()) {
600       const TopoDS_Shape& aSI=aShellIt.Value();
601       aBB.Add (aSolid, aSI);
602     }
603     //
604     // 2.4 Remove faces aMFP from aMF
605     aItMF.Initialize(aMFP);
606     for (; aItMF.More(); aItMF.Next()) {
607       const TopoDS_Shape& aF=aItMF.Key();
608       aMF.Remove(aF);
609     }
610     //
611     aNbFI=aMF.Extent();
612     if (!aNbFI) {
613       break;
614     }
615   } //for ( ; aSolidIt.More(); aSolidIt.Next()) {
616 }
617
618 //=======================================================================
619 //function : MakeInternalShells
620 //purpose  : 
621 //=======================================================================
622 void MakeInternalShells(const TopTools_MapOfShape& theMF,
623                         TopTools_ListOfShape& theShells)
624 {
625   TopTools_MapIteratorOfMapOfShape aItM;
626   TopTools_MapOfShape aAddedFacesMap;
627   TopTools_ListIteratorOfListOfShape aItF;
628   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
629   BRep_Builder aBB;
630   //
631   aItM.Initialize(theMF);
632   for (; aItM.More(); aItM.Next()) {
633     const TopoDS_Shape& aF=aItM.Key();
634     TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
635   }
636   //
637   aItM.Initialize(theMF);
638   for (; aItM.More(); aItM.Next()) {
639     TopoDS_Shape aFF=aItM.Key();
640     if (!aAddedFacesMap.Add(aFF)) {
641       continue;
642     }
643     //
644     // make a new shell
645     TopoDS_Shell aShell;
646     aBB.MakeShell(aShell);    
647     aFF.Orientation(TopAbs_INTERNAL);
648     aBB.Add(aShell, aFF);
649     //
650     TopoDS_Iterator aItAddedF (aShell);
651     for (; aItAddedF.More(); aItAddedF.Next()) {
652       const TopoDS_Shape& aF =aItAddedF.Value();
653       //
654       TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
655       for (; aEdgeExp.More(); aEdgeExp.Next()) {
656         const TopoDS_Shape& aE =aEdgeExp.Current();
657         const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE);
658         aItF.Initialize(aLF);
659         for (; aItF.More(); aItF.Next()) { 
660           TopoDS_Shape aFL=aItF.Value();
661           if (aAddedFacesMap.Add(aFL)){
662             aFL.Orientation(TopAbs_INTERNAL);
663             aBB.Add(aShell, aFL);
664           }
665         }
666       }
667     }
668     theShells.Append(aShell);
669   }
670 }
671 //=======================================================================
672 //function : IsHole
673 //purpose  : 
674 //=======================================================================
675 Standard_Boolean IsHole(const TopoDS_Shape& theS2,
676                         IntTools_PContext& theContext)
677 {
678   TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
679   BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
680   //
681   aClsf.PerformInfinitePoint(::RealSmall());
682   //
683   return (aClsf.State()==TopAbs_IN);
684 }
685 //=======================================================================
686 //function : IsInside
687 //purpose  : 
688 //=======================================================================
689 Standard_Boolean IsInside(const TopoDS_Shape& theS1,
690                           const TopoDS_Shape& theS2,
691                           IntTools_PContext& theContext)
692 {
693   TopExp_Explorer aExp;
694   TopAbs_State aState;
695   //
696   TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
697   //
698   aExp.Init(theS1, TopAbs_FACE);
699   if (!aExp.More()){
700     BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
701     aClsf.PerformInfinitePoint(::RealSmall());
702     aState=aClsf.State();
703   }
704   else {
705     TopTools_IndexedMapOfShape aBounds;
706     const TopoDS_Face& aF = TopoDS::Face(aExp.Current());
707     aState=GEOMAlgo_Tools3D::ComputeState(aF, *pS2, 1.e-14, aBounds, *theContext);
708   }
709   return (aState==TopAbs_IN);
710 }
711 //=======================================================================
712 //function : IsGrowthShell
713 //purpose  : 
714 //=======================================================================
715 Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
716                                const TopTools_IndexedMapOfShape& theMHF)
717 {
718   Standard_Boolean bRet;
719   TopoDS_Iterator aIt;
720   // 
721   bRet=Standard_False;
722   if (theMHF.Extent()) {
723     aIt.Initialize(theShell);
724     for(; aIt.More(); aIt.Next()) {
725       const TopoDS_Shape& aF=aIt.Value();
726       if (theMHF.Contains(aF)) {
727         return !bRet;
728       }
729     }
730   }
731   return bRet;
732 }
733
734 //BRepTools::Write(aFF, "ff");
735 //
736 //  ErrorStatus :
737 // 11 - Null Context