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 |
55 | static |
56 | void RemoveInternals(const TopoDS_Face& , |
57 | TopoDS_Face& ); |
58 | |
59 | static |
60 | Standard_Boolean GetShells(TopTools_SequenceOfShape& , |
61 | const TopTools_MapOfShape& , |
62 | TopTools_SequenceOfShape& , |
63 | TopTools_DataMapOfShapeShape& , |
64 | TopTools_SequenceOfShape& ) ; |
65 | |
66 | static |
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 | |
74 | static |
75 | Standard_Boolean SplitShell(const TopoDS_Shell& , |
76 | TopoDS_Shape& ); |
77 | static |
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 | //======================================================================= |
232 | void 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 | //======================================================================= |
451 | Standard_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 | //======================================================================= |
639 | Standard_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 | //======================================================================= |
796 | void 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 | } |