// Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // // File: GEOMAlgo_BuilderSolid.cxx // Created: // Author: Peter KURNEV // #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // static Standard_Boolean IsGrowthShell(const TopoDS_Shape& , const TopTools_IndexedMapOfShape& ); static Standard_Boolean IsHole(const TopoDS_Shape& , const Handle(IntTools_Context)& ); static Standard_Boolean IsInside(const TopoDS_Shape& , const TopoDS_Shape& , const Handle(IntTools_Context)& ); static void MakeInternalShells(const TopTools_MapOfShape& , TopTools_ListOfShape& ); static Standard_Boolean IsClosedShell(const TopoDS_Shell& ); static Standard_Boolean RefineShell(const TopoDS_Shell& , TopoDS_Shell& ); //======================================================================= //function : //purpose : //======================================================================= GEOMAlgo_BuilderSolid::GEOMAlgo_BuilderSolid() : GEOMAlgo_BuilderArea() { } //======================================================================= //function : ~ //purpose : //======================================================================= GEOMAlgo_BuilderSolid::~GEOMAlgo_BuilderSolid() { } //======================================================================= //function : Perform //purpose : //======================================================================= void GEOMAlgo_BuilderSolid::Perform() { myErrorStatus=0; // // Initialize the context GEOMAlgo_BuilderArea::Perform(); // TopoDS_Compound aC; BRep_Builder aBB; TopTools_ListIteratorOfListOfShape aIt; aBB.MakeCompound(aC); aIt.Initialize(myShapes); for(; aIt.More(); aIt.Next()) { const TopoDS_Shape& aF=aIt.Value(); aBB.Add(aC, aF); } // PerformShapesToAvoid(); if (myErrorStatus) { return; } // PerformLoops(); if (myErrorStatus) { return; } PerformAreas(); if (myErrorStatus) { return; } if (myComputeInternalShapes) { PerformInternalShapes(); if (myErrorStatus) { return; } } } //======================================================================= //function :PerformShapesToAvoid //purpose : //======================================================================= void GEOMAlgo_BuilderSolid::PerformShapesToAvoid() { Standard_Boolean bFound; Standard_Integer i, iCnt, aNbE, aNbF; TopAbs_Orientation aOrE; TopTools_IndexedDataMapOfShapeListOfShape aMEF; TopTools_ListIteratorOfListOfShape aIt; // myShapesToAvoid.Clear(); // iCnt=0; while (1) { ++iCnt; bFound=Standard_False; // // 1. MEF aMEF.Clear(); aIt.Initialize (myShapes); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aF=aIt.Value(); if (!myShapesToAvoid.Contains(aF)) { TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF); } /* else { int a=0; } */ } aNbE=aMEF.Extent(); // // 2. myFacesToAvoid for (i=1; i<=aNbE; ++i) { const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aMEF.FindKey(i))); if (BRep_Tool::Degenerated(aE)) { continue; } // TopTools_ListOfShape& aLF=aMEF.ChangeFromKey(aE); // aNbF=aLF.Extent(); if (!aNbF) { continue; } // aOrE=aE.Orientation(); // const TopoDS_Face& aF1=*((TopoDS_Face*)(&aLF.First())); if (aNbF==1) { if (aOrE==TopAbs_INTERNAL) { continue; } bFound=Standard_True; myShapesToAvoid.Add(aF1); } else if (aNbF==2) { const TopoDS_Face& aF2=*((TopoDS_Face*)(&aLF.Last())); if (aF2.IsSame(aF1)) { if (BRep_Tool::IsClosed(aE, aF1)) { continue; } // if (aOrE==TopAbs_INTERNAL) { continue; } // bFound=Standard_True; myShapesToAvoid.Add(aF1); myShapesToAvoid.Add(aF2); } } /*//DEB else { TopTools_ListIteratorOfListOfShape aItLF; // aItLF.Initialize (aLF); for (; aItLF.More(); aItLF.Next()) { const TopoDS_Shape& aFx=aItLF.Value(); int a=0; } } *///DEB }// for (i=1; i<=aNbE; ++i) { // if (!bFound) { break; } // }//while (1) } //======================================================================= //function : PerformLoops //purpose : //======================================================================= void GEOMAlgo_BuilderSolid::PerformLoops() { myErrorStatus=0; // myLoops.Clear(); // Standard_Integer aNbLF, aNbOff, aNbFP; TopAbs_Orientation anOr; TopoDS_Edge aEL; BRep_Builder aBB; NMTTools_CoupleOfShape aCSOff; TopTools_MapOfOrientedShape AddedFacesMap; TopTools_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP; TopTools_ListIteratorOfListOfShape aItF, aIt; TopTools_MapIteratorOfMapOfOrientedShape aItM; TopoDS_Iterator aItS; // //================================================= // // 1. Shells Usual // aItF.Initialize (myShapes); for (; aItF.More(); aItF.Next()) { const TopoDS_Shape& aFF = aItF.Value(); TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap); } // aItF.Initialize (myShapes); for (; aItF.More(); aItF.Next()) { const TopoDS_Shape& aFF = aItF.Value(); if (myShapesToAvoid.Contains(aFF)) { continue; } if (!AddedFacesMap.Add(aFF)) { continue; } // // make a new shell TopoDS_Shell aShell; aBB.MakeShell(aShell); aBB.Add(aShell, aFF); // aMEFP.Clear(); TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aMEFP); // // loop on faces added to Shell; add their neighbor faces to Shell and so on TopoDS_Iterator aItAddedF (aShell); for (; aItAddedF.More(); aItAddedF.Next()) { const TopoDS_Face& aF = *((TopoDS_Face*)(&aItAddedF.Value())); // // loop on edges of aF; find a good neighbor face of aF by aE TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE); for (; aEdgeExp.More(); aEdgeExp.Next()) { const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aEdgeExp.Current())); // //1 if (aMEFP.Contains(aE)) { const TopTools_ListOfShape& aLFP=aMEFP.FindFromKey(aE); aNbFP=aLFP.Extent(); if (aNbFP>1) { continue; } } //2 anOr=aE.Orientation(); if (anOr==TopAbs_INTERNAL) { continue; } //3 if (BRep_Tool::Degenerated(aE)) { continue; } // // candidate faces list const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE); aNbLF=aLF.Extent(); if (!aNbLF) { continue; } // // try to select one of neighbors // check if a face already added to Shell shares E Standard_Boolean bFound; TopTools_ListIteratorOfListOfShape aItLF; NMTTools_ListOfCoupleOfShape aLCSOff; // aItLF.Initialize(aLF); for (; aItLF.More(); aItLF.Next()) { const TopoDS_Face& aFL=*((TopoDS_Face*)(&aItLF.Value())); if (myShapesToAvoid.Contains(aFL)) { continue; } if (aF.IsSame(aFL)) { continue; } if (AddedFacesMap.Contains(aFL)){ continue; } // bFound=GEOMAlgo_Tools3D::GetEdgeOff(aE, aFL, aEL); if (!bFound) { continue; } // aCSOff.SetShape1(aEL); aCSOff.SetShape2(aFL); aLCSOff.Append(aCSOff); }//for (; aItLF.More(); aItLF.Next()) { // aNbOff=aLCSOff.Extent(); if (!aNbOff){ continue; } // TopoDS_Face aSelF; if (aNbOff==1) { aSelF=*((TopoDS_Face*)(&aLCSOff.First().Shape2())); } else if (aNbOff>1){ GEOMAlgo_Tools3D::GetFaceOff(aE, aF, aLCSOff, aSelF); } // if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) { aBB.Add(aShell, aSelF); TopExp::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP); } } // for (; aEdgeExp.More(); aEdgeExp.Next()) { } //for (; aItAddedF.More(); aItAddedF.Next()) { // if (IsClosedShell(aShell)) { myLoops.Append(aShell); } else { Standard_Boolean bRefine; TopoDS_Shell aShx; // bRefine=RefineShell(aShell, aShx); if (bRefine) { myLoops.Append(aShx); } } } // for (; aItF.More(); aItF.Next()) { // // Post Treatment TopTools_MapOfOrientedShape aMP; // // a. collect all edges that are in loops aIt.Initialize (myLoops); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aS=aIt.Value(); aItS.Initialize(aS); for (; aItS.More(); aItS.Next()) { const TopoDS_Shape& aF=aItS.Value(); aMP.Add(aF); } } // // b. collect all faces that are to avoid aItM.Initialize(myShapesToAvoid); for (; aItM.More(); aItM.Next()) { const TopoDS_Shape& aF=aItM.Key(); aMP.Add(aF); } // // c. add all faces that are not processed to myShapesToAvoid aIt.Initialize (myShapes); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aF=aIt.Value(); if (!aMP.Contains(aF)) { myShapesToAvoid.Add(aF); } } //================================================= // // 2.Internal Shells // myLoopsInternal.Clear(); // aEFMap.Clear(); AddedFacesMap.Clear(); // if (myComputeInternalShapes) { aItM.Initialize(myShapesToAvoid); for (; aItM.More(); aItM.Next()) { const TopoDS_Shape& aFF=aItM.Key(); TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap); } // aItM.Initialize(myShapesToAvoid); for (; aItM.More(); aItM.Next()) { const TopoDS_Shape& aFF=aItM.Key(); if (!AddedFacesMap.Add(aFF)) { continue; } // // make a new shell TopoDS_Shell aShell; aBB.MakeShell(aShell); aBB.Add(aShell, aFF); // TopoDS_Iterator aItAddedF (aShell); for (; aItAddedF.More(); aItAddedF.Next()) { const TopoDS_Face& aF = *((TopoDS_Face*)(&aItAddedF.Value())); // TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE); for (; aEdgeExp.More(); aEdgeExp.Next()) { const TopoDS_Edge& aE = *((TopoDS_Edge*)(&aEdgeExp.Current())); const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE); aItF.Initialize(aLF); for (; aItF.More(); aItF.Next()) { const TopoDS_Face& aFL=*((TopoDS_Face*)(&aItF.Value())); if (AddedFacesMap.Add(aFL)){ aBB.Add(aShell, aFL); } } } } myLoopsInternal.Append(aShell); } } } //======================================================================= //function : PerformAreas //purpose : //======================================================================= void GEOMAlgo_BuilderSolid::PerformAreas() { myErrorStatus=0; // Standard_Boolean bIsGrowthShell, bIsHole; TopTools_ListOfShape aNewSolids, aHoleShells; TopoDS_Shape anInfinitePointShape; TopTools_DataMapOfShapeShape aInOutMap; TopTools_DataMapOfShapeListOfShape aMSH; TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH; TopTools_ListIteratorOfListOfShape aShellIt, aSolidIt; TopTools_IndexedMapOfShape aMHF; BRep_Builder aBB; // myAreas.Clear(); // // Draft solids [aNewSolids] aShellIt.Initialize(myLoops); for ( ; aShellIt.More(); aShellIt.Next()) { const TopoDS_Shape& aShell = aShellIt.Value(); // bIsGrowthShell=IsGrowthShell(aShell, aMHF); if (bIsGrowthShell) { // make a growth solid from a shell TopoDS_Solid Solid; aBB.MakeSolid(Solid); aBB.Add (Solid, aShell); // aNewSolids.Append (Solid); } else{ // check if a shell is a hole bIsHole=IsHole(aShell, myContext); // if (bIsHole) { aHoleShells.Append(aShell); TopExp::MapShapes(aShell, TopAbs_FACE, aMHF); } else { // make a growth solid from a shell TopoDS_Solid Solid; aBB.MakeSolid(Solid); aBB.Add (Solid, aShell); // aNewSolids.Append (Solid); } } } // // 2. Find outer growth shell that is most close to each hole shell aShellIt.Initialize(aHoleShells); for (; aShellIt.More(); aShellIt.Next()) { const TopoDS_Shape& aHole = aShellIt.Value(); // aSolidIt.Initialize(aNewSolids); for ( ; aSolidIt.More(); aSolidIt.Next()) { const TopoDS_Shape& aSolid = aSolidIt.Value(); // if (!IsInside(aHole, aSolid, myContext)){ continue; } // if ( aInOutMap.IsBound (aHole)){ const TopoDS_Shape& aSolid2 = aInOutMap(aHole); if (IsInside(aSolid, aSolid2, myContext)) { aInOutMap.UnBind(aHole); aInOutMap.Bind (aHole, aSolid); } } else{ aInOutMap.Bind (aHole, aSolid); } } // // Add aHole to a map Solid/ListOfHoles [aMSH] if (aInOutMap.IsBound(aHole)){ const TopoDS_Shape& aSolid=aInOutMap(aHole); if (aMSH.IsBound(aSolid)) { TopTools_ListOfShape& aLH=aMSH.ChangeFind(aSolid); aLH.Append(aHole); } else { TopTools_ListOfShape aLH; aLH.Append(aHole); aMSH.Bind(aSolid, aLH); } //aBB.Add (aSolid, aHole); } }// for (; aShellIt.More(); aShellIt.Next()) { // // 3. Add aHoles to Solids aItMSH.Initialize(aMSH); for (; aItMSH.More(); aItMSH.Next()) { TopoDS_Solid aSolid=*((TopoDS_Solid*)(&aItMSH.Key())); // const TopTools_ListOfShape& aLH=aItMSH.Value(); aShellIt.Initialize(aLH); for (; aShellIt.More(); aShellIt.Next()) { const TopoDS_Shape& aHole = aShellIt.Value(); aBB.Add (aSolid, aHole); } // // update classifier BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid); aSC.Load(aSolid); // } // // These aNewSolids are draft solids that // do not contain any internal shapes // myAreas.Append(aNewSolids); } //======================================================================= //function : PerformInternalShapes //purpose : //======================================================================= void GEOMAlgo_BuilderSolid::PerformInternalShapes() { myErrorStatus=0; // Standard_Integer aNbFI=myLoopsInternal.Extent(); if (!aNbFI) {// nothing to do return; } // Standard_Integer bFlag; BRep_Builder aBB; TopTools_ListIteratorOfListOfShape aShellIt, aSolidIt; TopoDS_Iterator aIt; TopTools_MapOfShape aMF, aMFP, aMFS; TopTools_MapIteratorOfMapOfShape aItMF; TopTools_IndexedDataMapOfShapeListOfShape aMEF; TopTools_ListOfShape aLSI; // // 1. All internal faces aShellIt.Initialize(myLoopsInternal); for (; aShellIt.More(); aShellIt.Next()) { const TopoDS_Shape& aShell=aShellIt.Value(); aIt.Initialize(aShell); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aF=aIt.Value(); aMF.Add(aF); } } aNbFI=aMF.Extent(); // // 2 Process solids aSolidIt.Initialize(myAreas); for ( ; aSolidIt.More(); aSolidIt.Next()) { TopoDS_Solid& aSolid=*((TopoDS_Solid*)(&aSolidIt.Value())); // //modified by NIZNHY-PKV Wed Mar 07 08:52:18 2012f aMFS.Clear(); { TopExp_Explorer aExp(aSolid, TopAbs_FACE); while (aExp.More()) { aMFS.Add(aExp.Current()); aExp.Next(); } } //modified by NIZNHY-PKV Wed Mar 07 08:52:20 2012t aMEF.Clear(); TopExp::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF); // // 2.1 Separate faces to process aMFP aMFP.Clear(); aItMF.Initialize(aMF); for (; aItMF.More(); aItMF.Next()) { const TopoDS_Face& aF=*((TopoDS_Face*)(&aItMF.Key())); //modified by NIZNHY-PKV Wed Mar 07 08:54:56 2012f if (!aMFS.Contains(aF)) { bFlag=GEOMAlgo_Tools3D::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext); if (bFlag) { aMFP.Add(aF); } } //if (GEOMAlgo_Tools3D::IsInternalFace(aF, aSolid, aMEF, 1.e-14, myContext)) { // aMFP.Add(aF); //} //modified by NIZNHY-PKV Wed Mar 07 08:56:07 2012t } // // 2.2 Make Internal Shells aLSI.Clear(); MakeInternalShells(aMFP, aLSI); // // 2.3 Add them to aSolid aShellIt.Initialize(aLSI); for (; aShellIt.More(); aShellIt.Next()) { const TopoDS_Shape& aSI=aShellIt.Value(); aBB.Add (aSolid, aSI); } // // 2.4 Remove faces aMFP from aMF aItMF.Initialize(aMFP); for (; aItMF.More(); aItMF.Next()) { const TopoDS_Shape& aF=aItMF.Key(); aMF.Remove(aF); } // aNbFI=aMF.Extent(); if (!aNbFI) { break; } } //for ( ; aSolidIt.More(); aSolidIt.Next()) { } //======================================================================= //function : MakeInternalShells //purpose : //======================================================================= void MakeInternalShells(const TopTools_MapOfShape& theMF, TopTools_ListOfShape& theShells) { TopTools_MapIteratorOfMapOfShape aItM; TopTools_MapOfShape aAddedFacesMap; TopTools_ListIteratorOfListOfShape aItF; TopTools_IndexedDataMapOfShapeListOfShape aMEF; BRep_Builder aBB; // aItM.Initialize(theMF); for (; aItM.More(); aItM.Next()) { const TopoDS_Shape& aF=aItM.Key(); TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF); } // aItM.Initialize(theMF); for (; aItM.More(); aItM.Next()) { TopoDS_Shape aFF=aItM.Key(); if (!aAddedFacesMap.Add(aFF)) { continue; } // // make a new shell TopoDS_Shell aShell; aBB.MakeShell(aShell); aFF.Orientation(TopAbs_INTERNAL); aBB.Add(aShell, aFF); // TopoDS_Iterator aItAddedF (aShell); for (; aItAddedF.More(); aItAddedF.Next()) { const TopoDS_Shape& aF =aItAddedF.Value(); // TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE); for (; aEdgeExp.More(); aEdgeExp.Next()) { const TopoDS_Shape& aE =aEdgeExp.Current(); const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE); aItF.Initialize(aLF); for (; aItF.More(); aItF.Next()) { TopoDS_Shape aFL=aItF.Value(); if (aAddedFacesMap.Add(aFL)){ aFL.Orientation(TopAbs_INTERNAL); aBB.Add(aShell, aFL); } } } } theShells.Append(aShell); } } //======================================================================= //function : IsHole //purpose : //======================================================================= Standard_Boolean IsHole(const TopoDS_Shape& theS2, const Handle(IntTools_Context)& theContext) { TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2; BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2); // aClsf.PerformInfinitePoint(::RealSmall()); // return (aClsf.State()==TopAbs_IN); } //======================================================================= //function : IsInside //purpose : //======================================================================= Standard_Boolean IsInside(const TopoDS_Shape& theS1, const TopoDS_Shape& theS2, const Handle(IntTools_Context)& theContext) { TopExp_Explorer aExp; TopAbs_State aState; // TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2; // aExp.Init(theS1, TopAbs_FACE); if (!aExp.More()){ BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2); aClsf.PerformInfinitePoint(::RealSmall()); aState=aClsf.State(); } else { TopTools_IndexedMapOfShape aBounds; const TopoDS_Face& aF = TopoDS::Face(aExp.Current()); aState=GEOMAlgo_Tools3D::ComputeState(aF, *pS2, 1.e-14, aBounds, theContext); } return (aState==TopAbs_IN); } //======================================================================= //function : IsGrowthShell //purpose : //======================================================================= Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell, const TopTools_IndexedMapOfShape& theMHF) { Standard_Boolean bRet; TopoDS_Iterator aIt; // bRet=Standard_False; if (theMHF.Extent()) { aIt.Initialize(theShell); for(; aIt.More(); aIt.Next()) { const TopoDS_Shape& aF=aIt.Value(); if (theMHF.Contains(aF)) { return !bRet; } } } return bRet; } //======================================================================= //function : IsClosedShell //purpose : //======================================================================= Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell) { Standard_Integer aNbE; Standard_Boolean bRet; TopoDS_Iterator aIt; TopExp_Explorer aExp; TopTools_MapOfShape aM; // bRet=Standard_False; aIt.Initialize(theShell); for(; aIt.More(); aIt.Next()) { const TopoDS_Face& aF=TopoDS::Face(aIt.Value()); aExp.Init(aF, TopAbs_EDGE); for (; aExp.More(); aExp.Next()) { const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aExp.Current())); if (BRep_Tool::Degenerated(aE)) { continue; } // if (aE.Orientation()==TopAbs_INTERNAL) { continue; } // if (!aM.Add(aE)) { aM.Remove(aE); } } } // aNbE=aM.Extent(); if (!aNbE) { bRet=!bRet; } return bRet; } //======================================================================= //function : RefineShell //purpose : //======================================================================= Standard_Boolean RefineShell(const TopoDS_Shell& aShell, TopoDS_Shell& aShx) { Standard_Boolean bRet; Standard_Integer i, aNbE, aNbF; TopAbs_Orientation aOrE; TopTools_IndexedDataMapOfShapeListOfShape aMEF; TopTools_MapOfOrientedShape aMFx; // bRet=Standard_False; // TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF); aNbE=aMEF.Extent(); for (i=1; i<=aNbE; ++i) { const TopoDS_Edge &aE=*((TopoDS_Edge*)(&aMEF.FindKey(i))); // if (BRep_Tool::Degenerated(aE)) { continue; } // aOrE=aE.Orientation(); // const TopTools_ListOfShape& aLF=aMEF(i); aNbF=aLF.Extent(); if (!aNbF) { continue; } // const TopoDS_Face& aF1=*((TopoDS_Face*)(&aLF.First())); if (aNbF==1) { if (aOrE==TopAbs_INTERNAL) { continue; } aMFx.Add(aF1); } // else if (aNbF==2) { const TopoDS_Face& aF2=*((TopoDS_Face*)(&aLF.Last())); if (aF2.IsSame(aF1)) { if (BRep_Tool::IsClosed(aE, aF1)) { continue; } if (aOrE==TopAbs_INTERNAL) { continue; } aMFx.Add(aF1); aMFx.Add(aF2); } } } // aNbF=aMFx.Extent(); if (!aNbF) { return bRet; } // BRep_Builder aBB; TopoDS_Iterator aIt; // aNbF=0; aBB.MakeShell(aShx); aIt.Initialize(aShell); for (; aIt.More(); aIt.Next()) { const TopoDS_Shape& aF=aIt.Value(); if (!aMFx.Contains(aF)) { aBB.Add(aShx, aF); ++aNbF; } } // if (aNbF) { bRet=IsClosedShell(aShx); } // return bRet; } // // ErrorStatus : // 11 - Null Context