Back to index

salome-geom  6.5.0
GEOMAlgo_BuilderSolid.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 // File:        GEOMAlgo_BuilderSolid.cxx
00024 // Created:
00025 // Author:      Peter KURNEV
00026 //
00027 #include <GEOMAlgo_BuilderSolid.hxx>
00028 
00029 #include <gp_Pnt2d.hxx>
00030 #include <gp_Pln.hxx>
00031 #include <gp_Vec.hxx>
00032 #include <gp_Dir.hxx>
00033 #include <gp_Pnt.hxx>
00034 
00035 #include <Geom_Curve.hxx>
00036 #include <Geom_Surface.hxx>
00037 #include <Geom2d_Curve.hxx>
00038 
00039 #include <TopAbs.hxx>
00040 
00041 #include <TopoDS_Iterator.hxx>
00042 #include <TopoDS_Face.hxx>
00043 #include <TopoDS.hxx>
00044 #include <TopoDS_Shape.hxx>
00045 #include <TopoDS_Shell.hxx>
00046 #include <TopoDS_Edge.hxx>
00047 #include <TopoDS_Solid.hxx>
00048 #include <TopoDS_Vertex.hxx>
00049 #include <TopoDS_Compound.hxx>
00050 
00051 #include <BRep_Builder.hxx>
00052 #include <BRep_Tool.hxx>
00053 #include <BRepTools.hxx>
00054 #include <BRepClass3d_SolidClassifier.hxx>
00055 
00056 #include <TopExp.hxx>
00057 #include <TopExp_Explorer.hxx>
00058 
00059 #include <TopTools_MapOfShape.hxx>
00060 #include <TopTools_MapIteratorOfMapOfShape.hxx>
00061 #include <TopTools_MapOfOrientedShape.hxx>
00062 #include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
00063 #include <TopTools_ListOfShape.hxx>
00064 #include <TopTools_ListIteratorOfListOfShape.hxx>
00065 #include <TopTools_DataMapOfShapeShape.hxx>
00066 #include <TopTools_IndexedMapOfShape.hxx>
00067 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
00068 #include <TopTools_DataMapOfShapeListOfShape.hxx>
00069 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
00070 
00071 #include <IntTools_Context.hxx>
00072 
00073 #include <BOPTools_Tools2D.hxx>
00074 #include <BOPTools_Tools3D.hxx>
00075 
00076 #include <NMTTools_ListOfCoupleOfShape.hxx>
00077 #include <NMTTools_CoupleOfShape.hxx>
00078 #include <NMTTools_ListIteratorOfListOfCoupleOfShape.hxx>
00079 
00080 #include <GEOMAlgo_Tools3D.hxx>
00081 #include <GEOMAlgo_BuilderTools.hxx>
00082 
00083 //
00084 static
00085   Standard_Boolean IsGrowthShell(const TopoDS_Shape& ,
00086                                  const TopTools_IndexedMapOfShape& );
00087 static
00088   Standard_Boolean IsHole(const TopoDS_Shape& ,
00089                           const Handle(IntTools_Context)& );
00090 static
00091   Standard_Boolean IsInside(const TopoDS_Shape& ,
00092                             const TopoDS_Shape& ,
00093                             const Handle(IntTools_Context)& );
00094 static
00095   void MakeInternalShells(const TopTools_MapOfShape& ,
00096                           TopTools_ListOfShape& );
00097 
00098 static
00099   Standard_Boolean IsClosedShell(const TopoDS_Shell& );
00100 
00101 static
00102   Standard_Boolean RefineShell(const TopoDS_Shell& ,
00103                             TopoDS_Shell& );
00104 
00105 //=======================================================================
00106 //function :
00107 //purpose  :
00108 //=======================================================================
00109 GEOMAlgo_BuilderSolid::GEOMAlgo_BuilderSolid()
00110 :
00111   GEOMAlgo_BuilderArea()
00112 {
00113 }
00114 //=======================================================================
00115 //function : ~
00116 //purpose  :
00117 //=======================================================================
00118 GEOMAlgo_BuilderSolid::~GEOMAlgo_BuilderSolid()
00119 {
00120 }
00121 //=======================================================================
00122 //function : Perform
00123 //purpose  :
00124 //=======================================================================
00125 void GEOMAlgo_BuilderSolid::Perform()
00126 {
00127   myErrorStatus=0;
00128   //
00129   // Initialize the context
00130   GEOMAlgo_BuilderArea::Perform();
00131   //
00132   TopoDS_Compound aC;
00133   BRep_Builder aBB;
00134   TopTools_ListIteratorOfListOfShape aIt;
00135 
00136   aBB.MakeCompound(aC);
00137   aIt.Initialize(myShapes);
00138   for(; aIt.More(); aIt.Next()) {
00139     const TopoDS_Shape& aF=aIt.Value();
00140     aBB.Add(aC, aF);
00141   }
00142   //
00143   PerformShapesToAvoid();
00144   if (myErrorStatus) {
00145     return;
00146   }
00147   //
00148   PerformLoops();
00149   if (myErrorStatus) {
00150     return;
00151   }
00152   PerformAreas();
00153   if (myErrorStatus) {
00154     return;
00155   }
00156   if (myComputeInternalShapes) {
00157     PerformInternalShapes();
00158     if (myErrorStatus) {
00159       return;
00160     }
00161   }
00162 }
00163 //=======================================================================
00164 //function :PerformShapesToAvoid
00165 //purpose  :
00166 //=======================================================================
00167 void GEOMAlgo_BuilderSolid::PerformShapesToAvoid()
00168 {
00169   Standard_Boolean bFound;
00170   Standard_Integer i, iCnt, aNbE, aNbF;
00171   TopAbs_Orientation aOrE;
00172   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
00173   TopTools_ListIteratorOfListOfShape aIt;
00174   //
00175   myShapesToAvoid.Clear();
00176   //
00177   iCnt=0;
00178   while (1) {
00179     ++iCnt;
00180     bFound=Standard_False;
00181     //
00182     // 1. MEF
00183     aMEF.Clear();
00184     aIt.Initialize (myShapes);
00185     for (; aIt.More(); aIt.Next()) {
00186       const TopoDS_Shape& aF=aIt.Value();
00187       if (!myShapesToAvoid.Contains(aF)) {
00188         TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
00189       }
00190       /*
00191       else {
00192        int a=0;
00193       }
00194       */
00195     }
00196     aNbE=aMEF.Extent();
00197     //
00198     // 2. myFacesToAvoid
00199     for (i=1; i<=aNbE; ++i) {
00200       const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aMEF.FindKey(i)));
00201       if (BRep_Tool::Degenerated(aE)) {
00202         continue;
00203       }
00204       //
00205       TopTools_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
00206       //
00207       aNbF=aLF.Extent();
00208       if (!aNbF) {
00209         continue;
00210       }
00211       //
00212       aOrE=aE.Orientation();
00213       //
00214       const TopoDS_Face& aF1=*((TopoDS_Face*)(&aLF.First()));
00215       if (aNbF==1) {
00216         if (aOrE==TopAbs_INTERNAL) {
00217           continue;
00218         }
00219         bFound=Standard_True;
00220         myShapesToAvoid.Add(aF1);
00221       }
00222       else if (aNbF==2) {
00223         const TopoDS_Face& aF2=*((TopoDS_Face*)(&aLF.Last()));
00224         if (aF2.IsSame(aF1)) {
00225           if (BRep_Tool::IsClosed(aE, aF1)) {
00226             continue;
00227           }
00228           //
00229           if (aOrE==TopAbs_INTERNAL) {
00230             continue;
00231           }
00232           //
00233           bFound=Standard_True;
00234           myShapesToAvoid.Add(aF1);
00235           myShapesToAvoid.Add(aF2);
00236         }
00237       }
00238       /*//DEB
00239       else {
00240         TopTools_ListIteratorOfListOfShape aItLF;
00241         //
00242         aItLF.Initialize (aLF);
00243         for (; aItLF.More(); aItLF.Next()) {
00244           const TopoDS_Shape& aFx=aItLF.Value();
00245           int a=0;
00246         }
00247       }
00248       *///DEB
00249     }// for (i=1; i<=aNbE; ++i) {
00250     //
00251     if (!bFound) {
00252       break;
00253     }
00254     //
00255   }//while (1)
00256 }
00257 //=======================================================================
00258 //function : PerformLoops
00259 //purpose  :
00260 //=======================================================================
00261 void GEOMAlgo_BuilderSolid::PerformLoops()
00262 {
00263   myErrorStatus=0;
00264   //
00265   myLoops.Clear();
00266   //
00267   Standard_Integer aNbLF, aNbOff, aNbFP;
00268   TopAbs_Orientation anOr;
00269   TopoDS_Edge aEL;
00270   BRep_Builder aBB;
00271   NMTTools_CoupleOfShape aCSOff;
00272   TopTools_MapOfOrientedShape AddedFacesMap;
00273   TopTools_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
00274   TopTools_ListIteratorOfListOfShape aItF, aIt;
00275   TopTools_MapIteratorOfMapOfOrientedShape aItM;
00276   TopoDS_Iterator aItS;
00277   //
00278   //=================================================
00279   //
00280   // 1. Shells Usual
00281   //
00282   aItF.Initialize (myShapes);
00283   for (; aItF.More(); aItF.Next()) {
00284     const TopoDS_Shape& aFF = aItF.Value();
00285     TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
00286   }
00287   //
00288   aItF.Initialize (myShapes);
00289   for (; aItF.More(); aItF.Next()) {
00290     const TopoDS_Shape& aFF = aItF.Value();
00291     if (myShapesToAvoid.Contains(aFF)) {
00292       continue;
00293     }
00294     if (!AddedFacesMap.Add(aFF)) {
00295       continue;
00296     }
00297     //
00298     // make a new shell
00299     TopoDS_Shell aShell;
00300     aBB.MakeShell(aShell);
00301     aBB.Add(aShell, aFF);
00302     //
00303     aMEFP.Clear();
00304     TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
00305     //
00306     // loop on faces added to Shell; add their neighbor faces to Shell and so on
00307     TopoDS_Iterator aItAddedF (aShell);
00308     for (; aItAddedF.More(); aItAddedF.Next()) {
00309       const TopoDS_Face& aF = *((TopoDS_Face*)(&aItAddedF.Value()));
00310       //
00311       // loop on edges of aF; find a good neighbor face of aF by aE
00312       TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
00313       for (; aEdgeExp.More(); aEdgeExp.Next()) {
00314         const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aEdgeExp.Current()));
00315         //
00316         //1
00317         if (aMEFP.Contains(aE)) {
00318           const TopTools_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
00319           aNbFP=aLFP.Extent();
00320           if (aNbFP>1) {
00321             continue;
00322           }
00323         }
00324         //2
00325         anOr=aE.Orientation();
00326         if (anOr==TopAbs_INTERNAL) {
00327           continue;
00328         }
00329         //3
00330         if (BRep_Tool::Degenerated(aE)) {
00331           continue;
00332         }
00333         //
00334         // candidate faces list
00335         const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE);
00336         aNbLF=aLF.Extent();
00337         if (!aNbLF) {
00338           continue;
00339         }
00340         //
00341         // try to select one of neighbors
00342         // check if a face already added to Shell shares E
00343         Standard_Boolean bFound;
00344         TopTools_ListIteratorOfListOfShape aItLF;
00345         NMTTools_ListOfCoupleOfShape aLCSOff;
00346         //
00347         aItLF.Initialize(aLF);
00348         for (; aItLF.More(); aItLF.Next()) {
00349           const TopoDS_Face& aFL=*((TopoDS_Face*)(&aItLF.Value()));
00350           if (myShapesToAvoid.Contains(aFL)) {
00351             continue;
00352           }
00353           if (aF.IsSame(aFL)) {
00354             continue;
00355           }
00356           if (AddedFacesMap.Contains(aFL)){
00357             continue;
00358           }
00359           //
00360           bFound=GEOMAlgo_Tools3D::GetEdgeOff(aE, aFL, aEL);
00361           if (!bFound) {
00362             continue;
00363           }
00364           //
00365           aCSOff.SetShape1(aEL);
00366           aCSOff.SetShape2(aFL);
00367           aLCSOff.Append(aCSOff);
00368         }//for (; aItLF.More(); aItLF.Next()) {
00369         //
00370         aNbOff=aLCSOff.Extent();
00371         if (!aNbOff){
00372           continue;
00373         }
00374         //
00375         TopoDS_Face aSelF;
00376         if (aNbOff==1) {
00377           aSelF=*((TopoDS_Face*)(&aLCSOff.First().Shape2()));
00378         }
00379         else if (aNbOff>1){
00380           GEOMAlgo_Tools3D::GetFaceOff(aE, aF, aLCSOff, aSelF);
00381         }
00382         //
00383         if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
00384           aBB.Add(aShell, aSelF);
00385           TopExp::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
00386         }
00387       } // for (; aEdgeExp.More(); aEdgeExp.Next()) {
00388     } //for (; aItAddedF.More(); aItAddedF.Next()) {
00389     //
00390     if (IsClosedShell(aShell)) {
00391       myLoops.Append(aShell);
00392     }
00393     else {
00394       Standard_Boolean bRefine;
00395       TopoDS_Shell aShx;
00396       //
00397       bRefine=RefineShell(aShell, aShx);
00398       if (bRefine) {
00399        myLoops.Append(aShx);
00400       }
00401     }
00402   } // for (; aItF.More(); aItF.Next()) {
00403   //
00404   // Post Treatment
00405   TopTools_MapOfOrientedShape aMP;
00406   //
00407   // a. collect all edges that are in loops
00408   aIt.Initialize (myLoops);
00409   for (; aIt.More(); aIt.Next()) {
00410     const TopoDS_Shape& aS=aIt.Value();
00411     aItS.Initialize(aS);
00412     for (; aItS.More(); aItS.Next()) {
00413       const TopoDS_Shape& aF=aItS.Value();
00414       aMP.Add(aF);
00415     }
00416   }
00417   //
00418   // b. collect all faces that are to avoid
00419   aItM.Initialize(myShapesToAvoid);
00420   for (; aItM.More(); aItM.Next()) {
00421     const TopoDS_Shape& aF=aItM.Key();
00422     aMP.Add(aF);
00423   }
00424   //
00425   // c. add all faces that are not processed to myShapesToAvoid
00426   aIt.Initialize (myShapes);
00427   for (; aIt.More(); aIt.Next()) {
00428     const TopoDS_Shape& aF=aIt.Value();
00429     if (!aMP.Contains(aF)) {
00430       myShapesToAvoid.Add(aF);
00431     }
00432   }
00433   //=================================================
00434   //
00435   // 2.Internal Shells
00436   //
00437   myLoopsInternal.Clear();
00438   //
00439   aEFMap.Clear();
00440   AddedFacesMap.Clear();
00441   //
00442   if (myComputeInternalShapes) {
00443     aItM.Initialize(myShapesToAvoid);
00444     for (; aItM.More(); aItM.Next()) {
00445       const TopoDS_Shape& aFF=aItM.Key();
00446       TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
00447     }
00448     //
00449     aItM.Initialize(myShapesToAvoid);
00450     for (; aItM.More(); aItM.Next()) {
00451       const TopoDS_Shape& aFF=aItM.Key();
00452       if (!AddedFacesMap.Add(aFF)) {
00453         continue;
00454       }
00455       //
00456       // make a new shell
00457       TopoDS_Shell aShell;
00458       aBB.MakeShell(aShell);
00459       aBB.Add(aShell, aFF);
00460       //
00461       TopoDS_Iterator aItAddedF (aShell);
00462       for (; aItAddedF.More(); aItAddedF.Next()) {
00463         const TopoDS_Face& aF = *((TopoDS_Face*)(&aItAddedF.Value()));
00464         //
00465         TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
00466         for (; aEdgeExp.More(); aEdgeExp.Next()) {
00467           const TopoDS_Edge& aE = *((TopoDS_Edge*)(&aEdgeExp.Current()));
00468           const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE);
00469           aItF.Initialize(aLF);
00470           for (; aItF.More(); aItF.Next()) {
00471             const TopoDS_Face& aFL=*((TopoDS_Face*)(&aItF.Value()));
00472             if (AddedFacesMap.Add(aFL)){
00473               aBB.Add(aShell, aFL);
00474             }
00475           }
00476         }
00477       }
00478       myLoopsInternal.Append(aShell);
00479     }
00480   }
00481 }
00482 //=======================================================================
00483 //function : PerformAreas
00484 //purpose  :
00485 //=======================================================================
00486 void GEOMAlgo_BuilderSolid::PerformAreas()
00487 {
00488   myErrorStatus=0;
00489   //
00490   Standard_Boolean bIsGrowthShell, bIsHole;
00491   TopTools_ListOfShape aNewSolids, aHoleShells;
00492   TopoDS_Shape anInfinitePointShape;
00493   TopTools_DataMapOfShapeShape aInOutMap;
00494   TopTools_DataMapOfShapeListOfShape aMSH;
00495   TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
00496   TopTools_ListIteratorOfListOfShape aShellIt, aSolidIt;
00497   TopTools_IndexedMapOfShape aMHF;
00498   BRep_Builder aBB;
00499   //
00500   myAreas.Clear();
00501   //
00502   //  Draft solids [aNewSolids]
00503   aShellIt.Initialize(myLoops);
00504   for ( ; aShellIt.More(); aShellIt.Next()) {
00505     const TopoDS_Shape& aShell = aShellIt.Value();
00506     //
00507     bIsGrowthShell=IsGrowthShell(aShell, aMHF);
00508     if (bIsGrowthShell) {
00509       // make a growth solid from a shell
00510       TopoDS_Solid Solid;
00511       aBB.MakeSolid(Solid);
00512       aBB.Add (Solid, aShell);
00513       //
00514       aNewSolids.Append (Solid);
00515     }
00516     else{
00517       // check if a shell is a hole
00518       bIsHole=IsHole(aShell, myContext);
00519       //
00520       if (bIsHole) {
00521         aHoleShells.Append(aShell);
00522         TopExp::MapShapes(aShell, TopAbs_FACE, aMHF);
00523       }
00524       else {
00525         // make a growth solid from a shell
00526         TopoDS_Solid Solid;
00527         aBB.MakeSolid(Solid);
00528         aBB.Add (Solid, aShell);
00529         //
00530         aNewSolids.Append (Solid);
00531       }
00532     }
00533   }
00534   //
00535   // 2. Find outer growth shell that is most close to each hole shell
00536   aShellIt.Initialize(aHoleShells);
00537   for (; aShellIt.More(); aShellIt.Next()) {
00538     const TopoDS_Shape& aHole = aShellIt.Value();
00539     //
00540     aSolidIt.Initialize(aNewSolids);
00541     for ( ; aSolidIt.More(); aSolidIt.Next())    {
00542       const TopoDS_Shape& aSolid = aSolidIt.Value();
00543       //
00544       if (!IsInside(aHole, aSolid, myContext)){
00545         continue;
00546       }
00547       //
00548       if ( aInOutMap.IsBound (aHole)){
00549         const TopoDS_Shape& aSolid2 = aInOutMap(aHole);
00550         if (IsInside(aSolid, aSolid2, myContext)) {
00551           aInOutMap.UnBind(aHole);
00552           aInOutMap.Bind (aHole, aSolid);
00553         }
00554       }
00555       else{
00556         aInOutMap.Bind (aHole, aSolid);
00557       }
00558     }
00559     //
00560     // Add aHole to a map Solid/ListOfHoles [aMSH]
00561     if (aInOutMap.IsBound(aHole)){
00562       const TopoDS_Shape& aSolid=aInOutMap(aHole);
00563       if (aMSH.IsBound(aSolid)) {
00564         TopTools_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
00565         aLH.Append(aHole);
00566       }
00567       else {
00568         TopTools_ListOfShape aLH;
00569         aLH.Append(aHole);
00570         aMSH.Bind(aSolid, aLH);
00571       }
00572       //aBB.Add (aSolid, aHole);
00573     }
00574   }// for (; aShellIt.More(); aShellIt.Next()) {
00575   //
00576   // 3. Add aHoles to Solids
00577   aItMSH.Initialize(aMSH);
00578   for (; aItMSH.More(); aItMSH.Next()) {
00579     TopoDS_Solid aSolid=*((TopoDS_Solid*)(&aItMSH.Key()));
00580     //
00581     const TopTools_ListOfShape& aLH=aItMSH.Value();
00582     aShellIt.Initialize(aLH);
00583     for (; aShellIt.More(); aShellIt.Next()) {
00584       const TopoDS_Shape& aHole = aShellIt.Value();
00585       aBB.Add (aSolid, aHole);
00586     }
00587     //
00588     // update classifier
00589     BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid);
00590     aSC.Load(aSolid);
00591     //
00592   }
00593   //
00594   // These aNewSolids are draft solids that
00595   // do not contain any internal shapes
00596   //
00597   myAreas.Append(aNewSolids);
00598 }
00599 //=======================================================================
00600 //function : PerformInternalShapes
00601 //purpose  :
00602 //=======================================================================
00603 void GEOMAlgo_BuilderSolid::PerformInternalShapes()
00604 {
00605   myErrorStatus=0;
00606   //
00607   Standard_Integer aNbFI=myLoopsInternal.Extent();
00608   if (!aNbFI) {// nothing to do
00609     return;
00610   }
00611   //
00612   Standard_Integer bFlag;
00613   BRep_Builder aBB;
00614   TopTools_ListIteratorOfListOfShape aShellIt, aSolidIt;
00615   TopoDS_Iterator aIt;
00616   TopTools_MapOfShape aMF, aMFP, aMFS;
00617   TopTools_MapIteratorOfMapOfShape aItMF;
00618   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
00619   TopTools_ListOfShape aLSI;
00620   //
00621   // 1. All internal faces
00622   aShellIt.Initialize(myLoopsInternal);
00623   for (; aShellIt.More(); aShellIt.Next()) {
00624     const TopoDS_Shape& aShell=aShellIt.Value();
00625     aIt.Initialize(aShell);
00626     for (; aIt.More(); aIt.Next()) {
00627       const TopoDS_Shape& aF=aIt.Value();
00628       aMF.Add(aF);
00629     }
00630   }
00631   aNbFI=aMF.Extent();
00632   //
00633   // 2 Process solids
00634   aSolidIt.Initialize(myAreas);
00635   for ( ; aSolidIt.More(); aSolidIt.Next()) {
00636     TopoDS_Solid& aSolid=*((TopoDS_Solid*)(&aSolidIt.Value()));
00637     //
00638     //modified by NIZNHY-PKV Wed Mar 07 08:52:18 2012f
00639     aMFS.Clear();
00640     {
00641       TopExp_Explorer aExp(aSolid, TopAbs_FACE);
00642       while (aExp.More()) {
00643        aMFS.Add(aExp.Current());
00644        aExp.Next();
00645       }
00646     }
00647     //modified by NIZNHY-PKV Wed Mar 07 08:52:20 2012t
00648     aMEF.Clear();
00649     TopExp::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF);
00650     //
00651     // 2.1 Separate faces to process aMFP
00652     aMFP.Clear();
00653     aItMF.Initialize(aMF);
00654     for (; aItMF.More(); aItMF.Next()) {
00655       const TopoDS_Face& aF=*((TopoDS_Face*)(&aItMF.Key()));
00656       //modified by NIZNHY-PKV Wed Mar 07 08:54:56 2012f
00657       if (!aMFS.Contains(aF)) {
00658        bFlag=GEOMAlgo_Tools3D::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext);
00659        if (bFlag) {
00660          aMFP.Add(aF);
00661        }
00662       }
00663       //if (GEOMAlgo_Tools3D::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext)) {
00664       //  aMFP.Add(aF);
00665       //}
00666       //modified by NIZNHY-PKV Wed Mar 07 08:56:07 2012t
00667     }
00668     //
00669     // 2.2 Make Internal Shells
00670     aLSI.Clear();
00671     MakeInternalShells(aMFP, aLSI);
00672     //
00673     // 2.3 Add them to aSolid
00674     aShellIt.Initialize(aLSI);
00675     for (; aShellIt.More(); aShellIt.Next()) {
00676       const TopoDS_Shape& aSI=aShellIt.Value();
00677       aBB.Add (aSolid, aSI);
00678     }
00679     //
00680     // 2.4 Remove faces aMFP from aMF
00681     aItMF.Initialize(aMFP);
00682     for (; aItMF.More(); aItMF.Next()) {
00683       const TopoDS_Shape& aF=aItMF.Key();
00684       aMF.Remove(aF);
00685     }
00686     //
00687     aNbFI=aMF.Extent();
00688     if (!aNbFI) {
00689       break;
00690     }
00691   } //for ( ; aSolidIt.More(); aSolidIt.Next()) {
00692 }
00693 
00694 //=======================================================================
00695 //function : MakeInternalShells
00696 //purpose  :
00697 //=======================================================================
00698 void MakeInternalShells(const TopTools_MapOfShape& theMF,
00699                         TopTools_ListOfShape& theShells)
00700 {
00701   TopTools_MapIteratorOfMapOfShape aItM;
00702   TopTools_MapOfShape aAddedFacesMap;
00703   TopTools_ListIteratorOfListOfShape aItF;
00704   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
00705   BRep_Builder aBB;
00706   //
00707   aItM.Initialize(theMF);
00708   for (; aItM.More(); aItM.Next()) {
00709     const TopoDS_Shape& aF=aItM.Key();
00710     TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
00711   }
00712   //
00713   aItM.Initialize(theMF);
00714   for (; aItM.More(); aItM.Next()) {
00715     TopoDS_Shape aFF=aItM.Key();
00716     if (!aAddedFacesMap.Add(aFF)) {
00717       continue;
00718     }
00719     //
00720     // make a new shell
00721     TopoDS_Shell aShell;
00722     aBB.MakeShell(aShell);
00723     aFF.Orientation(TopAbs_INTERNAL);
00724     aBB.Add(aShell, aFF);
00725     //
00726     TopoDS_Iterator aItAddedF (aShell);
00727     for (; aItAddedF.More(); aItAddedF.Next()) {
00728       const TopoDS_Shape& aF =aItAddedF.Value();
00729       //
00730       TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
00731       for (; aEdgeExp.More(); aEdgeExp.Next()) {
00732         const TopoDS_Shape& aE =aEdgeExp.Current();
00733         const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE);
00734         aItF.Initialize(aLF);
00735         for (; aItF.More(); aItF.Next()) {
00736           TopoDS_Shape aFL=aItF.Value();
00737           if (aAddedFacesMap.Add(aFL)){
00738             aFL.Orientation(TopAbs_INTERNAL);
00739             aBB.Add(aShell, aFL);
00740           }
00741         }
00742       }
00743     }
00744     theShells.Append(aShell);
00745   }
00746 }
00747 //=======================================================================
00748 //function : IsHole
00749 //purpose  :
00750 //=======================================================================
00751 Standard_Boolean IsHole(const TopoDS_Shape& theS2,
00752                         const Handle(IntTools_Context)& theContext)
00753 {
00754   TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
00755   BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
00756   //
00757   aClsf.PerformInfinitePoint(::RealSmall());
00758   //
00759   return (aClsf.State()==TopAbs_IN);
00760 }
00761 //=======================================================================
00762 //function : IsInside
00763 //purpose  :
00764 //=======================================================================
00765 Standard_Boolean IsInside(const TopoDS_Shape& theS1,
00766                           const TopoDS_Shape& theS2,
00767                           const Handle(IntTools_Context)& theContext)
00768 {
00769   TopExp_Explorer aExp;
00770   TopAbs_State aState;
00771   //
00772   TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
00773   //
00774   aExp.Init(theS1, TopAbs_FACE);
00775   if (!aExp.More()){
00776     BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
00777     aClsf.PerformInfinitePoint(::RealSmall());
00778     aState=aClsf.State();
00779   }
00780   else {
00781     TopTools_IndexedMapOfShape aBounds;
00782     const TopoDS_Face& aF = TopoDS::Face(aExp.Current());
00783     aState=GEOMAlgo_Tools3D::ComputeState(aF, *pS2, 1.e-14, aBounds, theContext);
00784   }
00785   return (aState==TopAbs_IN);
00786 }
00787 //=======================================================================
00788 //function : IsGrowthShell
00789 //purpose  :
00790 //=======================================================================
00791 Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
00792                                const TopTools_IndexedMapOfShape& theMHF)
00793 {
00794   Standard_Boolean bRet;
00795   TopoDS_Iterator aIt;
00796   //
00797   bRet=Standard_False;
00798   if (theMHF.Extent()) {
00799     aIt.Initialize(theShell);
00800     for(; aIt.More(); aIt.Next()) {
00801       const TopoDS_Shape& aF=aIt.Value();
00802       if (theMHF.Contains(aF)) {
00803         return !bRet;
00804       }
00805     }
00806   }
00807   return bRet;
00808 }
00809 //=======================================================================
00810 //function : IsClosedShell
00811 //purpose  :
00812 //=======================================================================
00813 Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
00814 {
00815   Standard_Integer aNbE;
00816   Standard_Boolean bRet;
00817   TopoDS_Iterator aIt;
00818   TopExp_Explorer aExp;
00819   TopTools_MapOfShape aM;
00820   //
00821   bRet=Standard_False;
00822   aIt.Initialize(theShell);
00823   for(; aIt.More(); aIt.Next()) {
00824     const TopoDS_Face& aF=TopoDS::Face(aIt.Value());
00825     aExp.Init(aF, TopAbs_EDGE);
00826     for (; aExp.More(); aExp.Next()) {
00827       const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aExp.Current()));
00828       if (BRep_Tool::Degenerated(aE)) {
00829         continue;
00830       }
00831       //
00832       if (aE.Orientation()==TopAbs_INTERNAL) {
00833         continue;
00834       }
00835       //
00836       if (!aM.Add(aE)) {
00837         aM.Remove(aE);
00838       }
00839     }
00840   }
00841   //
00842   aNbE=aM.Extent();
00843   if (!aNbE) {
00844     bRet=!bRet;
00845   }
00846   return bRet;
00847 }
00848 //=======================================================================
00849 //function : RefineShell
00850 //purpose  :
00851 //=======================================================================
00852 Standard_Boolean RefineShell(const TopoDS_Shell& aShell,
00853                           TopoDS_Shell& aShx)
00854 
00855 {
00856   Standard_Boolean bRet;
00857   Standard_Integer i, aNbE, aNbF;
00858   TopAbs_Orientation aOrE;
00859   TopTools_IndexedDataMapOfShapeListOfShape aMEF;
00860   TopTools_MapOfOrientedShape aMFx;
00861   //
00862   bRet=Standard_False;
00863   //
00864   TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
00865   aNbE=aMEF.Extent();
00866   for (i=1; i<=aNbE; ++i) {
00867     const TopoDS_Edge &aE=*((TopoDS_Edge*)(&aMEF.FindKey(i)));
00868     //
00869     if (BRep_Tool::Degenerated(aE)) {
00870       continue;
00871     }
00872     //
00873     aOrE=aE.Orientation();
00874     //
00875     const TopTools_ListOfShape& aLF=aMEF(i);
00876     aNbF=aLF.Extent();
00877     if (!aNbF) {
00878       continue;
00879     }
00880     //
00881     const TopoDS_Face& aF1=*((TopoDS_Face*)(&aLF.First()));
00882     if (aNbF==1) {
00883       if (aOrE==TopAbs_INTERNAL) {
00884        continue;
00885       }
00886       aMFx.Add(aF1);
00887     }
00888     //
00889     else if (aNbF==2) {
00890       const TopoDS_Face& aF2=*((TopoDS_Face*)(&aLF.Last()));
00891       if (aF2.IsSame(aF1)) {
00892        if (BRep_Tool::IsClosed(aE, aF1)) {
00893          continue;
00894        }
00895        if (aOrE==TopAbs_INTERNAL) {
00896          continue;
00897        }
00898        aMFx.Add(aF1);
00899        aMFx.Add(aF2);
00900       }
00901     }
00902   }
00903   //
00904   aNbF=aMFx.Extent();
00905   if (!aNbF) {
00906     return bRet;
00907   }
00908   //
00909   BRep_Builder aBB;
00910   TopoDS_Iterator aIt;
00911   //
00912   aNbF=0;
00913   aBB.MakeShell(aShx);
00914   aIt.Initialize(aShell);
00915   for (; aIt.More(); aIt.Next()) {
00916     const TopoDS_Shape& aF=aIt.Value();
00917     if (!aMFx.Contains(aF)) {
00918       aBB.Add(aShx, aF);
00919       ++aNbF;
00920     }
00921   }
00922   //
00923   if (aNbF) {
00924     bRet=IsClosedShell(aShx);
00925   }
00926   //
00927   return bRet;
00928 }
00929 //
00930 //  ErrorStatus :
00931 // 11 - Null Context