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