1 // Created on: 2001-04-09
2 // Created by: Peter KURNEV
3 // Copyright (c) 2001-2012 OPEN CASCADE SAS
5 // The content of this file is subject to the Open CASCADE Technology Public
6 // License Version 6.5 (the "License"). You may not use the content of this file
7 // except in compliance with the License. Please obtain a copy of the License
8 // at http://www.opencascade.org and read it completely before using this file.
10 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
13 // The Original Code and all software distributed under the License is
14 // distributed on an "AS IS" basis, without warranty of any kind, and the
15 // Initial Developer hereby disclaims all such warranties, including without
16 // limitation, any warranties of merchantability, fitness for a particular
17 // purpose or non-infringement. Please see the License for the specific terms
18 // and conditions governing the rights and limitations under the License.
22 #include <BOP_ShellSplitter.ixx>
24 #include <TColStd_SequenceOfInteger.hxx>
26 #include <Geom_Surface.hxx>
29 #include <TopoDS_Edge.hxx>
30 #include <TopoDS_Face.hxx>
31 #include <TopoDS_Shell.hxx>
32 #include <TopoDS_Vertex.hxx>
33 #include <TopoDS_Wire.hxx>
34 #include <TopoDS_Iterator.hxx>
35 #include <TopoDS_Shape.hxx>
36 #include <TopoDS_Compound.hxx>
39 #include <TopExp_Explorer.hxx>
40 #include <TopLoc_Location.hxx>
42 #include <TopTools_ListOfShape.hxx>
43 #include <TopTools_ListIteratorOfListOfShape.hxx>
44 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
45 #include <TopTools_SequenceOfShape.hxx>
46 #include <TopTools_MapOfShape.hxx>
47 #include <TopTools_MapIteratorOfMapOfShape.hxx>
48 #include <TopTools_DataMapOfShapeShape.hxx>
49 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
50 #include <TopTools_IndexedMapOfShape.hxx>
52 #include <BRep_Tool.hxx>
53 #include <BRep_Builder.hxx>
56 void RemoveInternals(const TopoDS_Face& ,
60 Standard_Boolean GetShells(TopTools_SequenceOfShape& ,
61 const TopTools_MapOfShape& ,
62 TopTools_SequenceOfShape& ,
63 TopTools_DataMapOfShapeShape& ,
64 TopTools_SequenceOfShape& ) ;
67 Standard_Boolean AddMultiConexityFaces(TopTools_SequenceOfShape& ,
68 const TopTools_MapOfShape& ,
69 TopTools_SequenceOfShape& ,
70 const TopTools_DataMapOfShapeShape& ,
71 const TopTools_IndexedDataMapOfShapeListOfShape& ,
72 TopTools_SequenceOfShape& );
75 Standard_Boolean SplitShell(const TopoDS_Shell& ,
78 void CreateClosedShell(TopTools_SequenceOfShape& ,
79 const TopTools_MapOfShape& ,
80 const TopTools_IndexedDataMapOfShapeListOfShape& );
82 //=======================================================================
83 // function: BOP_ShellSplitter::BOP_ShellSplitter
85 //=======================================================================
86 BOP_ShellSplitter::BOP_ShellSplitter()
88 myIsDone(Standard_False),
89 myNothingToDo(Standard_False)
93 //=======================================================================
94 // function: IsNothingToDo
96 //=======================================================================
97 Standard_Boolean BOP_ShellSplitter::IsNothingToDo()const
102 //=======================================================================
105 //=======================================================================
106 Standard_Boolean BOP_ShellSplitter::IsDone()const
111 //=======================================================================
114 //=======================================================================
115 const BOPTColStd_ListOfListOfShape& BOP_ShellSplitter::Shapes()const
120 //=======================================================================
121 // function: SetShell
123 //=======================================================================
124 void BOP_ShellSplitter::SetShell(const TopoDS_Shell& aShell)
128 //=======================================================================
131 //=======================================================================
132 const TopoDS_Shell& BOP_ShellSplitter::Shell()const
137 //=======================================================================
138 // function: DoWithShell
140 //=======================================================================
141 void BOP_ShellSplitter::DoWithShell ()
145 TopExp_Explorer anExpFaces (myShell, TopAbs_FACE);
146 for (; anExpFaces.More(); anExpFaces.Next()) {
147 const TopoDS_Face& aF = TopoDS::Face(anExpFaces.Current());
153 //=======================================================================
154 // function: DoWithListOfEdges
156 //=======================================================================
157 void BOP_ShellSplitter::DoWithListOfEdges(const TopTools_ListOfShape& aLE)
161 TopTools_ListIteratorOfListOfShape anItList;
163 anItList.Initialize(aLE);
164 for (; anItList.More(); anItList.Next()) {
165 const TopoDS_Face& aF = TopoDS::Face(anItList.Value());
171 //=======================================================================
174 //=======================================================================
175 void BOP_ShellSplitter::Do()
177 myIsDone=Standard_False;
178 myNothingToDo=Standard_False;
180 TopTools_ListIteratorOfListOfShape anItList;
181 TopTools_IndexedDataMapOfShapeShape aMFNewOld;
185 // insert the code about myNothingToDo
187 // 1. Make the formal shell
188 aBB.MakeShell(aShell);
190 anItList.Initialize(myFaces);
191 for (; anItList.More(); anItList.Next()) {
192 const TopoDS_Face& aF = TopoDS::Face(anItList.Value());
194 RemoveInternals (aF, aFNew);
195 aMFNewOld.Add (aFNew, aF);
197 aBB.Add(aShell, aFNew);
200 // 2. Split the Shell
203 SplitShell (aShell, aShape);
205 // 3. Post-pro the result aShape
206 // and filling the myShapes field .
207 TopExp_Explorer aShellExp(aShape, TopAbs_SHELL);
208 for (; aShellExp.More(); aShellExp.Next()) {
209 const TopoDS_Shape& aSh= aShellExp.Current();
211 TopTools_ListOfShape aLF;
212 TopExp_Explorer aFaceExp(aSh, TopAbs_FACE);
213 for (; aFaceExp.More(); aFaceExp.Next()) {
214 const TopoDS_Shape& aFNew= aFaceExp.Current();
216 const TopoDS_Shape& aFOld=aMFNewOld.FindFromKey(aFNew);
221 myShapes.Append(aLF);
225 myIsDone=Standard_True;
228 //=======================================================================
229 // function: RemoveInternals
231 //=======================================================================
232 void RemoveInternals(const TopoDS_Face& aF,
236 Standard_Integer iCnt;
240 TopLoc_Location aLoc;
241 Handle(Geom_Surface) aSurface=BRep_Tool::Surface(aF, aLoc);
242 aTol=BRep_Tool::Tolerance(aF);
243 aBB.MakeFace (aFNew, aSurface, aLoc, aTol);
244 aFNew.Orientation(aF.Orientation());
246 TopExp_Explorer aFExp(aF, TopAbs_WIRE);
247 for (; aFExp.More(); aFExp.Next()) {
248 const TopoDS_Wire& aW= TopoDS::Wire(aFExp.Current());
251 aWNew.Orientation(aW.Orientation());
254 TopExp_Explorer aWExp(aW, TopAbs_EDGE);
255 for (; aWExp.More(); aWExp.Next()) {
256 const TopoDS_Edge& aE=TopoDS::Edge(aWExp.Current());
257 if (aE.Orientation()!=TopAbs_INTERNAL) {
263 aBB.Add(aFNew, aWNew);
270 //=======================================================================
271 // function : SplitShell
273 //=======================================================================
274 Standard_Boolean SplitShell (const TopoDS_Shell& aShellIn,
275 TopoDS_Shape& aShellsOut)
277 Standard_Boolean done;
278 Standard_Integer i, j, aNumMultShell;
280 TopTools_SequenceOfShape aSeqShells, aErrFaces, Lface;
281 TopTools_DataMapOfShapeShape aMapFaceShells;
282 TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
283 TopTools_MapOfShape aMapMultiConnectEdges;
284 TopoDS_Compound aCmpErrFaces;
286 done = Standard_False;
288 aShellsOut = aShellIn;
290 TopoDS_Iterator iter(aShellIn);
291 for (; iter.More(); iter.Next()) {
292 Lface.Append(iter.Value());
295 TopExp::MapShapesAndAncestors(aShellIn, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
297 //Finds multishared edges
298 Standard_Integer aNbEdges, aNbFaces;
299 aNbEdges=aMapEdgeFaces.Extent();
300 for(j=1; j<=aNbEdges; j++) {
301 const TopTools_ListOfShape& aLF=aMapEdgeFaces(j);
302 aNbFaces=aLF.Extent();
304 const TopoDS_Shape& aE=aMapEdgeFaces.FindKey(j);
305 aMapMultiConnectEdges.Add(aE);
309 //Gets shells without taking in account of multiconnexity.
310 Standard_Boolean isGetShells = Standard_True;
312 while(isGetShells && Lface.Length()) {
313 TopTools_SequenceOfShape aTmpSeqShells;
314 Standard_Boolean bGetShells;
316 bGetShells=GetShells(Lface,
317 aMapMultiConnectEdges,
322 done = Standard_True;
325 isGetShells = !aTmpSeqShells.IsEmpty();
327 aSeqShells.Append(aTmpSeqShells);
332 Standard_Boolean aIsDone = Standard_False;
333 Standard_Integer aLfaceLength, aErrFacesLength;
335 aLfaceLength=Lface.Length();
336 aNumMultShell=aSeqShells.Length();
338 if(aLfaceLength && aNumMultShell) {
339 //Crating shells in the case of compsolid
340 aIsDone = AddMultiConexityFaces(Lface,
341 aMapMultiConnectEdges,
348 aNumMultShell = aSeqShells.Length();
349 aErrFacesLength=aErrFaces.Length();
351 if (aErrFacesLength) {
353 TopoDS_Compound aCompShells;
355 B.MakeCompound (aCmpErrFaces);
356 B.MakeCompound(aCompShells);
358 for(j =1; j <= aErrFacesLength; j++){
359 B.Add(aCmpErrFaces, aErrFaces.Value(j));
364 if(aNumMultShell == 1) {
365 aShellsOut = aSeqShells.Value(1);
366 B.Add(aCompShells, aSeqShells.Value(1));
368 for(j=1; j <= aErrFacesLength; j++) {
371 B.Add(aSh, aErrFaces.Value(j));
372 B.Add(aCompShells, aSh);
374 aShellsOut = aCompShells;
378 for(i=1; i <= aNumMultShell; i++) {
379 B.Add(aCompShells, aSeqShells.Value(i));
382 for(j=1; j<= aErrFacesLength; j++) {
385 B.Add(aSh,aErrFaces.Value(j));
386 B.Add(aCompShells, aSh);
388 aShellsOut = aCompShells;
390 } //if(aNumMultShell)
392 done = Standard_True;
394 } // if (aErrFacesLength)
397 if(aNumMultShell>1) {
398 TopTools_SequenceOfShape OpenShells;
400 for(i=1; i <= aSeqShells.Length(); i++) {
401 TopoDS_Shape aShell = aSeqShells.Value(i);
402 if(!BRep_Tool::IsClosed(aShell)) {
403 OpenShells.Append(aShell);
404 aSeqShells.Remove(i--);
408 j=OpenShells.Length();
410 // Attempt of creation closed shell from open shells
411 // with taking into account multiconnexity.
413 CreateClosedShell(OpenShells, aMapMultiConnectEdges, aMapEdgeFaces);
414 aSeqShells.Append(OpenShells);
416 } //if(aNumMultShell>1)
421 for(i=1; i <= j; i++) {
423 TopoDS_Shell OneShell;
424 aB.MakeShell(OneShell);
425 aB.Add(OneShell, Lface.Value(i));
426 aSeqShells.Append(OneShell);
431 aNumMultShell = aSeqShells.Length();
433 done = (aNumMultShell>1 || aIsDone);
437 TopoDS_Compound aCompShells;
438 B.MakeCompound(aCompShells);
439 for(i=1; i <= aNumMultShell; i++){
440 B.Add(aCompShells, aSeqShells.Value(i));
442 aShellsOut = aCompShells;
447 //=======================================================================
448 // function : GetShells
450 //=======================================================================
451 Standard_Boolean GetShells(TopTools_SequenceOfShape& Lface,
452 const TopTools_MapOfShape& aMapMultiConnectEdges,
453 TopTools_SequenceOfShape& aSeqShells,
454 TopTools_DataMapOfShapeShape& aMapFaceShells,
455 TopTools_SequenceOfShape& ErrFaces)
457 Standard_Boolean done = Standard_False;
458 Standard_Integer i, j, aNbLfaceLength;
465 Standard_Boolean isMultiConnex;
467 TopTools_MapOfShape dire, reve;
469 TopTools_SequenceOfShape aSeqUnconnectFaces;
472 isMultiConnex = !aMapMultiConnectEdges.IsEmpty();
476 for(; i<=Lface.Length(); i++) {
477 aNbLfaceLength=Lface.Length();
478 TopTools_MapOfShape dtemp, rtemp;
479 Standard_Integer nbbe=0, nbe = 0;
481 TopoDS_Face aF = TopoDS::Face(Lface.Value(i));
483 TopExp_Explorer anExpe(aF, TopAbs_EDGE);
484 for(; anExpe.More(); anExpe.Next()) {
485 const TopoDS_Edge& aE = TopoDS::Edge(anExpe.Current());
487 if(isMultiConnex && aMapMultiConnectEdges.Contains(aE)){
491 if (BRep_Tool::Degenerated (aE)) {
495 if (BRep_Tool::IsClosed(aE, aF)) {
499 TopAbs_Orientation anEOr;
500 anEOr=aE.Orientation();
502 Standard_Boolean bDireContains, bReveContains;
504 bDireContains=dire.Contains(aE);
505 bReveContains=reve.Contains(aE);
507 if((anEOr == TopAbs_FORWARD && bDireContains) ||
508 (anEOr == TopAbs_REVERSED && bReveContains)) {
511 else if((anEOr == TopAbs_FORWARD && bReveContains) ||
512 (anEOr == TopAbs_REVERSED && bDireContains)) {
519 else if(bReveContains) {
523 if(anEOr == TopAbs_FORWARD) {
526 if(anEOr == TopAbs_REVERSED) {
530 } // for(; expe.More(); expe.Next())
533 if(!nbbe && !nbe && dtemp.IsEmpty() && rtemp.IsEmpty()) {
537 if( nbe != 0 && nbbe != 0) {
540 aNbLfaceLength=Lface.Length();
545 if((nbe != 0 || nbbe != 0) || j == 1) {
546 TopTools_MapIteratorOfMapOfShape ite;
550 ite.Initialize(dtemp);
551 for(; ite.More(); ite.Next()) {
555 ite.Initialize(rtemp);
556 for(; ite.More(); ite.Next()){
559 done = Standard_True;
562 ite.Initialize(dtemp);
563 for(; ite.More(); ite.Next()) {
567 ite.Initialize(rtemp);
568 for(; ite.More(); ite.Next()){
575 aMapFaceShells.Bind(aF, nshell);
577 aNbLfaceLength=Lface.Length();
578 if(isMultiConnex && BRep_Tool::IsClosed(nshell)) {
579 aSeqShells.Append(nshell);
580 TopoDS_Shell nshellnext;
581 B.MakeShell(nshellnext);
586 } // if((nbe != 0 || nbbe != 0) || j == 1)
589 if(Lface.Length() && i == Lface.Length() && j <=2) {
590 TopoDS_Iterator aItf(nshell,Standard_False);
592 aSeqUnconnectFaces.Append(aItf.Value());
594 TopoDS_Shell nshellnext;
595 B.MakeShell(nshellnext);
600 }//for(; i<=Lface.Length(); i++)
602 Standard_Boolean isContains = Standard_False;
603 j=aSeqShells.Length();
604 for(i=1 ; i <= j; i++){
605 isContains = nshell.IsSame(aSeqShells.Value(i));
612 Standard_Integer numFace =0;
615 TopoDS_Iterator aItf(nshell, Standard_False) ;
616 for(; aItf.More(); aItf.Next()) {
617 aFace = aItf.Value();
622 aSeqShells.Append(nshell);
624 else if(numFace == 1) {
629 for(i=1; i<= aSeqUnconnectFaces.Length(); i++){
630 Lface.Append(aSeqUnconnectFaces);
635 //=======================================================================
636 // function : AddMultiConexityFaces
638 //=======================================================================
639 Standard_Boolean AddMultiConexityFaces(TopTools_SequenceOfShape& Lface,
640 const TopTools_MapOfShape& aMapMultiConnectEdges,
641 TopTools_SequenceOfShape& SeqShells,
642 const TopTools_DataMapOfShapeShape& aMapFaceShells,
643 const TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces,
644 TopTools_SequenceOfShape& ErrFaces)
646 Standard_Boolean done = Standard_False;
650 for(i1 = 1 ; i1<=Lface.Length(); ) {
651 TopTools_MapOfShape dire, reve;
652 TopTools_IndexedMapOfShape MapOtherShells;
653 Standard_Integer aNbOtherShells;
655 const TopoDS_Face& aFace = TopoDS::Face(Lface.Value(i1));
657 //Finds shells containg multishared edges from this face
658 TopExp_Explorer aExpEdges(aFace, TopAbs_EDGE);
659 for(; aExpEdges.More(); aExpEdges.Next()) {
660 const TopoDS_Shape& aE = aExpEdges.Current();
662 if(!aMapMultiConnectEdges.Contains(aE)) {
666 if( aE.Orientation() == TopAbs_FORWARD) {
673 const TopTools_ListOfShape& aLF = aMapEdgeFaces.FindFromKey(aE);
674 TopTools_ListIteratorOfListOfShape aItl(aLF);
675 for(; aItl.More(); aItl.Next()) {
676 const TopoDS_Shape& aF = aItl.Value();
678 if(aF.IsSame(aFace)) {
682 TopoDS_Shape aOthershell;
683 if(aMapFaceShells.IsBound(aF)) {
684 aOthershell = aMapFaceShells.Find(aF);
685 if(!MapOtherShells.Contains(aOthershell)) {
686 MapOtherShells.Add(aOthershell);
690 }//for(; aExpEdges.More(); aExpEdges.Next())
693 aNbOtherShells=MapOtherShells.Extent();
695 if(!aNbOtherShells) {
701 //Adds face to open shells containg the same multishared edges.
702 //For nonmanifold mode creation ine shell from face and shells
703 // containing the same multishared edges.
704 done = Standard_True;
706 Standard_Integer j, k;
708 TColStd_SequenceOfInteger SeqOtherShells;
709 for(j =1; j <= aNbOtherShells; j++) {
710 Standard_Integer index=0;
711 for(k =1; k <= SeqShells.Length() && !index; k++) {
712 if(SeqShells.Value(k) == MapOtherShells.FindKey(j)){
716 SeqOtherShells.Append(index);
719 aNbOtherShells= SeqOtherShells.Length();
721 for(j =1; j <= aNbOtherShells; j++) {
722 Standard_Integer nbdir =0,nbrev =0;
723 TopTools_MapOfShape mapEdges;
725 k = SeqOtherShells.Value(j);
726 const TopoDS_Shape& aShk=SeqShells.Value(k);
728 TopExp_Explorer aExpF(aShk, TopAbs_FACE);
729 for(; aExpF.More(); aExpF.Next()) {
730 const TopoDS_Shape& aFC=aExpF.Current();
732 TopExp_Explorer aExpE(aFC,TopAbs_EDGE);
733 for(; aExpE.More(); aExpE.Next()) {
735 const TopoDS_Shape& aEC = aExpE.Current();
736 if(!mapEdges.Contains(aEC)){
740 mapEdges.Remove(aEC);
743 }// for(; aExpE.More(); aExpE.Next())
744 }// for(; aExpF.More(); aExpF.Next()) {
747 TopTools_MapIteratorOfMapOfShape aIte(mapEdges);
748 for(;aIte.More(); aIte.Next()) {
749 const TopoDS_Shape& aEC = aIte.Key();
750 TopAbs_Orientation anOrEC=aEC.Orientation();
752 Standard_Boolean bDireContains, bReveContains;
754 bDireContains=dire.Contains(aEC);
755 bReveContains=reve.Contains(aEC);
757 if((anOrEC == TopAbs_FORWARD && bDireContains) ||
758 (anOrEC == TopAbs_REVERSED && bReveContains)) {
761 else if((anOrEC == TopAbs_FORWARD && bReveContains)||
762 (anOrEC == TopAbs_REVERSED && bDireContains)) {
765 }// for(;aIte.More(); aIte.Next())
768 ErrFaces.Append(aFace);
771 else if(nbdir || nbrev) {
772 // for manifold mode face containing multiconnexity
773 // edges will be added in the each shell
774 // containing the same edges. ???
777 aShell = SeqShells.Value(k);
779 aB.Add(aShell, aFace);
780 SeqShells.ChangeValue(k) = aShell;
782 }// else if(nbdir || nbrev)
783 }// for(j =1; j <= aNbOtherShells; j++)
792 //=======================================================================
793 // function : CreateClosedShell
795 //=======================================================================
796 void CreateClosedShell(TopTools_SequenceOfShape& OpenShells,
797 const TopTools_MapOfShape& aMapMultiConnectEdges,
798 const TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces)
800 TopTools_MapOfShape amapFaces;
802 TopTools_MapIteratorOfMapOfShape aItEdg(aMapMultiConnectEdges);
803 for(; aItEdg.More(); aItEdg.Next()) {
804 const TopTools_ListOfShape& aLF = aMapEdgeFaces.FindFromKey(aItEdg.Key());
805 TopTools_ListIteratorOfListOfShape aItF(aLF);
806 for(; aItF.More(); aItF.Next()) {
807 amapFaces.Add(aItF.Value());
811 // Creating new shells if some open shells contain the same edges.
812 Standard_Integer i, j;
813 Standard_Boolean isClosedShell;
815 for(i=1; i <= OpenShells.Length(); i++) {
816 TopTools_MapOfShape dire, reve;
818 isClosedShell = Standard_False;
819 const TopoDS_Shape& anOpenShelli=OpenShells.Value(i);
820 TopExp_Explorer aExpF(anOpenShelli, TopAbs_FACE);
822 for(; aExpF.More(); aExpF.Next()) {
823 const TopoDS_Shape& aFace = aExpF.Current();
825 if(!amapFaces.Contains(aFace)) {
829 TopExp_Explorer aExpEdges(aFace, TopAbs_EDGE);
830 for(; aExpEdges.More(); aExpEdges.Next()) {
831 const TopoDS_Shape& aE = aExpEdges.Current();
833 if(!aMapMultiConnectEdges.Contains(aE)) {
837 TopAbs_Orientation anOrE;
838 anOrE=aE.Orientation();
840 if(anOrE == TopAbs_FORWARD) {
843 else if(anOrE == TopAbs_REVERSED) {
847 }// for(; aExpF.More(); aExpF.Next())
850 for(j=i+1; j<=OpenShells.Length(); j++) {
851 Standard_Integer nbedge =0;
852 Standard_Boolean isReversed = Standard_False;
854 const TopoDS_Shape& anOpenShellj=OpenShells.Value(j);
856 TopExp_Explorer aExpF2(anOpenShellj, TopAbs_FACE);
857 for(; aExpF2.More() && !nbedge; aExpF2.Next()) {
859 const TopoDS_Shape& aFace2 = aExpF2.Current();
861 if(!amapFaces.Contains(aFace2)) {
865 TopExp_Explorer aExpEdges2(aFace2, TopAbs_EDGE);
866 for(; aExpEdges2.More()&& !nbedge; aExpEdges2.Next()) {
867 const TopoDS_Shape& aE2 = aExpEdges2.Current();
869 if(!aMapMultiConnectEdges.Contains(aE2)) {
873 Standard_Boolean bDireContains, bReveContains;
875 bDireContains=dire.Contains(aE2);
876 bReveContains=reve.Contains(aE2);
878 if(!bDireContains && !bReveContains) {
882 isClosedShell = Standard_True;
884 TopAbs_Orientation anOrE2;
885 anOrE2=aE2.Orientation();
886 if((anOrE2 == TopAbs_FORWARD && bDireContains) ||
887 (anOrE2 == TopAbs_REVERSED && bReveContains)) {
888 isReversed = Standard_True;
892 }// for(; aExpF2.More() && !nbedge; aExpF2.Next())
899 TopoDS_Shape aShell = OpenShells.Value(i);
901 TopExp_Explorer aExpF21(anOpenShellj, TopAbs_FACE);
902 for(; aExpF21.More(); aExpF21.Next()) {
903 const TopoDS_Shape& aFace = aExpF21.Current();
907 aB.Add(aShell, aFace);
910 OpenShells.ChangeValue(i) = aShell;
911 OpenShells.Remove(j--);
912 }// for(j=i+1 ; j<=OpenShells.Length();j++ )
913 }//for(i=1; i <= OpenShells.Length(); i++)