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