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