0031035: Coding - uninitialized class fields reported by Visual Studio Code Analysis
[occt.git] / src / BRepCheck / BRepCheck_Shell.cxx
1 // Created on: 1995-12-12
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16
17
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepCheck.hxx>
21 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
22 #include <BRepCheck_ListOfStatus.hxx>
23 #include <BRepCheck_Shell.hxx>
24 #include <Standard_Type.hxx>
25 #include <TopExp.hxx>
26 #include <TopExp_Explorer.hxx>
27 #include <TopoDS.hxx>
28 #include <TopoDS_Edge.hxx>
29 #include <TopoDS_Face.hxx>
30 #include <TopoDS_Shape.hxx>
31 #include <TopoDS_Shell.hxx>
32 #include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx>
33 #include <TopTools_DataMapOfShapeInteger.hxx>
34 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
35 #include <TopTools_ListIteratorOfListOfShape.hxx>
36 #include <TopTools_ListOfShape.hxx>
37 #include <TopTools_MapIteratorOfMapOfShape.hxx>
38 #include <TopTools_MapOfShape.hxx>
39
40 IMPLEMENT_STANDARD_RTTIEXT(BRepCheck_Shell,BRepCheck_Result)
41
42 //=======================================================================
43 //function : Propagate
44 //purpose  : 
45 //=======================================================================
46 static void Propagate(const TopTools_IndexedDataMapOfShapeListOfShape& mapEF,
47                       const TopoDS_Shape& theFace,
48                       TopTools_IndexedMapOfShape& theMapF)
49 {
50   // Base for the traverse procedure.
51   theMapF.Add(theFace);
52
53   // Perform well-known width-first traverse.
54   for (Standard_Integer anIdx = 1; anIdx <= theMapF.Extent(); ++anIdx)
55   {
56     const TopoDS_Shape& aFace = theMapF(anIdx);
57     for (TopExp_Explorer ex(aFace, TopAbs_EDGE); ex.More(); ex.Next())
58     {
59       const TopoDS_Edge& edg = TopoDS::Edge(ex.Current());
60
61       // Test if the edge is in the map (only oriented edges are present).
62       const TopTools_ListOfShape* aList = mapEF.Seek(edg);
63
64       if ( aList == NULL )
65         continue;
66
67       for (TopTools_ListIteratorOfListOfShape itl(*aList); itl.More(); itl.Next())
68       {
69         // This code assumes that shape is added to an end of the map.
70         // The idea is simple: existing objects will not be added, new objects
71         // will be added to an end.
72         theMapF.Add(itl.Value());
73       }
74     }
75   }
76 }
77
78 //=======================================================================
79 //function : BRepCheck_Trace
80 //purpose  : 
81 //=======================================================================
82 Standard_EXPORT Standard_Integer BRepCheck_Trace(const Standard_Integer phase) {
83   static int BRC_Trace = 0;
84   if (phase < 0) BRC_Trace =0;
85   else if (phase > 0) BRC_Trace=phase;
86   return BRC_Trace;
87 }
88
89 void PrintShape(const TopoDS_Shape& theShape, const Standard_Integer upper) {
90   if (!theShape.IsNull()) {
91     Standard_Integer code = theShape.HashCode(upper);
92     std::cout << TopAbs::ShapeTypeToString (theShape.ShapeType()) << " : " << code
93        << " " << TopAbs::ShapeOrientationToString(theShape.Orientation()) << std::endl;
94   }
95 }
96     
97 //=======================================================================
98 //function : IsOriented
99 //purpose  : 
100 //=======================================================================
101 inline Standard_Boolean IsOriented(const TopoDS_Shape& S)
102 {
103   return (S.Orientation() == TopAbs_FORWARD ||
104           S.Orientation() == TopAbs_REVERSED);
105 }
106
107
108 //=======================================================================
109 //function : BRepCheck_Shell
110 //purpose  : 
111 //=======================================================================
112
113 BRepCheck_Shell::BRepCheck_Shell(const TopoDS_Shell& S)
114 : myNbori(0),
115   myCdone(Standard_False),
116   myCstat(BRepCheck_NoError),
117   myOdone(Standard_False),
118   myOstat(BRepCheck_NoError)
119 {
120   Init(S);
121 }
122
123
124 //=======================================================================
125 //function : Minimum
126 //purpose  : 
127 //=======================================================================
128 void BRepCheck_Shell::Minimum()
129 {
130   myCdone = Standard_False;
131   myOdone = Standard_False;
132
133   if (!myMin)
134   {
135     BRepCheck_ListOfStatus thelist;
136     myMap.Bind(myShape, thelist);
137     BRepCheck_ListOfStatus& lst = myMap(myShape);
138
139     // it is checked if the shell is "connected"
140     TopExp_Explorer exp(myShape,TopAbs_FACE);
141     Standard_Integer nbface = 0;
142     myMapEF.Clear();
143     for (; exp.More(); exp.Next())
144     {
145       nbface++;
146       TopExp_Explorer expe;
147       for (expe.Init(exp.Current(),TopAbs_EDGE);
148                         expe.More(); expe.Next())
149       {
150         const TopoDS_Shape& edg = expe.Current();
151         Standard_Integer index = myMapEF.FindIndex(edg);
152         if (index == 0)
153         {
154           TopTools_ListOfShape thelist1;
155           index = myMapEF.Add(edg, thelist1);
156         }
157
158         myMapEF(index).Append(exp.Current());
159       }
160     }//for (; exp.More(); exp.Next())
161
162     if (nbface == 0)
163     {
164       BRepCheck::Add(lst,BRepCheck_EmptyShell);
165     }
166     else if (nbface >= 2)
167     {
168       TopTools_IndexedMapOfShape mapF;
169       exp.ReInit();
170
171       Propagate(myMapEF,exp.Current(),mapF);
172
173       if (mapF.Extent() != nbface)
174       {
175         BRepCheck::Add(lst,BRepCheck_NotConnected);
176       }
177     }//else if (nbface >= 2)
178
179     if (lst.IsEmpty())
180     {
181       lst.Append(BRepCheck_NoError);
182     }
183     
184     myMapEF.Clear();
185     myMin = Standard_True;
186   }
187 }
188
189 //=======================================================================
190 //function : InContext
191 //purpose  : 
192 //=======================================================================
193
194 void BRepCheck_Shell::InContext(const TopoDS_Shape& S)
195 {
196
197   if (myMap.IsBound(S)) {
198     return;
199   }
200   BRepCheck_ListOfStatus thelist;
201   myMap.Bind(S, thelist);
202
203   BRepCheck_ListOfStatus& lst = myMap(S);
204
205 //  for (TopExp_Explorer exp(S,TopAbs_SHELL); exp.More(); exp.Next()) {
206   TopExp_Explorer exp(S,TopAbs_SHELL) ;
207   for ( ; exp.More(); exp.Next()) {
208     if (exp.Current().IsSame(myShape)) {
209       break;
210     }
211   }
212   if (!exp.More()) {
213     BRepCheck::Add(lst,BRepCheck_SubshapeNotInShape);
214     return;
215   }
216
217   TopAbs_ShapeEnum styp = S.ShapeType();
218   switch (styp) {
219
220   case TopAbs_SOLID:
221     {
222       BRepCheck_Status fst = Closed();
223       if ((fst == BRepCheck_NotClosed && S.Closed()) ||
224           (fst != BRepCheck_NoError)) {
225         BRepCheck::Add(lst,fst);
226       }
227       else if (!IsUnorientable()) {
228         fst = Orientation();
229         BRepCheck::Add(lst,fst);
230       }
231     }
232     break;
233
234   default:
235     break;
236   }
237
238
239   if (lst.IsEmpty()) {
240     lst.Append(BRepCheck_NoError);
241   }
242 }
243
244
245 //=======================================================================
246 //function : Blind
247 //purpose  : 
248 //=======================================================================
249
250 void BRepCheck_Shell::Blind()
251 {
252   if (!myBlind) {
253     // nothing more than in the minimum
254     myBlind = Standard_True;
255   }
256 }
257
258
259 //=======================================================================
260 //function : Closed
261 //purpose  : 
262 //=======================================================================
263 BRepCheck_Status BRepCheck_Shell::Closed(const Standard_Boolean Update)
264 {
265   if (myCdone)
266   {
267     if (Update)
268     {
269       BRepCheck::Add(myMap(myShape), myCstat);
270     }
271
272     return myCstat;
273   }
274
275   myCdone = Standard_True; // it will be done...
276
277   BRepCheck_ListIteratorOfListOfStatus itl(myMap(myShape));
278   if (itl.Value() != BRepCheck_NoError)
279   {
280     myCstat = itl.Value();
281     return myCstat; // already saved
282   }
283
284   myCstat = BRepCheck_NoError;
285   //
286   Standard_Integer index, aNbF;
287   TopExp_Explorer exp, ede;
288   TopTools_IndexedMapOfShape mapS;
289   TopTools_MapOfShape aMEToAvoid;
290   myMapEF.Clear();
291   
292
293   // Checks if the oriented faces of the shell give a "closed" shell,
294   // i-e if each oriented edge on oriented faces is found 2 times.
295   //
296   //modified by NIZNHY-PKV Mon Jun  4 13:59:21 2007f
297   exp.Init(myShape,TopAbs_FACE);
298   for (; exp.More(); exp.Next())
299   {
300     const TopoDS_Shape& aF=exp.Current();
301     if (IsOriented(aF))
302     {
303       ede.Init(exp.Current(),TopAbs_EDGE);
304       for (; ede.More(); ede.Next())
305       {
306         const TopoDS_Shape& aE=ede.Current();
307         if (!IsOriented(aE))
308         {
309           aMEToAvoid.Add(aE);
310         }
311       }
312     }
313   }
314   //modified by NIZNHY-PKV Mon Jun  4 13:59:23 2007t
315   //
316   exp.Init(myShape,TopAbs_FACE);
317   for (; exp.More(); exp.Next())
318   {
319     const TopoDS_Shape& aF=exp.Current();
320     if (IsOriented(aF))
321     {
322       if (!mapS.Add(aF))
323       {
324         myCstat = BRepCheck_RedundantFace;
325         
326         if (Update)
327         {
328           BRepCheck::Add(myMap(myShape),myCstat);
329         }
330
331         return myCstat;
332       }
333
334       //
335       ede.Init(exp.Current(),TopAbs_EDGE);
336       for (; ede.More(); ede.Next())
337       {
338         const TopoDS_Shape& aE=ede.Current();
339         //modified by NIZNHY-PKV Mon Jun  4 14:07:57 2007f
340         //if (IsOriented(aE)) {
341         if (!aMEToAvoid.Contains(aE))
342         {
343           //modified by NIZNHY-PKV Mon Jun  4 14:08:01 2007
344           index = myMapEF.FindIndex(aE);
345           
346           if (!index)
347           {
348             TopTools_ListOfShape thelist;
349             index = myMapEF.Add(aE, thelist);
350           }
351
352           myMapEF(index).Append(aF);
353         }
354       }
355     }
356   }
357
358   //
359   myNbori = mapS.Extent();
360   if (myNbori >= 2)
361   {
362     mapS.Clear();
363     // Search for the first oriented face
364     TopoDS_Shape aF;
365     exp.Init(myShape, TopAbs_FACE);
366     for (;exp.More(); exp.Next())
367     {
368       aF=exp.Current();
369       if (IsOriented(aF))
370       {
371         break;
372       }
373     }
374
375     Propagate(myMapEF, aF, mapS);
376   }
377   //
378
379   //
380   aNbF=mapS.Extent();
381   if (myNbori != aNbF)
382   {
383     myCstat = BRepCheck_NotConnected;
384     if (Update)
385     {
386       BRepCheck::Add(myMap(myShape),myCstat);
387     }
388     return myCstat;
389   }
390   //
391   //
392   Standard_Integer i, Nbedges, nboc, nbSet;
393   //
394   Nbedges = myMapEF.Extent();
395   for (i = 1; i<=Nbedges; ++i)
396   {
397     nboc = myMapEF(i).Extent();
398     if (nboc == 0 || nboc >= 3)
399     {
400       TopTools_ListOfShape theSet;
401       nbSet=NbConnectedSet(theSet);
402       // If there is more than one closed cavity the shell is considered invalid
403       // this corresponds to the criteria of a solid (not those of a shell)
404       if (nbSet>1)
405       {
406         myCstat = BRepCheck_InvalidMultiConnexity;
407         if (Update)
408         {
409           BRepCheck::Add(myMap(myShape),myCstat);
410         }
411
412         return myCstat;
413       }
414     }
415     else if (nboc == 1)
416     {
417       if (!BRep_Tool::Degenerated(TopoDS::Edge(myMapEF.FindKey(i))))
418       {
419         myCstat=BRepCheck_NotClosed;
420         if (Update)
421         {
422           BRepCheck::Add(myMap(myShape),myCstat);
423         }
424
425         return myCstat;
426       }
427     }
428   }
429   
430   if (Update) {
431     BRepCheck::Add(myMap(myShape),myCstat);
432   }
433   return myCstat;
434 }
435
436
437 //=======================================================================
438 //function : Orientation
439 //purpose  : 
440 //=======================================================================
441
442 BRepCheck_Status BRepCheck_Shell::Orientation(const Standard_Boolean Update)
443 {
444   if (myOdone) {
445     if (Update) {
446       BRepCheck::Add(myMap(myShape), myOstat);
447     }
448     return myOstat;
449   }
450   myOdone = Standard_True;
451
452   myOstat = Closed();
453   if (myOstat != BRepCheck_NotClosed && myOstat != BRepCheck_NoError) {
454     if (Update) {
455       BRepCheck::Add(myMap(myShape), myOstat);
456     }
457     return myOstat;
458   }
459
460   myOstat = BRepCheck_NoError;
461
462
463 // First the orientation of each face in relation to the shell is found.
464 // It is used to check BRepCheck_RedundantFace
465
466   TopTools_DataMapOfShapeInteger MapOfShapeOrientation;
467   TopExp_Explorer exp,ede;
468
469   for (exp.Init(myShape,TopAbs_FACE); exp.More(); exp.Next()) {
470     if (!MapOfShapeOrientation.Bind(exp.Current(), (Standard_Integer)(exp.Current().Orientation()))) {
471       myOstat = BRepCheck_RedundantFace;
472       if (Update) {
473         BRepCheck::Add(myMap(myShape), myOstat);
474       }
475       else {
476         return myOstat;
477       }
478     }
479   }
480
481 #ifdef OCCT_DEBUG
482   if (BRepCheck_Trace(0) > 1) {
483     TopTools_DataMapIteratorOfDataMapOfShapeInteger itt(MapOfShapeOrientation);
484     Standard_Integer upper = MapOfShapeOrientation.NbBuckets();
485     std::cout << "La map shape Orientation :" << std::endl;
486     for (; itt.More(); itt.Next()) {
487       PrintShape(itt.Key(), upper);
488     }
489     std::cout << std::endl;
490   }
491 #endif
492
493
494 // Then the orientation of faces by their connectivity is checked
495 // BRepCheck_BadOrientationOfSubshape and 
496 //         BRepCheck_SubshapeNotInShape are checked;
497
498   Standard_Integer Nbedges = myMapEF.Extent();
499   TopoDS_Face Fref;
500   TopAbs_Orientation orf;
501
502   for (Standard_Integer i = 1; i<= Nbedges; i++) {
503
504     const TopoDS_Edge& edg = TopoDS::Edge(myMapEF.FindKey(i));
505     if (BRep_Tool::Degenerated(edg)) continue;
506     TopTools_ListOfShape& lface = myMapEF(i);
507     TopTools_ListIteratorOfListOfShape lite(lface);
508
509     if (lface.Extent() <= 2)
510       {
511         lite.Initialize(lface);
512         Fref = TopoDS::Face(lite.Value());
513         
514         if (!MapOfShapeOrientation.IsBound(Fref)) {
515           myOstat = BRepCheck_SubshapeNotInShape;
516           if (Update) {
517             BRepCheck::Add(myMap(myShape), myOstat);
518             }
519           // quit because no workaround for the incoherence is possible
520           return myOstat;
521         }
522         lite.Next();
523         
524         if (lite.More()) { // Edge of connectivity
525           //JR/Hp :
526           Standard_Integer iorf = MapOfShapeOrientation.Find(Fref);
527           orf = (TopAbs_Orientation) iorf;
528           //orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fref);
529           Fref.Orientation(orf);
530           
531           // edge is examined
532           if (!lite.Value().IsSame(Fref)) { // edge non "closed"
533             for (ede.Init(Fref,TopAbs_EDGE); ede.More(); ede.Next()) {
534               if (ede.Current().IsSame(edg)) {
535                 break;
536               }
537             }
538             TopAbs_Orientation orient = ede.Current().Orientation();
539             TopoDS_Face Fcur= TopoDS::Face(lite.Value());
540             
541             if (!MapOfShapeOrientation.IsBound(Fcur)) {
542               myOstat = BRepCheck_SubshapeNotInShape;
543               if (Update) {
544                 BRepCheck::Add(myMap(myShape), myOstat);
545                 }
546               // quit because no workaround for the incoherence is possible
547               return myOstat;
548             }
549             
550             //JR/Hp :
551             Standard_Integer anOriFCur = MapOfShapeOrientation.Find(Fcur) ;
552             orf = (TopAbs_Orientation)anOriFCur;
553             //  orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fcur);
554             Fcur.Orientation(orf);
555             
556             for (ede.Init(Fcur, TopAbs_EDGE); ede.More(); ede.Next()) {
557               if (ede.Current().IsSame(edg)) {
558                 break;
559               }
560             }
561             if (ede.Current().Orientation() == orient) {
562               // The loop is continued on the edges as many times 
563               // as the same edge is present in the wire
564
565               // modified by NIZHNY-MKK  Tue Sep 30 11:11:42 2003
566               Standard_Boolean bfound = Standard_False;
567               ede.Next();
568               for (; ede.More(); ede.Next()) {
569                 if (ede.Current().IsSame(edg)) {
570                   // modified by NIZHNY-MKK  Tue Sep 30 11:12:03 2003
571                   bfound = Standard_True;
572                   break;
573                 }
574               }
575               //              if (ede.Current().Orientation() == orient) {
576               // modified by NIZHNY-MKK  Thu Oct  2 17:56:47 2003
577               if (!bfound || (ede.Current().Orientation() == orient)) {
578                 myOstat = BRepCheck_BadOrientationOfSubshape;
579                 if (Update) {
580                   BRepCheck::Add(myMap(myShape), myOstat);
581                     break;
582                   }
583                 return myOstat;
584               }
585             }
586           }
587         }
588       }
589     else //more than two faces
590       {
591         Standard_Integer numF = 0, numR = 0;
592         TopTools_MapOfShape Fmap;
593
594         for (lite.Initialize(lface); lite.More(); lite.Next())
595           {
596             TopoDS_Face Fcur= TopoDS::Face(lite.Value());
597             if (!MapOfShapeOrientation.IsBound(Fcur))
598               {
599                 myOstat = BRepCheck_SubshapeNotInShape;
600                 if (Update)
601                   BRepCheck::Add(myMap(myShape), myOstat);
602               // quit because no workaround for the incoherence is possible
603                 return myOstat;
604               }
605
606             Standard_Integer iorf = MapOfShapeOrientation.Find(Fcur);
607             orf = (TopAbs_Orientation) iorf;
608             //orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fcur);
609             Fcur.Orientation(orf);
610
611             for (ede.Init(Fcur,TopAbs_EDGE); ede.More(); ede.Next())
612               if (ede.Current().IsSame(edg))
613                 break;
614             if (Fmap.Contains(Fcur)) //edge is "closed" on Fcur, we meet Fcur twice
615               {
616                 ede.Next();
617                 for (; ede.More(); ede.Next())
618                   if (ede.Current().IsSame(edg))
619                     break;
620               }
621             TopAbs_Orientation orient = ede.Current().Orientation();
622             if (orient == TopAbs_FORWARD)
623               numF++;
624             else
625               numR++;
626
627             Fmap.Add(Fcur);
628           }
629
630         if (numF != numR)
631           {
632             myOstat = BRepCheck_BadOrientationOfSubshape;
633             if (Update)
634               {
635                 BRepCheck::Add(myMap(myShape), myOstat);
636                 break;
637               }
638             return myOstat;
639           }
640       }
641   }
642
643 // If at least one incorrectly oriented face has been found, it is checked if the shell can be oriented. 
644 //          i.e. : if by modification of the orientation of a face it is possible to find 
645 //          a coherent orientation. (it is not possible on a Moebius band)
646 //          BRepCheck_UnorientableShape is checked
647
648   if (myOstat == BRepCheck_BadOrientationOfSubshape) {
649     if (!Fref.IsNull()) {
650       if (Nbedges > 0) {
651         TopTools_MapOfShape alre;
652         TopTools_ListOfShape voisin;
653         voisin.Append(Fref);
654         alre.Clear();
655         while (!voisin.IsEmpty()) {
656           Fref=TopoDS::Face(voisin.First());
657           voisin.RemoveFirst();
658           if (!MapOfShapeOrientation.IsBound(Fref)) {
659             myOstat = BRepCheck_SubshapeNotInShape;
660             if (Update) {
661               BRepCheck::Add(myMap(myShape), myOstat);
662             }
663             // quit because no workaround for the incoherence is possible
664             return myOstat;
665           }
666 //JR/Hp :
667           Standard_Integer iorf = MapOfShapeOrientation.Find(Fref) ;
668           orf = (TopAbs_Orientation) iorf ;
669 //        orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fref);
670           Fref.Orientation(orf);
671
672 #ifdef OCCT_DEBUG
673   if (BRepCheck_Trace(0) > 3) {
674     std::cout << "Fref : " ;
675     PrintShape(Fref, MapOfShapeOrientation.NbBuckets());
676   }
677 #endif
678
679           TopExp_Explorer edFcur;
680           alre.Add(Fref);
681
682           for (ede.Init(Fref,TopAbs_EDGE); ede.More(); ede.Next()) {
683             const TopoDS_Edge& edg = TopoDS::Edge(ede.Current());
684             TopAbs_Orientation orient = edg.Orientation();
685             TopTools_ListOfShape& lface = myMapEF.ChangeFromKey(edg);
686             TopTools_ListIteratorOfListOfShape lite(lface);
687           
688             TopoDS_Face Fcur= TopoDS::Face(lite.Value());
689             if (Fcur.IsSame(Fref)) {
690               lite.Next();
691               if (lite.More()) {
692                 Fcur=TopoDS::Face(lite.Value());
693               }
694               else {
695                 // from the free border one goes to the next edge
696                 continue;
697               }
698             }
699
700             if (!MapOfShapeOrientation.IsBound(Fcur)) {
701               myOstat = BRepCheck_SubshapeNotInShape;
702               if (Update) {
703                 BRepCheck::Add(myMap(myShape), myOstat);
704               }
705               // quit because no workaround for the incoherence is possible
706               return myOstat;
707             }
708
709 //JR/Hp :
710             Standard_Integer anOriFCur = MapOfShapeOrientation.Find(Fcur) ;
711             orf = (TopAbs_Orientation)anOriFCur;
712 //          orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fcur);
713             Fcur.Orientation(orf);
714
715 #ifdef OCCT_DEBUG
716   if (BRepCheck_Trace(0) > 3) {
717     std::cout << "    Fcur : " ;
718     PrintShape(Fcur, MapOfShapeOrientation.NbBuckets());
719   }
720 #endif
721             for (edFcur.Init(Fcur, TopAbs_EDGE); edFcur.More(); edFcur.Next()) {
722               if (edFcur.Current().IsSame(edg)) {
723                 break;
724               }
725             }
726             if (edFcur.Current().Orientation() == orient) {
727               if (alre.Contains(Fcur)) {
728                 // It is necessary to return a face that has been already examined or returned
729                 // if one gets nowhere, the shell cannot be oriented.
730                 myOstat = BRepCheck_UnorientableShape;
731                 if (Update) {
732                   BRepCheck::Add(myMap(myShape), myOstat);
733                 }
734                 // quit, otherwise there is a risk of taking too much time.
735 #ifdef OCCT_DEBUG
736   if (BRepCheck_Trace(0) > 3) {
737     orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fcur);
738     Fcur.Orientation(orf);
739     std::cout << "    Error : this face has been already examined " << std::endl;
740     std::cout << "    Imposible to return it ";
741     PrintShape(Fcur, MapOfShapeOrientation.NbBuckets());
742   }
743 #endif
744                 return myOstat;
745               }
746               orf = TopAbs::Reverse(orf);
747               MapOfShapeOrientation(Fcur)=orf;
748
749
750 #ifdef OCCT_DEBUG
751   if (BRepCheck_Trace(0) > 3) {
752     orf = (TopAbs_Orientation)MapOfShapeOrientation.Find(Fcur);
753     Fcur.Orientation(orf);
754     std::cout << "    Resulting Fcur is returned : " ;
755     PrintShape(Fcur, MapOfShapeOrientation.NbBuckets());
756   }
757 #endif
758
759             }
760             if (alre.Add(Fcur)) {
761               voisin.Append(Fcur);
762             }
763           }
764         }
765       }
766     }
767   }
768
769   if (Update) {
770     BRepCheck::Add(myMap(myShape), myOstat);
771   }
772   return myOstat;
773 }
774
775 //=======================================================================
776 //function : SetUnorientable
777 //purpose  : 
778 //=======================================================================
779
780 void BRepCheck_Shell::SetUnorientable()
781 {
782   BRepCheck::Add(myMap(myShape),BRepCheck_UnorientableShape);
783 }
784
785
786 //=======================================================================
787 //function : IsUnorientable
788 //purpose  : 
789 //=======================================================================
790
791 Standard_Boolean BRepCheck_Shell::IsUnorientable() const
792 {
793   if (myOdone) {
794     return (myOstat != BRepCheck_NoError);
795   }
796   for (BRepCheck_ListIteratorOfListOfStatus itl(myMap(myShape));
797        itl.More();
798        itl.Next()) {
799     if (itl.Value() == BRepCheck_UnorientableShape) {
800       return Standard_True;
801     }
802   }
803   return Standard_False;
804 }
805
806 //=======================================================================
807 //function : NbConnectedSet
808 //purpose  : 
809 //=======================================================================
810
811 Standard_Integer BRepCheck_Shell::NbConnectedSet(TopTools_ListOfShape& theSets)
812 {
813   // The connections are found 
814   TopTools_IndexedDataMapOfShapeListOfShape parents;
815   TopExp::MapShapesAndAncestors(myShape, TopAbs_EDGE, TopAbs_FACE, parents);
816   // All faces are taken
817   TopTools_MapOfShape theFaces;
818   TopExp_Explorer exsh(myShape, TopAbs_FACE);
819   for (; exsh.More(); exsh.Next()) theFaces.Add(exsh.Current());
820   // The edges that are not oriented or have more than 2 connections are missing
821   Standard_Integer iCur;
822   TopTools_MapOfShape theMultiEd;
823   TopTools_MapOfShape theUnOriEd;
824   for (iCur=1; iCur<=parents.Extent(); iCur++) {
825     const TopoDS_Edge& Ed = TopoDS::Edge(parents.FindKey(iCur));
826     if (parents(iCur).Extent()> 2) theMultiEd.Add(Ed);
827     if (Ed.Orientation()!=TopAbs_REVERSED &&
828         Ed.Orientation()!=TopAbs_FORWARD) theUnOriEd.Add(Ed);
829   }
830   // Starting from multiconnected edges propagation by simple connections
831   TopTools_ListIteratorOfListOfShape lconx1, lconx2;
832   TopTools_MapIteratorOfMapOfShape itmsh(theMultiEd);
833   TopoDS_Shell CurShell;
834   TopoDS_Shape adFac;
835   TopTools_ListOfShape lesCur;
836   BRep_Builder BRB;
837   Standard_Boolean newCur=Standard_True;
838   BRB.MakeShell(CurShell);
839   for (; itmsh.More(); itmsh.Next()) {
840     const TopoDS_Shape& Ed = itmsh.Key();
841     if (!theUnOriEd.Contains(Ed)) {
842       for (lconx1.Initialize(parents.FindFromKey(Ed)); lconx1.More(); lconx1.Next()) {
843         if (theFaces.Contains(lconx1.Value())) {
844           adFac=lconx1.Value();
845           BRB.Add(CurShell, adFac);
846           theFaces.Remove(adFac);
847           newCur=Standard_False;
848           if (theFaces.IsEmpty()) break;
849           lesCur.Append(adFac);
850           while (!lesCur.IsEmpty()) {
851             adFac=lesCur.First();
852             lesCur.RemoveFirst();
853             for (exsh.Init(adFac, TopAbs_EDGE); exsh.More(); exsh.Next()) {
854               const TopoDS_Shape& ced = exsh.Current();
855               if (!theMultiEd.Contains(ced)) {
856                 for (lconx2.Initialize(parents.FindFromKey(ced)); lconx2.More(); lconx2.Next()) {
857                   if (theFaces.Contains(lconx2.Value())) {
858                     adFac=lconx2.Value();
859                     BRB.Add(CurShell, adFac);
860                     theFaces.Remove(adFac);
861                     newCur=Standard_False;
862                     if (theFaces.IsEmpty()) break;
863                     lesCur.Append(adFac);
864                   }
865                 }
866               }
867               if (theFaces.IsEmpty()) break;
868             }
869           }
870           if (!newCur) {
871             CurShell.Closed (BRep_Tool::IsClosed (CurShell));
872             theSets.Append(CurShell);
873             CurShell.Nullify();
874             newCur=Standard_True;
875             BRB.MakeShell(CurShell);
876           }
877         }
878         if (theFaces.IsEmpty()) break;
879       }
880     }
881     if (theFaces.IsEmpty()) break;
882   }
883   return theSets.Extent();
884 }