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