1 // Created by: Peter KURNEV
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
4 // This file is part of Open CASCADE Technology software library.
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
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.
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
15 // File: BOPAlgo_ShellSplitter.cxx
16 // Created: Thu Jan 16 08:33:50 2014
19 #include <BOPAlgo_ShellSplitter.ixx>
21 #include <TopoDS_Shape.hxx>
22 #include <TopoDS_Shell.hxx>
23 #include <TopoDS_Edge.hxx>
25 #include <BRep_Builder.hxx>
26 #include <TopExp_Explorer.hxx>
28 #include <BOPCol_TBB.hxx>
29 #include <BOPCol_IndexedMapOfShape.hxx>
30 #include <BOPCol_MapOfShape.hxx>
31 #include <BOPCol_MapOfOrientedShape.hxx>
32 #include <BOPCol_NCVector.hxx>
33 #include <BOPCol_IndexedDataMapOfShapeListOfShape.hxx>
35 #include <BOPInt_Context.hxx>
37 #include <BOPTools.hxx>
38 #include <BOPTools_AlgoTools.hxx>
39 #include <BOPTools_CoupleOfShape.hxx>
43 Standard_Boolean IsClosedShell(const TopoDS_Shell& );
46 void MakeShell(const BOPCol_ListOfShape& ,
50 void RefineShell(TopoDS_Shell& theShell);
52 //=======================================================================
55 //=======================================================================
65 void SetConnexityBlock (const BOPTools_ConnexityBlock& aCB) {
66 myPCB=(BOPTools_ConnexityBlock*)&aCB;
69 BOPTools_ConnexityBlock& ConnexityBlock () {
74 BOPAlgo_ShellSplitter::SplitBlock(*myPCB);
77 BOPTools_ConnexityBlock *myPCB;
79 //=======================================================================
80 typedef BOPCol_NCVector
81 <BOPAlgo_CBK> BOPAlgo_VectorOfCBK;
83 typedef BOPCol_TBBFunctor
85 BOPAlgo_VectorOfCBK> BOPAlgo_CBKFunctor;
89 BOPAlgo_VectorOfCBK> BOPAlgo_CBKCnt;
91 //=======================================================================
94 //=======================================================================
95 BOPAlgo_ShellSplitter::BOPAlgo_ShellSplitter()
98 myStartShapes(myAllocator),
99 myShells(myAllocator),
103 //=======================================================================
106 //=======================================================================
107 BOPAlgo_ShellSplitter::BOPAlgo_ShellSplitter
108 (const Handle(NCollection_BaseAllocator)& theAllocator)
110 BOPAlgo_Algo(theAllocator),
111 myStartShapes(theAllocator),
112 myShells(theAllocator),
116 //=======================================================================
119 //=======================================================================
120 BOPAlgo_ShellSplitter::~BOPAlgo_ShellSplitter()
123 //=======================================================================
124 //function : AddStartElement
126 //=======================================================================
127 void BOPAlgo_ShellSplitter::AddStartElement(const TopoDS_Shape& aE)
129 myStartShapes.Append(aE);
131 //=======================================================================
132 //function : StartElements
134 //=======================================================================
135 const BOPCol_ListOfShape& BOPAlgo_ShellSplitter::StartElements()const
137 return myStartShapes;
139 //=======================================================================
142 //=======================================================================
143 const BOPCol_ListOfShape& BOPAlgo_ShellSplitter::Shells()const
147 //=======================================================================
150 //=======================================================================
151 void BOPAlgo_ShellSplitter::Perform()
155 MakeConnexityBlocks();
162 //=======================================================================
163 //function : MakeConnexityBlocks
165 //=======================================================================
166 void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
168 Standard_Boolean bRegular;
169 Standard_Integer i, j, aNbE, aNbES, aNbEP, k, aNbCB;
171 TopExp_Explorer aExpF;
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;
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)) {
191 BOPTools::MapShapesAndAncestors(aSE,
203 for (i=1; i<=aNbE; ++i) {
209 const TopoDS_Shape& aE=aMEF.FindKey(i);
214 // aMES - globally processed edges
216 //------------------------------------- goal: aMEC
217 aMFC.Clear(); // aMEC - edges of CB
218 aMEP.Clear(); // aMVP - edges to process right now
219 aMEAdd.Clear(); // aMVAdd edges to process on next step of for(;;) {
225 for (k=1; k<=aNbEP; ++k) {
226 const TopoDS_Shape& aEP=aMEP(k);
227 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aEP);
229 for (; aIt.More(); aIt.Next()) {
230 const TopoDS_Shape& aF=aIt.Value();
232 aExpF.Init(aF, TopAbs_EDGE);
233 for (; aExpF.More(); aExpF.Next()) {
234 const TopoDS_Shape& aEF=aExpF.Current();
243 aNbEP=aMEAdd.Extent();
245 break; // from for(;;) {
250 for (k=1; k<=aNbEP; ++k) {
251 const TopoDS_Shape& aEF=aMEAdd(k);
257 //-------------------------------------
258 BOPTools_ConnexityBlock aCB(myAllocator);
260 BOPCol_ListOfShape& aLECB=aCB.ChangeShapes();
261 BOPCol_IndexedDataMapOfShapeListOfShape aMEFR(100, myAllocator);
263 bRegular=Standard_True;
264 aNbCB = aMFC.Extent();
265 for (j=1; j<=aNbCB; ++j) {
268 if (aMER.Contains(aFR)) {
269 aFR.Orientation(TopAbs_FORWARD);
271 aFR.Orientation(TopAbs_REVERSED);
273 bRegular=Standard_False;
280 BOPTools::MapShapesAndAncestors(aFR,
288 Standard_Integer aNbER, aNbFR;
290 aNbER=aMEFR.Extent();
291 for (k=1; k<=aNbER; ++k) {
292 const BOPCol_ListOfShape& aLFR=aMEFR(k);
301 aCB.SetRegular(bRegular);
305 //=======================================================================
306 //function : SplitBlock
308 //=======================================================================
309 void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
311 Standard_Integer aNbLF, aNbOff, aNbFP;
313 TopAbs_Orientation anOr;
316 TopoDS_Iterator aItS;
317 TopExp_Explorer aExp;
318 BOPCol_ListIteratorOfListOfShape aItF;
319 BOPTools_CoupleOfShape aCSOff;
320 BOPCol_MapOfOrientedShape AddedFacesMap;
321 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
323 Handle (BOPInt_Context) aContext=new BOPInt_Context;
325 const BOPCol_ListOfShape& myShapes=aCB.Shapes();
327 BOPCol_ListOfShape& myLoops=aCB.ChangeLoops();
331 aItF.Initialize (myShapes);
332 for (; aItF.More(); aItF.Next()) {
333 const TopoDS_Shape& aFF = aItF.Value();
334 BOPTools::MapShapesAndAncestors (aFF,
340 aItF.Initialize (myShapes);
341 for (i=1; aItF.More(); aItF.Next(), ++i) {
342 const TopoDS_Shape& aFF = aItF.Value();
343 if (!AddedFacesMap.Add(aFF)) {
349 aBB.MakeShell(aShell);
350 aBB.Add(aShell, aFF);
353 BOPTools::MapShapesAndAncestors(aFF,
358 // loop on faces added to Shell;
359 // add their neighbor faces to Shell and so on
360 aItS.Initialize (aShell);
361 for (; aItS.More(); aItS.Next()) {
362 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItS.Value()));
364 // loop on edges of aF; find a good neighbor face of aF by aE
365 aExp.Init(aF, TopAbs_EDGE);
366 for (; aExp.More(); aExp.Next()) {
367 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current()));
370 if (aMEFP.Contains(aE)) {
371 const BOPCol_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
378 anOr=aE.Orientation();
379 if (anOr==TopAbs_INTERNAL) {
383 if (BRep_Tool::Degenerated(aE)) {
387 // candidate faces list
388 const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
394 // try to select one of neighbors
395 // check if a face already added to Shell shares E
396 Standard_Boolean bFound;
397 BOPCol_ListIteratorOfListOfShape aItLF;
398 BOPTools_ListOfCoupleOfShape aLCSOff;
400 aItLF.Initialize(aLF);
401 for (; aItLF.More(); aItLF.Next()) {
402 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
403 if (aF.IsSame(aFL)) {
406 if (AddedFacesMap.Contains(aFL)){
410 bFound=BOPTools_AlgoTools::GetEdgeOff(aE, aFL, aEL);
415 aCSOff.SetShape1(aEL);
416 aCSOff.SetShape2(aFL);
417 aLCSOff.Append(aCSOff);
418 }//for (; aItLF.More(); aItLF.Next()) {
420 aNbOff=aLCSOff.Extent();
427 aSelF=(*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
430 BOPTools_AlgoTools::GetFaceOff(aE,
437 if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
438 aBB.Add(aShell, aSelF);
439 BOPTools::MapShapesAndAncestors(aSelF,
444 } // for (; aExp.More(); aExp.Next()) {
445 } // for (; aItS.More(); aItS.Next()) {
447 if (IsClosedShell(aShell)) {
448 myLoops.Append(aShell);
452 if (IsClosedShell(aShell)) {
453 myLoops.Append(aShell);
456 } // for (; aItF.More(); aItF.Next()) {
458 //=======================================================================
459 //function : RefineShell
461 //=======================================================================
462 void RefineShell(TopoDS_Shell& theShell)
466 aIt.Initialize(theShell);
471 Standard_Integer i, aNbMEF, aNbF;
472 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
474 TopExp_Explorer aExp;
475 BOPCol_MapOfShape aMEStop, aMFB;
476 BOPCol_MapIteratorOfMapOfShape aItM;
477 BOPCol_ListIteratorOfListOfShape aItLF, aItLFP;
478 BOPCol_ListOfShape aLFP, aLFP1;
481 BOPTools::MapShapesAndAncestors (theShell,
485 aNbMEF=aMEF.Extent();
486 for (i=1; i<=aNbMEF; ++i) {
487 const TopoDS_Shape& aE=aMEF.FindKey(i);
488 const BOPCol_ListOfShape& aLF=aMEF.FindFromIndex(i);
495 if (aMEStop.IsEmpty()) {
500 const TopoDS_Shape& aF1=aIt.Value();
504 // Trying to reach the branch point
506 aItLFP.Initialize(aLFP);
507 for (; aItLFP.More(); aItLFP.Next()) {
508 const TopoDS_Shape& aFP=aItLFP.Value();
510 aExp.Init(aFP, TopAbs_EDGE);
511 for (; aExp.More(); aExp.Next()) {
512 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
513 if (aMEStop.Contains(aE)) {
517 if (BRep_Tool::Degenerated(aE)) {
521 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
523 aItLF.Initialize(aLF);
524 for (; aItLF.More(); aItLF.Next()) {
525 const TopoDS_Shape& aFP1=aItLF.Value();
526 if (aFP1.IsSame(aFP)) {
529 if (aMFB.Contains(aFP1)) {
534 }// for (; aItLF.More(); aItLF.Next()) {
535 }// for (; aExp.More(); aExp.Next()) {
536 }// for (; aItLFP.More(); aItLFP.Next()) {
539 if (aLFP1.IsEmpty()) {
544 aItLF.Initialize(aLFP1);
545 for (; aItLF.More(); aItLF.Next()) {
546 const TopoDS_Shape& aFP1=aItLF.Value();
552 // Remove all faces before the branch point
553 aItM.Initialize(aMFB);
554 for (; aItM.More(); aItM.Next()) {
555 const TopoDS_Shape& aFB=aItM.Value();
556 aBB.Remove(theShell, aFB);
559 //=======================================================================
560 //function : IsClosedShell
562 //=======================================================================
563 Standard_Boolean IsClosedShell(const TopoDS_Shell& theShell)
565 Standard_Integer i, aNbE;
566 Standard_Boolean bRet;
568 TopExp_Explorer aExp;
569 BOPCol_MapOfShape aM;
573 aIt.Initialize(theShell);
574 for(i=0; aIt.More(); aIt.Next(), ++i) {
575 const TopoDS_Shape& aF=aIt.Value();
577 aExp.Init(aF, TopAbs_EDGE);
578 for (; aExp.More(); aExp.Next()) {
579 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
580 if (BRep_Tool::Degenerated(aE)) {
584 if (aE.Orientation()==TopAbs_INTERNAL) {
601 //=======================================================================
602 //function : MakeShells
604 //=======================================================================
605 void BOPAlgo_ShellSplitter::MakeShells()
607 Standard_Boolean bIsRegular;
608 Standard_Integer aNbVCBK, k;
609 BOPTools_ListIteratorOfListOfConnexityBlock aItCB;
610 BOPCol_ListIteratorOfListOfShape aIt;
611 BOPAlgo_VectorOfCBK aVCBK;
616 aItCB.Initialize(myLCB);
617 for (; aItCB.More(); aItCB.Next()) {
618 BOPTools_ConnexityBlock& aCB=aItCB.ChangeValue();
619 bIsRegular=aCB.IsRegular();
623 const BOPCol_ListOfShape& aLF=aCB.Shapes();
624 MakeShell(aLF, aShell);
625 aShell.TShape()->Closed(Standard_True);
626 myShells.Append(aShell);
629 BOPAlgo_CBK& aCBK=aVCBK.Append1();
630 aCBK.SetConnexityBlock(aCB);
634 aNbVCBK=aVCBK.Extent();
635 //===================================================
636 BOPAlgo_CBKCnt::Perform(myRunParallel, aVCBK);
637 //===================================================
638 for (k=0; k<aNbVCBK; ++k) {
639 BOPAlgo_CBK& aCBK=aVCBK(k);
640 const BOPTools_ConnexityBlock& aCB=aCBK.ConnexityBlock();
641 const BOPCol_ListOfShape& aLS=aCB.Loops();
643 for (; aIt.More(); aIt.Next()) {
644 const TopoDS_Shape& aShell=aIt.Value();
645 aShell.TShape()->Closed(Standard_True);
646 myShells.Append(aShell);
650 //=======================================================================
651 //function : MakeShell
653 //=======================================================================
654 void MakeShell(const BOPCol_ListOfShape& aLS,
655 TopoDS_Shell& aShell)
658 BOPCol_ListIteratorOfListOfShape aIt;
660 aBB.MakeShell(aShell);
663 for (; aIt.More(); aIt.Next()) {
664 const TopoDS_Shape& aF=aIt.Value();