Salome HOME
Internal issue 0022865: Restructurization of Partition packages.
[modules/geom.git] / src / GEOMAlgo_NEW / 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.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     //modified by NIZNHY-PKV Wed Oct 27 07:10:41 2010f
394     else {
395       Standard_Boolean bRefine;
396       TopoDS_Shell aShx;
397       //
398       bRefine=RefineShell(aShell, aShx);
399       if (bRefine) {
400         myLoops.Append(aShx);
401       }
402     }
403     //modified by NIZNHY-PKV Wed Oct 27 07:10:44 2010t
404   } // for (; aItF.More(); aItF.Next()) { 
405   //
406   // Post Treatment
407   TopTools_MapOfOrientedShape aMP;
408   // 
409   // a. collect all edges that are in loops
410   aIt.Initialize (myLoops);
411   for (; aIt.More(); aIt.Next()) {
412     const TopoDS_Shape& aS=aIt.Value();
413     aItS.Initialize(aS);
414     for (; aItS.More(); aItS.Next()) {
415       const TopoDS_Shape& aF=aItS.Value();
416       aMP.Add(aF);
417     }
418   }
419   // 
420   // b. collect all faces that are to avoid
421   aItM.Initialize(myShapesToAvoid);
422   for (; aItM.More(); aItM.Next()) {
423     const TopoDS_Shape& aF=aItM.Key();
424     aMP.Add(aF);
425   }
426   //
427   // c. add all faces that are not processed to myShapesToAvoid
428   aIt.Initialize (myShapes);
429   for (; aIt.More(); aIt.Next()) {
430     const TopoDS_Shape& aF=aIt.Value();
431     if (!aMP.Contains(aF)) {
432       myShapesToAvoid.Add(aF);
433     }
434   }
435   //=================================================
436   //
437   // 2.Internal Shells
438   //
439   myLoopsInternal.Clear();
440   //
441   aEFMap.Clear();
442   AddedFacesMap.Clear();
443   //
444   if (myComputeInternalShapes) {
445     aItM.Initialize(myShapesToAvoid);
446     for (; aItM.More(); aItM.Next()) {
447       const TopoDS_Shape& aFF=aItM.Key();
448       TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
449     }
450     //
451     aItM.Initialize(myShapesToAvoid);
452     for (; aItM.More(); aItM.Next()) {
453       const TopoDS_Shape& aFF=aItM.Key();
454       if (!AddedFacesMap.Add(aFF)) {
455         continue;
456       }
457       //
458       // make a new shell
459       TopoDS_Shell aShell;
460       aBB.MakeShell(aShell);
461       aBB.Add(aShell, aFF);
462       //
463       TopoDS_Iterator aItAddedF (aShell);
464       for (; aItAddedF.More(); aItAddedF.Next()) {
465         const TopoDS_Face& aF = *((TopoDS_Face*)(&aItAddedF.Value()));
466         //
467         TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
468         for (; aEdgeExp.More(); aEdgeExp.Next()) {
469           const TopoDS_Edge& aE = *((TopoDS_Edge*)(&aEdgeExp.Current()));
470           const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE);
471           aItF.Initialize(aLF);
472           for (; aItF.More(); aItF.Next()) { 
473             const TopoDS_Face& aFL=*((TopoDS_Face*)(&aItF.Value()));
474             if (AddedFacesMap.Add(aFL)){
475               aBB.Add(aShell, aFL);
476             }
477           }
478         }
479       }
480       myLoopsInternal.Append(aShell);
481     }
482   }
483 }
484 //=======================================================================
485 //function : PerformAreas
486 //purpose  : 
487 //=======================================================================
488 void GEOMAlgo_BuilderSolid::PerformAreas()
489 {
490   myErrorStatus=0;
491   //
492   Standard_Boolean bIsGrowthShell, bIsHole;
493   TopTools_ListOfShape aNewSolids, aHoleShells; 
494   TopoDS_Shape anInfinitePointShape;
495   TopTools_DataMapOfShapeShape aInOutMap;
496   TopTools_DataMapOfShapeListOfShape aMSH;
497   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
498   TopTools_ListIteratorOfListOfShape aShellIt, aSolidIt;
499   TopTools_IndexedMapOfShape aMHF;
500   BRep_Builder aBB;
501   //
502   myAreas.Clear();
503   //
504   //  Draft solids [aNewSolids]
505   aShellIt.Initialize(myLoops);
506   for ( ; aShellIt.More(); aShellIt.Next()) {
507     const TopoDS_Shape& aShell = aShellIt.Value();
508     //
509     bIsGrowthShell=IsGrowthShell(aShell, aMHF);
510     if (bIsGrowthShell) {
511       // make a growth solid from a shell
512       TopoDS_Solid Solid;
513       aBB.MakeSolid(Solid);
514       aBB.Add (Solid, aShell);
515       //
516       aNewSolids.Append (Solid);
517     }
518     else{
519       // check if a shell is a hole
520       bIsHole=IsHole(aShell, myContext);
521       //
522       if (bIsHole) {
523         aHoleShells.Append(aShell);
524         TopExp::MapShapes(aShell, TopAbs_FACE, aMHF);
525       }
526       else {
527         // make a growth solid from a shell
528         TopoDS_Solid Solid;
529         aBB.MakeSolid(Solid);
530         aBB.Add (Solid, aShell);
531         //
532         aNewSolids.Append (Solid);
533       }
534     }
535   }
536   //
537   // 2. Find outer growth shell that is most close to each hole shell
538   aShellIt.Initialize(aHoleShells);
539   for (; aShellIt.More(); aShellIt.Next()) {
540     const TopoDS_Shape& aHole = aShellIt.Value();
541     //
542     aSolidIt.Initialize(aNewSolids);
543     for ( ; aSolidIt.More(); aSolidIt.Next())    {
544       const TopoDS_Shape& aSolid = aSolidIt.Value();
545       //
546       if (!IsInside(aHole, aSolid, myContext)){
547         continue;
548       }
549       //
550       if ( aInOutMap.IsBound (aHole)){
551         const TopoDS_Shape& aSolid2 = aInOutMap(aHole);
552         if (IsInside(aSolid, aSolid2, myContext)) {
553           aInOutMap.UnBind(aHole);
554           aInOutMap.Bind (aHole, aSolid);
555         }
556       }
557       else{
558         aInOutMap.Bind (aHole, aSolid);
559       }
560     }
561     //
562     // Add aHole to a map Solid/ListOfHoles [aMSH]
563     if (aInOutMap.IsBound(aHole)){
564       const TopoDS_Shape& aSolid=aInOutMap(aHole);
565       if (aMSH.IsBound(aSolid)) {
566         TopTools_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
567         aLH.Append(aHole);
568       }
569       else {
570         TopTools_ListOfShape aLH;
571         aLH.Append(aHole);
572         aMSH.Bind(aSolid, aLH);
573       }
574       //aBB.Add (aSolid, aHole);
575     }
576   }// for (; aShellIt.More(); aShellIt.Next()) {
577   //
578   // 3. Add aHoles to Solids
579   aItMSH.Initialize(aMSH);
580   for (; aItMSH.More(); aItMSH.Next()) {
581     TopoDS_Solid aSolid=*((TopoDS_Solid*)(&aItMSH.Key()));
582     //
583     const TopTools_ListOfShape& aLH=aItMSH.Value();
584     aShellIt.Initialize(aLH);
585     for (; aShellIt.More(); aShellIt.Next()) {
586       const TopoDS_Shape& aHole = aShellIt.Value();
587       aBB.Add (aSolid, aHole);
588     }
589     //
590     // update classifier
591     BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid);
592     aSC.Load(aSolid);
593     //
594   }
595   //
596   // These aNewSolids are draft solids that 
597   // do not contain any internal shapes
598   //
599   myAreas.Append(aNewSolids);
600 }
601 //=======================================================================
602 //function : PerformInternalShapes
603 //purpose  : 
604 //=======================================================================
605 void GEOMAlgo_BuilderSolid::PerformInternalShapes()
606 {
607   myErrorStatus=0;
608   //
609   Standard_Integer aNbFI=myLoopsInternal.Extent();
610   if (!aNbFI) {// nothing to do
611     return;
612   }
613   // 
614   BRep_Builder aBB;
615   TopTools_ListIteratorOfListOfShape aShellIt, aSolidIt;
616   TopoDS_Iterator aIt; 
617   TopTools_MapOfShape aMF, aMFP;
618   TopTools_MapIteratorOfMapOfShape aItMF;
619   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
620   TopTools_ListOfShape aLSI;
621   //
622   // 1. All internal faces
623   aShellIt.Initialize(myLoopsInternal);
624   for (; aShellIt.More(); aShellIt.Next()) {
625     const TopoDS_Shape& aShell=aShellIt.Value();
626     aIt.Initialize(aShell);
627     for (; aIt.More(); aIt.Next()) {
628       const TopoDS_Shape& aF=aIt.Value();
629       aMF.Add(aF);
630     }
631   }
632   aNbFI=aMF.Extent();
633   //
634   // 2 Process solids
635   aSolidIt.Initialize(myAreas);
636   for ( ; aSolidIt.More(); aSolidIt.Next()) {
637     TopoDS_Solid& aSolid=*((TopoDS_Solid*)(&aSolidIt.Value()));
638     //
639     aMEF.Clear();
640     TopExp::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF);
641     //
642     // 2.1 Separate faces to process aMFP
643     aMFP.Clear();
644     aItMF.Initialize(aMF);
645     for (; aItMF.More(); aItMF.Next()) {
646       const TopoDS_Face& aF=*((TopoDS_Face*)(&aItMF.Key()));
647       if (GEOMAlgo_Tools3D::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext)) {
648         aMFP.Add(aF);
649       }
650     }
651     //
652     // 2.2 Make Internal Shells
653     aLSI.Clear();
654     MakeInternalShells(aMFP, aLSI);
655     //
656     // 2.3 Add them to aSolid
657     aShellIt.Initialize(aLSI);
658     for (; aShellIt.More(); aShellIt.Next()) {
659       const TopoDS_Shape& aSI=aShellIt.Value();
660       aBB.Add (aSolid, aSI);
661     }
662     //
663     // 2.4 Remove faces aMFP from aMF
664     aItMF.Initialize(aMFP);
665     for (; aItMF.More(); aItMF.Next()) {
666       const TopoDS_Shape& aF=aItMF.Key();
667       aMF.Remove(aF);
668     }
669     //
670     aNbFI=aMF.Extent();
671     if (!aNbFI) {
672       break;
673     }
674   } //for ( ; aSolidIt.More(); aSolidIt.Next()) {
675 }
676
677 //=======================================================================
678 //function : MakeInternalShells
679 //purpose  : 
680 //=======================================================================
681 void MakeInternalShells(const TopTools_MapOfShape& theMF,
682                         TopTools_ListOfShape& theShells)
683 {
684   TopTools_MapIteratorOfMapOfShape aItM;
685   TopTools_MapOfShape aAddedFacesMap;
686   TopTools_ListIteratorOfListOfShape aItF;
687   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
688   BRep_Builder aBB;
689   //
690   aItM.Initialize(theMF);
691   for (; aItM.More(); aItM.Next()) {
692     const TopoDS_Shape& aF=aItM.Key();
693     TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
694   }
695   //
696   aItM.Initialize(theMF);
697   for (; aItM.More(); aItM.Next()) {
698     TopoDS_Shape aFF=aItM.Key();
699     if (!aAddedFacesMap.Add(aFF)) {
700       continue;
701     }
702     //
703     // make a new shell
704     TopoDS_Shell aShell;
705     aBB.MakeShell(aShell);    
706     aFF.Orientation(TopAbs_INTERNAL);
707     aBB.Add(aShell, aFF);
708     //
709     TopoDS_Iterator aItAddedF (aShell);
710     for (; aItAddedF.More(); aItAddedF.Next()) {
711       const TopoDS_Shape& aF =aItAddedF.Value();
712       //
713       TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
714       for (; aEdgeExp.More(); aEdgeExp.Next()) {
715         const TopoDS_Shape& aE =aEdgeExp.Current();
716         const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE);
717         aItF.Initialize(aLF);
718         for (; aItF.More(); aItF.Next()) { 
719           TopoDS_Shape aFL=aItF.Value();
720           if (aAddedFacesMap.Add(aFL)){
721             aFL.Orientation(TopAbs_INTERNAL);
722             aBB.Add(aShell, aFL);
723           }
724         }
725       }
726     }
727     theShells.Append(aShell);
728   }
729 }
730 //=======================================================================
731 //function : IsHole
732 //purpose  : 
733 //=======================================================================
734 Standard_Boolean IsHole(const TopoDS_Shape& theS2,
735                         const Handle(IntTools_Context)& theContext)
736 {
737   TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
738   BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
739   //
740   aClsf.PerformInfinitePoint(::RealSmall());
741   //
742   return (aClsf.State()==TopAbs_IN);
743 }
744 //=======================================================================
745 //function : IsInside
746 //purpose  : 
747 //=======================================================================
748 Standard_Boolean IsInside(const TopoDS_Shape& theS1,
749                           const TopoDS_Shape& theS2,
750                           const Handle(IntTools_Context)& theContext)
751 {
752   TopExp_Explorer aExp;
753   TopAbs_State aState;
754   //
755   TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
756   //
757   aExp.Init(theS1, TopAbs_FACE);
758   if (!aExp.More()){
759     BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
760     aClsf.PerformInfinitePoint(::RealSmall());
761     aState=aClsf.State();
762   }
763   else {
764     TopTools_IndexedMapOfShape aBounds;
765     const TopoDS_Face& aF = TopoDS::Face(aExp.Current());
766     aState=GEOMAlgo_Tools3D::ComputeState(aF, *pS2, 1.e-14, aBounds, theContext);
767   }
768   return (aState==TopAbs_IN);
769 }
770 //=======================================================================
771 //function : IsGrowthShell
772 //purpose  : 
773 //=======================================================================
774 Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
775                                const TopTools_IndexedMapOfShape& theMHF)
776 {
777   Standard_Boolean bRet;
778   TopoDS_Iterator aIt;
779   // 
780   bRet=Standard_False;
781   if (theMHF.Extent()) {
782     aIt.Initialize(theShell);
783     for(; aIt.More(); aIt.Next()) {
784       const TopoDS_Shape& aF=aIt.Value();
785       if (theMHF.Contains(aF)) {
786         return !bRet;
787       }
788     }
789   }
790   return bRet;
791 }
792 //=======================================================================
793 //function : IsClosedShell
794 //purpose  : 
795 //=======================================================================
796 Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
797 {
798   Standard_Integer aNbE;
799   Standard_Boolean bRet;
800   TopoDS_Iterator aIt;
801   TopExp_Explorer aExp;
802   TopTools_MapOfShape aM;
803   // 
804   bRet=Standard_False;
805   aIt.Initialize(theShell);
806   for(; aIt.More(); aIt.Next()) {
807     const TopoDS_Face& aF=TopoDS::Face(aIt.Value());
808     aExp.Init(aF, TopAbs_EDGE);
809     for (; aExp.More(); aExp.Next()) {
810       const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aExp.Current()));
811       if (BRep_Tool::Degenerated(aE)) {
812         continue;
813       }
814       //
815       if (aE.Orientation()==TopAbs_INTERNAL) {
816         continue;
817       }
818       //
819       if (!aM.Add(aE)) {
820         aM.Remove(aE);
821       }
822     }
823   }
824   //
825   aNbE=aM.Extent();
826   if (!aNbE) {
827     bRet=!bRet;
828   }
829   return bRet;
830 }
831 //=======================================================================
832 //function : RefineShell
833 //purpose  :
834 //=======================================================================
835   Standard_Boolean RefineShell(const TopoDS_Shell& aShell,
836                                TopoDS_Shell& aShx)
837                                
838 {
839   Standard_Boolean bRet;
840   Standard_Integer i, aNbE, aNbF;
841   TopAbs_Orientation aOrE;
842   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
843   TopTools_MapOfOrientedShape aMFx;
844   // 
845   bRet=Standard_False;
846   //
847   TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
848   aNbE=aMEF.Extent();
849   for (i=1; i<=aNbE; ++i) {
850     const TopoDS_Edge &aE=*((TopoDS_Edge*)(&aMEF.FindKey(i)));
851     //
852     if (BRep_Tool::Degenerated(aE)) {
853       continue;
854     }
855     //
856     aOrE=aE.Orientation();
857     //
858     const TopTools_ListOfShape& aLF=aMEF(i);
859     aNbF=aLF.Extent();
860     if (!aNbF) {
861       continue;
862     }
863     //
864     const TopoDS_Face& aF1=*((TopoDS_Face*)(&aLF.First()));
865     if (aNbF==1) {
866       if (aOrE==TopAbs_INTERNAL) {
867         continue;
868       }
869       aMFx.Add(aF1);
870     }
871     //
872     else if (aNbF==2) {
873       const TopoDS_Face& aF2=*((TopoDS_Face*)(&aLF.Last()));
874       if (aF2.IsSame(aF1)) {
875         if (BRep_Tool::IsClosed(aE, aF1)) {
876           continue;
877         }
878         if (aOrE==TopAbs_INTERNAL) {
879           continue;
880         }
881         aMFx.Add(aF1);
882         aMFx.Add(aF2);
883       }
884     }
885   }
886   //
887   aNbF=aMFx.Extent();
888   if (!aNbF) {
889     return bRet;
890   } 
891   //
892   BRep_Builder aBB;
893   TopoDS_Iterator aIt;
894   //
895   aNbF=0;
896   aBB.MakeShell(aShx);
897   aIt.Initialize(aShell);
898   for (; aIt.More(); aIt.Next()) {
899     const TopoDS_Shape& aF=aIt.Value();
900     if (!aMFx.Contains(aF)) {
901       aBB.Add(aShx, aF);
902       ++aNbF;
903     }
904   }
905   //
906   if (aNbF) {
907     bRet=IsClosedShell(aShx);
908   }
909   //
910   return bRet;
911 }
912 //
913 //  ErrorStatus :
914 // 11 - Null Context