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