1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 // File: GEOMAlgo_BuilderSolid.cxx
25 // Author: Peter KURNEV
27 #include <GEOMAlgo_BuilderSolid.ixx>
29 #include <gp_Pnt2d.hxx>
35 #include <Geom_Curve.hxx>
36 #include <Geom_Surface.hxx>
37 #include <Geom2d_Curve.hxx>
41 #include <TopoDS_Iterator.hxx>
42 #include <TopoDS_Face.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>
51 #include <BRep_Builder.hxx>
52 #include <BRep_Tool.hxx>
53 #include <BRepTools.hxx>
54 #include <BRepClass3d_SolidClassifier.hxx>
57 #include <TopExp_Explorer.hxx>
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>
71 #include <IntTools_Context.hxx>
73 #include <BOPTools_Tools2D.hxx>
74 #include <BOPTools_Tools3D.hxx>
76 #include <NMTTools_ListOfCoupleOfShape.hxx>
77 #include <NMTTools_CoupleOfShape.hxx>
78 #include <NMTTools_ListIteratorOfListOfCoupleOfShape.hxx>
80 #include <GEOMAlgo_Tools3D.hxx>
81 #include <GEOMAlgo_BuilderTools.hxx>
85 Standard_Boolean IsGrowthShell(const TopoDS_Shape& ,
86 const TopTools_IndexedMapOfShape& );
88 Standard_Boolean IsHole(const TopoDS_Shape& ,
91 Standard_Boolean IsInside(const TopoDS_Shape& ,
95 void MakeInternalShells(const TopTools_MapOfShape& ,
96 TopTools_ListOfShape& );
99 Standard_Boolean IsClosedShell(const TopoDS_Shell& );
101 //modified by NIZNHY-PKV Tue Oct 26 13:30:39 2010f
103 Standard_Boolean RefineShell(const TopoDS_Shell& ,
105 //modified by NIZNHY-PKV Tue Oct 26 13:30:42 2010t
107 //=======================================================================
110 //=======================================================================
111 GEOMAlgo_BuilderSolid::GEOMAlgo_BuilderSolid()
113 GEOMAlgo_BuilderArea()
116 //=======================================================================
119 //=======================================================================
120 GEOMAlgo_BuilderSolid::~GEOMAlgo_BuilderSolid()
123 //=======================================================================
126 //=======================================================================
127 void GEOMAlgo_BuilderSolid::Perform()
134 TopTools_ListIteratorOfListOfShape aIt;
136 aBB.MakeCompound(aC);
137 aIt.Initialize(myShapes);
138 for(; aIt.More(); aIt.Next()) {
139 const TopoDS_Shape& aF=aIt.Value();
144 if (myContext==NULL) {
145 myErrorStatus=11;// Null Context
149 PerformShapesToAvoid();
162 PerformInternalShapes();
167 //=======================================================================
168 //function :PerformShapesToAvoid
170 //=======================================================================
171 void GEOMAlgo_BuilderSolid::PerformShapesToAvoid()
173 Standard_Boolean bFound;
174 Standard_Integer i, iCnt, aNbE, aNbF;
175 TopAbs_Orientation aOrE;
176 TopTools_IndexedDataMapOfShapeListOfShape aMEF;
177 TopTools_ListIteratorOfListOfShape aIt;
179 myShapesToAvoid.Clear();
184 bFound=Standard_False;
188 aIt.Initialize (myShapes);
189 for (; aIt.More(); aIt.Next()) {
190 const TopoDS_Shape& aF=aIt.Value();
191 if (!myShapesToAvoid.Contains(aF)) {
192 TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
203 for (i=1; i<=aNbE; ++i) {
204 const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aMEF.FindKey(i)));
205 if (BRep_Tool::Degenerated(aE)) {
209 TopTools_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
216 aOrE=aE.Orientation();
218 const TopoDS_Face& aF1=*((TopoDS_Face*)(&aLF.First()));
220 if (aOrE==TopAbs_INTERNAL) {
223 bFound=Standard_True;
224 myShapesToAvoid.Add(aF1);
227 const TopoDS_Face& aF2=*((TopoDS_Face*)(&aLF.Last()));
228 if (aF2.IsSame(aF1)) {
229 if (BRep_Tool::IsClosed(aE, aF1)) {
233 if (aOrE==TopAbs_INTERNAL) {
237 bFound=Standard_True;
238 myShapesToAvoid.Add(aF1);
239 myShapesToAvoid.Add(aF2);
244 TopTools_ListIteratorOfListOfShape aItLF;
246 aItLF.Initialize (aLF);
247 for (; aItLF.More(); aItLF.Next()) {
248 const TopoDS_Shape& aFx=aItLF.Value();
253 }// for (i=1; i<=aNbE; ++i) {
261 //=======================================================================
262 //function : PerformLoops
264 //=======================================================================
265 void GEOMAlgo_BuilderSolid::PerformLoops()
271 Standard_Integer aNbLF, aNbOff, aNbFP;
272 TopAbs_Orientation anOr;
275 NMTTools_CoupleOfShape aCSOff;
276 TopTools_MapOfOrientedShape AddedFacesMap;
277 TopTools_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
278 TopTools_ListIteratorOfListOfShape aItF, aIt;
279 TopTools_MapIteratorOfMapOfOrientedShape aItM;
280 TopoDS_Iterator aItS;
282 //=================================================
286 aItF.Initialize (myShapes);
287 for (; aItF.More(); aItF.Next()) {
288 const TopoDS_Shape& aFF = aItF.Value();
289 TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
292 aItF.Initialize (myShapes);
293 for (; aItF.More(); aItF.Next()) {
294 const TopoDS_Shape& aFF = aItF.Value();
295 if (myShapesToAvoid.Contains(aFF)) {
298 if (!AddedFacesMap.Add(aFF)) {
304 aBB.MakeShell(aShell);
305 aBB.Add(aShell, aFF);
308 TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
310 // loop on faces added to Shell; add their neighbor faces to Shell and so on
311 TopoDS_Iterator aItAddedF (aShell);
312 for (; aItAddedF.More(); aItAddedF.Next()) {
313 const TopoDS_Face& aF = *((TopoDS_Face*)(&aItAddedF.Value()));
315 // loop on edges of aF; find a good neighbor face of aF by aE
316 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
317 for (; aEdgeExp.More(); aEdgeExp.Next()) {
318 const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aEdgeExp.Current()));
321 if (aMEFP.Contains(aE)) {
322 const TopTools_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
329 anOr=aE.Orientation();
330 if (anOr==TopAbs_INTERNAL) {
334 if (BRep_Tool::Degenerated(aE)) {
338 // candidate faces list
339 const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE);
345 // try to select one of neighbors
346 // check if a face already added to Shell shares E
347 Standard_Boolean bFound;
348 TopTools_ListIteratorOfListOfShape aItLF;
349 NMTTools_ListOfCoupleOfShape aLCSOff;
351 aItLF.Initialize(aLF);
352 for (; aItLF.More(); aItLF.Next()) {
353 const TopoDS_Face& aFL=*((TopoDS_Face*)(&aItLF.Value()));
354 if (myShapesToAvoid.Contains(aFL)) {
357 if (aF.IsSame(aFL)) {
360 if (AddedFacesMap.Contains(aFL)){
364 bFound=GEOMAlgo_Tools3D::GetEdgeOff(aE, aFL, aEL);
369 aCSOff.SetShape1(aEL);
370 aCSOff.SetShape2(aFL);
371 aLCSOff.Append(aCSOff);
372 }//for (; aItLF.More(); aItLF.Next()) {
374 aNbOff=aLCSOff.Extent();
381 aSelF=*((TopoDS_Face*)(&aLCSOff.First().Shape2()));
384 GEOMAlgo_Tools3D::GetFaceOff(aE, aF, aLCSOff, aSelF);
387 if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
388 aBB.Add(aShell, aSelF);
389 TopExp::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
391 } // for (; aEdgeExp.More(); aEdgeExp.Next()) {
392 } //for (; aItAddedF.More(); aItAddedF.Next()) {
394 if (IsClosedShell(aShell)) {
395 myLoops.Append(aShell);
397 //modified by NIZNHY-PKV Wed Oct 27 07:10:41 2010f
399 Standard_Boolean bRefine;
402 bRefine=RefineShell(aShell, aShx);
404 myLoops.Append(aShx);
407 //modified by NIZNHY-PKV Wed Oct 27 07:10:44 2010t
408 } // for (; aItF.More(); aItF.Next()) {
411 TopTools_MapOfOrientedShape aMP;
413 // a. collect all edges that are in loops
414 aIt.Initialize (myLoops);
415 for (; aIt.More(); aIt.Next()) {
416 const TopoDS_Shape& aS=aIt.Value();
418 for (; aItS.More(); aItS.Next()) {
419 const TopoDS_Shape& aF=aItS.Value();
424 // b. collect all faces that are to avoid
425 aItM.Initialize(myShapesToAvoid);
426 for (; aItM.More(); aItM.Next()) {
427 const TopoDS_Shape& aF=aItM.Key();
431 // c. add all faces that are not processed to myShapesToAvoid
432 aIt.Initialize (myShapes);
433 for (; aIt.More(); aIt.Next()) {
434 const TopoDS_Shape& aF=aIt.Value();
435 if (!aMP.Contains(aF)) {
436 myShapesToAvoid.Add(aF);
439 //=================================================
443 myLoopsInternal.Clear();
446 AddedFacesMap.Clear();
448 aItM.Initialize(myShapesToAvoid);
449 for (; aItM.More(); aItM.Next()) {
450 const TopoDS_Shape& aFF=aItM.Key();
451 TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
454 aItM.Initialize(myShapesToAvoid);
455 for (; aItM.More(); aItM.Next()) {
456 const TopoDS_Shape& aFF=aItM.Key();
457 if (!AddedFacesMap.Add(aFF)) {
463 aBB.MakeShell(aShell);
464 aBB.Add(aShell, aFF);
466 TopoDS_Iterator aItAddedF (aShell);
467 for (; aItAddedF.More(); aItAddedF.Next()) {
468 const TopoDS_Face& aF = *((TopoDS_Face*)(&aItAddedF.Value()));
470 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
471 for (; aEdgeExp.More(); aEdgeExp.Next()) {
472 const TopoDS_Edge& aE = *((TopoDS_Edge*)(&aEdgeExp.Current()));
473 const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE);
474 aItF.Initialize(aLF);
475 for (; aItF.More(); aItF.Next()) {
476 const TopoDS_Face& aFL=*((TopoDS_Face*)(&aItF.Value()));
477 if (AddedFacesMap.Add(aFL)){
478 aBB.Add(aShell, aFL);
483 myLoopsInternal.Append(aShell);
486 //=======================================================================
487 //function : PerformAreas
489 //=======================================================================
490 void GEOMAlgo_BuilderSolid::PerformAreas()
494 Standard_Boolean bIsGrowthShell, bIsHole;
495 TopTools_ListOfShape aNewSolids, aHoleShells;
496 TopoDS_Shape anInfinitePointShape;
497 TopTools_DataMapOfShapeShape aInOutMap;
498 TopTools_DataMapOfShapeListOfShape aMSH;
499 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
500 TopTools_ListIteratorOfListOfShape aShellIt, aSolidIt;
501 TopTools_IndexedMapOfShape aMHF;
506 // Draft solids [aNewSolids]
507 aShellIt.Initialize(myLoops);
508 for ( ; aShellIt.More(); aShellIt.Next()) {
509 const TopoDS_Shape& aShell = aShellIt.Value();
511 bIsGrowthShell=IsGrowthShell(aShell, aMHF);
512 if (bIsGrowthShell) {
513 // make a growth solid from a shell
515 aBB.MakeSolid(Solid);
516 aBB.Add (Solid, aShell);
518 aNewSolids.Append (Solid);
521 // check if a shell is a hole
522 bIsHole=IsHole(aShell, myContext);
525 aHoleShells.Append(aShell);
526 TopExp::MapShapes(aShell, TopAbs_FACE, aMHF);
529 // make a growth solid from a shell
531 aBB.MakeSolid(Solid);
532 aBB.Add (Solid, aShell);
534 aNewSolids.Append (Solid);
539 // 2. Find outer growth shell that is most close to each hole shell
540 aShellIt.Initialize(aHoleShells);
541 for (; aShellIt.More(); aShellIt.Next()) {
542 const TopoDS_Shape& aHole = aShellIt.Value();
544 aSolidIt.Initialize(aNewSolids);
545 for ( ; aSolidIt.More(); aSolidIt.Next()) {
546 const TopoDS_Shape& aSolid = aSolidIt.Value();
548 if (!IsInside(aHole, aSolid, myContext)){
552 if ( aInOutMap.IsBound (aHole)){
553 const TopoDS_Shape& aSolid2 = aInOutMap(aHole);
554 if (IsInside(aSolid, aSolid2, myContext)) {
555 aInOutMap.UnBind(aHole);
556 aInOutMap.Bind (aHole, aSolid);
560 aInOutMap.Bind (aHole, aSolid);
564 // Add aHole to a map Solid/ListOfHoles [aMSH]
565 if (aInOutMap.IsBound(aHole)){
566 const TopoDS_Shape& aSolid=aInOutMap(aHole);
567 if (aMSH.IsBound(aSolid)) {
568 TopTools_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
572 TopTools_ListOfShape aLH;
574 aMSH.Bind(aSolid, aLH);
576 //aBB.Add (aSolid, aHole);
578 }// for (; aShellIt.More(); aShellIt.Next()) {
580 // 3. Add aHoles to Solids
581 aItMSH.Initialize(aMSH);
582 for (; aItMSH.More(); aItMSH.Next()) {
583 TopoDS_Solid aSolid=*((TopoDS_Solid*)(&aItMSH.Key()));
585 const TopTools_ListOfShape& aLH=aItMSH.Value();
586 aShellIt.Initialize(aLH);
587 for (; aShellIt.More(); aShellIt.Next()) {
588 const TopoDS_Shape& aHole = aShellIt.Value();
589 aBB.Add (aSolid, aHole);
593 BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid);
598 // These aNewSolids are draft solids that
599 // do not contain any internal shapes
601 myAreas.Append(aNewSolids);
603 //=======================================================================
604 //function : PerformInternalShapes
606 //=======================================================================
607 void GEOMAlgo_BuilderSolid::PerformInternalShapes()
611 Standard_Integer aNbFI=myLoopsInternal.Extent();
612 if (!aNbFI) {// nothing to do
617 TopTools_ListIteratorOfListOfShape aShellIt, aSolidIt;
619 TopTools_MapOfShape aMF, aMFP;
620 TopTools_MapIteratorOfMapOfShape aItMF;
621 TopTools_IndexedDataMapOfShapeListOfShape aMEF;
622 TopTools_ListOfShape aLSI;
624 // 1. All internal faces
625 aShellIt.Initialize(myLoopsInternal);
626 for (; aShellIt.More(); aShellIt.Next()) {
627 const TopoDS_Shape& aShell=aShellIt.Value();
628 aIt.Initialize(aShell);
629 for (; aIt.More(); aIt.Next()) {
630 const TopoDS_Shape& aF=aIt.Value();
637 aSolidIt.Initialize(myAreas);
638 for ( ; aSolidIt.More(); aSolidIt.Next()) {
639 TopoDS_Solid& aSolid=*((TopoDS_Solid*)(&aSolidIt.Value()));
642 TopExp::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF);
644 // 2.1 Separate faces to process aMFP
646 aItMF.Initialize(aMF);
647 for (; aItMF.More(); aItMF.Next()) {
648 const TopoDS_Face& aF=*((TopoDS_Face*)(&aItMF.Key()));
649 if (GEOMAlgo_Tools3D::IsInternalFace(aF, aSolid, aMEF, 1.e-14, *myContext)) {
654 // 2.2 Make Internal Shells
656 MakeInternalShells(aMFP, aLSI);
658 // 2.3 Add them to aSolid
659 aShellIt.Initialize(aLSI);
660 for (; aShellIt.More(); aShellIt.Next()) {
661 const TopoDS_Shape& aSI=aShellIt.Value();
662 aBB.Add (aSolid, aSI);
665 // 2.4 Remove faces aMFP from aMF
666 aItMF.Initialize(aMFP);
667 for (; aItMF.More(); aItMF.Next()) {
668 const TopoDS_Shape& aF=aItMF.Key();
676 } //for ( ; aSolidIt.More(); aSolidIt.Next()) {
679 //=======================================================================
680 //function : MakeInternalShells
682 //=======================================================================
683 void MakeInternalShells(const TopTools_MapOfShape& theMF,
684 TopTools_ListOfShape& theShells)
686 TopTools_MapIteratorOfMapOfShape aItM;
687 TopTools_MapOfShape aAddedFacesMap;
688 TopTools_ListIteratorOfListOfShape aItF;
689 TopTools_IndexedDataMapOfShapeListOfShape aMEF;
692 aItM.Initialize(theMF);
693 for (; aItM.More(); aItM.Next()) {
694 const TopoDS_Shape& aF=aItM.Key();
695 TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
698 aItM.Initialize(theMF);
699 for (; aItM.More(); aItM.Next()) {
700 TopoDS_Shape aFF=aItM.Key();
701 if (!aAddedFacesMap.Add(aFF)) {
707 aBB.MakeShell(aShell);
708 aFF.Orientation(TopAbs_INTERNAL);
709 aBB.Add(aShell, aFF);
711 TopoDS_Iterator aItAddedF (aShell);
712 for (; aItAddedF.More(); aItAddedF.Next()) {
713 const TopoDS_Shape& aF =aItAddedF.Value();
715 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
716 for (; aEdgeExp.More(); aEdgeExp.Next()) {
717 const TopoDS_Shape& aE =aEdgeExp.Current();
718 const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE);
719 aItF.Initialize(aLF);
720 for (; aItF.More(); aItF.Next()) {
721 TopoDS_Shape aFL=aItF.Value();
722 if (aAddedFacesMap.Add(aFL)){
723 aFL.Orientation(TopAbs_INTERNAL);
724 aBB.Add(aShell, aFL);
729 theShells.Append(aShell);
732 //=======================================================================
735 //=======================================================================
736 Standard_Boolean IsHole(const TopoDS_Shape& theS2,
737 IntTools_PContext& theContext)
739 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
740 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
742 aClsf.PerformInfinitePoint(::RealSmall());
744 return (aClsf.State()==TopAbs_IN);
746 //=======================================================================
747 //function : IsInside
749 //=======================================================================
750 Standard_Boolean IsInside(const TopoDS_Shape& theS1,
751 const TopoDS_Shape& theS2,
752 IntTools_PContext& theContext)
754 TopExp_Explorer aExp;
757 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
759 aExp.Init(theS1, TopAbs_FACE);
761 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
762 aClsf.PerformInfinitePoint(::RealSmall());
763 aState=aClsf.State();
766 TopTools_IndexedMapOfShape aBounds;
767 const TopoDS_Face& aF = TopoDS::Face(aExp.Current());
768 aState=GEOMAlgo_Tools3D::ComputeState(aF, *pS2, 1.e-14, aBounds, *theContext);
770 return (aState==TopAbs_IN);
772 //=======================================================================
773 //function : IsGrowthShell
775 //=======================================================================
776 Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
777 const TopTools_IndexedMapOfShape& theMHF)
779 Standard_Boolean bRet;
783 if (theMHF.Extent()) {
784 aIt.Initialize(theShell);
785 for(; aIt.More(); aIt.Next()) {
786 const TopoDS_Shape& aF=aIt.Value();
787 if (theMHF.Contains(aF)) {
794 //=======================================================================
795 //function : IsClosedShell
797 //=======================================================================
798 Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
800 Standard_Integer aNbE;
801 Standard_Boolean bRet;
803 TopExp_Explorer aExp;
804 TopTools_MapOfShape aM;
807 aIt.Initialize(theShell);
808 for(; aIt.More(); aIt.Next()) {
809 const TopoDS_Face& aF=TopoDS::Face(aIt.Value());
810 aExp.Init(aF, TopAbs_EDGE);
811 for (; aExp.More(); aExp.Next()) {
812 const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aExp.Current()));
813 if (BRep_Tool::Degenerated(aE)) {
817 if (aE.Orientation()==TopAbs_INTERNAL) {
833 //modified by NIZNHY-PKV Tue Oct 26 13:30:23 2010f
834 //=======================================================================
835 //function : RefineShell
837 //=======================================================================
838 Standard_Boolean RefineShell(const TopoDS_Shell& aShell,
842 Standard_Boolean bRet;
843 Standard_Integer i, aNbE, aNbF;
844 TopAbs_Orientation aOrE;
845 TopTools_IndexedDataMapOfShapeListOfShape aMEF;
846 TopTools_MapOfOrientedShape aMFx;
850 TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
852 for (i=1; i<=aNbE; ++i) {
853 const TopoDS_Edge &aE=*((TopoDS_Edge*)(&aMEF.FindKey(i)));
855 if (BRep_Tool::Degenerated(aE)) {
859 aOrE=aE.Orientation();
861 const TopTools_ListOfShape& aLF=aMEF(i);
867 const TopoDS_Face& aF1=*((TopoDS_Face*)(&aLF.First()));
869 if (aOrE==TopAbs_INTERNAL) {
876 const TopoDS_Face& aF2=*((TopoDS_Face*)(&aLF.Last()));
877 if (aF2.IsSame(aF1)) {
878 if (BRep_Tool::IsClosed(aE, aF1)) {
881 if (aOrE==TopAbs_INTERNAL) {
900 aIt.Initialize(aShell);
901 for (; aIt.More(); aIt.Next()) {
902 const TopoDS_Shape& aF=aIt.Value();
903 if (!aMFx.Contains(aF)) {
910 bRet=IsClosedShell(aShx);
915 //modified by NIZNHY-PKV Tue Oct 26 13:30:26 2010t