1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2012 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 // The content of this file is subject to the Open CASCADE Technology Public
8 // License Version 6.5 (the "License"). You may not use the content of this file
9 // except in compliance with the License. Please obtain a copy of the License
10 // at http://www.opencascade.org and read it completely before using this file.
12 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
13 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
15 // The Original Code and all software distributed under the License is
16 // distributed on an "AS IS" basis, without warranty of any kind, and the
17 // Initial Developer hereby disclaims all such warranties, including without
18 // limitation, any warranties of merchantability, fitness for a particular
19 // purpose or non-infringement. Please see the License for the specific terms
20 // and conditions governing the rights and limitations under the License.
22 #include <BOPAlgo_Builder.ixx>
24 #include <NCollection_IncAllocator.hxx>
26 #include <TopoDS_Shape.hxx>
27 #include <TopoDS_Face.hxx>
28 #include <TopoDS_Edge.hxx>
29 #include <TopoDS_Vertex.hxx>
30 #include <TopoDS_Compound.hxx>
32 #include <BRep_Tool.hxx>
33 #include <BRep_Builder.hxx>
35 #include <TopExp_Explorer.hxx>
37 #include <BOPCol_ListOfShape.hxx>
38 #include <BOPCol_ListOfInteger.hxx>
39 #include <BOPCol_MapOfInteger.hxx>
40 #include <BOPCol_DataMapOfIntegerListOfShape.hxx>
41 #include <BOPCol_DataMapOfShapeShape.hxx>
43 #include <BOPInt_Context.hxx>
45 #include <BOPDS_PaveBlock.hxx>
46 #include <BOPDS_ShapeInfo.hxx>
47 #include <BOPDS_DS.hxx>
48 #include <BOPDS_FaceInfo.hxx>
49 #include <BOPDS_MapOfPaveBlock.hxx>
50 #include <BOPDS_VectorOfInterfFF.hxx>
51 #include <BOPDS_Interf.hxx>
52 #include <BOPDS_VectorOfCurve.hxx>
53 #include <BOPDS_VectorOfPoint.hxx>
55 #include <BOPTools.hxx>
56 #include <BOPTools_AlgoTools.hxx>
57 #include <BOPTools_AlgoTools2D.hxx>
58 #include <BOPTools_AlgoTools3D.hxx>
59 #include <BOPAlgo_BuilderFace.hxx>
60 #include <BOPTools_CoupleOfShape.hxx>
61 #include <BOPTools_ListOfCoupleOfShape.hxx>
62 #include <BOPTools_MapOfSet.hxx>
63 #include <BOPTools_DataMapOfShapeSet.hxx>
64 #include <BOPAlgo_Builder_2Cnt.hxx>
67 Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
68 const BOPDS_FaceInfo& aFI2);
70 void FillMap(const TopoDS_Shape& aS1,
71 const TopoDS_Shape& aS2,
72 BOPCol_IndexedDataMapOfShapeListOfShape& aDMSLS,
73 Handle(NCollection_IncAllocator)& aAllocator);
75 void MakeBlocksCnx(const BOPCol_IndexedDataMapOfShapeListOfShape& aMILI,
76 BOPCol_DataMapOfIntegerListOfShape& aMBlocks,
77 Handle(NCollection_IncAllocator)& aAllocator);
80 //=======================================================================
81 //function : FillImagesFaces
83 //=======================================================================
84 void BOPAlgo_Builder::FillImagesFaces()
89 FillSameDomainFaces();
92 //=======================================================================
93 //function : BuildSplitFaces
95 //=======================================================================
96 void BOPAlgo_Builder::BuildSplitFaces()
98 Standard_Boolean bHasFaceInfo, bIsClosed, bIsDegenerated, bToReverse;
99 Standard_Integer i, j, k, aNbS, aNbPBIn, aNbPBOn, aNbPBSc, aNbAV, nSp;
100 Standard_Boolean bRunParallel;
102 TopoDS_Face aFF, aFSD;
103 TopoDS_Edge aSp, aEE;
104 TopAbs_Orientation anOriF, anOriE;
105 TopExp_Explorer aExp;
106 BOPCol_ListIteratorOfListOfShape aIt;
107 BOPCol_ListOfInteger aLIAV;
108 BOPCol_MapOfShape aMFence;
109 Handle(NCollection_BaseAllocator) aAllocator;
110 BOPCol_ListOfShape aLFIm(myAllocator);
111 BOPCol_MapIteratorOfMapOfShape aItMS;
112 BOPAlgo_VectorOfBuilderFace aVBF;
116 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~scope f
117 aAllocator=new NCollection_IncAllocator();
119 BOPCol_ListOfShape aLE(aAllocator);
120 BOPCol_MapOfShape aMDE(100, aAllocator);
122 aNbS=myDS->NbSourceShapes();
124 for (i=0; i<aNbS; ++i) {
125 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
126 if (aSI.ShapeType()!=TopAbs_FACE) {
130 const TopoDS_Face& aF=(*(TopoDS_Face*)(&aSI.Shape()));
132 bHasFaceInfo=myDS->HasFaceInfo(i);
137 const BOPDS_FaceInfo& aFI=myDS->FaceInfo(i);
139 const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
140 const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
141 const BOPDS_IndexedMapOfPaveBlock& aMPBSc=aFI.PaveBlocksSc();
143 myDS->AloneVertices(i, aLIAV);
145 aNbPBIn=aMPBIn.Extent();
146 aNbPBOn=aMPBOn.Extent();
147 aNbPBSc=aMPBSc.Extent();
148 aNbAV=aLIAV.Extent();
149 if (!aNbPBIn && !aNbPBOn && !aNbPBSc && !aNbAV) { // not compete
155 anOriF=aF.Orientation();
157 aFF.Orientation(TopAbs_FORWARD);
161 // 1. Fill the egdes set for the face aFF -> LE
165 // 1.1 Bounding edges
166 aExp.Init(aFF, TopAbs_EDGE);
167 for (; aExp.More(); aExp.Next()) {
168 const TopoDS_Edge& aE=(*(TopoDS_Edge*)(&aExp.Current()));
169 anOriE=aE.Orientation();
170 bIsDegenerated=BRep_Tool::Degenerated(aE);
171 bIsClosed=BRep_Tool::IsClosed(aE, aF);
173 if (!myImages.IsBound(aE)) {
174 if (anOriE==TopAbs_INTERNAL) {
176 aEE.Orientation(TopAbs_FORWARD);
178 aEE.Orientation(TopAbs_REVERSED);
186 const BOPCol_ListOfShape& aLIE=myImages.Find(aE);
187 aIt.Initialize(aLIE);
188 for (; aIt.More(); aIt.Next()) {
189 aSp=(*(TopoDS_Edge*)(&aIt.Value()));
190 if (bIsDegenerated) {
191 aSp.Orientation(anOriE);
196 if (anOriE==TopAbs_INTERNAL) {
197 aSp.Orientation(TopAbs_FORWARD);
199 aSp.Orientation(TopAbs_REVERSED);
205 if (aMFence.Add(aSp)) {
206 if (!BRep_Tool::IsClosed(aSp, aF)){
207 BOPTools_AlgoTools3D::DoSplitSEAMOnFace(aSp, aF);
210 aSp.Orientation(TopAbs_FORWARD);
212 aSp.Orientation(TopAbs_REVERSED);
214 }// if (aMFence.Add(aSp))
218 aSp.Orientation(anOriE);
219 bToReverse=BOPTools_AlgoTools::IsSplitToReverse(aSp, aE, myContext);
224 }// for (; aIt.More(); aIt.Next()) {
226 }// for (; aExp.More(); aExp.Next()) {
230 for (j=1; j<=aNbPBIn; ++j) {
231 const Handle(BOPDS_PaveBlock)& aPB=aMPBIn(j);
233 aSp=(*(TopoDS_Edge*)(&myDS->Shape(nSp)));
235 aSp.Orientation(TopAbs_FORWARD);
237 aSp.Orientation(TopAbs_REVERSED);
243 for (j=1; j<=aNbPBSc; ++j) {
244 const Handle(BOPDS_PaveBlock)& aPB=aMPBSc(j);
246 aSp=(*(TopoDS_Edge*)(&myDS->Shape(nSp)));
248 aSp.Orientation(TopAbs_FORWARD);
250 aSp.Orientation(TopAbs_REVERSED);
254 BOPTools_AlgoTools2D::BuildPCurveForEdgesOnPlane (aLE, aFF);
256 // 3 Build split faces
257 BOPAlgo_BuilderFace& aBF=aVBF.Append1();
261 }// for (i=0; i<aNbS; ++i) {
265 //===================================================
266 bRunParallel=Standard_True;
267 BOPAlgo_BuilderFaceCnt::Perform(bRunParallel, aVBF);
268 //===================================================
270 for (k=0; k<(Standard_Integer)aNbBF; ++k) {
273 BOPAlgo_BuilderFace& aBF=aVBF(k);
274 TopoDS_Face aF=aBF.Face();
275 anOriF=aBF.Orientation();
276 aF.Orientation(anOriF);
278 const BOPCol_ListOfShape& aLFR=aBF.Areas();
279 aIt.Initialize(aLFR);
280 for (; aIt.More(); aIt.Next()) {
281 TopoDS_Shape& aFR=aIt.ChangeValue();
282 if (anOriF==TopAbs_REVERSED) {
283 aFR.Orientation(TopAbs_REVERSED);
285 //aFR.Orientation(anOriF);
289 mySplits.Bind(aF, aLFIm);
290 }// for (k=0; k<aNbBF; ++k) {
292 aAllocator.Nullify();
293 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~scope t
295 //=======================================================================
296 //function : FillSameDomainFaces
298 //=======================================================================
299 void BOPAlgo_Builder::FillSameDomainFaces()
301 Standard_Boolean bFlag;
302 Standard_Integer i, j, k, aNbFFs, aNbCurves, aNbPoints, nF1, nF2, aNbS;
303 Handle(NCollection_IncAllocator) aAllocator;
304 BOPCol_ListIteratorOfListOfShape aItF;
305 BOPCol_MapOfShape aMFence;
306 BOPAlgo_IndexedDataMapOfSetInteger aIDMSS;
307 BOPAlgo_VectorOfVectorOfShape aVVS;
311 const BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
313 aNbFFs=aFFs.Extent();
318 for (i=0; i<aNbFFs; ++i) {
319 const BOPDS_InterfFF& aFF=aFFs(i);
320 aFF.Indices(nF1, nF2);
322 const BOPDS_VectorOfCurve& aCurves=aFF.Curves();
323 aNbCurves=aCurves.Extent();
326 bFlag=Standard_False;
327 for (j=0; j<aNbCurves; ++j) {
328 const BOPDS_Curve& aNC=aCurves.Value(j);
340 const BOPDS_VectorOfPoint& aPoints=aFF.Points();
341 aNbPoints=aPoints.Extent();
346 if (!myDS->HasFaceInfo(nF1) || !myDS->HasFaceInfo(nF2) ) {
350 const BOPDS_FaceInfo& aFI1=myDS->FaceInfo(nF1);
351 const BOPDS_FaceInfo& aFI2=myDS->FaceInfo(nF2);
353 const TopoDS_Shape& aF1=myDS->Shape(nF1);
354 const TopoDS_Shape& aF2=myDS->Shape(nF2);
356 bFlag=HasPaveBlocksOnIn(aFI1, aFI2);
357 bFlag=bFlag && (mySplits.IsBound(aF1) && mySplits.IsBound(aF2));
360 for (k=0; k<2; ++k) {
361 const TopoDS_Shape& aF=(!k) ? aF1 : aF2;
362 const BOPCol_ListOfShape& aLF=mySplits.Find(aF);
364 aItF.Initialize(aLF);
365 for (; aItF.More(); aItF.Next()) {
366 const TopoDS_Shape& aFx=aItF.Value();
368 if (aMFence.Add(aFx)) {
373 if (!aIDMSS.Contains(aSTx)) {
374 BOPAlgo_VectorOfShape& aVS=aVVS.Append1();
378 aIDMSS.Add (aSTx, j);
381 j=aIDMSS.ChangeFromKey(aSTx);
382 BOPAlgo_VectorOfShape& aVS=aVVS(j);
390 BOPTools_Set aST1, aST2;
395 if (aST1.IsEqual(aST2)) {
396 if (!aIDMSS.Contains(aST1)) {
397 BOPAlgo_VectorOfShape& aVS=aVVS.Append1();
398 if (aMFence.Add(aF1)) {
401 if (aMFence.Add(aF2)) {
406 aIDMSS.Add (aST1, k);
409 k=aIDMSS.ChangeFromKey(aST1);
410 BOPAlgo_VectorOfShape& aVS=aVVS(k);
411 if (aMFence.Add(aF1)) {
414 if (aMFence.Add(aF2)) {
418 }//if (aST1.IsEqual(aST2)) {
419 }// else {// if (!bFlag)
421 }// for (i=0; i<aNbFFs; ++i) {
425 Standard_Boolean bRunParallel, bFlagSD;
426 Standard_Integer aNbVPSB, aNbVVS, aNbF, aNbF1;
427 BOPAlgo_VectorOfPairOfShapeBoolean aVPSB;
429 aNbVVS=aVVS.Extent();
430 for (i=0; i<aNbVVS; ++i) {
431 const BOPAlgo_VectorOfShape& aVS=aVVS(i);
438 for (j=0; j<aNbF1; ++j) {
439 const TopoDS_Shape& aFj=aVS(j);
440 for (k=j+1; k<aNbF; ++k) {
441 const TopoDS_Shape& aFk=aVS(k);
442 BOPAlgo_PairOfShapeBoolean& aPSB=aVPSB.Append1();
448 //====================================================
449 bRunParallel=Standard_True;
450 BOPAlgo_BuilderSDFaceCnt::Perform(bRunParallel, aVPSB);
451 //====================================================
452 aAllocator=new NCollection_IncAllocator();
453 BOPCol_IndexedDataMapOfShapeListOfShape aDMSLS(100, aAllocator);
454 BOPCol_DataMapOfIntegerListOfShape aMBlocks(100, aAllocator);
456 aNbVPSB=aVPSB.Extent();
457 for (i=0; i<aNbVPSB; ++i) {
458 BOPAlgo_PairOfShapeBoolean& aPSB=aVPSB(i);
461 const TopoDS_Shape& aFj=aPSB.Shape1();
462 const TopoDS_Shape& aFk=aPSB.Shape2();
463 FillMap(aFj, aFk, aDMSLS, aAllocator);
469 MakeBlocksCnx(aDMSLS, aMBlocks, aAllocator);
471 // 3. Fill same domain faces map -> aMSDF
472 aNbS = aMBlocks.Extent();
473 for (i=0; i<aNbS; ++i) {
474 const BOPCol_ListOfShape& aLSD=aMBlocks.Find(i);
475 if (aLSD.IsEmpty()) {
479 const TopoDS_Shape& aFSD1=aLSD.First();
480 aItF.Initialize(aLSD);
481 for (; aItF.More(); aItF.Next()) {
482 const TopoDS_Shape& aFSD=aItF.Value();
483 myShapesSD.Bind(aFSD, aFSD1);
485 // If the face has no splits but are SD face,
486 // it is considered as splitted face
487 if (!mySplits.IsBound(aFSD)) {
488 BOPCol_ListOfShape aLS;
490 mySplits.Bind(aFSD, aLS);
496 aAllocator.Nullify();
498 //=======================================================================
499 // function: FillImagesFaces1
501 //=======================================================================
502 void BOPAlgo_Builder::FillImagesFaces1()
504 Standard_Integer i, aNbS, iSense;
506 BOPCol_ListOfInteger aLIAV;
507 BOPCol_ListOfShape aLFIm;
508 BOPCol_ListIteratorOfListOfShape aItLS;
510 aNbS=myDS->NbSourceShapes();
511 for (i=0; i<aNbS; ++i) {
512 const BOPDS_ShapeInfo& aSI=myDS->ShapeInfo(i);
513 if (aSI.ShapeType()!=TopAbs_FACE) {
517 const TopoDS_Face& aF=(*(TopoDS_Face*)(&aSI.Shape()));
519 if (!mySplits.IsBound(aF)) {
524 myDS->AloneVertices(i, aLIAV);
527 const BOPCol_ListOfShape& aLSp=mySplits.Find(aF);
528 aItLS.Initialize(aLSp);
529 for (; aItLS.More(); aItLS.Next()) {
530 const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
531 if (!myShapesSD.IsBound(aFSp)) {
535 aFSD=(*(TopoDS_Face*)(&myShapesSD.Find(aFSp)));
536 iSense=BOPTools_AlgoTools::Sense(aFSp, aFSD);
544 FillInternalVertices(aLFIm, aLIAV);
546 myImages.Bind(aF, aLFIm);
549 aItLS.Initialize(aLFIm);
550 for (; aItLS.More(); aItLS.Next()) {
551 const TopoDS_Face& aFSp=(*(TopoDS_Face*)(&aItLS.Value()));
552 myOrigins.Bind(aFSp, aF);
554 }// for (i=0; i<aNbS; ++i) {
556 //=======================================================================
557 // function: FillInternalVertices
559 //=======================================================================
560 void BOPAlgo_Builder::FillInternalVertices(BOPCol_ListOfShape& aLFIm,
561 BOPCol_ListOfInteger& aLIAV)
563 Standard_Integer nV, iFlag;
564 Standard_Real aU1, aU2;
567 BOPCol_ListIteratorOfListOfInteger aItV;
568 BOPCol_ListIteratorOfListOfShape aItF;
570 aItV.Initialize(aLIAV);
571 for (; aItV.More(); aItV.Next()) {
573 aV=(*(TopoDS_Vertex*)(&myDS->Shape(nV)));
574 aV.Orientation(TopAbs_INTERNAL);
576 aItF.Initialize(aLFIm);
577 for (; aItF.More(); aItF.Next()) {
578 TopoDS_Face& aF=(*(TopoDS_Face*)(&aItF.Value()));
579 iFlag=myContext->ComputeVF(aV, aF, aU1, aU2);
587 //=======================================================================
588 //function : MakeBlocksCnx
590 //=======================================================================
591 void MakeBlocksCnx(const BOPCol_IndexedDataMapOfShapeListOfShape& aMILI,
592 BOPCol_DataMapOfIntegerListOfShape& aMBlocks,
593 Handle(NCollection_IncAllocator)& aAllocator)
595 Standard_Integer aNbV, aNbVS, aNbVP, aNbEC, k, i, j;
596 BOPCol_ListIteratorOfListOfShape aItLI;
598 BOPCol_MapOfShape aMVS(100, aAllocator);
599 BOPCol_IndexedMapOfShape aMEC(100, aAllocator);
600 BOPCol_IndexedMapOfShape aMVP(100, aAllocator);
601 BOPCol_IndexedMapOfShape aMVAdd(100, aAllocator);
605 for (k=0,i=1; i<=aNbV; ++i) {
611 const TopoDS_Shape& nV=aMILI.FindKey(i);
612 if (aMVS.Contains(nV)){
624 for (j=1; j<=aNbVP; ++j) {
625 const TopoDS_Shape& nVP=aMVP(j);
626 const BOPCol_ListOfShape& aLV=aMILI.FindFromKey(nVP);
627 aItLI.Initialize(aLV);
628 for (; aItLI.More(); aItLI.Next()) {
629 const TopoDS_Shape& nVx=aItLI.Value();
630 if (aMEC.Contains(nVx)) {
640 aNbVP=aMVAdd.Extent();
642 break; // from while(1)
646 for (j=1; j<=aNbVP; ++j) {
652 BOPCol_ListOfShape aLIx(aAllocator);
654 aNbEC = aMEC.Extent();
655 for (j=1; j<=aNbEC; ++j) {
656 const TopoDS_Shape& nVx=aMEC(j);
660 aMBlocks.Bind(k, aLIx);
662 }//for (k=0,i=1; i<=aNbV; ++i)
669 //=======================================================================
672 //=======================================================================
673 void FillMap(const TopoDS_Shape& aS1,
674 const TopoDS_Shape& aS2,
675 BOPCol_IndexedDataMapOfShapeListOfShape& aDMSLS,
676 Handle(NCollection_IncAllocator)& aAllocator)
678 if (aDMSLS.Contains(aS1)) {
679 BOPCol_ListOfShape& aLS=aDMSLS.ChangeFromKey(aS1);
683 BOPCol_ListOfShape aLS(aAllocator);
685 aDMSLS.Add(aS1, aLS);
688 if (aDMSLS.Contains(aS2)) {
689 BOPCol_ListOfShape& aLS=aDMSLS.ChangeFromKey(aS2);
693 BOPCol_ListOfShape aLS(aAllocator);
695 aDMSLS.Add(aS2, aLS);
698 //=======================================================================
699 //function :HasPaveBlocksOnIn
701 //=======================================================================
702 Standard_Boolean HasPaveBlocksOnIn(const BOPDS_FaceInfo& aFI1,
703 const BOPDS_FaceInfo& aFI2)
705 Standard_Boolean bRet;
706 BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
709 const BOPDS_IndexedMapOfPaveBlock& aMPBOn1=aFI1.PaveBlocksOn();
710 const BOPDS_IndexedMapOfPaveBlock& aMPBIn1=aFI1.PaveBlocksIn();
712 const BOPDS_IndexedMapOfPaveBlock& aMPBOn2=aFI2.PaveBlocksOn();
713 aItMPB.Initialize(aMPBOn2);
714 for (; aItMPB.More(); aItMPB.Next()) {
715 const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
716 bRet=aMPBOn1.Contains(aPB) || aMPBIn1.Contains(aPB);
722 const BOPDS_IndexedMapOfPaveBlock& aMPBIn2=aFI2.PaveBlocksIn();
723 aItMPB.Initialize(aMPBIn2);
724 for (; aItMPB.More(); aItMPB.Next()) {
725 const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
726 bRet=aMPBOn1.Contains(aPB) || aMPBIn1.Contains(aPB);
738 BOPCol_ListIteratorOfListOfShape aItx;
740 aBBx.MakeCompound(aCx);
742 aItx.Initialize(aLE);
743 for (; aItx.More(); aItx.Next()) {
744 const TopoDS_Shape& aEx=aItx.Value();