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 if (myComputeInternalShapes) {
163 PerformInternalShapes();
169 //=======================================================================
170 //function :PerformShapesToAvoid
172 //=======================================================================
173 void GEOMAlgo_BuilderSolid::PerformShapesToAvoid()
175 Standard_Boolean bFound;
176 Standard_Integer i, iCnt, aNbE, aNbF;
177 TopAbs_Orientation aOrE;
178 TopTools_IndexedDataMapOfShapeListOfShape aMEF;
179 TopTools_ListIteratorOfListOfShape aIt;
181 myShapesToAvoid.Clear();
186 bFound=Standard_False;
190 aIt.Initialize (myShapes);
191 for (; aIt.More(); aIt.Next()) {
192 const TopoDS_Shape& aF=aIt.Value();
193 if (!myShapesToAvoid.Contains(aF)) {
194 TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
205 for (i=1; i<=aNbE; ++i) {
206 const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aMEF.FindKey(i)));
207 if (BRep_Tool::Degenerated(aE)) {
211 TopTools_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
218 aOrE=aE.Orientation();
220 const TopoDS_Face& aF1=*((TopoDS_Face*)(&aLF.First()));
222 if (aOrE==TopAbs_INTERNAL) {
225 bFound=Standard_True;
226 myShapesToAvoid.Add(aF1);
229 const TopoDS_Face& aF2=*((TopoDS_Face*)(&aLF.Last()));
230 if (aF2.IsSame(aF1)) {
231 if (BRep_Tool::IsClosed(aE, aF1)) {
235 if (aOrE==TopAbs_INTERNAL) {
239 bFound=Standard_True;
240 myShapesToAvoid.Add(aF1);
241 myShapesToAvoid.Add(aF2);
246 TopTools_ListIteratorOfListOfShape aItLF;
248 aItLF.Initialize (aLF);
249 for (; aItLF.More(); aItLF.Next()) {
250 const TopoDS_Shape& aFx=aItLF.Value();
255 }// for (i=1; i<=aNbE; ++i) {
263 //=======================================================================
264 //function : PerformLoops
266 //=======================================================================
267 void GEOMAlgo_BuilderSolid::PerformLoops()
273 Standard_Integer aNbLF, aNbOff, aNbFP;
274 TopAbs_Orientation anOr;
277 NMTTools_CoupleOfShape aCSOff;
278 TopTools_MapOfOrientedShape AddedFacesMap;
279 TopTools_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
280 TopTools_ListIteratorOfListOfShape aItF, aIt;
281 TopTools_MapIteratorOfMapOfOrientedShape aItM;
282 TopoDS_Iterator aItS;
284 //=================================================
288 aItF.Initialize (myShapes);
289 for (; aItF.More(); aItF.Next()) {
290 const TopoDS_Shape& aFF = aItF.Value();
291 TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
294 aItF.Initialize (myShapes);
295 for (; aItF.More(); aItF.Next()) {
296 const TopoDS_Shape& aFF = aItF.Value();
297 if (myShapesToAvoid.Contains(aFF)) {
300 if (!AddedFacesMap.Add(aFF)) {
306 aBB.MakeShell(aShell);
307 aBB.Add(aShell, aFF);
310 TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
312 // loop on faces added to Shell; add their neighbor faces to Shell and so on
313 TopoDS_Iterator aItAddedF (aShell);
314 for (; aItAddedF.More(); aItAddedF.Next()) {
315 const TopoDS_Face& aF = *((TopoDS_Face*)(&aItAddedF.Value()));
317 // loop on edges of aF; find a good neighbor face of aF by aE
318 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
319 for (; aEdgeExp.More(); aEdgeExp.Next()) {
320 const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aEdgeExp.Current()));
323 if (aMEFP.Contains(aE)) {
324 const TopTools_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
331 anOr=aE.Orientation();
332 if (anOr==TopAbs_INTERNAL) {
336 if (BRep_Tool::Degenerated(aE)) {
340 // candidate faces list
341 const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE);
347 // try to select one of neighbors
348 // check if a face already added to Shell shares E
349 Standard_Boolean bFound;
350 TopTools_ListIteratorOfListOfShape aItLF;
351 NMTTools_ListOfCoupleOfShape aLCSOff;
353 aItLF.Initialize(aLF);
354 for (; aItLF.More(); aItLF.Next()) {
355 const TopoDS_Face& aFL=*((TopoDS_Face*)(&aItLF.Value()));
356 if (myShapesToAvoid.Contains(aFL)) {
359 if (aF.IsSame(aFL)) {
362 if (AddedFacesMap.Contains(aFL)){
366 bFound=GEOMAlgo_Tools3D::GetEdgeOff(aE, aFL, aEL);
371 aCSOff.SetShape1(aEL);
372 aCSOff.SetShape2(aFL);
373 aLCSOff.Append(aCSOff);
374 }//for (; aItLF.More(); aItLF.Next()) {
376 aNbOff=aLCSOff.Extent();
383 aSelF=*((TopoDS_Face*)(&aLCSOff.First().Shape2()));
386 GEOMAlgo_Tools3D::GetFaceOff(aE, aF, aLCSOff, aSelF);
389 if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
390 aBB.Add(aShell, aSelF);
391 TopExp::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
393 } // for (; aEdgeExp.More(); aEdgeExp.Next()) {
394 } //for (; aItAddedF.More(); aItAddedF.Next()) {
396 if (IsClosedShell(aShell)) {
397 myLoops.Append(aShell);
399 //modified by NIZNHY-PKV Wed Oct 27 07:10:41 2010f
401 Standard_Boolean bRefine;
404 bRefine=RefineShell(aShell, aShx);
406 myLoops.Append(aShx);
409 //modified by NIZNHY-PKV Wed Oct 27 07:10:44 2010t
410 } // for (; aItF.More(); aItF.Next()) {
413 TopTools_MapOfOrientedShape aMP;
415 // a. collect all edges that are in loops
416 aIt.Initialize (myLoops);
417 for (; aIt.More(); aIt.Next()) {
418 const TopoDS_Shape& aS=aIt.Value();
420 for (; aItS.More(); aItS.Next()) {
421 const TopoDS_Shape& aF=aItS.Value();
426 // b. collect all faces that are to avoid
427 aItM.Initialize(myShapesToAvoid);
428 for (; aItM.More(); aItM.Next()) {
429 const TopoDS_Shape& aF=aItM.Key();
433 // c. add all faces that are not processed to myShapesToAvoid
434 aIt.Initialize (myShapes);
435 for (; aIt.More(); aIt.Next()) {
436 const TopoDS_Shape& aF=aIt.Value();
437 if (!aMP.Contains(aF)) {
438 myShapesToAvoid.Add(aF);
441 //=================================================
445 myLoopsInternal.Clear();
448 AddedFacesMap.Clear();
450 if (myComputeInternalShapes) {
451 aItM.Initialize(myShapesToAvoid);
452 for (; aItM.More(); aItM.Next()) {
453 const TopoDS_Shape& aFF=aItM.Key();
454 TopExp::MapShapesAndAncestors(aFF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
457 aItM.Initialize(myShapesToAvoid);
458 for (; aItM.More(); aItM.Next()) {
459 const TopoDS_Shape& aFF=aItM.Key();
460 if (!AddedFacesMap.Add(aFF)) {
466 aBB.MakeShell(aShell);
467 aBB.Add(aShell, aFF);
469 TopoDS_Iterator aItAddedF (aShell);
470 for (; aItAddedF.More(); aItAddedF.Next()) {
471 const TopoDS_Face& aF = *((TopoDS_Face*)(&aItAddedF.Value()));
473 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
474 for (; aEdgeExp.More(); aEdgeExp.Next()) {
475 const TopoDS_Edge& aE = *((TopoDS_Edge*)(&aEdgeExp.Current()));
476 const TopTools_ListOfShape& aLF=aEFMap.FindFromKey(aE);
477 aItF.Initialize(aLF);
478 for (; aItF.More(); aItF.Next()) {
479 const TopoDS_Face& aFL=*((TopoDS_Face*)(&aItF.Value()));
480 if (AddedFacesMap.Add(aFL)){
481 aBB.Add(aShell, aFL);
486 myLoopsInternal.Append(aShell);
490 //=======================================================================
491 //function : PerformAreas
493 //=======================================================================
494 void GEOMAlgo_BuilderSolid::PerformAreas()
498 Standard_Boolean bIsGrowthShell, bIsHole;
499 TopTools_ListOfShape aNewSolids, aHoleShells;
500 TopoDS_Shape anInfinitePointShape;
501 TopTools_DataMapOfShapeShape aInOutMap;
502 TopTools_DataMapOfShapeListOfShape aMSH;
503 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape aItMSH;
504 TopTools_ListIteratorOfListOfShape aShellIt, aSolidIt;
505 TopTools_IndexedMapOfShape aMHF;
510 // Draft solids [aNewSolids]
511 aShellIt.Initialize(myLoops);
512 for ( ; aShellIt.More(); aShellIt.Next()) {
513 const TopoDS_Shape& aShell = aShellIt.Value();
515 bIsGrowthShell=IsGrowthShell(aShell, aMHF);
516 if (bIsGrowthShell) {
517 // make a growth solid from a shell
519 aBB.MakeSolid(Solid);
520 aBB.Add (Solid, aShell);
522 aNewSolids.Append (Solid);
525 // check if a shell is a hole
526 bIsHole=IsHole(aShell, myContext);
529 aHoleShells.Append(aShell);
530 TopExp::MapShapes(aShell, TopAbs_FACE, aMHF);
533 // make a growth solid from a shell
535 aBB.MakeSolid(Solid);
536 aBB.Add (Solid, aShell);
538 aNewSolids.Append (Solid);
543 // 2. Find outer growth shell that is most close to each hole shell
544 aShellIt.Initialize(aHoleShells);
545 for (; aShellIt.More(); aShellIt.Next()) {
546 const TopoDS_Shape& aHole = aShellIt.Value();
548 aSolidIt.Initialize(aNewSolids);
549 for ( ; aSolidIt.More(); aSolidIt.Next()) {
550 const TopoDS_Shape& aSolid = aSolidIt.Value();
552 if (!IsInside(aHole, aSolid, myContext)){
556 if ( aInOutMap.IsBound (aHole)){
557 const TopoDS_Shape& aSolid2 = aInOutMap(aHole);
558 if (IsInside(aSolid, aSolid2, myContext)) {
559 aInOutMap.UnBind(aHole);
560 aInOutMap.Bind (aHole, aSolid);
564 aInOutMap.Bind (aHole, aSolid);
568 // Add aHole to a map Solid/ListOfHoles [aMSH]
569 if (aInOutMap.IsBound(aHole)){
570 const TopoDS_Shape& aSolid=aInOutMap(aHole);
571 if (aMSH.IsBound(aSolid)) {
572 TopTools_ListOfShape& aLH=aMSH.ChangeFind(aSolid);
576 TopTools_ListOfShape aLH;
578 aMSH.Bind(aSolid, aLH);
580 //aBB.Add (aSolid, aHole);
582 }// for (; aShellIt.More(); aShellIt.Next()) {
584 // 3. Add aHoles to Solids
585 aItMSH.Initialize(aMSH);
586 for (; aItMSH.More(); aItMSH.Next()) {
587 TopoDS_Solid aSolid=*((TopoDS_Solid*)(&aItMSH.Key()));
589 const TopTools_ListOfShape& aLH=aItMSH.Value();
590 aShellIt.Initialize(aLH);
591 for (; aShellIt.More(); aShellIt.Next()) {
592 const TopoDS_Shape& aHole = aShellIt.Value();
593 aBB.Add (aSolid, aHole);
597 BRepClass3d_SolidClassifier& aSC=myContext->SolidClassifier(aSolid);
602 // These aNewSolids are draft solids that
603 // do not contain any internal shapes
605 myAreas.Append(aNewSolids);
607 //=======================================================================
608 //function : PerformInternalShapes
610 //=======================================================================
611 void GEOMAlgo_BuilderSolid::PerformInternalShapes()
615 Standard_Integer aNbFI=myLoopsInternal.Extent();
616 if (!aNbFI) {// nothing to do
621 TopTools_ListIteratorOfListOfShape aShellIt, aSolidIt;
623 TopTools_MapOfShape aMF, aMFP;
624 TopTools_MapIteratorOfMapOfShape aItMF;
625 TopTools_IndexedDataMapOfShapeListOfShape aMEF;
626 TopTools_ListOfShape aLSI;
628 // 1. All internal faces
629 aShellIt.Initialize(myLoopsInternal);
630 for (; aShellIt.More(); aShellIt.Next()) {
631 const TopoDS_Shape& aShell=aShellIt.Value();
632 aIt.Initialize(aShell);
633 for (; aIt.More(); aIt.Next()) {
634 const TopoDS_Shape& aF=aIt.Value();
641 aSolidIt.Initialize(myAreas);
642 for ( ; aSolidIt.More(); aSolidIt.Next()) {
643 TopoDS_Solid& aSolid=*((TopoDS_Solid*)(&aSolidIt.Value()));
646 TopExp::MapShapesAndAncestors(aSolid, TopAbs_EDGE, TopAbs_FACE, aMEF);
648 // 2.1 Separate faces to process aMFP
650 aItMF.Initialize(aMF);
651 for (; aItMF.More(); aItMF.Next()) {
652 const TopoDS_Face& aF=*((TopoDS_Face*)(&aItMF.Key()));
653 if (GEOMAlgo_Tools3D::IsInternalFace(aF, aSolid, aMEF, 1.e-14, *myContext)) {
658 // 2.2 Make Internal Shells
660 MakeInternalShells(aMFP, aLSI);
662 // 2.3 Add them to aSolid
663 aShellIt.Initialize(aLSI);
664 for (; aShellIt.More(); aShellIt.Next()) {
665 const TopoDS_Shape& aSI=aShellIt.Value();
666 aBB.Add (aSolid, aSI);
669 // 2.4 Remove faces aMFP from aMF
670 aItMF.Initialize(aMFP);
671 for (; aItMF.More(); aItMF.Next()) {
672 const TopoDS_Shape& aF=aItMF.Key();
680 } //for ( ; aSolidIt.More(); aSolidIt.Next()) {
683 //=======================================================================
684 //function : MakeInternalShells
686 //=======================================================================
687 void MakeInternalShells(const TopTools_MapOfShape& theMF,
688 TopTools_ListOfShape& theShells)
690 TopTools_MapIteratorOfMapOfShape aItM;
691 TopTools_MapOfShape aAddedFacesMap;
692 TopTools_ListIteratorOfListOfShape aItF;
693 TopTools_IndexedDataMapOfShapeListOfShape aMEF;
696 aItM.Initialize(theMF);
697 for (; aItM.More(); aItM.Next()) {
698 const TopoDS_Shape& aF=aItM.Key();
699 TopExp::MapShapesAndAncestors(aF, TopAbs_EDGE, TopAbs_FACE, aMEF);
702 aItM.Initialize(theMF);
703 for (; aItM.More(); aItM.Next()) {
704 TopoDS_Shape aFF=aItM.Key();
705 if (!aAddedFacesMap.Add(aFF)) {
711 aBB.MakeShell(aShell);
712 aFF.Orientation(TopAbs_INTERNAL);
713 aBB.Add(aShell, aFF);
715 TopoDS_Iterator aItAddedF (aShell);
716 for (; aItAddedF.More(); aItAddedF.Next()) {
717 const TopoDS_Shape& aF =aItAddedF.Value();
719 TopExp_Explorer aEdgeExp(aF, TopAbs_EDGE);
720 for (; aEdgeExp.More(); aEdgeExp.Next()) {
721 const TopoDS_Shape& aE =aEdgeExp.Current();
722 const TopTools_ListOfShape& aLF=aMEF.FindFromKey(aE);
723 aItF.Initialize(aLF);
724 for (; aItF.More(); aItF.Next()) {
725 TopoDS_Shape aFL=aItF.Value();
726 if (aAddedFacesMap.Add(aFL)){
727 aFL.Orientation(TopAbs_INTERNAL);
728 aBB.Add(aShell, aFL);
733 theShells.Append(aShell);
736 //=======================================================================
739 //=======================================================================
740 Standard_Boolean IsHole(const TopoDS_Shape& theS2,
741 IntTools_PContext& theContext)
743 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
744 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
746 aClsf.PerformInfinitePoint(::RealSmall());
748 return (aClsf.State()==TopAbs_IN);
750 //=======================================================================
751 //function : IsInside
753 //=======================================================================
754 Standard_Boolean IsInside(const TopoDS_Shape& theS1,
755 const TopoDS_Shape& theS2,
756 IntTools_PContext& theContext)
758 TopExp_Explorer aExp;
761 TopoDS_Solid *pS2=(TopoDS_Solid *)&theS2;
763 aExp.Init(theS1, TopAbs_FACE);
765 BRepClass3d_SolidClassifier& aClsf=theContext->SolidClassifier(*pS2);
766 aClsf.PerformInfinitePoint(::RealSmall());
767 aState=aClsf.State();
770 TopTools_IndexedMapOfShape aBounds;
771 const TopoDS_Face& aF = TopoDS::Face(aExp.Current());
772 aState=GEOMAlgo_Tools3D::ComputeState(aF, *pS2, 1.e-14, aBounds, *theContext);
774 return (aState==TopAbs_IN);
776 //=======================================================================
777 //function : IsGrowthShell
779 //=======================================================================
780 Standard_Boolean IsGrowthShell(const TopoDS_Shape& theShell,
781 const TopTools_IndexedMapOfShape& theMHF)
783 Standard_Boolean bRet;
787 if (theMHF.Extent()) {
788 aIt.Initialize(theShell);
789 for(; aIt.More(); aIt.Next()) {
790 const TopoDS_Shape& aF=aIt.Value();
791 if (theMHF.Contains(aF)) {
798 //=======================================================================
799 //function : IsClosedShell
801 //=======================================================================
802 Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
804 Standard_Integer aNbE;
805 Standard_Boolean bRet;
807 TopExp_Explorer aExp;
808 TopTools_MapOfShape aM;
811 aIt.Initialize(theShell);
812 for(; aIt.More(); aIt.Next()) {
813 const TopoDS_Face& aF=TopoDS::Face(aIt.Value());
814 aExp.Init(aF, TopAbs_EDGE);
815 for (; aExp.More(); aExp.Next()) {
816 const TopoDS_Edge& aE=*((TopoDS_Edge*)(&aExp.Current()));
817 if (BRep_Tool::Degenerated(aE)) {
821 if (aE.Orientation()==TopAbs_INTERNAL) {
837 //modified by NIZNHY-PKV Tue Oct 26 13:30:23 2010f
838 //=======================================================================
839 //function : RefineShell
841 //=======================================================================
842 Standard_Boolean RefineShell(const TopoDS_Shell& aShell,
846 Standard_Boolean bRet;
847 Standard_Integer i, aNbE, aNbF;
848 TopAbs_Orientation aOrE;
849 TopTools_IndexedDataMapOfShapeListOfShape aMEF;
850 TopTools_MapOfOrientedShape aMFx;
854 TopExp::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEF);
856 for (i=1; i<=aNbE; ++i) {
857 const TopoDS_Edge &aE=*((TopoDS_Edge*)(&aMEF.FindKey(i)));
859 if (BRep_Tool::Degenerated(aE)) {
863 aOrE=aE.Orientation();
865 const TopTools_ListOfShape& aLF=aMEF(i);
871 const TopoDS_Face& aF1=*((TopoDS_Face*)(&aLF.First()));
873 if (aOrE==TopAbs_INTERNAL) {
880 const TopoDS_Face& aF2=*((TopoDS_Face*)(&aLF.Last()));
881 if (aF2.IsSame(aF1)) {
882 if (BRep_Tool::IsClosed(aE, aF1)) {
885 if (aOrE==TopAbs_INTERNAL) {
904 aIt.Initialize(aShell);
905 for (; aIt.More(); aIt.Next()) {
906 const TopoDS_Shape& aF=aIt.Value();
907 if (!aMFx.Contains(aF)) {
914 bRet=IsClosedShell(aShx);
919 //modified by NIZNHY-PKV Tue Oct 26 13:30:26 2010t