0028474: Boolean operations - General Fuse operator breaks validity of resulting...
[occt.git] / src / BOPAlgo / BOPAlgo_ShellSplitter.cxx
CommitLineData
682c9d06 1// Created by: Peter KURNEV
2// Copyright (c) 1999-2014 OPEN CASCADE SAS
3//
4// This file is part of Open CASCADE Technology software library.
5//
d5f74e42 6// This library is free software; you can redistribute it and/or modify it under
7// the terms of the GNU Lesser General Public License version 2.1 as published
682c9d06 8// by the Free Software Foundation, with special exception defined in the file
9// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10// distribution for complete text of the license and disclaimer of any warranty.
11//
12// Alternatively, this file may be used under the terms of Open CASCADE
13// commercial license or contractual agreement.
14
df80c6dd 15// File: BOPAlgo_ShellSplitter.cxx
16// Created: Thu Jan 16 08:33:50 2014
682c9d06 17
42cf5bc1 18#include <BOPAlgo_ShellSplitter.hxx>
19#include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
682c9d06 20#include <BOPCol_IndexedMapOfShape.hxx>
682c9d06 21#include <BOPCol_MapOfOrientedShape.hxx>
42cf5bc1 22#include <BOPCol_MapOfShape.hxx>
682c9d06 23#include <BOPCol_NCVector.hxx>
42cf5bc1 24#include <BOPCol_Parallel.hxx>
682c9d06 25#include <BOPTools.hxx>
26#include <BOPTools_AlgoTools.hxx>
27#include <BOPTools_CoupleOfShape.hxx>
42cf5bc1 28#include <BRep_Builder.hxx>
29#include <IntTools_Context.hxx>
30#include <TopExp_Explorer.hxx>
093a3fe5 31#include <TopoDS.hxx>
42cf5bc1 32#include <TopoDS_Edge.hxx>
33#include <TopoDS_Shape.hxx>
34#include <TopoDS_Shell.hxx>
69b558c4 35
69b558c4 36//
682c9d06 37static
38 void MakeShell(const BOPCol_ListOfShape& ,
df80c6dd 39 TopoDS_Shell& );
69b558c4 40//
41static
a2ab2702 42 void RefineShell(TopoDS_Shell& theShell,
093a3fe5 43 const BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
a2ab2702 44 BOPCol_ListOfShape& aLShX);
0090ae85 45//
46static
47 void MapEdgesAndFaces
48 (const TopoDS_Shape& aF,
49 BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
50 const Handle(NCollection_BaseAllocator)& theAllocator);
682c9d06 51
69b558c4 52//=======================================================================
53//class : BOPAlgo_CBK
54//purpose :
55//=======================================================================
56class BOPAlgo_CBK {
57 public:
58 BOPAlgo_CBK() :
59 myPCB (NULL) {
60 }
61 //
62 ~BOPAlgo_CBK() {
63 }
64 //
65 void SetConnexityBlock (const BOPTools_ConnexityBlock& aCB) {
66 myPCB=(BOPTools_ConnexityBlock*)&aCB;
67 }
68 //
69 BOPTools_ConnexityBlock& ConnexityBlock () {
70 return *myPCB;
71 }
72 //
73 void Perform() {
74 BOPAlgo_ShellSplitter::SplitBlock(*myPCB);
75 }
76 protected:
77 BOPTools_ConnexityBlock *myPCB;
78};
79//=======================================================================
80typedef BOPCol_NCVector
81 <BOPAlgo_CBK> BOPAlgo_VectorOfCBK;
82//
c7b59798 83typedef BOPCol_Functor
69b558c4 84 <BOPAlgo_CBK,
85 BOPAlgo_VectorOfCBK> BOPAlgo_CBKFunctor;
86//
c7b59798 87typedef BOPCol_Cnt
69b558c4 88 <BOPAlgo_CBKFunctor,
89 BOPAlgo_VectorOfCBK> BOPAlgo_CBKCnt;
90//
682c9d06 91//=======================================================================
92//function :
93//purpose :
94//=======================================================================
95BOPAlgo_ShellSplitter::BOPAlgo_ShellSplitter()
96:
97 BOPAlgo_Algo(),
98 myStartShapes(myAllocator),
99 myShells(myAllocator),
100 myLCB(myAllocator)
101{
102}
103//=======================================================================
104//function :
105//purpose :
106//=======================================================================
107BOPAlgo_ShellSplitter::BOPAlgo_ShellSplitter
108 (const Handle(NCollection_BaseAllocator)& theAllocator)
109:
110 BOPAlgo_Algo(theAllocator),
111 myStartShapes(theAllocator),
112 myShells(theAllocator),
113 myLCB(myAllocator)
114{
115}
116//=======================================================================
117//function : ~
118//purpose :
119//=======================================================================
120BOPAlgo_ShellSplitter::~BOPAlgo_ShellSplitter()
121{
122}
123//=======================================================================
124//function : AddStartElement
125//purpose :
126//=======================================================================
127void BOPAlgo_ShellSplitter::AddStartElement(const TopoDS_Shape& aE)
128{
129 myStartShapes.Append(aE);
130}
131//=======================================================================
132//function : StartElements
133//purpose :
134//=======================================================================
135const BOPCol_ListOfShape& BOPAlgo_ShellSplitter::StartElements()const
136{
137 return myStartShapes;
138}
139//=======================================================================
140//function : Loops
141//purpose :
142//=======================================================================
143const BOPCol_ListOfShape& BOPAlgo_ShellSplitter::Shells()const
144{
145 return myShells;
146}
147//=======================================================================
148//function : Perform
149//purpose :
150//=======================================================================
151void BOPAlgo_ShellSplitter::Perform()
152{
153 myErrorStatus=0;
154 //
155 MakeConnexityBlocks();
156 if (myErrorStatus) {
157 return;
158 }
159 //
160 MakeShells();
161}
162//=======================================================================
163//function : MakeConnexityBlocks
164//purpose :
165//=======================================================================
166void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
167{
168 Standard_Boolean bRegular;
169 Standard_Integer i, j, aNbE, aNbES, aNbEP, k, aNbCB;
170 TopoDS_Shape aFR;
0090ae85 171 TopoDS_Iterator aItF, aItW;
682c9d06 172 BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, myAllocator);
173 BOPCol_IndexedMapOfShape aMEP(100, myAllocator);
174 BOPCol_IndexedMapOfShape aMFC(100, myAllocator);
175 BOPCol_MapOfShape aMER(100, myAllocator);
176 BOPCol_MapOfShape aMFP(100, myAllocator);
177 BOPCol_IndexedMapOfShape aMEAdd(100, myAllocator);
178 BOPCol_MapOfShape aMES(100, myAllocator);
179 BOPCol_ListIteratorOfListOfShape aIt;
180 //
181 myErrorStatus=0;
182 //
183 myLCB.Clear();
184 //
185 const BOPCol_ListOfShape& aLSE=myStartShapes;
186 aIt.Initialize(aLSE);
187 for (i=1; aIt.More(); aIt.Next(), ++i) {
188 const TopoDS_Shape& aSE=aIt.Value();
189 if (!aMEP.Contains(aSE)) {
190 aMEP.Add(aSE);
0090ae85 191 MapEdgesAndFaces(aSE, aMEF, myAllocator);
682c9d06 192 }
193 else {
194 aMER.Add(aSE);
195 }
196 }
197 //
198 // 2
199 aNbE=aMEF.Extent();
200 for (i=1; i<=aNbE; ++i) {
201 aNbES=aMES.Extent();
202 if (aNbES==aNbE) {
203 break;
204 }
205 //
206 const TopoDS_Shape& aE=aMEF.FindKey(i);
207 //
208 if (!aMES.Add(aE)) {
209 continue;
210 }
211 // aMES - globally processed edges
212 //
213 //------------------------------------- goal: aMEC
214 aMFC.Clear(); // aMEC - edges of CB
215 aMEP.Clear(); // aMVP - edges to process right now
216 aMEAdd.Clear(); // aMVAdd edges to process on next step of for(;;) {
217 //
218 aMEP.Add(aE);
219 //
220 for(;;) {
221 aNbEP=aMEP.Extent();
222 for (k=1; k<=aNbEP; ++k) {
223 const TopoDS_Shape& aEP=aMEP(k);
224 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aEP);
225 aIt.Initialize(aLF);
226 for (; aIt.More(); aIt.Next()) {
227 const TopoDS_Shape& aF=aIt.Value();
228 if (aMFC.Add(aF)) {
0090ae85 229 aItF.Initialize(aF);
230 while (aItF.More()) {
231 const TopoDS_Shape& aW=aItF.Value();
232 if (aW.ShapeType()!=TopAbs_WIRE) {
233 aItF.Next();
234 continue;
235 }
236 //
237 aItW.Initialize(aW);
238 while (aItW.More()) {
239 const TopoDS_Shape& aEF=aItW.Value();
240 //
241 if (aMES.Add(aEF)) {
242 aMEAdd.Add(aEF);
243 }
244 //
245 aItW.Next();
682c9d06 246 }
0090ae85 247 //
248 aItF.Next();
682c9d06 249 }
250 }
251 }
252 }
253 //
254 aNbEP=aMEAdd.Extent();
255 if (!aNbEP) {
256 break; // from for(;;) {
257 }
258 //
259 aMEP.Clear();
260 //
261 for (k=1; k<=aNbEP; ++k) {
262 const TopoDS_Shape& aEF=aMEAdd(k);
263 aMEP.Add(aEF);
264 }
265 aMEAdd.Clear();
266 }// for(;;) {
267 //
268 //-------------------------------------
269 BOPTools_ConnexityBlock aCB(myAllocator);
270 //
271 BOPCol_ListOfShape& aLECB=aCB.ChangeShapes();
272 BOPCol_IndexedDataMapOfShapeListOfShape aMEFR(100, myAllocator);
273 //
274 bRegular=Standard_True;
275 aNbCB = aMFC.Extent();
276 for (j=1; j<=aNbCB; ++j) {
277 aFR = aMFC(j);
278 //
279 if (aMER.Contains(aFR)) {
280 aFR.Orientation(TopAbs_FORWARD);
281 aLECB.Append(aFR);
282 aFR.Orientation(TopAbs_REVERSED);
283 aLECB.Append(aFR);
284 bRegular=Standard_False;
285 }
286 else {
287 aLECB.Append(aFR);
288 }
289 //
290 if (bRegular) {
0090ae85 291 MapEdgesAndFaces(aFR, aMEFR, myAllocator);
682c9d06 292 }
293 }
294 //
295 if (bRegular) {
296 Standard_Integer aNbER, aNbFR;
297 //
298 aNbER=aMEFR.Extent();
299 for (k=1; k<=aNbER; ++k) {
300 const BOPCol_ListOfShape& aLFR=aMEFR(k);
301 aNbFR=aLFR.Extent();
302 if (aNbFR>2) {
303 bRegular=!bRegular;
304 break;
305 }
306 }
307 }
308 //
309 aCB.SetRegular(bRegular);
310 myLCB.Append(aCB);
311 }
312}
313//=======================================================================
314//function : SplitBlock
315//purpose :
316//=======================================================================
317void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
318{
319 Standard_Integer aNbLF, aNbOff, aNbFP;
320 Standard_Integer i;
321 TopAbs_Orientation anOr;
322 TopoDS_Edge aEL;
323 BRep_Builder aBB;
324 TopoDS_Iterator aItS;
325 TopExp_Explorer aExp;
326 BOPCol_ListIteratorOfListOfShape aItF;
327 BOPTools_CoupleOfShape aCSOff;
328 BOPCol_MapOfOrientedShape AddedFacesMap;
329 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
a2ab2702 330 Handle (IntTools_Context) aContext;
682c9d06 331 //
a2ab2702 332 aContext=new IntTools_Context;
682c9d06 333 //
334 const BOPCol_ListOfShape& myShapes=aCB.Shapes();
335 //
336 BOPCol_ListOfShape& myLoops=aCB.ChangeLoops();
337 myLoops.Clear();
338 //
093a3fe5 339 // Copy faces into the map, for recursive search of free bounds
340 BOPCol_MapOfOrientedShape aMFaces;
682c9d06 341 aItF.Initialize (myShapes);
342 for (; aItF.More(); aItF.Next()) {
093a3fe5 343 aMFaces.Add(aItF.Value());
682c9d06 344 }
345 //
093a3fe5 346 // remove the faces with free edges from processing
347 for (;;) {
348 // map the shapes
349 aEFMap.Clear();
350 aItF.Initialize(myShapes);
351 for (; aItF.More(); aItF.Next()) {
352 const TopoDS_Shape& aF = aItF.Value();
353 if (aMFaces.Contains(aF)) {
354 BOPTools::MapShapesAndAncestors (aF, TopAbs_EDGE, TopAbs_FACE, aEFMap);
355 }
356 }
357 //
358 Standard_Integer aNbBegin = aMFaces.Extent();
359 // check the free edges
360 Standard_Integer aNbE = aEFMap.Extent();
361 for (i = 1; i <= aNbE; ++i) {
362 const TopoDS_Edge& aE = TopoDS::Edge(aEFMap.FindKey(i));
363 if (!(BRep_Tool::Degenerated(aE) || aE.Orientation() == TopAbs_INTERNAL)) {
364 const BOPCol_ListOfShape& aLF = aEFMap(i);
365 if (aLF.Extent() == 1) {
366 // remove the face
367 aMFaces.Remove(aLF.First());
368 }
369 }
370 }
371 //
372 // check if any faces have been removed
373 Standard_Integer aNbEnd = aMFaces.Extent();
374 if ((aNbEnd == aNbBegin) || (aNbEnd == 0)) {
375 break;
376 }
377 }
378 //
379 if (aMFaces.IsEmpty()) {
380 return;
381 }
382 //
383 // use only connected faces
384 BOPCol_ListOfShape aLFConnected;
682c9d06 385 aItF.Initialize (myShapes);
093a3fe5 386 for (; aItF.More(); aItF.Next()) {
387 const TopoDS_Shape& aF = aItF.Value();
388 if (aMFaces.Contains(aF)) {
389 aLFConnected.Append(aF);
390 }
391 }
392 //
393 const Standard_Integer aNbShapes = aLFConnected.Extent();
394 Standard_Boolean bAllFacesTaken = Standard_False;
395 //
396 // Build the shells
397 aItF.Initialize (aLFConnected);
398 for (i = 1; aItF.More() && !bAllFacesTaken; aItF.Next(), ++i) {
682c9d06 399 const TopoDS_Shape& aFF = aItF.Value();
400 if (!AddedFacesMap.Add(aFF)) {
401 continue;
402 }
403 //
404 // make a new shell
093a3fe5 405 TopoDS_Shell aShellStart;
406 aBB.MakeShell(aShellStart);
407 aBB.Add(aShellStart, aFF);
682c9d06 408 //
093a3fe5 409 BOPCol_ListOfShape aLShells;
410 aLShells.Append(aShellStart);
682c9d06 411 //
093a3fe5 412 BOPCol_ListIteratorOfListOfShape aItLShells(aLShells);
413 for (; aItLShells.More(); aItLShells.Next()) {
414 TopoDS_Shell& aShell = TopoDS::Shell(aItLShells.ChangeValue());
682c9d06 415 //
093a3fe5 416 aMEFP.Clear();
417 BOPTools::MapShapesAndAncestors(aShell, TopAbs_EDGE, TopAbs_FACE, aMEFP);
418 //
419 // loop on faces added to Shell;
420 // add their neighbor faces to Shell and so on
421 aItS.Initialize(aShell);
422 for (; aItS.More(); aItS.Next()) {
423 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItS.Value()));
682c9d06 424 //
093a3fe5 425 // loop on edges of aF; find a good neighbor face of aF by aE
426 aExp.Init(aF, TopAbs_EDGE);
427 for (; aExp.More(); aExp.Next()) {
428 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current()));
429 //
430 // proceed only free edges in this shell
431 if (aMEFP.Contains(aE)) {
432 const BOPCol_ListOfShape& aLFP = aMEFP.FindFromKey(aE);
433 aNbFP = aLFP.Extent();
434 if (aNbFP > 1) {
435 continue;
436 }
437 }
438 // avoid processing of internal edges
439 anOr = aE.Orientation();
440 if (anOr == TopAbs_INTERNAL) {
682c9d06 441 continue;
442 }
093a3fe5 443 // avoid processing of degenerated edges
444 if (BRep_Tool::Degenerated(aE)) {
682c9d06 445 continue;
093a3fe5 446 }
447 //
448 // candidate faces list
449 const BOPCol_ListOfShape& aLF = aEFMap.FindFromKey(aE);
450 aNbLF = aLF.Extent();
451 if (!aNbLF) {
682c9d06 452 continue;
453 }
454 //
093a3fe5 455 // prepare for selecting the next face
456 // take only not-processed faces as a candidates
457 BOPTools_ListOfCoupleOfShape aLCSOff;
458 //
459 BOPCol_ListIteratorOfListOfShape aItLF(aLF);
460 for (; aItLF.More(); aItLF.Next()) {
461 const TopoDS_Face& aFL = (*(TopoDS_Face*)(&aItLF.Value()));
462 if (aF.IsSame(aFL) || AddedFacesMap.Contains(aFL)) {
463 continue;
464 }
465 //
466 // find current edge in the face
467 if (!BOPTools_AlgoTools::GetEdgeOff(aE, aFL, aEL)) {
468 continue;
469 }
470 //
471 aCSOff.SetShape1(aEL);
472 aCSOff.SetShape2(aFL);
473 aLCSOff.Append(aCSOff);
474 }//for (; aItLF.More(); aItLF.Next()) {
475 //
476 aNbOff = aLCSOff.Extent();
477 if (!aNbOff){
682c9d06 478 continue;
479 }
480 //
093a3fe5 481 // among all the adjacent faces chose one with the minimal
482 // angle to the current one
483 TopoDS_Face aSelF;
484 if (aNbOff == 1) {
485 aSelF = (*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
486 }
487 else if (aNbOff > 1) {
488 BOPTools_AlgoTools::GetFaceOff(aE, aF, aLCSOff, aSelF, aContext);
489 }
490 //
491 if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
492 aBB.Add(aShell, aSelF);
493 BOPTools::MapShapesAndAncestors(aSelF, TopAbs_EDGE, TopAbs_FACE, aMEFP);
494 }
495 } // for (; aExp.More(); aExp.Next()) {
496 } // for (; aItS.More(); aItS.Next()) {
497 //
498 // split the shell on multi-connected edges
499 BOPCol_ListOfShape aLShSp;
500 RefineShell(aShell, aMEFP, aLShSp);
501 //
502 // collect the not closed shells for further processing
503 BOPCol_ListOfShape aLShNC;
504 //
505 BOPCol_ListIteratorOfListOfShape aItLShSp(aLShSp);
506 for (; aItLShSp.More(); aItLShSp.Next()) {
507 TopoDS_Shell& aShSp = *((TopoDS_Shell*)&aItLShSp.Value());
682c9d06 508 //
093a3fe5 509 if (BRep_Tool::IsClosed(aShSp)) {
510 aShSp.Closed(Standard_True);
511 myLoops.Append(aShSp);
682c9d06 512 }
093a3fe5 513 else {
514 aLShNC.Append(aShSp);
682c9d06 515 }
093a3fe5 516 }
517 //
518 bAllFacesTaken = (AddedFacesMap.Extent() == aNbShapes);
519 if (bAllFacesTaken) {
520 break;
521 }
522 //
523 if (aLShSp.Extent() == 1) {
524 // not further processing of not closed shells is needed,
525 // as it will not bring any new results
526 continue;
527 }
a2ab2702 528 //
093a3fe5 529 Standard_Integer aNbShNC = aLShNC.Extent();
530 if (aNbShNC == 1) {
531 // try to complete the shell with other faces
532 aLShells.Append(aLShNC);
533 }
534 else if (aNbShNC > 1) {
535 // remove th faces of not closed shells from the map of processed faces
536 // and try to rebuild the shells using all not processed faces,
537 // because faces of one shell might be needed for building the other
538 BOPCol_ListIteratorOfListOfShape aItLShNC(aLShNC);
539 for (; aItLShNC.More(); aItLShNC.Next()) {
540 TopoDS_Iterator aItNC(aItLShNC.Value());
541 for (; aItNC.More(); aItNC.Next()) {
542 AddedFacesMap.Remove(aItNC.Value());
543 }
544 }
69b558c4 545 }
546 }
682c9d06 547 } // for (; aItF.More(); aItF.Next()) {
548}
549//=======================================================================
69b558c4 550//function : RefineShell
551//purpose :
682c9d06 552//=======================================================================
093a3fe5 553void RefineShell(TopoDS_Shell& theShell,
554 const BOPCol_IndexedDataMapOfShapeListOfShape& theMEF,
555 BOPCol_ListOfShape& theLShSp)
69b558c4 556{
093a3fe5 557 TopoDS_Iterator aIt(theShell);
69b558c4 558 if(!aIt.More()) {
559 return;
682c9d06 560 }
561 //
093a3fe5 562 // Find edges with more than 2 adjacent faces - branch edges -
563 // edges on which the input shell should be split
564 BOPCol_MapOfShape aMEStop;
69b558c4 565 //
093a3fe5 566 Standard_Integer i, aNbMEF = theMEF.Extent();
567 for (i = 1; i <= aNbMEF; ++i) {
568 const TopoDS_Edge& aE = TopoDS::Edge(theMEF.FindKey(i));
569 const BOPCol_ListOfShape& aLF = theMEF(i);
570 if (aLF.Extent() > 2) {
571 aMEStop.Add(aE);
572 continue;
573 }
574 //
575 // check for internal edges - count faces, in which the edge
576 // is internal, twice
577 Standard_Integer aNbF = 0;
578 BOPCol_ListIteratorOfListOfShape aItLF(aLF);
579 for (; aItLF.More() && aNbF <= 2; aItLF.Next()) {
580 const TopoDS_Face& aF = TopoDS::Face(aItLF.Value());
581 ++aNbF;
582 TopExp_Explorer aExp(aF, TopAbs_EDGE);
583 for (; aExp.More(); aExp.Next()) {
584 const TopoDS_Shape& aEF = aExp.Current();
585 if (aEF.IsSame(aE)) {
586 if (aEF.Orientation() == TopAbs_INTERNAL) {
587 ++aNbF;
588 }
589 break;
590 }
591 }
592 }
593 //
594 if (aNbF > 2) {
69b558c4 595 aMEStop.Add(aE);
596 }
597 }
598 //
599 if (aMEStop.IsEmpty()) {
093a3fe5 600 theLShSp.Append(theShell);
69b558c4 601 return;
602 }
603 //
093a3fe5 604 TopoDS_Builder aBB;
605 TopExp_Explorer aExp;
606 BOPCol_IndexedMapOfShape aMFB;
607 BOPCol_MapOfOrientedShape aMFProcessed;
608 BOPCol_ListOfShape aLFP, aLFP1;
609 BOPCol_ListIteratorOfListOfShape aItLF, aItLFP;
610 //
611 // The first Face
a2ab2702 612 for (; aIt.More(); aIt.Next()) {
093a3fe5 613 const TopoDS_Shape& aF1 = aIt.Value();
a2ab2702 614 if (!aMFProcessed.Add(aF1)) {
615 continue;
616 }
617 //
618 aMFB.Clear();
619 aLFP.Clear();
620 //
621 aMFB.Add(aF1);
622 aLFP.Append(aF1);
623 //
624 // Trying to reach the branch point
0f04f1e1 625 for (;;) {
a2ab2702 626 aItLFP.Initialize(aLFP);
093a3fe5 627 for (; aItLFP.More(); aItLFP.Next()) {
628 const TopoDS_Shape& aFP = aItLFP.Value();
69b558c4 629 //
a2ab2702 630 aExp.Init(aFP, TopAbs_EDGE);
631 for (; aExp.More(); aExp.Next()) {
093a3fe5 632 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current()));
a2ab2702 633 if (aMEStop.Contains(aE)) {
69b558c4 634 continue;
635 }
a2ab2702 636 //
0f04f1e1 637 if (aE.Orientation() == TopAbs_INTERNAL) {
638 continue;
639 }
640 //
a2ab2702 641 if (BRep_Tool::Degenerated(aE)) {
69b558c4 642 continue;
643 }
a2ab2702 644 //
093a3fe5 645 const BOPCol_ListOfShape& aLF = theMEF.FindFromKey(aE);
a2ab2702 646 //
647 aItLF.Initialize(aLF);
093a3fe5 648 for (; aItLF.More(); aItLF.Next()) {
649 const TopoDS_Shape& aFP1 = aItLF.Value();
a2ab2702 650 if (aFP1.IsSame(aFP)) {
651 continue;
652 }
653 if (aMFB.Contains(aFP1)) {
654 continue;
655 }
656 //
093a3fe5 657 if (aMFProcessed.Add(aFP1)) {
658 aMFB.Add(aFP1);
659 aLFP1.Append(aFP1);
660 }
a2ab2702 661 }// for (; aItLF.More(); aItLF.Next()) {
662 }// for (; aExp.More(); aExp.Next()) {
663 } // for (; aItLFP.More(); aItLFP.Next()) {
664 //
665 //
666 if (aLFP1.IsEmpty()) {
667 break;
668 }
669 //
670 aLFP.Clear();
093a3fe5 671 aLFP.Append(aLFP1);
0f04f1e1 672 }// for (;;) {
69b558c4 673 //
093a3fe5 674 Standard_Integer aNbMFB = aMFB.Extent();
a2ab2702 675 if (aNbMFB) {
093a3fe5 676 TopoDS_Shell aShSp;
677 aBB.MakeShell(aShSp);
a2ab2702 678 //
093a3fe5 679 for (i = 1; i <= aNbMFB; ++i) {
680 const TopoDS_Shape& aFB = aMFB(i);
681 aBB.Add(aShSp, aFB);
a2ab2702 682 }
093a3fe5 683 theLShSp.Append(aShSp);
682c9d06 684 }
a2ab2702 685 }//for (; aIt.More(); aIt.Next()) {
0f04f1e1 686}
682c9d06 687//=======================================================================
69b558c4 688//function : MakeShells
682c9d06 689//purpose :
690//=======================================================================
691void BOPAlgo_ShellSplitter::MakeShells()
692{
693 Standard_Boolean bIsRegular;
69b558c4 694 Standard_Integer aNbVCBK, k;
682c9d06 695 BOPTools_ListIteratorOfListOfConnexityBlock aItCB;
696 BOPCol_ListIteratorOfListOfShape aIt;
69b558c4 697 BOPAlgo_VectorOfCBK aVCBK;
682c9d06 698 //
699 myErrorStatus=0;
700 myShells.Clear();
701 //
702 aItCB.Initialize(myLCB);
703 for (; aItCB.More(); aItCB.Next()) {
704 BOPTools_ConnexityBlock& aCB=aItCB.ChangeValue();
705 bIsRegular=aCB.IsRegular();
706 if (bIsRegular) {
707 TopoDS_Shell aShell;
708 //
709 const BOPCol_ListOfShape& aLF=aCB.Shapes();
710 MakeShell(aLF, aShell);
ab860031 711 aShell.Closed(Standard_True);
682c9d06 712 myShells.Append(aShell);
713 }
714 else {
69b558c4 715 BOPAlgo_CBK& aCBK=aVCBK.Append1();
716 aCBK.SetConnexityBlock(aCB);
682c9d06 717 }
718 }
719 //
69b558c4 720 aNbVCBK=aVCBK.Extent();
682c9d06 721 //===================================================
69b558c4 722 BOPAlgo_CBKCnt::Perform(myRunParallel, aVCBK);
682c9d06 723 //===================================================
69b558c4 724 for (k=0; k<aNbVCBK; ++k) {
725 BOPAlgo_CBK& aCBK=aVCBK(k);
726 const BOPTools_ConnexityBlock& aCB=aCBK.ConnexityBlock();
682c9d06 727 const BOPCol_ListOfShape& aLS=aCB.Loops();
728 aIt.Initialize(aLS);
729 for (; aIt.More(); aIt.Next()) {
ab860031 730 TopoDS_Shape& aShell=aIt.ChangeValue();
731 aShell.Closed(Standard_True);
682c9d06 732 myShells.Append(aShell);
733 }
734 }
735}
736//=======================================================================
682c9d06 737//function : MakeShell
738//purpose :
739//=======================================================================
740void MakeShell(const BOPCol_ListOfShape& aLS,
df80c6dd 741 TopoDS_Shell& aShell)
682c9d06 742{
743 BRep_Builder aBB;
744 BOPCol_ListIteratorOfListOfShape aIt;
745 //
746 aBB.MakeShell(aShell);
747 //
748 aIt.Initialize(aLS);
749 for (; aIt.More(); aIt.Next()) {
750 const TopoDS_Shape& aF=aIt.Value();
751 aBB.Add(aShell, aF);
752 }
6fd4ffd9 753 //
754 BOPTools_AlgoTools::OrientFacesOnShell(aShell);
682c9d06 755}
0090ae85 756//=======================================================================
757// function: MapEdgesAndFaces
758// purpose:
759//=======================================================================
760void MapEdgesAndFaces
761 (const TopoDS_Shape& aF,
762 BOPCol_IndexedDataMapOfShapeListOfShape& aMEF,
763 const Handle(NCollection_BaseAllocator)& theAllocator)
764{
765 TopoDS_Iterator aItF, aItW;
766 //
767 aItF.Initialize(aF);
768 while (aItF.More()) {
769 const TopoDS_Shape& aW=aItF.Value();
770 if (aW.ShapeType()!=TopAbs_WIRE) {
771 aItF.Next();
772 continue;
773 }
774 //
775 aItW.Initialize(aW);
776 while (aItW.More()) {
777 const TopoDS_Shape& aE=aItW.Value();
778 //
779 if (aMEF.Contains(aE)) {
780 BOPCol_ListOfShape& aLF=aMEF.ChangeFromKey(aE);
781 aLF.Append(aF);
782 }
783 else {
784 BOPCol_ListOfShape aLS(theAllocator);
785 //
786 aLS.Append(aF);
787 aMEF.Add(aE, aLS);
788 }
789 //
790 aItW.Next();
791 }
792 //
793 aItF.Next();
794 }
795}