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