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 <IntTools_Context.hxx>
37 #include <BOPTools.hxx>
38 #include <BOPTools_AlgoTools.hxx>
39 #include <BOPTools_CoupleOfShape.hxx>
43 void MakeShell(const BOPCol_ListOfShape& ,
47 void RefineShell(TopoDS_Shell& theShell);
49 //=======================================================================
52 //=======================================================================
62 void SetConnexityBlock (const BOPTools_ConnexityBlock& aCB) {
63 myPCB=(BOPTools_ConnexityBlock*)&aCB;
66 BOPTools_ConnexityBlock& ConnexityBlock () {
71 BOPAlgo_ShellSplitter::SplitBlock(*myPCB);
74 BOPTools_ConnexityBlock *myPCB;
76 //=======================================================================
77 typedef BOPCol_NCVector
78 <BOPAlgo_CBK> BOPAlgo_VectorOfCBK;
80 typedef BOPCol_TBBFunctor
82 BOPAlgo_VectorOfCBK> BOPAlgo_CBKFunctor;
86 BOPAlgo_VectorOfCBK> BOPAlgo_CBKCnt;
88 //=======================================================================
91 //=======================================================================
92 BOPAlgo_ShellSplitter::BOPAlgo_ShellSplitter()
95 myStartShapes(myAllocator),
96 myShells(myAllocator),
100 //=======================================================================
103 //=======================================================================
104 BOPAlgo_ShellSplitter::BOPAlgo_ShellSplitter
105 (const Handle(NCollection_BaseAllocator)& theAllocator)
107 BOPAlgo_Algo(theAllocator),
108 myStartShapes(theAllocator),
109 myShells(theAllocator),
113 //=======================================================================
116 //=======================================================================
117 BOPAlgo_ShellSplitter::~BOPAlgo_ShellSplitter()
120 //=======================================================================
121 //function : AddStartElement
123 //=======================================================================
124 void BOPAlgo_ShellSplitter::AddStartElement(const TopoDS_Shape& aE)
126 myStartShapes.Append(aE);
128 //=======================================================================
129 //function : StartElements
131 //=======================================================================
132 const BOPCol_ListOfShape& BOPAlgo_ShellSplitter::StartElements()const
134 return myStartShapes;
136 //=======================================================================
139 //=======================================================================
140 const BOPCol_ListOfShape& BOPAlgo_ShellSplitter::Shells()const
144 //=======================================================================
147 //=======================================================================
148 void BOPAlgo_ShellSplitter::Perform()
152 MakeConnexityBlocks();
159 //=======================================================================
160 //function : MakeConnexityBlocks
162 //=======================================================================
163 void BOPAlgo_ShellSplitter::MakeConnexityBlocks()
165 Standard_Boolean bRegular;
166 Standard_Integer i, j, aNbE, aNbES, aNbEP, k, aNbCB;
168 TopExp_Explorer aExpF;
169 BOPCol_IndexedDataMapOfShapeListOfShape aMEF(100, myAllocator);
170 BOPCol_IndexedMapOfShape aMEP(100, myAllocator);
171 BOPCol_IndexedMapOfShape aMFC(100, myAllocator);
172 BOPCol_MapOfShape aMER(100, myAllocator);
173 BOPCol_MapOfShape aMFP(100, myAllocator);
174 BOPCol_IndexedMapOfShape aMEAdd(100, myAllocator);
175 BOPCol_MapOfShape aMES(100, myAllocator);
176 BOPCol_ListIteratorOfListOfShape aIt;
182 const BOPCol_ListOfShape& aLSE=myStartShapes;
183 aIt.Initialize(aLSE);
184 for (i=1; aIt.More(); aIt.Next(), ++i) {
185 const TopoDS_Shape& aSE=aIt.Value();
186 if (!aMEP.Contains(aSE)) {
188 BOPTools::MapShapesAndAncestors(aSE,
200 for (i=1; i<=aNbE; ++i) {
206 const TopoDS_Shape& aE=aMEF.FindKey(i);
211 // aMES - globally processed edges
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(;;) {
222 for (k=1; k<=aNbEP; ++k) {
223 const TopoDS_Shape& aEP=aMEP(k);
224 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aEP);
226 for (; aIt.More(); aIt.Next()) {
227 const TopoDS_Shape& aF=aIt.Value();
229 aExpF.Init(aF, TopAbs_EDGE);
230 for (; aExpF.More(); aExpF.Next()) {
231 const TopoDS_Shape& aEF=aExpF.Current();
240 aNbEP=aMEAdd.Extent();
242 break; // from for(;;) {
247 for (k=1; k<=aNbEP; ++k) {
248 const TopoDS_Shape& aEF=aMEAdd(k);
254 //-------------------------------------
255 BOPTools_ConnexityBlock aCB(myAllocator);
257 BOPCol_ListOfShape& aLECB=aCB.ChangeShapes();
258 BOPCol_IndexedDataMapOfShapeListOfShape aMEFR(100, myAllocator);
260 bRegular=Standard_True;
261 aNbCB = aMFC.Extent();
262 for (j=1; j<=aNbCB; ++j) {
265 if (aMER.Contains(aFR)) {
266 aFR.Orientation(TopAbs_FORWARD);
268 aFR.Orientation(TopAbs_REVERSED);
270 bRegular=Standard_False;
277 BOPTools::MapShapesAndAncestors(aFR,
285 Standard_Integer aNbER, aNbFR;
287 aNbER=aMEFR.Extent();
288 for (k=1; k<=aNbER; ++k) {
289 const BOPCol_ListOfShape& aLFR=aMEFR(k);
298 aCB.SetRegular(bRegular);
302 //=======================================================================
303 //function : SplitBlock
305 //=======================================================================
306 void BOPAlgo_ShellSplitter::SplitBlock(BOPTools_ConnexityBlock& aCB)
308 Standard_Integer aNbLF, aNbOff, aNbFP;
310 TopAbs_Orientation anOr;
313 TopoDS_Iterator aItS;
314 TopExp_Explorer aExp;
315 BOPCol_ListIteratorOfListOfShape aItF;
316 BOPTools_CoupleOfShape aCSOff;
317 BOPCol_MapOfOrientedShape AddedFacesMap;
318 BOPCol_IndexedDataMapOfShapeListOfShape aEFMap, aMEFP;
320 Handle (IntTools_Context) aContext=new IntTools_Context;
322 const BOPCol_ListOfShape& myShapes=aCB.Shapes();
324 BOPCol_ListOfShape& myLoops=aCB.ChangeLoops();
328 aItF.Initialize (myShapes);
329 for (; aItF.More(); aItF.Next()) {
330 const TopoDS_Shape& aFF = aItF.Value();
331 BOPTools::MapShapesAndAncestors (aFF,
337 aItF.Initialize (myShapes);
338 for (i=1; aItF.More(); aItF.Next(), ++i) {
339 const TopoDS_Shape& aFF = aItF.Value();
340 if (!AddedFacesMap.Add(aFF)) {
346 aBB.MakeShell(aShell);
347 aBB.Add(aShell, aFF);
350 BOPTools::MapShapesAndAncestors(aFF,
355 // loop on faces added to Shell;
356 // add their neighbor faces to Shell and so on
357 aItS.Initialize (aShell);
358 for (; aItS.More(); aItS.Next()) {
359 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aItS.Value()));
361 // loop on edges of aF; find a good neighbor face of aF by aE
362 aExp.Init(aF, TopAbs_EDGE);
363 for (; aExp.More(); aExp.Next()) {
364 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&aExp.Current()));
367 if (aMEFP.Contains(aE)) {
368 const BOPCol_ListOfShape& aLFP=aMEFP.FindFromKey(aE);
375 anOr=aE.Orientation();
376 if (anOr==TopAbs_INTERNAL) {
380 if (BRep_Tool::Degenerated(aE)) {
384 // candidate faces list
385 const BOPCol_ListOfShape& aLF=aEFMap.FindFromKey(aE);
391 // try to select one of neighbors
392 // check if a face already added to Shell shares E
393 Standard_Boolean bFound;
394 BOPCol_ListIteratorOfListOfShape aItLF;
395 BOPTools_ListOfCoupleOfShape aLCSOff;
397 aItLF.Initialize(aLF);
398 for (; aItLF.More(); aItLF.Next()) {
399 const TopoDS_Face& aFL=(*(TopoDS_Face*)(&aItLF.Value()));
400 if (aF.IsSame(aFL)) {
403 if (AddedFacesMap.Contains(aFL)){
407 bFound=BOPTools_AlgoTools::GetEdgeOff(aE, aFL, aEL);
412 aCSOff.SetShape1(aEL);
413 aCSOff.SetShape2(aFL);
414 aLCSOff.Append(aCSOff);
415 }//for (; aItLF.More(); aItLF.Next()) {
417 aNbOff=aLCSOff.Extent();
424 aSelF=(*(TopoDS_Face*)(&aLCSOff.First().Shape2()));
427 BOPTools_AlgoTools::GetFaceOff(aE,
434 if (!aSelF.IsNull() && AddedFacesMap.Add(aSelF)) {
435 aBB.Add(aShell, aSelF);
436 BOPTools::MapShapesAndAncestors(aSelF,
441 } // for (; aExp.More(); aExp.Next()) {
442 } // for (; aItS.More(); aItS.Next()) {
444 if (BRep_Tool::IsClosed(aShell)) {
445 aShell.Closed (Standard_True);
446 myLoops.Append(aShell);
450 if (BRep_Tool::IsClosed(aShell)) {
451 aShell.Closed (Standard_True);
452 myLoops.Append(aShell);
455 } // for (; aItF.More(); aItF.Next()) {
457 //=======================================================================
458 //function : RefineShell
460 //=======================================================================
461 void RefineShell(TopoDS_Shell& theShell)
465 aIt.Initialize(theShell);
470 Standard_Integer i, aNbMEF, aNbF;
471 BOPCol_IndexedDataMapOfShapeListOfShape aMEF;
473 TopExp_Explorer aExp;
474 BOPCol_MapOfShape aMEStop, aMFB;
475 BOPCol_MapIteratorOfMapOfShape aItM;
476 BOPCol_ListIteratorOfListOfShape aItLF, aItLFP;
477 BOPCol_ListOfShape aLFP, aLFP1;
480 BOPTools::MapShapesAndAncestors (theShell,
484 aNbMEF=aMEF.Extent();
485 for (i=1; i<=aNbMEF; ++i) {
486 const TopoDS_Shape& aE=aMEF.FindKey(i);
487 const BOPCol_ListOfShape& aLF=aMEF.FindFromIndex(i);
494 if (aMEStop.IsEmpty()) {
499 const TopoDS_Shape& aF1=aIt.Value();
503 // Trying to reach the branch point
505 aItLFP.Initialize(aLFP);
506 for (; aItLFP.More(); aItLFP.Next()) {
507 const TopoDS_Shape& aFP=aItLFP.Value();
509 aExp.Init(aFP, TopAbs_EDGE);
510 for (; aExp.More(); aExp.Next()) {
511 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
512 if (aMEStop.Contains(aE)) {
516 if (BRep_Tool::Degenerated(aE)) {
520 const BOPCol_ListOfShape& aLF=aMEF.FindFromKey(aE);
522 aItLF.Initialize(aLF);
523 for (; aItLF.More(); aItLF.Next()) {
524 const TopoDS_Shape& aFP1=aItLF.Value();
525 if (aFP1.IsSame(aFP)) {
528 if (aMFB.Contains(aFP1)) {
533 }// for (; aItLF.More(); aItLF.Next()) {
534 }// for (; aExp.More(); aExp.Next()) {
535 }// for (; aItLFP.More(); aItLFP.Next()) {
538 if (aLFP1.IsEmpty()) {
543 aItLF.Initialize(aLFP1);
544 for (; aItLF.More(); aItLF.Next()) {
545 const TopoDS_Shape& aFP1=aItLF.Value();
551 // Remove all faces before the branch point
552 aItM.Initialize(aMFB);
553 for (; aItM.More(); aItM.Next()) {
554 const TopoDS_Shape& aFB=aItM.Value();
555 aBB.Remove(theShell, aFB);
559 //=======================================================================
560 //function : MakeShells
562 //=======================================================================
563 void BOPAlgo_ShellSplitter::MakeShells()
565 Standard_Boolean bIsRegular;
566 Standard_Integer aNbVCBK, k;
567 BOPTools_ListIteratorOfListOfConnexityBlock aItCB;
568 BOPCol_ListIteratorOfListOfShape aIt;
569 BOPAlgo_VectorOfCBK aVCBK;
574 aItCB.Initialize(myLCB);
575 for (; aItCB.More(); aItCB.Next()) {
576 BOPTools_ConnexityBlock& aCB=aItCB.ChangeValue();
577 bIsRegular=aCB.IsRegular();
581 const BOPCol_ListOfShape& aLF=aCB.Shapes();
582 MakeShell(aLF, aShell);
583 aShell.Closed(Standard_True);
584 myShells.Append(aShell);
587 BOPAlgo_CBK& aCBK=aVCBK.Append1();
588 aCBK.SetConnexityBlock(aCB);
592 aNbVCBK=aVCBK.Extent();
593 //===================================================
594 BOPAlgo_CBKCnt::Perform(myRunParallel, aVCBK);
595 //===================================================
596 for (k=0; k<aNbVCBK; ++k) {
597 BOPAlgo_CBK& aCBK=aVCBK(k);
598 const BOPTools_ConnexityBlock& aCB=aCBK.ConnexityBlock();
599 const BOPCol_ListOfShape& aLS=aCB.Loops();
601 for (; aIt.More(); aIt.Next()) {
602 TopoDS_Shape& aShell=aIt.ChangeValue();
603 aShell.Closed(Standard_True);
604 myShells.Append(aShell);
608 //=======================================================================
609 //function : MakeShell
611 //=======================================================================
612 void MakeShell(const BOPCol_ListOfShape& aLS,
613 TopoDS_Shell& aShell)
616 BOPCol_ListIteratorOfListOfShape aIt;
618 aBB.MakeShell(aShell);
621 for (; aIt.More(); aIt.Next()) {
622 const TopoDS_Shape& aF=aIt.Value();