Adding of testing cases from subgroups 937 940 and 941 of CHL group
[occt.git] / src / BOP / BOP_ShellSplitter.cxx
1 // Created on: 2001-04-09
2 // Created by: Peter KURNEV
3 // Copyright (c) 2001-2012 OPEN CASCADE SAS
4 //
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.
9 //
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.
12 //
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.
19
20
21
22 #include <BOP_ShellSplitter.ixx>
23
24 #include <TColStd_SequenceOfInteger.hxx>
25
26 #include <Geom_Surface.hxx>
27
28 #include <TopoDS.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>
37
38 #include <TopExp.hxx>
39 #include <TopExp_Explorer.hxx>
40 #include <TopLoc_Location.hxx>
41
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>
51
52 #include <BRep_Tool.hxx>
53 #include <BRep_Builder.hxx>
54
55 static
56   void RemoveInternals(const TopoDS_Face& ,
57                        TopoDS_Face& );
58
59 static
60   Standard_Boolean GetShells(TopTools_SequenceOfShape& ,
61                              const TopTools_MapOfShape& ,
62                              TopTools_SequenceOfShape& ,
63                              TopTools_DataMapOfShapeShape& ,
64                              TopTools_SequenceOfShape& ) ;
65
66 static 
67   Standard_Boolean AddMultiConexityFaces(TopTools_SequenceOfShape& ,
68                                          const TopTools_MapOfShape& ,
69                                          TopTools_SequenceOfShape& ,
70                                          const TopTools_DataMapOfShapeShape& ,
71                                          const TopTools_IndexedDataMapOfShapeListOfShape& ,
72                                          TopTools_SequenceOfShape& );
73
74 static
75    Standard_Boolean SplitShell(const TopoDS_Shell& ,
76                                TopoDS_Shape& );
77 static 
78   void CreateClosedShell(TopTools_SequenceOfShape& ,
79                          const TopTools_MapOfShape& ,
80                          const TopTools_IndexedDataMapOfShapeListOfShape& );
81 // 
82 //=======================================================================
83 // function: BOP_ShellSplitter::BOP_ShellSplitter
84 // purpose: 
85 //=======================================================================
86   BOP_ShellSplitter::BOP_ShellSplitter()
87 :
88   myIsDone(Standard_False),
89   myNothingToDo(Standard_False)
90 {
91 }
92
93 //=======================================================================
94 // function: IsNothingToDo
95 // purpose: 
96 //=======================================================================
97   Standard_Boolean BOP_ShellSplitter::IsNothingToDo()const
98 {
99   return myNothingToDo;
100 }
101
102 //=======================================================================
103 // function: IsDone
104 // purpose: 
105 //=======================================================================
106   Standard_Boolean BOP_ShellSplitter::IsDone()const
107 {
108   return myIsDone;
109 }
110
111 //=======================================================================
112 // function: Shapes
113 // purpose: 
114 //=======================================================================
115   const BOPTColStd_ListOfListOfShape& BOP_ShellSplitter::Shapes()const
116 {
117   return myShapes;
118 }
119
120 //=======================================================================
121 // function: SetShell
122 // purpose: 
123 //=======================================================================
124    void BOP_ShellSplitter::SetShell(const TopoDS_Shell& aShell)
125 {
126   myShell=aShell;
127 }
128 //=======================================================================
129 // function: Shell
130 // purpose: 
131 //=======================================================================
132   const TopoDS_Shell& BOP_ShellSplitter::Shell()const 
133 {
134   return myShell;
135 }
136
137 //=======================================================================
138 // function: DoWithShell
139 // purpose: 
140 //=======================================================================
141   void BOP_ShellSplitter::DoWithShell ()
142 {
143   myFaces.Clear();
144
145   TopExp_Explorer anExpFaces (myShell, TopAbs_FACE);
146   for (; anExpFaces.More(); anExpFaces.Next()) {
147     const TopoDS_Face& aF = TopoDS::Face(anExpFaces.Current());
148     myFaces.Append(aF);
149   }
150   Do();
151 }
152
153 //=======================================================================
154 // function: DoWithListOfEdges
155 // purpose: 
156 //=======================================================================
157   void BOP_ShellSplitter::DoWithListOfEdges(const TopTools_ListOfShape& aLE)
158 {
159   myFaces.Clear();
160  
161   TopTools_ListIteratorOfListOfShape anItList;
162
163   anItList.Initialize(aLE);
164   for (; anItList.More(); anItList.Next()) {
165     const TopoDS_Face& aF = TopoDS::Face(anItList.Value());
166     myFaces.Append(aF);
167   }
168   Do();
169 }
170
171 //=======================================================================
172 // function: Do
173 // purpose: 
174 //=======================================================================
175   void BOP_ShellSplitter::Do()
176 {
177   myIsDone=Standard_False;
178   myNothingToDo=Standard_False;
179   //
180   TopTools_ListIteratorOfListOfShape anItList;
181   TopTools_IndexedDataMapOfShapeShape  aMFNewOld;
182   TopoDS_Shell aShell;
183   BRep_Builder aBB;
184   //
185   // insert the code about myNothingToDo
186   //
187   // 1. Make the formal shell  
188   aBB.MakeShell(aShell);
189   //
190   anItList.Initialize(myFaces);
191   for (; anItList.More(); anItList.Next()) {
192     const TopoDS_Face& aF = TopoDS::Face(anItList.Value());
193     TopoDS_Face aFNew;
194     RemoveInternals (aF, aFNew);
195     aMFNewOld.Add (aFNew, aF);
196
197     aBB.Add(aShell, aFNew);
198   }
199   //
200   // 2. Split the Shell
201   
202   TopoDS_Shape aShape;
203   SplitShell (aShell, aShape);
204   //
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();
210
211     TopTools_ListOfShape aLF;
212     TopExp_Explorer aFaceExp(aSh, TopAbs_FACE);
213     for (; aFaceExp.More(); aFaceExp.Next()) {
214       const TopoDS_Shape& aFNew= aFaceExp.Current();
215       
216       const TopoDS_Shape& aFOld=aMFNewOld.FindFromKey(aFNew);
217       aLF.Append(aFOld);
218     }
219     
220     if (aLF.Extent()) {
221       myShapes.Append(aLF);
222     }
223   }
224   
225   myIsDone=Standard_True;
226 }
227
228 //=======================================================================
229 // function: RemoveInternals
230 // purpose: 
231 //=======================================================================
232 void RemoveInternals(const TopoDS_Face& aF,
233                      TopoDS_Face& aFNew)
234 {
235   BRep_Builder aBB;
236   Standard_Integer iCnt;
237   Standard_Real    aTol;
238   
239
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());
245
246   TopExp_Explorer aFExp(aF, TopAbs_WIRE);
247   for (; aFExp.More(); aFExp.Next()) {
248     const TopoDS_Wire& aW= TopoDS::Wire(aFExp.Current());
249     TopoDS_Wire aWNew;
250     aBB.MakeWire(aWNew);
251     aWNew.Orientation(aW.Orientation());
252
253     iCnt=0;
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) {
258         aBB.Add(aWNew, aE);
259         iCnt++;
260       }
261     }
262     if (iCnt) {
263       aBB.Add(aFNew, aWNew);
264     }
265   }
266 }
267
268 ////////
269 //
270 //=======================================================================
271 // function : SplitShell
272 // purpose  : 
273 //=======================================================================
274   Standard_Boolean SplitShell    (const TopoDS_Shell& aShellIn,
275                                   TopoDS_Shape& aShellsOut) 
276 {
277   Standard_Boolean done;
278   Standard_Integer i, j, aNumMultShell;
279
280   TopTools_SequenceOfShape aSeqShells, aErrFaces, Lface;
281   TopTools_DataMapOfShapeShape aMapFaceShells;
282   TopTools_IndexedDataMapOfShapeListOfShape aMapEdgeFaces;
283   TopTools_MapOfShape aMapMultiConnectEdges;
284   TopoDS_Compound aCmpErrFaces;
285   //
286   done = Standard_False;
287   aNumMultShell =0;
288   aShellsOut = aShellIn;
289
290   TopoDS_Iterator iter(aShellIn);
291   for (; iter.More(); iter.Next()) {
292     Lface.Append(iter.Value());
293   }
294   //
295   TopExp::MapShapesAndAncestors(aShellIn, TopAbs_EDGE, TopAbs_FACE, aMapEdgeFaces);
296   //
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();
303     if(aNbFaces>2) {
304       const TopoDS_Shape& aE=aMapEdgeFaces.FindKey(j);
305       aMapMultiConnectEdges.Add(aE);
306     }
307   }
308   //
309   //Gets shells without taking in account of multiconnexity.
310   Standard_Boolean isGetShells = Standard_True;
311
312   while(isGetShells && Lface.Length()) {
313     TopTools_SequenceOfShape aTmpSeqShells;
314     Standard_Boolean bGetShells;
315
316     bGetShells=GetShells(Lface, 
317                          aMapMultiConnectEdges, 
318                          aTmpSeqShells,
319                          aMapFaceShells,
320                          aErrFaces);
321     if(bGetShells) {
322       done = Standard_True;
323     }
324     
325     isGetShells = !aTmpSeqShells.IsEmpty();
326     if(isGetShells) {
327       aSeqShells.Append(aTmpSeqShells);
328     }
329   } // while(...)
330   //
331   //
332   Standard_Boolean aIsDone = Standard_False;
333   Standard_Integer aLfaceLength, aErrFacesLength;
334   
335   aLfaceLength=Lface.Length();
336   aNumMultShell=aSeqShells.Length();
337
338   if(aLfaceLength  && aNumMultShell) { 
339     //Crating shells in the case of compsolid
340     aIsDone = AddMultiConexityFaces(Lface,
341                                     aMapMultiConnectEdges,
342                                     aSeqShells,
343                                     aMapFaceShells,
344                                     aMapEdgeFaces,
345                                     aErrFaces);
346   }
347   //
348   aNumMultShell = aSeqShells.Length();
349   aErrFacesLength=aErrFaces.Length();
350   //
351   if (aErrFacesLength)  {
352     BRep_Builder B;
353     TopoDS_Compound aCompShells;
354     
355     B.MakeCompound  (aCmpErrFaces);
356     B.MakeCompound(aCompShells);
357
358     for(j =1; j <= aErrFacesLength; j++){
359       B.Add(aCmpErrFaces, aErrFaces.Value(j));
360     }
361
362     if(aNumMultShell) {
363       
364       if(aNumMultShell == 1) {
365         aShellsOut = aSeqShells.Value(1);
366         B.Add(aCompShells, aSeqShells.Value(1));
367
368         for(j=1; j <= aErrFacesLength; j++) {
369           TopoDS_Shell aSh;
370           B.MakeShell(aSh);
371           B.Add(aSh, aErrFaces.Value(j));
372           B.Add(aCompShells, aSh);
373         }
374         aShellsOut = aCompShells;
375       }
376       
377       else {
378         for(i=1; i <= aNumMultShell; i++) {
379           B.Add(aCompShells, aSeqShells.Value(i));
380         }
381
382         for(j=1; j<= aErrFacesLength; j++) {
383           TopoDS_Shell aSh;
384           B.MakeShell(aSh);
385           B.Add(aSh,aErrFaces.Value(j));
386           B.Add(aCompShells, aSh);
387         }
388         aShellsOut = aCompShells;
389       }
390     } //if(aNumMultShell)
391
392     done = Standard_True;
393     return done;
394   } // if (aErrFacesLength) 
395   //
396   //
397   if(aNumMultShell>1) {
398     TopTools_SequenceOfShape OpenShells;
399     
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--);
405       }
406     }
407
408     j=OpenShells.Length();
409     if(j>1) {
410       // Attempt of creation closed shell from open shells 
411       // with taking into account multiconnexity.
412       //
413       CreateClosedShell(OpenShells, aMapMultiConnectEdges, aMapEdgeFaces);
414       aSeqShells.Append(OpenShells);
415     }
416   } //if(aNumMultShell>1)
417   //
418   //
419   j=Lface.Length();
420   if(j) {
421     for(i=1; i <= j; i++) {
422       BRep_Builder aB;
423       TopoDS_Shell OneShell;
424       aB.MakeShell(OneShell);
425       aB.Add(OneShell, Lface.Value(i));
426       aSeqShells.Append(OneShell);
427     }
428   }
429   //
430   //
431   aNumMultShell = aSeqShells.Length();
432   if(!done) {
433     done = (aNumMultShell>1 || aIsDone);
434   }
435
436   BRep_Builder B;
437   TopoDS_Compound aCompShells;
438   B.MakeCompound(aCompShells);
439   for(i=1; i <= aNumMultShell; i++){
440     B.Add(aCompShells, aSeqShells.Value(i));  
441   }
442   aShellsOut = aCompShells;
443   //
444   return done;
445 }
446
447 //=======================================================================
448 // function : GetShells
449 // purpose  : 
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) 
456 {
457   Standard_Boolean done = Standard_False;
458   Standard_Integer i, j, aNbLfaceLength;
459
460   j=Lface.Length();
461   if(!j) {
462     return done;
463   }
464
465   Standard_Boolean isMultiConnex;
466   TopoDS_Shell nshell;
467   TopTools_MapOfShape dire, reve;
468   BRep_Builder B;
469   TopTools_SequenceOfShape aSeqUnconnectFaces;
470
471   B.MakeShell(nshell);
472   isMultiConnex = !aMapMultiConnectEdges.IsEmpty();
473   i=1; 
474   j=1;
475   //
476   for(; i<=Lface.Length(); i++)  {
477     aNbLfaceLength=Lface.Length();
478     TopTools_MapOfShape dtemp, rtemp;
479     Standard_Integer nbbe=0, nbe = 0;
480     
481     TopoDS_Face aF = TopoDS::Face(Lface.Value(i));
482
483     TopExp_Explorer anExpe(aF, TopAbs_EDGE);
484     for(; anExpe.More(); anExpe.Next()) {
485       const TopoDS_Edge& aE = TopoDS::Edge(anExpe.Current());
486       
487       if(isMultiConnex && aMapMultiConnectEdges.Contains(aE)){
488         continue;
489       }
490       
491       if (BRep_Tool::Degenerated (aE)) {
492         continue;
493       }
494
495       if (BRep_Tool::IsClosed(aE, aF)) {
496         continue;
497       }
498
499       TopAbs_Orientation anEOr;
500       anEOr=aE.Orientation();
501
502       Standard_Boolean bDireContains, bReveContains;
503
504       bDireContains=dire.Contains(aE);
505       bReveContains=reve.Contains(aE);
506
507       if((anEOr == TopAbs_FORWARD  && bDireContains) || 
508          (anEOr == TopAbs_REVERSED && bReveContains)) {
509         nbbe++;
510       }
511       else if((anEOr == TopAbs_FORWARD  && bReveContains) ||
512               (anEOr == TopAbs_REVERSED && bDireContains)) {   
513         nbe++;
514       }
515       
516       if(bDireContains) {
517         dire.Remove(aE);
518       }
519       else if(bReveContains) {
520         reve.Remove(aE);
521       }
522       else {
523         if(anEOr == TopAbs_FORWARD) {
524           dtemp.Add(aE);
525         }
526         if(anEOr == TopAbs_REVERSED) {
527           rtemp.Add(aE);
528         }
529       }
530     } // for(; expe.More(); expe.Next())
531     //
532     //
533     if(!nbbe && !nbe && dtemp.IsEmpty() && rtemp.IsEmpty()) {
534       continue;
535     }
536     //
537     if( nbe != 0 && nbbe != 0) {
538       ErrFaces.Append(aF);
539       Lface.Remove(i);
540       aNbLfaceLength=Lface.Length();
541       j++;
542       continue;
543     }
544     //
545     if((nbe != 0 || nbbe != 0) || j == 1) {
546       TopTools_MapIteratorOfMapOfShape ite;
547       if(nbbe != 0) {
548         aF.Reverse();
549         
550         ite.Initialize(dtemp);
551         for(; ite.More(); ite.Next()) {
552           reve.Add(ite.Key());
553         }
554         
555         ite.Initialize(rtemp);
556         for(; ite.More(); ite.Next()){
557           dire.Add(ite.Key());
558         }
559         done = Standard_True;
560       }
561       else {
562         ite.Initialize(dtemp);
563         for(; ite.More(); ite.Next()) {
564           dire.Add(ite.Key());
565         }
566         
567         ite.Initialize(rtemp);
568         for(; ite.More(); ite.Next()){
569           reve.Add(ite.Key());
570         }
571       }
572
573       j++;
574       B.Add(nshell, aF);
575       aMapFaceShells.Bind(aF, nshell);
576       Lface.Remove(i);
577       aNbLfaceLength=Lface.Length();
578       if(isMultiConnex && BRep_Tool::IsClosed(nshell)) {
579         aSeqShells.Append(nshell);
580         TopoDS_Shell nshellnext;
581         B.MakeShell(nshellnext);
582         nshell = nshellnext;
583         j=1;
584       }
585       i=0;
586     } // if((nbe != 0 || nbbe != 0) || j == 1)
587     //
588     //
589     if(Lface.Length() && i == Lface.Length() && j <=2) {
590       TopoDS_Iterator aItf(nshell,Standard_False);
591       if(aItf.More()){
592         aSeqUnconnectFaces.Append(aItf.Value());
593       }
594       TopoDS_Shell nshellnext;
595       B.MakeShell(nshellnext);
596       nshell = nshellnext;
597       i=0;
598       j=1;
599     }
600   }//for(; i<=Lface.Length(); i++) 
601
602   Standard_Boolean isContains = Standard_False;
603   j=aSeqShells.Length();
604   for(i=1 ; i <= j; i++){
605     isContains = nshell.IsSame(aSeqShells.Value(i));
606     if (isContains) {
607       break;
608     }
609   }
610
611   if(!isContains) {
612     Standard_Integer numFace =0;
613     TopoDS_Shape aFace;
614     
615     TopoDS_Iterator aItf(nshell, Standard_False) ;
616     for(; aItf.More(); aItf.Next()) {
617       aFace = aItf.Value();
618       numFace++;
619     }
620     
621     if(numFace >1) {
622       aSeqShells.Append(nshell);
623     }
624     else if(numFace == 1) {
625       Lface.Append(aFace);
626     }
627   }
628   
629   for(i=1; i<= aSeqUnconnectFaces.Length(); i++){
630     Lface.Append(aSeqUnconnectFaces);
631   }
632   return done;
633 }
634
635 //=======================================================================
636 // function : AddMultiConexityFaces
637 // purpose  : 
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)
645 {
646   Standard_Boolean done = Standard_False;
647   BRep_Builder aB;
648   Standard_Integer i1;
649
650   for(i1 = 1 ; i1<=Lface.Length(); )  {
651     TopTools_MapOfShape dire, reve;
652     TopTools_IndexedMapOfShape MapOtherShells;
653     Standard_Integer aNbOtherShells;
654
655     const TopoDS_Face& aFace = TopoDS::Face(Lface.Value(i1));
656     //
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();
661       
662       if(!aMapMultiConnectEdges.Contains(aE)) {
663         continue;
664       }
665
666       if( aE.Orientation() == TopAbs_FORWARD) {
667         dire.Add(aE);
668       }
669       else {
670         reve.Add(aE);
671       }
672
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();
677         
678         if(aF.IsSame(aFace)) {
679           continue;
680         }
681
682         TopoDS_Shape aOthershell;
683         if(aMapFaceShells.IsBound(aF)) {
684           aOthershell = aMapFaceShells.Find(aF);
685           if(!MapOtherShells.Contains(aOthershell)) {
686             MapOtherShells.Add(aOthershell);
687           }
688         }
689       }
690     }//for(; aExpEdges.More(); aExpEdges.Next())
691     //
692     //
693     aNbOtherShells=MapOtherShells.Extent();
694     //
695     if(!aNbOtherShells) {
696       i1++;
697       continue;
698     }
699     
700     else {
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;
705       
706       Standard_Integer j, k;
707       
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)){
713             index = k;
714           }
715         }
716         SeqOtherShells.Append(index);
717       }
718
719       aNbOtherShells= SeqOtherShells.Length();
720
721       for(j =1; j <= aNbOtherShells; j++) {
722         Standard_Integer nbdir =0,nbrev =0;
723         TopTools_MapOfShape mapEdges;
724         
725         k = SeqOtherShells.Value(j);
726         const TopoDS_Shape& aShk=SeqShells.Value(k);
727         
728         TopExp_Explorer aExpF(aShk, TopAbs_FACE);
729         for(; aExpF.More(); aExpF.Next()) {
730           const TopoDS_Shape& aFC=aExpF.Current();
731           
732           TopExp_Explorer aExpE(aFC,TopAbs_EDGE);
733           for(; aExpE.More(); aExpE.Next()) {
734             
735             const TopoDS_Shape& aEC = aExpE.Current();
736             if(!mapEdges.Contains(aEC)){
737               mapEdges.Add(aEC);
738             }
739             else {
740               mapEdges.Remove(aEC);
741             }
742
743           }// for(; aExpE.More(); aExpE.Next())
744         }// for(; aExpF.More(); aExpF.Next()) {
745         //
746         //
747         TopTools_MapIteratorOfMapOfShape aIte(mapEdges);
748         for(;aIte.More(); aIte.Next()) {
749           const TopoDS_Shape& aEC = aIte.Key();
750           TopAbs_Orientation anOrEC=aEC.Orientation();
751           
752           Standard_Boolean bDireContains, bReveContains;
753
754           bDireContains=dire.Contains(aEC);
755           bReveContains=reve.Contains(aEC);
756
757           if((anOrEC == TopAbs_FORWARD  && bDireContains) || 
758              (anOrEC == TopAbs_REVERSED && bReveContains)) {
759             nbrev++;
760           }
761           else if((anOrEC == TopAbs_FORWARD  && bReveContains)||
762                   (anOrEC == TopAbs_REVERSED && bDireContains)) {
763             nbdir++;
764           }
765         }// for(;aIte.More(); aIte.Next())
766
767         if(nbdir && nbrev) {
768           ErrFaces.Append(aFace);
769         }
770
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. ???
775           
776           TopoDS_Shape aShell;
777           aShell = SeqShells.Value(k);
778           if (!nbrev) {
779             aB.Add(aShell, aFace);
780             SeqShells.ChangeValue(k) = aShell;
781           }
782         }// else if(nbdir || nbrev)
783       }// for(j =1; j <= aNbOtherShells; j++)
784       //
785       dire.Clear();
786       reve.Clear();
787       Lface.Remove(i1);
788     }
789   }
790   return done;
791 }
792 //=======================================================================
793 // function : CreateClosedShell
794 // purpose  : 
795 //=======================================================================
796 void CreateClosedShell(TopTools_SequenceOfShape& OpenShells,
797                        const TopTools_MapOfShape& aMapMultiConnectEdges,
798                        const TopTools_IndexedDataMapOfShapeListOfShape& aMapEdgeFaces)
799 {
800   TopTools_MapOfShape amapFaces;
801   
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());
808     }
809   }
810   //
811   // Creating new shells if some open shells contain the same edges.
812   Standard_Integer i, j;
813   Standard_Boolean isClosedShell; 
814
815   for(i=1; i <= OpenShells.Length(); i++)  {
816     TopTools_MapOfShape dire, reve;
817
818     isClosedShell = Standard_False;
819     const TopoDS_Shape& anOpenShelli=OpenShells.Value(i);
820     TopExp_Explorer aExpF(anOpenShelli, TopAbs_FACE);
821     
822     for(; aExpF.More(); aExpF.Next()) {
823       const TopoDS_Shape& aFace = aExpF.Current();
824       
825       if(!amapFaces.Contains(aFace)) {
826         continue;
827       }
828
829       TopExp_Explorer aExpEdges(aFace, TopAbs_EDGE);
830       for(; aExpEdges.More(); aExpEdges.Next()) {
831         const TopoDS_Shape& aE = aExpEdges.Current();
832         
833         if(!aMapMultiConnectEdges.Contains(aE)) {
834           continue;
835         }
836         
837         TopAbs_Orientation anOrE;
838         anOrE=aE.Orientation();
839         
840         if(anOrE == TopAbs_FORWARD) {
841           dire.Add(aE);
842         }
843         else if(anOrE == TopAbs_REVERSED) {
844           reve.Add(aE);
845         }
846       }
847     }// for(; aExpF.More(); aExpF.Next())
848     //
849     // 
850     for(j=i+1; j<=OpenShells.Length(); j++)  {
851       Standard_Integer nbedge =0;
852       Standard_Boolean isReversed = Standard_False;
853       
854       const TopoDS_Shape& anOpenShellj=OpenShells.Value(j);
855
856       TopExp_Explorer aExpF2(anOpenShellj, TopAbs_FACE);
857       for(; aExpF2.More() && !nbedge; aExpF2.Next()) {
858
859         const TopoDS_Shape& aFace2 = aExpF2.Current();
860         
861         if(!amapFaces.Contains(aFace2)) {
862           continue;
863         }
864
865         TopExp_Explorer aExpEdges2(aFace2, TopAbs_EDGE);
866         for(; aExpEdges2.More()&& !nbedge; aExpEdges2.Next()) {
867           const TopoDS_Shape& aE2 = aExpEdges2.Current();
868
869           if(!aMapMultiConnectEdges.Contains(aE2)) {
870             continue;
871           }
872
873           Standard_Boolean bDireContains, bReveContains;
874
875           bDireContains=dire.Contains(aE2);
876           bReveContains=reve.Contains(aE2);
877
878           if(!bDireContains && !bReveContains) {
879             continue;
880           }
881
882           isClosedShell = Standard_True;
883
884           TopAbs_Orientation anOrE2;
885           anOrE2=aE2.Orientation();
886           if((anOrE2 == TopAbs_FORWARD  && bDireContains) || 
887              (anOrE2 == TopAbs_REVERSED && bReveContains)) {
888             isReversed = Standard_True;
889           }
890           nbedge++;
891         }
892       }// for(; aExpF2.More() && !nbedge; aExpF2.Next())
893       
894       if(!isClosedShell){
895         continue;
896       }
897
898       BRep_Builder aB;
899       TopoDS_Shape aShell = OpenShells.Value(i);
900
901       TopExp_Explorer aExpF21(anOpenShellj, TopAbs_FACE);
902       for(; aExpF21.More(); aExpF21.Next()) {
903         const TopoDS_Shape& aFace = aExpF21.Current();
904         //if(isReversed) {
905         //  aFace.Reverse();
906         //}
907         aB.Add(aShell, aFace);
908       }
909       
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++)
914 }