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