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 under
10 // the terms of the GNU Lesser General Public License 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.
19 #include <BOPAlgo_PaveFiller.hxx>
20 #include <BOPAlgo_SectionAttribute.hxx>
21 #include <BOPCol_MapOfShape.hxx>
22 #include <BOPCol_NCVector.hxx>
23 #include <BOPCol_Parallel.hxx>
24 #include <BOPDS_CommonBlock.hxx>
25 #include <BOPDS_Curve.hxx>
26 #include <BOPDS_DS.hxx>
27 #include <BOPDS_FaceInfo.hxx>
28 #include <BOPDS_Interf.hxx>
29 #include <BOPDS_Iterator.hxx>
30 #include <BOPDS_ListOfPaveBlock.hxx>
31 #include <BOPDS_MapOfPaveBlock.hxx>
32 #include <BOPDS_Pave.hxx>
33 #include <BOPDS_PaveBlock.hxx>
34 #include <BOPDS_ShapeInfo.hxx>
35 #include <BOPDS_VectorOfCurve.hxx>
36 #include <BOPDS_VectorOfFaceInfo.hxx>
37 #include <BOPDS_VectorOfInterfFF.hxx>
38 #include <BOPDS_VectorOfListOfPaveBlock.hxx>
39 #include <BOPTools_AlgoTools.hxx>
40 #include <BOPTools_AlgoTools2D.hxx>
41 #include <BRep_Builder.hxx>
42 #include <BRep_Tool.hxx>
43 #include <BRepBndLib.hxx>
44 #include <Geom2d_Curve.hxx>
45 #include <Geom_Curve.hxx>
46 #include <Geom_Plane.hxx>
47 #include <Geom_RectangularTrimmedSurface.hxx>
48 #include <Geom_Surface.hxx>
50 #include <IntTools_Context.hxx>
51 #include <NCollection_IncAllocator.hxx>
53 #include <TopExp_Explorer.hxx>
54 #include <TopoDS_Edge.hxx>
55 #include <TopoDS_Face.hxx>
56 #include <TopoDS_Vertex.hxx>
59 Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF);
62 static void UpdateVertices(const TopoDS_Edge& aE,
63 const TopoDS_Face& aF);
65 //=======================================================================
66 //class : BOPAlgo_SplitEdge
68 //=======================================================================
69 class BOPAlgo_SplitEdge : public BOPAlgo_Algo {
80 virtual ~BOPAlgo_SplitEdge() {
83 void SetData(const TopoDS_Edge& aE,
84 const TopoDS_Vertex& aV1,
85 const Standard_Real aT1,
86 const TopoDS_Vertex& aV2,
87 const Standard_Real aT2) {
96 void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
100 Handle(BOPDS_PaveBlock)& PaveBlock() {
104 void SetCommonBlock(const Handle(BOPDS_CommonBlock)& aCB) {
108 Handle(BOPDS_CommonBlock)& CommonBlock() {
112 const TopoDS_Edge& SplitEdge() const {
116 const Bnd_Box Box() {
120 virtual void Perform () {
121 BOPAlgo_Algo::UserBreak();
122 BOPTools_AlgoTools::MakeSplitEdge(myE,
126 BRepBndLib::Add(myESp, myBox);
137 Handle(BOPDS_PaveBlock) myPB;
138 Handle(BOPDS_CommonBlock) myCB;
144 //=======================================================================
145 typedef BOPCol_NCVector
146 <BOPAlgo_SplitEdge> BOPAlgo_VectorOfSplitEdge;
148 typedef BOPCol_Functor
150 BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeFunctor;
153 <BOPAlgo_SplitEdgeFunctor,
154 BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeCnt;
156 //=======================================================================
157 //class : BOPAlgo_MPC
159 //=======================================================================
160 class BOPAlgo_MPC : public BOPAlgo_Algo {
163 DEFINE_STANDARD_ALLOC
167 myFlag(Standard_False) {
170 virtual ~BOPAlgo_MPC(){
173 void SetEdge(const TopoDS_Edge& aE) {
177 const TopoDS_Edge& Edge() const {
181 void SetFace(const TopoDS_Face& aF) {
185 const TopoDS_Face& Face() const {
189 void SetFlag(const Standard_Boolean bFlag) {
193 Standard_Boolean Flag() const {
197 void SetData(const TopoDS_Edge& aEz,
198 const TopoDS_Vertex& aV1,
199 const Standard_Real aT1,
200 const TopoDS_Vertex& aV2,
201 const Standard_Real aT2) {
209 void SetContext(const Handle(IntTools_Context)& aContext) {
213 const Handle(IntTools_Context)& Context()const {
217 virtual void Perform() {
218 Standard_Integer iErr;
221 if (!myEz.IsNull()) {
224 BOPTools_AlgoTools::MakeSplitEdge(myEz,myV1, myT1,
228 BOPTools_AlgoTools2D::AttachExistingPCurve(aSpz,
235 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(myE, myF);
239 UpdateVertices(myE, myF);
244 Standard_Boolean myFlag;
253 Handle(IntTools_Context) myContext;
256 //=======================================================================
257 typedef BOPCol_NCVector
258 <BOPAlgo_MPC> BOPAlgo_VectorOfMPC;
260 typedef BOPCol_ContextFunctor
263 Handle(IntTools_Context),
264 IntTools_Context> BOPAlgo_MPCFunctor;
266 typedef BOPCol_ContextCnt
269 Handle(IntTools_Context)> BOPAlgo_MPCCnt;
271 //=======================================================================
272 //class : BOPAlgo_BPC
274 //=======================================================================
283 void SetFace(const TopoDS_Face& aF) {
287 void SetEdge(const TopoDS_Edge& aE) {
292 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (myE, myF);
299 //=======================================================================
300 typedef BOPCol_NCVector
301 <BOPAlgo_BPC> BOPAlgo_VectorOfBPC;
303 typedef BOPCol_Functor
305 BOPAlgo_VectorOfBPC> BOPAlgo_BPCFunctor;
309 BOPAlgo_VectorOfBPC> BOPAlgo_BPCCnt;
312 //=======================================================================
313 // function: MakeSplitEdges
315 //=======================================================================
316 void BOPAlgo_PaveFiller::MakeSplitEdges()
318 Standard_Integer aNbPBP;
322 BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
323 aNbPBP=aPBP.Extent();
328 Standard_Boolean bCB, bV1, bV2;
329 Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, aNbVBSE, k;
330 Standard_Real aT1, aT2;
331 BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBCB;
332 Handle(BOPDS_PaveBlock) aPB;
333 BOPDS_MapOfPaveBlock aMPB(100);
334 TopoDS_Vertex aV1, aV2;
336 BOPAlgo_VectorOfSplitEdge aVBSE;
339 for (i=0; i<aNbPBP; ++i) {
340 BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
345 aPB->Indices(nV1, nV2);
346 bV1=myDS->IsNewShape(nV1);
347 bV2=myDS->IsNewShape(nV2);
350 nE=aPB->OriginalEdge();
356 aItPB.Initialize(aLPB);
357 for (; aItPB.More(); aItPB.Next()) {
359 const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
362 myDS->SortPaveBlocks(aCB);
363 aPB=aCB->PaveBlock1();
367 nE=aPB->OriginalEdge();
368 aPB->Indices(nV1, nV2);
369 aPB->Range(aT1, aT2);
371 aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
372 aE.Orientation(TopAbs_FORWARD);
374 aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
375 aV1.Orientation(TopAbs_FORWARD);
377 aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
378 aV2.Orientation(TopAbs_REVERSED);
380 BOPAlgo_SplitEdge& aBSE=aVBSE.Append1();
382 aBSE.SetData(aE, aV1, aT1, aV2, aT2);
383 aBSE.SetPaveBlock(aPB);
385 aBSE.SetCommonBlock(aCB);
387 aBSE.SetProgressIndicator(myProgressIndicator);
389 } // for (; aItPB.More(); aItPB.Next()) {
390 } // for (i=0; i<aNbPBP; ++i) {
392 aNbVBSE=aVBSE.Extent();
393 //======================================================
394 BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE);
395 //======================================================
399 aSI.SetShapeType(TopAbs_EDGE);
401 for (k=0; k < aNbVBSE; ++k) {
402 BOPAlgo_SplitEdge& aBSE=aVBSE(k);
404 const TopoDS_Edge& aSp=aBSE.SplitEdge();
405 const Bnd_Box& aBox=aBSE.Box();
407 Handle(BOPDS_PaveBlock) aPBk=aBSE.PaveBlock();
408 Handle(BOPDS_CommonBlock)& aCBk=aBSE.CommonBlock();
411 aSI.ChangeBox()=aBox;
413 nSp=myDS->Append(aSI);
415 if (!aCBk.IsNull()) {
423 //=======================================================================
424 // function: SplitEdge
426 //=======================================================================
427 Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE,
428 const Standard_Integer nV1,
429 const Standard_Real aT1,
430 const Standard_Integer nV2,
431 const Standard_Real aT2)
433 Standard_Integer nSp;
434 TopoDS_Vertex aV1, aV2;
438 aSI.SetShapeType(TopAbs_EDGE);
440 aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
441 aE.Orientation(TopAbs_FORWARD);
443 aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
444 aV1.Orientation(TopAbs_FORWARD);
446 aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
447 aV2.Orientation(TopAbs_REVERSED);
449 BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);
453 Bnd_Box& aBox=aSI.ChangeBox();
454 BRepBndLib::Add(aSp, aBox);
456 nSp=myDS->Append(aSI);
459 //=======================================================================
460 // function: MakePCurves
462 //=======================================================================
463 void BOPAlgo_PaveFiller::MakePCurves()
465 Standard_Boolean bHasPC;
466 Standard_Integer i, nF1, nF2, aNbC, k, nE, aNbFF, aNbFI, nEx;
467 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
468 BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
469 TopoDS_Face aF1F, aF2F;
470 BOPAlgo_VectorOfMPC aVMPC;
474 // 1. Process Common Blocks
475 const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool();
478 for (i=0; i<aNbFI; ++i) {
479 const BOPDS_FaceInfo& aFI=aFIP(i);
482 aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
483 aF1F.Orientation(TopAbs_FORWARD);
485 const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
486 aItMPB.Initialize(aMPBIn);
487 for(; aItMPB.More(); aItMPB.Next()) {
488 const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
490 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
492 BOPAlgo_MPC& aMPC=aVMPC.Append1();
495 aMPC.SetProgressIndicator(myProgressIndicator);
499 const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
500 aItMPB.Initialize(aMPBOn);
501 for(; aItMPB.More(); aItMPB.Next()) {
502 const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
504 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
505 bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF1F);
510 Handle(BOPDS_CommonBlock) aCB=myDS->CommonBlock(aPB);
515 const BOPDS_ListOfPaveBlock& aLPB=aCB->PaveBlocks();
516 if (aLPB.Extent()<2) {
520 BOPAlgo_MPC& aMPC=aVMPC.Append1();
522 aItLPB.Initialize(aLPB);
523 for(; aItLPB.More(); aItLPB.Next()) {
524 const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
529 nEx=aPBx->OriginalEdge();
530 const TopoDS_Edge& aEx=(*(TopoDS_Edge *)(&myDS->Shape(nEx)));
531 bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aEx, aF1F);
536 Standard_Integer nV1x, nV2x;
537 Standard_Real aT1x, aT2x;
538 TopoDS_Vertex aV1x, aV2x;
542 aEz.Orientation(TopAbs_FORWARD);
544 aPBx->Indices(nV1x, nV2x);
545 aPBx->Range(aT1x, aT2x);
547 aV1x=(*(TopoDS_Vertex *)(&myDS->Shape(nV1x)));
548 aV1x.Orientation(TopAbs_FORWARD);
550 aV2x=(*(TopoDS_Vertex *)(&myDS->Shape(nV2x)));
551 aV2x.Orientation(TopAbs_REVERSED);
553 aMPC.SetData(aEz, aV1x, aT1x, aV2x, aT2x);
560 aMPC.SetProgressIndicator(myProgressIndicator);
562 }// for (i=0; i<aNbFI; ++i) {
564 // 2. Process section edges
565 Standard_Boolean bPCurveOnS[2];
569 bPCurveOnS[0]=mySectionAttribute.PCurveOnS1();
570 bPCurveOnS[1]=mySectionAttribute.PCurveOnS2();
572 if (bPCurveOnS[0] || bPCurveOnS[1]) {
573 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
575 for (i=0; i<aNbFF; ++i) {
576 const BOPDS_InterfFF& aFF=aFFs(i);
577 aFF.Indices(nF1, nF2);
579 aFf[0]=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
580 aFf[0].Orientation(TopAbs_FORWARD);
582 aFf[1]=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
583 aFf[1].Orientation(TopAbs_FORWARD);
585 const BOPDS_VectorOfCurve& aVNC=aFF.Curves();
587 for (k=0; k<aNbC; ++k) {
588 const BOPDS_Curve& aNC=aVNC(k);
589 const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks();
590 aItLPB.Initialize(aLPB);
591 for(; aItLPB.More(); aItLPB.Next()) {
592 const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
594 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
596 for (m=0; m<2; ++m) {
598 BOPAlgo_MPC& aMPC=aVMPC.Append1();
600 aMPC.SetFace(aFf[m]);
601 aMPC.SetFlag(bPCurveOnS[m]);
602 aMPC.SetProgressIndicator(myProgressIndicator);
607 }// for (i=0; i<aNbFF; ++i) {
608 }//if (bPCurveOnS1 || bPCurveOnS2 ) {
610 //======================================================
611 BOPAlgo_MPCCnt::Perform(myRunParallel, aVMPC, myContext);
612 //======================================================
614 //=======================================================================
615 // function: RefineFaceInfoOn
617 //=======================================================================
618 void BOPAlgo_PaveFiller::RefineFaceInfoOn()
620 Standard_Integer aNbPBP;
624 BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
625 aNbPBP=aPBP.Extent();
630 Standard_Boolean bV1, bV2;
631 Standard_Integer i, nV1, nV2, aNbPB;
632 Handle(BOPDS_PaveBlock) aPB;
634 for (i=0; i<aNbPBP; ++i) {
635 BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
640 aPB->Indices(nV1, nV2);
641 bV1=myDS->IsNewShape(nV1);
642 bV2=myDS->IsNewShape(nV2);
645 if (!myDS->IsCommonBlock(aPB)) {
646 // the PB seems to be untouced
650 }//if (!(bV1 || bV2)) {
652 }//for (i=0; i<aNbPBP; ++i) {
653 myDS->RefineFaceInfoOn();
655 //=======================================================================
656 //function : UpdateVertices
657 //purpose : update tolerances of vertices comparing extremities of
659 //=======================================================================
660 void UpdateVertices(const TopoDS_Edge& aE,
661 const TopoDS_Face& aF)
664 Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD;
667 Handle(Geom_Surface) aS;
668 Handle(Geom_Curve) aC3D;
669 Handle(Geom2d_Curve) aC2D;
675 aEf.Orientation(TopAbs_FORWARD);
677 TopExp::Vertices(aEf, aV[0], aV[1]);
679 aS=BRep_Tool::Surface(aF);
680 aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]);
681 aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]);
683 for (j=0; j<2; ++j) {
684 aTolV2=BRep_Tool::Tolerance(aV[j]);
685 aTolV2=aTolV2*aTolV2;
687 aC3D->D0(aT[j], aP3D);
688 aC2D->D0(aT[j], aP2Dx);
689 aP2Dx.Coord(aUx, aVx);
690 aS->D0(aUx, aVx, aP3Dx);
691 aD2=aP3D.SquareDistance(aP3Dx);
694 aBB.UpdateVertex(aV[j], aD);
698 //=======================================================================
701 //=======================================================================
702 void BOPAlgo_PaveFiller::Prepare()
704 TopAbs_ShapeEnum aType[] = {
709 Standard_Boolean bJustAdd, bIsBasedOnPlane;
710 Standard_Integer i, aNb, n1, nF;
711 TopExp_Explorer aExp;
712 BOPCol_MapOfShape aMF;
713 BOPCol_MapIteratorOfMapOfShape aItMF;
718 for(i=0; i<aNb; ++i) {
719 myIterator->Initialize(aType[i], aType[2]);
720 for (; myIterator->More(); myIterator->Next()) {
721 myIterator->Value(n1, nF, bJustAdd);
722 const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF)));
724 bIsBasedOnPlane=IsBasedOnPlane(aF);
725 if (bIsBasedOnPlane) {
735 BOPAlgo_VectorOfBPC aVBPC;
737 aItMF.Initialize(aMF);
738 for (; aItMF.More(); aItMF.Next()) {
739 const TopoDS_Face& aF=*((TopoDS_Face *)&aItMF.Key());
740 aExp.Init(aF, aType[1]);
741 for (; aExp.More(); aExp.Next()) {
742 const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
743 BOPAlgo_BPC& aBPC=aVBPC.Append1();
749 //======================================================
750 BOPAlgo_BPCCnt::Perform(myRunParallel, aVBPC);
751 //======================================================
753 //=======================================================================
754 //function : IsBasedOnPlane
756 //=======================================================================
757 Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF)
759 TopLoc_Location aLoc;
760 Handle(Geom_RectangularTrimmedSurface) aGRTS;
761 Handle(Geom_Plane) aGP;
763 const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF, aLoc);
764 aGRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
765 if(!aGRTS.IsNull()) {
766 aGP = Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
769 aGP = Handle(Geom_Plane)::DownCast(aS);
772 return (!aGP.IsNull());