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.
18 #include <BOPAlgo_PaveFiller.ixx>
20 #include <NCollection_IncAllocator.hxx>
22 #include <Geom_RectangularTrimmedSurface.hxx>
23 #include <Geom_Plane.hxx>
24 #include <Geom_Surface.hxx>
25 #include <Geom_RectangularTrimmedSurface.hxx>
27 #include <TopoDS_Vertex.hxx>
28 #include <TopoDS_Edge.hxx>
29 #include <TopoDS_Face.hxx>
31 #include <BRepBndLib.hxx>
33 #include <BRep_Tool.hxx>
34 #include <BRep_Builder.hxx>
37 #include <TopExp_Explorer.hxx>
39 #include <Geom_Curve.hxx>
40 #include <Geom_Surface.hxx>
41 #include <Geom2d_Curve.hxx>
43 #include <BOPCol_NCVector.hxx>
44 #include <BOPCol_Parallel.hxx>
45 #include <BOPCol_MapOfShape.hxx>
47 #include <BOPDS_VectorOfListOfPaveBlock.hxx>
48 #include <BOPDS_ListOfPaveBlock.hxx>
49 #include <BOPDS_PaveBlock.hxx>
50 #include <BOPDS_CommonBlock.hxx>
51 #include <BOPDS_Pave.hxx>
52 #include <BOPDS_ShapeInfo.hxx>
53 #include <BOPDS_MapOfPaveBlock.hxx>
54 #include <BOPDS_VectorOfInterfFF.hxx>
55 #include <BOPDS_Interf.hxx>
56 #include <BOPDS_VectorOfCurve.hxx>
57 #include <BOPDS_VectorOfFaceInfo.hxx>
58 #include <BOPDS_FaceInfo.hxx>
59 #include <BOPDS_MapOfPaveBlock.hxx>
60 #include <BOPDS_Curve.hxx>
61 #include <BOPDS_Iterator.hxx>
63 #include <BOPTools_AlgoTools.hxx>
64 #include <BOPTools_AlgoTools2D.hxx>
67 Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF);
70 static void UpdateVertices(const TopoDS_Edge& aE,
71 const TopoDS_Face& aF);
73 //=======================================================================
74 //class : BOPAlgo_SplitEdge
76 //=======================================================================
77 class BOPAlgo_SplitEdge : public BOPAlgo_Algo {
88 virtual ~BOPAlgo_SplitEdge() {
91 void SetData(const TopoDS_Edge& aE,
92 const TopoDS_Vertex& aV1,
93 const Standard_Real aT1,
94 const TopoDS_Vertex& aV2,
95 const Standard_Real aT2) {
104 void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
108 Handle(BOPDS_PaveBlock)& PaveBlock() {
112 void SetCommonBlock(const Handle(BOPDS_CommonBlock)& aCB) {
116 Handle(BOPDS_CommonBlock)& CommonBlock() {
120 const TopoDS_Edge& SplitEdge() const {
124 const Bnd_Box Box() {
128 virtual void Perform () {
129 BOPAlgo_Algo::UserBreak();
130 BOPTools_AlgoTools::MakeSplitEdge(myE,
134 BRepBndLib::Add(myESp, myBox);
145 Handle(BOPDS_PaveBlock) myPB;
146 Handle(BOPDS_CommonBlock) myCB;
152 //=======================================================================
153 typedef BOPCol_NCVector
154 <BOPAlgo_SplitEdge> BOPAlgo_VectorOfSplitEdge;
156 typedef BOPCol_Functor
158 BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeFunctor;
161 <BOPAlgo_SplitEdgeFunctor,
162 BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeCnt;
164 //=======================================================================
165 //class : BOPAlgo_MPC
167 //=======================================================================
168 class BOPAlgo_MPC : public BOPAlgo_Algo {
171 DEFINE_STANDARD_ALLOC
175 myFlag(Standard_False) {
178 virtual ~BOPAlgo_MPC(){
181 void SetEdge(const TopoDS_Edge& aE) {
185 const TopoDS_Edge& Edge() const {
189 void SetFace(const TopoDS_Face& aF) {
193 const TopoDS_Face& Face() const {
197 void SetFlag(const Standard_Boolean bFlag) {
201 Standard_Boolean Flag() const {
205 void SetData(const TopoDS_Edge& aEz,
206 const TopoDS_Vertex& aV1,
207 const Standard_Real aT1,
208 const TopoDS_Vertex& aV2,
209 const Standard_Real aT2) {
217 void SetContext(const Handle(IntTools_Context)& aContext) {
221 const Handle(IntTools_Context)& Context()const {
225 virtual void Perform() {
226 Standard_Integer iErr;
229 if (!myEz.IsNull()) {
232 BOPTools_AlgoTools::MakeSplitEdge(myEz,myV1, myT1,
236 BOPTools_AlgoTools2D::AttachExistingPCurve(aSpz,
243 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(myE, myF);
247 UpdateVertices(myE, myF);
252 Standard_Boolean myFlag;
261 Handle(IntTools_Context) myContext;
264 //=======================================================================
265 typedef BOPCol_NCVector
266 <BOPAlgo_MPC> BOPAlgo_VectorOfMPC;
268 typedef BOPCol_ContextFunctor
271 Handle(IntTools_Context),
272 IntTools_Context> BOPAlgo_MPCFunctor;
274 typedef BOPCol_ContextCnt
277 Handle(IntTools_Context)> BOPAlgo_MPCCnt;
279 //=======================================================================
280 //class : BOPAlgo_BPC
282 //=======================================================================
291 void SetFace(const TopoDS_Face& aF) {
295 void SetEdge(const TopoDS_Edge& aE) {
300 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (myE, myF);
307 //=======================================================================
308 typedef BOPCol_NCVector
309 <BOPAlgo_BPC> BOPAlgo_VectorOfBPC;
311 typedef BOPCol_Functor
313 BOPAlgo_VectorOfBPC> BOPAlgo_BPCFunctor;
317 BOPAlgo_VectorOfBPC> BOPAlgo_BPCCnt;
320 //=======================================================================
321 // function: MakeSplitEdges
323 //=======================================================================
324 void BOPAlgo_PaveFiller::MakeSplitEdges()
326 Standard_Integer aNbPBP;
330 BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
331 aNbPBP=aPBP.Extent();
336 Standard_Boolean bCB, bV1, bV2;
337 Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, aNbVBSE, k;
338 Standard_Real aT1, aT2;
339 BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBCB;
340 Handle(BOPDS_PaveBlock) aPB;
341 BOPDS_MapOfPaveBlock aMPB(100);
342 TopoDS_Vertex aV1, aV2;
344 BOPAlgo_VectorOfSplitEdge aVBSE;
347 for (i=0; i<aNbPBP; ++i) {
348 BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
353 aPB->Indices(nV1, nV2);
354 bV1=myDS->IsNewShape(nV1);
355 bV2=myDS->IsNewShape(nV2);
358 nE=aPB->OriginalEdge();
364 aItPB.Initialize(aLPB);
365 for (; aItPB.More(); aItPB.Next()) {
367 const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
370 myDS->SortPaveBlocks(aCB);
371 aPB=aCB->PaveBlock1();
375 nE=aPB->OriginalEdge();
376 aPB->Indices(nV1, nV2);
377 aPB->Range(aT1, aT2);
379 aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
380 aE.Orientation(TopAbs_FORWARD);
382 aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
383 aV1.Orientation(TopAbs_FORWARD);
385 aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
386 aV2.Orientation(TopAbs_REVERSED);
388 BOPAlgo_SplitEdge& aBSE=aVBSE.Append1();
390 aBSE.SetData(aE, aV1, aT1, aV2, aT2);
391 aBSE.SetPaveBlock(aPB);
393 aBSE.SetCommonBlock(aCB);
395 aBSE.SetProgressIndicator(myProgressIndicator);
397 } // for (; aItPB.More(); aItPB.Next()) {
398 } // for (i=0; i<aNbPBP; ++i) {
400 aNbVBSE=aVBSE.Extent();
401 //======================================================
402 BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE);
403 //======================================================
407 aSI.SetShapeType(TopAbs_EDGE);
409 for (k=0; k < aNbVBSE; ++k) {
410 BOPAlgo_SplitEdge& aBSE=aVBSE(k);
412 const TopoDS_Edge& aSp=aBSE.SplitEdge();
413 const Bnd_Box& aBox=aBSE.Box();
415 Handle(BOPDS_PaveBlock) aPBk=aBSE.PaveBlock();
416 Handle(BOPDS_CommonBlock)& aCBk=aBSE.CommonBlock();
419 aSI.ChangeBox()=aBox;
421 nSp=myDS->Append(aSI);
423 if (!aCBk.IsNull()) {
431 //=======================================================================
432 // function: SplitEdge
434 //=======================================================================
435 Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE,
436 const Standard_Integer nV1,
437 const Standard_Real aT1,
438 const Standard_Integer nV2,
439 const Standard_Real aT2)
441 Standard_Integer nSp;
442 TopoDS_Vertex aV1, aV2;
446 aSI.SetShapeType(TopAbs_EDGE);
448 aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
449 aE.Orientation(TopAbs_FORWARD);
451 aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
452 aV1.Orientation(TopAbs_FORWARD);
454 aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
455 aV2.Orientation(TopAbs_REVERSED);
457 BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);
461 Bnd_Box& aBox=aSI.ChangeBox();
462 BRepBndLib::Add(aSp, aBox);
464 nSp=myDS->Append(aSI);
467 //=======================================================================
468 // function: MakePCurves
470 //=======================================================================
471 void BOPAlgo_PaveFiller::MakePCurves()
473 Standard_Boolean bHasPC;
474 Standard_Integer i, nF1, nF2, aNbC, k, nE, aNbFF, aNbFI, nEx;
475 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
476 BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
477 TopoDS_Face aF1F, aF2F;
478 BOPAlgo_VectorOfMPC aVMPC;
482 // 1. Process Common Blocks
483 const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool();
486 for (i=0; i<aNbFI; ++i) {
487 const BOPDS_FaceInfo& aFI=aFIP(i);
490 aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
491 aF1F.Orientation(TopAbs_FORWARD);
493 const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
494 aItMPB.Initialize(aMPBIn);
495 for(; aItMPB.More(); aItMPB.Next()) {
496 const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
498 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
500 BOPAlgo_MPC& aMPC=aVMPC.Append1();
503 aMPC.SetProgressIndicator(myProgressIndicator);
507 const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
508 aItMPB.Initialize(aMPBOn);
509 for(; aItMPB.More(); aItMPB.Next()) {
510 const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
512 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
513 bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF1F);
518 Handle(BOPDS_CommonBlock) aCB=myDS->CommonBlock(aPB);
523 const BOPDS_ListOfPaveBlock& aLPB=aCB->PaveBlocks();
524 if (aLPB.Extent()<2) {
528 BOPAlgo_MPC& aMPC=aVMPC.Append1();
530 aItLPB.Initialize(aLPB);
531 for(; aItLPB.More(); aItLPB.Next()) {
532 const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
537 nEx=aPBx->OriginalEdge();
538 const TopoDS_Edge& aEx=(*(TopoDS_Edge *)(&myDS->Shape(nEx)));
539 bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aEx, aF1F);
544 Standard_Integer nV1x, nV2x;
545 Standard_Real aT1x, aT2x;
546 TopoDS_Vertex aV1x, aV2x;
550 aEz.Orientation(TopAbs_FORWARD);
552 aPBx->Indices(nV1x, nV2x);
553 aPBx->Range(aT1x, aT2x);
555 aV1x=(*(TopoDS_Vertex *)(&myDS->Shape(nV1x)));
556 aV1x.Orientation(TopAbs_FORWARD);
558 aV2x=(*(TopoDS_Vertex *)(&myDS->Shape(nV2x)));
559 aV2x.Orientation(TopAbs_REVERSED);
561 aMPC.SetData(aEz, aV1x, aT1x, aV2x, aT2x);
568 aMPC.SetProgressIndicator(myProgressIndicator);
570 }// for (i=0; i<aNbFI; ++i) {
572 // 2. Process section edges
573 Standard_Boolean bPCurveOnS[2];
577 bPCurveOnS[0]=mySectionAttribute.PCurveOnS1();
578 bPCurveOnS[1]=mySectionAttribute.PCurveOnS2();
580 if (bPCurveOnS[0] || bPCurveOnS[1]) {
581 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
583 for (i=0; i<aNbFF; ++i) {
584 const BOPDS_InterfFF& aFF=aFFs(i);
585 aFF.Indices(nF1, nF2);
587 aFf[0]=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
588 aFf[0].Orientation(TopAbs_FORWARD);
590 aFf[1]=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
591 aFf[1].Orientation(TopAbs_FORWARD);
593 const BOPDS_VectorOfCurve& aVNC=aFF.Curves();
595 for (k=0; k<aNbC; ++k) {
596 const BOPDS_Curve& aNC=aVNC(k);
597 const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks();
598 aItLPB.Initialize(aLPB);
599 for(; aItLPB.More(); aItLPB.Next()) {
600 const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
602 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
604 for (m=0; m<2; ++m) {
606 BOPAlgo_MPC& aMPC=aVMPC.Append1();
608 aMPC.SetFace(aFf[m]);
609 aMPC.SetFlag(bPCurveOnS[m]);
610 aMPC.SetProgressIndicator(myProgressIndicator);
615 }// for (i=0; i<aNbFF; ++i) {
616 }//if (bPCurveOnS1 || bPCurveOnS2 ) {
618 //======================================================
619 BOPAlgo_MPCCnt::Perform(myRunParallel, aVMPC, myContext);
620 //======================================================
622 //=======================================================================
623 // function: RefineFaceInfoOn
625 //=======================================================================
626 void BOPAlgo_PaveFiller::RefineFaceInfoOn()
628 Standard_Integer aNbPBP;
632 BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
633 aNbPBP=aPBP.Extent();
638 Standard_Boolean bV1, bV2;
639 Standard_Integer i, nV1, nV2, aNbPB;
640 Handle(BOPDS_PaveBlock) aPB;
642 for (i=0; i<aNbPBP; ++i) {
643 BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
648 aPB->Indices(nV1, nV2);
649 bV1=myDS->IsNewShape(nV1);
650 bV2=myDS->IsNewShape(nV2);
653 if (!myDS->IsCommonBlock(aPB)) {
654 // the PB seems to be untouced
658 }//if (!(bV1 || bV2)) {
660 }//for (i=0; i<aNbPBP; ++i) {
661 myDS->RefineFaceInfoOn();
663 //=======================================================================
664 //function : UpdateVertices
665 //purpose : update tolerances of vertices comparing extremities of
667 //=======================================================================
668 void UpdateVertices(const TopoDS_Edge& aE,
669 const TopoDS_Face& aF)
672 Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD;
675 Handle(Geom_Surface) aS;
676 Handle(Geom_Curve) aC3D;
677 Handle(Geom2d_Curve) aC2D;
683 aEf.Orientation(TopAbs_FORWARD);
685 TopExp::Vertices(aEf, aV[0], aV[1]);
687 aS=BRep_Tool::Surface(aF);
688 aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]);
689 aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]);
691 for (j=0; j<2; ++j) {
692 aTolV2=BRep_Tool::Tolerance(aV[j]);
693 aTolV2=aTolV2*aTolV2;
695 aC3D->D0(aT[j], aP3D);
696 aC2D->D0(aT[j], aP2Dx);
697 aP2Dx.Coord(aUx, aVx);
698 aS->D0(aUx, aVx, aP3Dx);
699 aD2=aP3D.SquareDistance(aP3Dx);
702 aBB.UpdateVertex(aV[j], aD);
706 //=======================================================================
709 //=======================================================================
710 void BOPAlgo_PaveFiller::Prepare()
712 TopAbs_ShapeEnum aType[] = {
717 Standard_Boolean bJustAdd, bIsBasedOnPlane;
718 Standard_Integer i, aNb, n1, nF;
719 TopExp_Explorer aExp;
720 BOPCol_MapOfShape aMF;
721 BOPCol_MapIteratorOfMapOfShape aItMF;
726 for(i=0; i<aNb; ++i) {
727 myIterator->Initialize(aType[i], aType[2]);
728 for (; myIterator->More(); myIterator->Next()) {
729 myIterator->Value(n1, nF, bJustAdd);
730 const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF)));
732 bIsBasedOnPlane=IsBasedOnPlane(aF);
733 if (bIsBasedOnPlane) {
743 BOPAlgo_VectorOfBPC aVBPC;
745 aItMF.Initialize(aMF);
746 for (; aItMF.More(); aItMF.Next()) {
747 const TopoDS_Face& aF=*((TopoDS_Face *)&aItMF.Key());
748 aExp.Init(aF, aType[1]);
749 for (; aExp.More(); aExp.Next()) {
750 const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
751 BOPAlgo_BPC& aBPC=aVBPC.Append1();
757 //======================================================
758 BOPAlgo_BPCCnt::Perform(myRunParallel, aVBPC);
759 //======================================================
761 //=======================================================================
762 //function : IsBasedOnPlane
764 //=======================================================================
765 Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF)
767 TopLoc_Location aLoc;
768 Handle(Geom_RectangularTrimmedSurface) aGRTS;
769 Handle(Geom_Plane) aGP;
771 const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF, aLoc);
772 aGRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
773 if(!aGRTS.IsNull()) {
774 aGP = Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
777 aGP = Handle(Geom_Plane)::DownCast(aS);
780 return (!aGP.IsNull());