Salome HOME
Fix regression: storeViewParameters() does not work for OCC view
[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 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   PerformInternalShapes();
163   if (myErrorStatus) {
164     return;
165   }
166 }
167 //=======================================================================
168 //function :PerformShapesToAvoid
169 //purpose  : 
170 //=======================================================================
171   void GEOMAlgo_BuilderSolid::PerformShapesToAvoid()
172 {
173   Standard_Boolean bFound;
174   Standard_Integer i, iCnt, aNbE, aNbF;
175   TopAbs_Orientation aOrE;
176   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
177   TopTools_ListIteratorOfListOfShape aIt;
178   //
179   myShapesToAvoid.Clear();
180   //
181   iCnt=0;
182   while (1) {
183     ++iCnt;
184     bFound=Standard_False;
185     //
186     // 1. MEF
187     aMEF.Clear();
188     aIt.Initialize (myShapes);
189     for (; aIt.More(); aIt.Next()) {
190       const TopoDS_Shape& aF=aIt.Value();
191       if (!myShapesToAvoid.Contains(aF)) {
192         TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
193       }
194       /*
195       else { 
196         int a=0; 
197       }
198       */
199     }
200     aNbE=aMEF.Extent();
201     //
202     // 2. myFacesToAvoid
203     for (i=1; i<=aNbE; ++i) {
204       const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aMEF.FindKey(i)));
205       if (BRep_Tool::Degenerated(aE)) {
206         continue;
207       }
208       //
209       TopTools_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
210       //
211       aNbF=aLF.Extent();
212       if (!aNbF) {
213         continue;
214       }
215       //
216       aOrE=aE.Orientation();
217       //
218       const TopoDS_Face& aF1=*((TopoDS_Face*)(&aLF.First()));
219       if (aNbF==1) {
220         if (aOrE==TopAbs_INTERNAL) {
221           continue;
222         }
223         bFound=Standard_True;
224         myShapesToAvoid.Add(aF1);
225       }
226       else if (aNbF==2) {
227         const TopoDS_Face& aF2=*((TopoDS_Face*)(&aLF.Last()));
228         if (aF2.IsSame(aF1)) {
229           if (BRep_Tool::IsClosed(aE, aF1)) {
230             continue;
231           }
232           //
233           if (aOrE==TopAbs_INTERNAL) {
234             continue;
235           }
236           //
237           bFound=Standard_True;
238           myShapesToAvoid.Add(aF1);
239           myShapesToAvoid.Add(aF2);
240         }
241       }
242       /*//DEB          
243       else {
244         TopTools_ListIteratorOfListOfShape aItLF;
245         //
246         aItLF.Initialize (aLF);
247         for (; aItLF.More(); aItLF.Next()) {
248           const TopoDS_Shape& aFx=aItLF.Value();
249           int a=0;
250         }
251       }
252       *///DEB
253     }// for (i=1; i<=aNbE; ++i) {
254     //
255     if (!bFound) {
256       break;
257     }
258     //
259   }//while (1) 
260 }  
261 //=======================================================================
262 //function : PerformLoops
263 //purpose  : 
264 //=======================================================================
265   void GEOMAlgo_BuilderSolid::PerformLoops()
266 {
267   myErrorStatus=0;
268   //
269   myLoops.Clear();
270   //
271   Standard_Integer aNbLF, aNbOff, aNbFP;
272   TopAbs_Orientation anOr;
273   TopoDS_Edge aEL;
274   BRep_Builder aBB;
275   NMTTools_CoupleOfShape aCSOff;
276   TopTools_MapOfOrientedShape AddedFacesMap;
277   TopTools_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
278   TopTools_ListIteratorOfListOfShape aItF, aIt;
279   TopTools_MapIteratorOfMapOfOrientedShape aItM;
280   TopoDS_Iterator aItS;
281   //
282   //=================================================
283   //
284   // 1. Shells Usual
285   //
286   aItF.Initialize (myShapes);
287   for (; aItF.More(); aItF.Next()) {
288     const TopoDS_Shape& aFF = aItF.Value();
289     TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
290   }
291   //
292   aItF.Initialize (myShapes);
293   for (; aItF.More(); aItF.Next()) {
294     const TopoDS_Shape& aFF = aItF.Value();
295     if (myShapesToAvoid.Contains(aFF)) {
296       continue;
297     }
298     if (!AddedFacesMap.Add(aFF)) {
299       continue;
300     }
301     //
302     // make a new shell
303     TopoDS_Shell aShell;
304     aBB.MakeShell(aShell);
305     aBB.Add(aShell, aFF);
306     //
307     aMEFP.Clear();
308     TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
309     //
310     // loop on faces added to Shell; add their neighbor faces to Shell and so on
311     TopoDS_Iterator aItAddedF (aShell);
312     for (; aItAddedF.More(); aItAddedF.Next()) {
313       const TopoDS_Face& aF = *((TopoDS_Face*)(&aItAddedF.Value()));
314       //
315       // loop on edges of aF; find a good neighbor face of aF by aE
316       TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
317       for (; aEdgeExp.More(); aEdgeExp.Next()) {
318         const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aEdgeExp.Current()));
319         //
320         //1
321         if (aMEFP.Contains(aE)) {
322           const TopTools_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
323           aNbFP=aLFP.Extent();
324           if (aNbFP>1) { 
325             continue;
326           }
327         }
328         //2
329         anOr=aE.Orientation();
330         if (anOr==TopAbs_INTERNAL) {
331           continue;
332         }
333         //3
334         if (BRep_Tool::Degenerated(aE)) {
335           continue;
336         }
337         //
338         // candidate faces list
339         const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE);
340         aNbLF=aLF.Extent();
341         if (!aNbLF) {
342           continue;
343         }
344         //
345         // try to select one of neighbors
346         // check if a face already added to Shell shares E
347         Standard_Boolean bFound;
348         TopTools_ListIteratorOfListOfShape aItLF;
349         NMTTools_ListOfCoupleOfShape aLCSOff;
350         //
351         aItLF.Initialize(aLF);
352         for (; aItLF.More(); aItLF.Next()) { 
353           const TopoDS_Face& aFL=*((TopoDS_Face*)(&aItLF.Value()));
354           if (myShapesToAvoid.Contains(aFL)) {
355             continue;
356           }
357           if (aF.IsSame(aFL)) {
358             continue;
359           } 
360           if (AddedFacesMap.Contains(aFL)){
361             continue;
362           }
363           //
364           bFound=GEOMAlgo_Tools3D::GetEdgeOff(aE, aFL, aEL);
365           if (!bFound) {
366             continue;
367           }
368           //
369           aCSOff.SetShape1(aEL);
370           aCSOff.SetShape2(aFL);
371           aLCSOff.Append(aCSOff);
372         }//for (; aItLF.More(); aItLF.Next()) { 
373         //
374         aNbOff=aLCSOff.Extent();
375         if (!aNbOff){
376           continue;
377         }
378         //
379         TopoDS_Face aSelF;
380         if (aNbOff==1) {
381           aSelF=*((TopoDS_Face*)(&aLCSOff.First().Shape2()));
382         }
383         else if (aNbOff>1){
384           GEOMAlgo_Tools3D::GetFaceOff(aE, aF, aLCSOff, aSelF);
385         }
386         //
387         if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) { 
388           aBB.Add(aShell, aSelF);
389           TopExp::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
390         }
391       } // for (; aEdgeExp.More(); aEdgeExp.Next()) { 
392     } //for (; aItAddedF.More(); aItAddedF.Next()) {
393     //
394     if (IsClosedShell(aShell)) {
395       myLoops.Append(aShell);
396     }
397     //modified by NIZNHY-PKV Wed Oct 27 07:10:41 2010f
398     else {
399       Standard_Boolean bRefine;
400       TopoDS_Shell aShx;
401       //
402       bRefine=RefineShell(aShell, aShx);
403       if (bRefine) {
404         myLoops.Append(aShx);
405       }
406     }
407     //modified by NIZNHY-PKV Wed Oct 27 07:10:44 2010t
408   } // for (; aItF.More(); aItF.Next()) { 
409   //
410   // Post Treatment
411   TopTools_MapOfOrientedShape aMP;
412   // 
413   // a. collect all edges that are in loops
414   aIt.Initialize (myLoops);
415   for (; aIt.More(); aIt.Next()) {
416     const TopoDS_Shape& aS=aIt.Value();
417     aItS.Initialize(aS);
418     for (; aItS.More(); aItS.Next()) {
419       const TopoDS_Shape& aF=aItS.Value();
420       aMP.Add(aF);
421     }
422   }
423   // 
424   // b. collect all faces that are to avoid
425   aItM.Initialize(myShapesToAvoid);
426   for (; aItM.More(); aItM.Next()) {
427     const TopoDS_Shape& aF=aItM.Key();
428     aMP.Add(aF);
429   }
430   //
431   // c. add all faces that are not processed to myShapesToAvoid
432   aIt.Initialize (myShapes);
433   for (; aIt.More(); aIt.Next()) {
434     const TopoDS_Shape& aF=aIt.Value();
435     if (!aMP.Contains(aF)) {
436       myShapesToAvoid.Add(aF);
437     }
438   }
439   //=================================================
440   //
441   // 2.Internal Shells
442   //
443   myLoopsInternal.Clear();
444   //
445   aEFMap.Clear();
446   AddedFacesMap.Clear();
447   //
448   aItM.Initialize(myShapesToAvoid);
449   for (; aItM.More(); aItM.Next()) {
450     const TopoDS_Shape& aFF=aItM.Key();
451     TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
452   }
453   //
454   aItM.Initialize(myShapesToAvoid);
455   for (; aItM.More(); aItM.Next()) {
456     const TopoDS_Shape& aFF=aItM.Key();
457     if (!AddedFacesMap.Add(aFF)) {
458       continue;
459     }
460     //
461     // make a new shell
462     TopoDS_Shell aShell;
463     aBB.MakeShell(aShell);
464     aBB.Add(aShell, aFF);
465     //
466     TopoDS_Iterator aItAddedF (aShell);
467     for (; aItAddedF.More(); aItAddedF.Next()) {
468       const TopoDS_Face& aF = *((TopoDS_Face*)(&aItAddedF.Value()));
469       //
470       TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
471       for (; aEdgeExp.More(); aEdgeExp.Next()) {
472         const TopoDS_Edge& aE = *((TopoDS_Edge*)(&aEdgeExp.Current()));
473         const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE);
474         aItF.Initialize(aLF);
475         for (; aItF.More(); aItF.Next()) { 
476           const TopoDS_Face& aFL=*((TopoDS_Face*)(&aItF.Value()));
477           if (AddedFacesMap.Add(aFL)){
478             aBB.Add(aShell, aFL);
479           }
480         }
481       }
482     }
483     myLoopsInternal.Append(aShell);
484   }
485 }
486 //=======================================================================
487 //function : PerformAreas
488 //purpose  : 
489 //=======================================================================
490   void GEOMAlgo_BuilderSolid::PerformAreas()
491 {
492   myErrorStatus=0;
493   //
494   Standard_Boolean bIsGrowthShell, bIsHole;
495   TopTools_ListOfShape aNewSolids, aHoleShells; 
496   TopoDS_Shape anInfinitePointShape;
497   TopTools_DataMapOfShapeShape aInOutMap;
498   TopTools_DataMapOfShapeListOfShape aMSH;
499   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
500   TopTools_ListIteratorOfListOfShape aShellIt, aSolidIt;
501   TopTools_IndexedMapOfShape aMHF;
502   BRep_Builder aBB;
503   //
504   myAreas.Clear();
505   //
506   //  Draft solids [aNewSolids]
507   aShellIt.Initialize(myLoops);
508   for ( ; aShellIt.More(); aShellIt.Next()) {
509     const TopoDS_Shape& aShell = aShellIt.Value();
510     //
511     bIsGrowthShell=IsGrowthShell(aShell, aMHF);
512     if (bIsGrowthShell) {
513       // make a growth solid from a shell
514       TopoDS_Solid Solid;
515       aBB.MakeSolid(Solid);
516       aBB.Add (Solid, aShell);
517       //
518       aNewSolids.Append (Solid);
519     }
520     else{
521       // check if a shell is a hole
522       bIsHole=IsHole(aShell, myContext);
523       //
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 //=======================================================================
795 //function : IsClosedShell
796 //purpose  : 
797 //=======================================================================
798 Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
799 {
800   Standard_Integer aNbE;
801   Standard_Boolean bRet;
802   TopoDS_Iterator aIt;
803   TopExp_Explorer aExp;
804   TopTools_MapOfShape aM;
805   // 
806   bRet=Standard_False;
807   aIt.Initialize(theShell);
808   for(; aIt.More(); aIt.Next()) {
809     const TopoDS_Face& aF=TopoDS::Face(aIt.Value());
810     aExp.Init(aF, TopAbs_EDGE);
811     for (; aExp.More(); aExp.Next()) {
812       const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aExp.Current()));
813       if (BRep_Tool::Degenerated(aE)) {
814         continue;
815       }
816       //
817       if (aE.Orientation()==TopAbs_INTERNAL) {
818         continue;
819       }
820       //
821       if (!aM.Add(aE)) {
822         aM.Remove(aE);
823       }
824     }
825   }
826   //
827   aNbE=aM.Extent();
828   if (!aNbE) {
829     bRet=!bRet;
830   }
831   return bRet;
832 }
833 //modified by NIZNHY-PKV Tue Oct 26 13:30:23 2010f
834 //=======================================================================
835 //function : RefineShell
836 //purpose  :
837 //=======================================================================
838   Standard_Boolean RefineShell(const TopoDS_Shell& aShell,
839                                TopoDS_Shell& aShx)
840                                
841 {
842   Standard_Boolean bRet;
843   Standard_Integer i, aNbE, aNbF;
844   TopAbs_Orientation aOrE;
845   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
846   TopTools_MapOfOrientedShape aMFx;
847   // 
848   bRet=Standard_False;
849   //
850   TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
851   aNbE=aMEF.Extent();
852   for (i=1; i<=aNbE; ++i) {
853     const TopoDS_Edge &aE=*((TopoDS_Edge*)(&aMEF.FindKey(i)));
854     //
855     if (BRep_Tool::Degenerated(aE)) {
856       continue;
857     }
858     //
859     aOrE=aE.Orientation();
860     //
861     const TopTools_ListOfShape& aLF=aMEF(i);
862     aNbF=aLF.Extent();
863     if (!aNbF) {
864       continue;
865     }
866     //
867     const TopoDS_Face& aF1=*((TopoDS_Face*)(&aLF.First()));
868     if (aNbF==1) {
869       if (aOrE==TopAbs_INTERNAL) {
870         continue;
871       }
872       aMFx.Add(aF1);
873     }
874     //
875     else if (aNbF==2) {
876       const TopoDS_Face& aF2=*((TopoDS_Face*)(&aLF.Last()));
877       if (aF2.IsSame(aF1)) {
878         if (BRep_Tool::IsClosed(aE, aF1)) {
879           continue;
880         }
881         if (aOrE==TopAbs_INTERNAL) {
882           continue;
883         }
884         aMFx.Add(aF1);
885         aMFx.Add(aF2);
886       }
887     }
888   }
889   //
890   aNbF=aMFx.Extent();
891   if (!aNbF) {
892     return bRet;
893   } 
894   //
895   BRep_Builder aBB;
896   TopoDS_Iterator aIt;
897   //
898   aNbF=0;
899   aBB.MakeShell(aShx);
900   aIt.Initialize(aShell);
901   for (; aIt.More(); aIt.Next()) {
902     const TopoDS_Shape& aF=aIt.Value();
903     if (!aMFx.Contains(aF)) {
904       aBB.Add(aShx, aF);
905       ++aNbF;
906     }
907   }
908   //
909   if (aNbF) {
910     bRet=IsClosedShell(aShx);
911   }
912   //
913   return bRet;
914 }
915 //modified by NIZNHY-PKV Tue Oct 26 13:30:26 2010t
916 //
917 //  ErrorStatus :
918 // 11 - Null Context