1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 // EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
7 // This file is part of Open CASCADE Technology software library.
9 // This library is free software; you can redistribute it and / or modify it
10 // under the terms of the GNU Lesser General Public version 2.1 as published
11 // by the Free Software Foundation, with special exception defined in the file
12 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 // distribution for complete text of the license and disclaimer of any warranty.
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
18 #include <BOPAlgo_Builder.ixx>
20 #include <NCollection_IncAllocator.hxx>
22 #include <TopoDS_Shape.hxx>
23 #include <TopoDS_Face.hxx>
24 #include <TopoDS_Edge.hxx>
25 #include <TopoDS_Vertex.hxx>
26 #include <TopoDS_Compound.hxx>
28 #include <BRep_Tool.hxx>
29 #include <BRep_Builder.hxx>
31 #include <TopExp_Explorer.hxx>
33 #include <BOPCol_ListOfShape.hxx>
34 #include <BOPCol_ListOfInteger.hxx>
35 #include <BOPCol_MapOfInteger.hxx>
36 #include <BOPCol_DataMapOfIntegerListOfShape.hxx>
37 #include <BOPCol_DataMapOfShapeShape.hxx>
39 #include <BOPInt_Context.hxx>
41 #include <BOPDS_PaveBlock.hxx>
42 #include <BOPDS_ShapeInfo.hxx>
43 #include <BOPDS_DS.hxx>
44 #include <BOPDS_FaceInfo.hxx>
45 #include <BOPDS_MapOfPaveBlock.hxx>
46 #include <BOPDS_VectorOfInterfFF.hxx>
47 #include <BOPDS_Interf.hxx>
48 #include <BOPDS_VectorOfCurve.hxx>
49 #include <BOPDS_VectorOfPoint.hxx>
51 #include <BOPTools.hxx>
52 #include <BOPTools_AlgoTools.hxx>
53 #include <BOPTools_AlgoTools2D.hxx>
54 #include <BOPTools_AlgoTools3D.hxx>
55 #include <BOPAlgo_BuilderFace.hxx>
56 #include <BOPTools_CoupleOfShape.hxx>
57 #include <BOPTools_ListOfCoupleOfShape.hxx>
58 #include <BOPTools_MapOfSet.hxx>
59 #include <BOPTools_DataMapOfShapeSet.hxx>
60 #include <BOPAlgo_Builder_2Cnt.hxx>
63 Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
64 const BOPDS_FaceInfo& aFI2);
66 void FillMap(const TopoDS_Shape& aS1,
67 const TopoDS_Shape& aS2,
68 BOPCol_IndexedDataMapOfShapeListOfShape& aDMSLS,
69 Handle(NCollection_IncAllocator)& aAllocator);
71 void MakeBlocksCnx(const BOPCol_IndexedDataMapOfShapeListOfShape& aMILI,
72 BOPCol_DataMapOfIntegerListOfShape& aMBlocks,
73 Handle(NCollection_IncAllocator)& aAllocator);
76 //=======================================================================
77 //function : FillImagesFaces
79 //=======================================================================
80 void BOPAlgo_Builder::FillImagesFaces()
85 FillSameDomainFaces();
88 //=======================================================================
89 //function : BuildSplitFaces
91 //=======================================================================
92 void BOPAlgo_Builder::BuildSplitFaces()
94 Standard_Boolean bHasFaceInfo, bIsClosed, bIsDegenerated, bToReverse;
95 Standard_Integer i, j, k, aNbS, aNbPBIn, aNbPBOn, aNbPBSc, aNbAV, nSp;
97 TopoDS_Face aFF, aFSD;
99 TopAbs_Orientation anOriF, anOriE;
100 TopExp_Explorer aExp;
101 BOPCol_ListIteratorOfListOfShape aIt;
102 BOPCol_ListOfInteger aLIAV;
103 BOPCol_MapOfShape aMFence;
104 Handle(NCollection_BaseAllocator) aAllocator;
105 BOPCol_ListOfShape aLFIm(myAllocator);
106 BOPCol_MapIteratorOfMapOfShape aItMS;
107 BOPAlgo_VectorOfBuilderFace aVBF;
111 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~scope f
112 aAllocator=new NCollection_IncAllocator();
114 BOPCol_ListOfShape aLE(aAllocator);
115 BOPCol_MapOfShape aMDE(100, aAllocator);
117 aNbS=myDS->NbSourceShapes();
119 for (i=0; i<aNbS; ++i) {
120 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
121 if (aSI.ShapeType()!=TopAbs_FACE) {
125 const TopoDS_Face& aF=(*(TopoDS_Face*)(&aSI.Shape()));
127 bHasFaceInfo=myDS->HasFaceInfo(i);
132 const BOPDS_FaceInfo& aFI=myDS->FaceInfo(i);
134 const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
135 const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
136 const BOPDS_IndexedMapOfPaveBlock& aMPBSc=aFI.PaveBlocksSc();
138 myDS->AloneVertices(i, aLIAV);
140 aNbPBIn=aMPBIn.Extent();
141 aNbPBOn=aMPBOn.Extent();
142 aNbPBSc=aMPBSc.Extent();
143 aNbAV=aLIAV.Extent();
144 if (!aNbPBIn && !aNbPBOn && !aNbPBSc && !aNbAV) { // not compete
150 anOriF=aF.Orientation();
152 aFF.Orientation(TopAbs_FORWARD);
156 // 1. Fill the egdes set for the face aFF -> LE
160 // 1.1 Bounding edges
161 aExp.Init(aFF, TopAbs_EDGE);
162 for (; aExp.More(); aExp.Next()) {
163 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
164 anOriE=aE.Orientation();
165 bIsDegenerated=BRep_Tool::Degenerated(aE);
166 bIsClosed=BRep_Tool::IsClosed(aE, aF);
168 if (!myImages.IsBound(aE)) {
169 if (anOriE==TopAbs_INTERNAL) {
171 aEE.Orientation(TopAbs_FORWARD);
173 aEE.Orientation(TopAbs_REVERSED);
181 const BOPCol_ListOfShape& aLIE=myImages.Find(aE);
182 aIt.Initialize(aLIE);
183 for (; aIt.More(); aIt.Next()) {
184 aSp=(*(TopoDS_Edge*)(&aIt.Value()));
185 if (bIsDegenerated) {
186 aSp.Orientation(anOriE);
191 if (anOriE==TopAbs_INTERNAL) {
192 aSp.Orientation(TopAbs_FORWARD);
194 aSp.Orientation(TopAbs_REVERSED);
200 if (aMFence.Add(aSp)) {
201 if (!BRep_Tool::IsClosed(aSp, aF)){
202 BOPTools_AlgoTools3D::DoSplitSEAMOnFace(aSp, aF);
205 aSp.Orientation(TopAbs_FORWARD);
207 aSp.Orientation(TopAbs_REVERSED);
209 }// if (aMFence.Add(aSp))
213 aSp.Orientation(anOriE);
214 bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSp, aE, myContext);
219 }// for (; aIt.More(); aIt.Next()) {
221 }// for (; aExp.More(); aExp.Next()) {
225 for (j=1; j<=aNbPBIn; ++j) {
226 const Handle(BOPDS_PaveBlock)& aPB=aMPBIn(j);
228 aSp=(*(TopoDS_Edge*)(&myDS->Shape(nSp)));
230 aSp.Orientation(TopAbs_FORWARD);
232 aSp.Orientation(TopAbs_REVERSED);
238 for (j=1; j<=aNbPBSc; ++j) {
239 const Handle(BOPDS_PaveBlock)& aPB=aMPBSc(j);
241 aSp=(*(TopoDS_Edge*)(&myDS->Shape(nSp)));
243 aSp.Orientation(TopAbs_FORWARD);
245 aSp.Orientation(TopAbs_REVERSED);
249 BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane (aLE, aFF);
251 // 3 Build split faces
252 BOPAlgo_BuilderFace& aBF=aVBF.Append1();
256 }// for (i=0; i<aNbS; ++i) {
260 //===================================================
261 BOPAlgo_BuilderFaceCnt::Perform(myRunParallel, aVBF);
262 //===================================================
264 for (k=0; k<(Standard_Integer)aNbBF; ++k) {
267 BOPAlgo_BuilderFace& aBF=aVBF(k);
268 TopoDS_Face aF=aBF.Face();
269 anOriF=aBF.Orientation();
270 aF.Orientation(anOriF);
272 const BOPCol_ListOfShape& aLFR=aBF.Areas();
273 aIt.Initialize(aLFR);
274 for (; aIt.More(); aIt.Next()) {
275 TopoDS_Shape& aFR=aIt.ChangeValue();
276 if (anOriF==TopAbs_REVERSED) {
277 aFR.Orientation(TopAbs_REVERSED);
279 //aFR.Orientation(anOriF);
283 mySplits.Bind(aF, aLFIm);
284 }// for (k=0; k<aNbBF; ++k) {
286 aAllocator.Nullify();
287 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~scope t
289 //=======================================================================
290 //function : FillSameDomainFaces
292 //=======================================================================
293 void BOPAlgo_Builder::FillSameDomainFaces()
295 Standard_Boolean bFlag;
296 Standard_Integer i, j, k, aNbFFs, aNbCurves, aNbPoints, nF1, nF2, aNbS;
297 Handle(NCollection_IncAllocator) aAllocator;
298 BOPCol_ListIteratorOfListOfShape aItF;
299 BOPCol_MapOfShape aMFence;
300 BOPAlgo_IndexedDataMapOfSetInteger aIDMSS;
301 BOPAlgo_VectorOfVectorOfShape aVVS;
305 const BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
307 aNbFFs=aFFs.Extent();
312 for (i=0; i<aNbFFs; ++i) {
313 const BOPDS_InterfFF& aFF=aFFs(i);
314 aFF.Indices(nF1, nF2);
316 const BOPDS_VectorOfCurve& aCurves=aFF.Curves();
317 aNbCurves=aCurves.Extent();
320 bFlag=Standard_False;
321 for (j=0; j<aNbCurves; ++j) {
322 const BOPDS_Curve& aNC=aCurves.Value(j);
334 const BOPDS_VectorOfPoint& aPoints=aFF.Points();
335 aNbPoints=aPoints.Extent();
340 if (!myDS->HasFaceInfo(nF1) || !myDS->HasFaceInfo(nF2) ) {
344 const BOPDS_FaceInfo& aFI1=myDS->FaceInfo(nF1);
345 const BOPDS_FaceInfo& aFI2=myDS->FaceInfo(nF2);
347 const TopoDS_Shape& aF1=myDS->Shape(nF1);
348 const TopoDS_Shape& aF2=myDS->Shape(nF2);
350 bFlag=HasPaveBlocksOnIn(aFI1, aFI2);
351 bFlag=bFlag && (mySplits.IsBound(aF1) && mySplits.IsBound(aF2));
354 for (k=0; k<2; ++k) {
355 const TopoDS_Shape& aF=(!k) ? aF1 : aF2;
356 const BOPCol_ListOfShape& aLF=mySplits.Find(aF);
358 aItF.Initialize(aLF);
359 for (; aItF.More(); aItF.Next()) {
360 const TopoDS_Shape& aFx=aItF.Value();
362 if (aMFence.Add(aFx)) {
367 if (!aIDMSS.Contains(aSTx)) {
368 BOPAlgo_VectorOfShape& aVS=aVVS.Append1();
372 aIDMSS.Add (aSTx, j);
375 j=aIDMSS.ChangeFromKey(aSTx);
376 BOPAlgo_VectorOfShape& aVS=aVVS(j);
384 BOPTools_Set aST1, aST2;
389 if (aST1.IsEqual(aST2)) {
390 if (!aIDMSS.Contains(aST1)) {
391 BOPAlgo_VectorOfShape& aVS=aVVS.Append1();
392 if (aMFence.Add(aF1)) {
395 if (aMFence.Add(aF2)) {
400 aIDMSS.Add (aST1, k);
403 k=aIDMSS.ChangeFromKey(aST1);
404 BOPAlgo_VectorOfShape& aVS=aVVS(k);
405 if (aMFence.Add(aF1)) {
408 if (aMFence.Add(aF2)) {
412 }//if (aST1.IsEqual(aST2)) {
413 }// else {// if (!bFlag)
415 }// for (i=0; i<aNbFFs; ++i) {
419 Standard_Boolean bFlagSD;
420 Standard_Integer aNbVPSB, aNbVVS, aNbF, aNbF1;
421 BOPAlgo_VectorOfPairOfShapeBoolean aVPSB;
423 aNbVVS=aVVS.Extent();
424 for (i=0; i<aNbVVS; ++i) {
425 const BOPAlgo_VectorOfShape& aVS=aVVS(i);
432 for (j=0; j<aNbF1; ++j) {
433 const TopoDS_Shape& aFj=aVS(j);
434 for (k=j+1; k<aNbF; ++k) {
435 const TopoDS_Shape& aFk=aVS(k);
436 BOPAlgo_PairOfShapeBoolean& aPSB=aVPSB.Append1();
442 //====================================================
443 BOPAlgo_BuilderSDFaceCnt::Perform(myRunParallel, aVPSB);
444 //====================================================
445 aAllocator=new NCollection_IncAllocator();
446 BOPCol_IndexedDataMapOfShapeListOfShape aDMSLS(100, aAllocator);
447 BOPCol_DataMapOfIntegerListOfShape aMBlocks(100, aAllocator);
449 aNbVPSB=aVPSB.Extent();
450 for (i=0; i<aNbVPSB; ++i) {
451 BOPAlgo_PairOfShapeBoolean& aPSB=aVPSB(i);
454 const TopoDS_Shape& aFj=aPSB.Shape1();
455 const TopoDS_Shape& aFk=aPSB.Shape2();
456 FillMap(aFj, aFk, aDMSLS, aAllocator);
462 MakeBlocksCnx(aDMSLS, aMBlocks, aAllocator);
464 // 3. Fill same domain faces map -> aMSDF
465 aNbS = aMBlocks.Extent();
466 for (i=0; i<aNbS; ++i) {
467 const BOPCol_ListOfShape& aLSD=aMBlocks.Find(i);
468 if (aLSD.IsEmpty()) {
472 const TopoDS_Shape& aFSD1=aLSD.First();
473 aItF.Initialize(aLSD);
474 for (; aItF.More(); aItF.Next()) {
475 const TopoDS_Shape& aFSD=aItF.Value();
476 myShapesSD.Bind(aFSD, aFSD1);
478 // If the face has no splits but are SD face,
479 // it is considered as splitted face
480 if (!mySplits.IsBound(aFSD)) {
481 BOPCol_ListOfShape aLS;
483 mySplits.Bind(aFSD, aLS);
489 aAllocator.Nullify();
491 //=======================================================================
492 // function: FillImagesFaces1
494 //=======================================================================
495 void BOPAlgo_Builder::FillImagesFaces1()
497 Standard_Integer i, aNbS, iSense;
499 BOPCol_ListOfInteger aLIAV;
500 BOPCol_ListOfShape aLFIm;
501 BOPCol_ListIteratorOfListOfShape aItLS;
503 aNbS=myDS->NbSourceShapes();
504 for (i=0; i<aNbS; ++i) {
505 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
506 if (aSI.ShapeType()!=TopAbs_FACE) {
510 const TopoDS_Face& aF=(*(TopoDS_Face*)(&aSI.Shape()));
512 if (!mySplits.IsBound(aF)) {
517 myDS->AloneVertices(i, aLIAV);
520 const BOPCol_ListOfShape& aLSp=mySplits.Find(aF);
521 aItLS.Initialize(aLSp);
522 for (; aItLS.More(); aItLS.Next()) {
523 const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
524 if (!myShapesSD.IsBound(aFSp)) {
528 aFSD=(*(TopoDS_Face*)(&myShapesSD.Find(aFSp)));
529 iSense=BOPTools_AlgoTools::Sense(aFSp, aFSD);
537 FillInternalVertices(aLFIm, aLIAV);
539 myImages.Bind(aF, aLFIm);
542 aItLS.Initialize(aLFIm);
543 for (; aItLS.More(); aItLS.Next()) {
544 const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
545 myOrigins.Bind(aFSp, aF);
547 }// for (i=0; i<aNbS; ++i) {
549 //=======================================================================
550 // function: FillInternalVertices
552 //=======================================================================
553 void BOPAlgo_Builder::FillInternalVertices(BOPCol_ListOfShape& aLFIm,
554 BOPCol_ListOfInteger& aLIAV)
556 Standard_Integer nV, iFlag;
557 Standard_Real aU1, aU2;
560 BOPCol_ListIteratorOfListOfInteger aItV;
561 BOPCol_ListIteratorOfListOfShape aItF;
563 aItV.Initialize(aLIAV);
564 for (; aItV.More(); aItV.Next()) {
566 aV=(*(TopoDS_Vertex*)(&myDS->Shape(nV)));
567 aV.Orientation(TopAbs_INTERNAL);
569 aItF.Initialize(aLFIm);
570 for (; aItF.More(); aItF.Next()) {
571 TopoDS_Face& aF=(*(TopoDS_Face*)(&aItF.Value()));
572 iFlag=myContext->ComputeVF(aV, aF, aU1, aU2);
580 //=======================================================================
581 //function : MakeBlocksCnx
583 //=======================================================================
584 void MakeBlocksCnx(const BOPCol_IndexedDataMapOfShapeListOfShape& aMILI,
585 BOPCol_DataMapOfIntegerListOfShape& aMBlocks,
586 Handle(NCollection_IncAllocator)& aAllocator)
588 Standard_Integer aNbV, aNbVS, aNbVP, aNbEC, k, i, j;
589 BOPCol_ListIteratorOfListOfShape aItLI;
591 BOPCol_MapOfShape aMVS(100, aAllocator);
592 BOPCol_IndexedMapOfShape aMEC(100, aAllocator);
593 BOPCol_IndexedMapOfShape aMVP(100, aAllocator);
594 BOPCol_IndexedMapOfShape aMVAdd(100, aAllocator);
598 for (k=0,i=1; i<=aNbV; ++i) {
604 const TopoDS_Shape& nV=aMILI.FindKey(i);
605 if (aMVS.Contains(nV)){
617 for (j=1; j<=aNbVP; ++j) {
618 const TopoDS_Shape& nVP=aMVP(j);
619 const BOPCol_ListOfShape& aLV=aMILI.FindFromKey(nVP);
620 aItLI.Initialize(aLV);
621 for (; aItLI.More(); aItLI.Next()) {
622 const TopoDS_Shape& nVx=aItLI.Value();
623 if (aMEC.Contains(nVx)) {
633 aNbVP=aMVAdd.Extent();
635 break; // from while(1)
639 for (j=1; j<=aNbVP; ++j) {
645 BOPCol_ListOfShape aLIx(aAllocator);
647 aNbEC = aMEC.Extent();
648 for (j=1; j<=aNbEC; ++j) {
649 const TopoDS_Shape& nVx=aMEC(j);
653 aMBlocks.Bind(k, aLIx);
655 }//for (k=0,i=1; i<=aNbV; ++i)
662 //=======================================================================
665 //=======================================================================
666 void FillMap(const TopoDS_Shape& aS1,
667 const TopoDS_Shape& aS2,
668 BOPCol_IndexedDataMapOfShapeListOfShape& aDMSLS,
669 Handle(NCollection_IncAllocator)& aAllocator)
671 if (aDMSLS.Contains(aS1)) {
672 BOPCol_ListOfShape& aLS=aDMSLS.ChangeFromKey(aS1);
676 BOPCol_ListOfShape aLS(aAllocator);
678 aDMSLS.Add(aS1, aLS);
681 if (aDMSLS.Contains(aS2)) {
682 BOPCol_ListOfShape& aLS=aDMSLS.ChangeFromKey(aS2);
686 BOPCol_ListOfShape aLS(aAllocator);
688 aDMSLS.Add(aS2, aLS);
691 //=======================================================================
692 //function :HasPaveBlocksOnIn
694 //=======================================================================
695 Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
696 const BOPDS_FaceInfo& aFI2)
698 Standard_Boolean bRet;
699 BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
702 const BOPDS_IndexedMapOfPaveBlock& aMPBOn1=aFI1.PaveBlocksOn();
703 const BOPDS_IndexedMapOfPaveBlock& aMPBIn1=aFI1.PaveBlocksIn();
705 const BOPDS_IndexedMapOfPaveBlock& aMPBOn2=aFI2.PaveBlocksOn();
706 aItMPB.Initialize(aMPBOn2);
707 for (; aItMPB.More(); aItMPB.Next()) {
708 const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
709 bRet=aMPBOn1.Contains(aPB) || aMPBIn1.Contains(aPB);
715 const BOPDS_IndexedMapOfPaveBlock& aMPBIn2=aFI2.PaveBlocksIn();
716 aItMPB.Initialize(aMPBIn2);
717 for (; aItMPB.More(); aItMPB.Next()) {
718 const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
719 bRet=aMPBOn1.Contains(aPB) || aMPBIn1.Contains(aPB);
731 BOPCol_ListIteratorOfListOfShape aItx;
733 aBBx.MakeCompound(aCx);
735 aItx.Initialize(aLE);
736 for (; aItx.More(); aItx.Next()) {
737 const TopoDS_Shape& aEx=aItx.Value();