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.hxx>
19 #include <BOPAlgo_Alerts.hxx>
20 #include <BOPAlgo_SectionAttribute.hxx>
21 #include <BOPAlgo_Tools.hxx>
22 #include <BOPCol_IndexedMapOfShape.hxx>
23 #include <BOPCol_NCVector.hxx>
24 #include <BOPCol_Parallel.hxx>
25 #include <BOPDS_CommonBlock.hxx>
26 #include <BOPDS_Curve.hxx>
27 #include <BOPDS_DS.hxx>
28 #include <BOPDS_FaceInfo.hxx>
29 #include <BOPDS_Interf.hxx>
30 #include <BOPDS_Iterator.hxx>
31 #include <BOPDS_ListOfPaveBlock.hxx>
32 #include <BOPDS_MapOfPair.hxx>
33 #include <BOPDS_MapOfPaveBlock.hxx>
34 #include <BOPDS_Pave.hxx>
35 #include <BOPDS_PaveBlock.hxx>
36 #include <BOPDS_ShapeInfo.hxx>
37 #include <BOPDS_VectorOfCurve.hxx>
38 #include <BOPDS_VectorOfFaceInfo.hxx>
39 #include <BOPDS_VectorOfInterfFF.hxx>
40 #include <BOPDS_VectorOfListOfPaveBlock.hxx>
41 #include <BOPTools_AlgoTools.hxx>
42 #include <BOPTools_AlgoTools2D.hxx>
43 #include <BRep_Builder.hxx>
44 #include <BRep_Tool.hxx>
45 #include <BRepBndLib.hxx>
46 #include <Geom2d_Curve.hxx>
47 #include <Geom_Curve.hxx>
48 #include <Geom_Plane.hxx>
49 #include <Geom_RectangularTrimmedSurface.hxx>
50 #include <Geom_Surface.hxx>
51 #include <GeomAPI_ProjectPointOnCurve.hxx>
52 #include <GeomAPI_ProjectPointOnSurf.hxx>
54 #include <IntTools_Context.hxx>
55 #include <IntTools_Tools.hxx>
57 #include <TopExp_Explorer.hxx>
59 #include <TopoDS_Edge.hxx>
60 #include <TopoDS_Face.hxx>
61 #include <TopoDS_Vertex.hxx>
65 Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF);
68 static void UpdateVertices(const TopoDS_Edge& aE,
69 const TopoDS_Face& aF);
71 //=======================================================================
72 //class : BOPAlgo_SplitEdge
74 //=======================================================================
75 class BOPAlgo_SplitEdge : public BOPAlgo_Algo {
87 virtual ~BOPAlgo_SplitEdge() {
90 void SetData(const TopoDS_Edge& aE,
91 const TopoDS_Vertex& aV1,
92 const Standard_Real aT1,
93 const TopoDS_Vertex& aV2,
94 const Standard_Real aT2) {
103 void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
107 Handle(BOPDS_PaveBlock)& PaveBlock() {
111 void SetCommonBlock(const Handle(BOPDS_CommonBlock)& aCB) {
115 Handle(BOPDS_CommonBlock)& CommonBlock() {
119 const TopoDS_Edge& SplitEdge() const {
123 const Bnd_Box Box() {
127 Standard_Real Tolerance() const {
131 void SetDS(const BOPDS_PDS theDS) {
135 void SetContext(const Handle(IntTools_Context)& aContext) {
136 myContext = aContext;
139 virtual void Perform () {
140 BOPAlgo_Algo::UserBreak();
141 myTol = BOPAlgo_Tools::ComputeToleranceOfCB(myCB, myDS, myContext);
142 BOPTools_AlgoTools::MakeSplitEdge(myE,
146 BRepBndLib::Add(myESp, myBox);
147 myBox.SetGap(myBox.GetGap() + Precision::Confusion());
158 Handle(BOPDS_PaveBlock) myPB;
159 Handle(BOPDS_CommonBlock) myCB;
166 Handle(IntTools_Context) myContext;
169 //=======================================================================
170 typedef BOPCol_NCVector
171 <BOPAlgo_SplitEdge> BOPAlgo_VectorOfSplitEdge;
173 typedef BOPCol_ContextFunctor
175 BOPAlgo_VectorOfSplitEdge,
176 Handle(IntTools_Context),
177 IntTools_Context> BOPAlgo_SplitEdgeFunctor;
179 typedef BOPCol_ContextCnt
180 <BOPAlgo_SplitEdgeFunctor,
181 BOPAlgo_VectorOfSplitEdge,
182 Handle(IntTools_Context)> BOPAlgo_SplitEdgeCnt;
184 //=======================================================================
185 //class : BOPAlgo_MPC
187 //=======================================================================
188 class BOPAlgo_MPC : public BOPAlgo_Algo {
191 DEFINE_STANDARD_ALLOC
195 myFlag(Standard_False) {
198 virtual ~BOPAlgo_MPC(){
201 void SetEdge(const TopoDS_Edge& aE) {
205 const TopoDS_Edge& Edge() const {
209 void SetFace(const TopoDS_Face& aF) {
213 const TopoDS_Face& Face() const {
217 void SetFlag(const Standard_Boolean bFlag) {
221 Standard_Boolean Flag() const {
225 void SetData(const TopoDS_Edge& aEz,
226 const TopoDS_Vertex& aV1,
227 const Standard_Real aT1,
228 const TopoDS_Vertex& aV2,
229 const Standard_Real aT2) {
237 void SetContext(const Handle(IntTools_Context)& aContext) {
241 const Handle(IntTools_Context)& Context()const {
245 virtual void Perform() {
250 // Check if edge has pcurve. If no then make its copy to avoid data races,
251 // and use it to build pcurve.
252 TopoDS_Edge aCopyE = myE;
254 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(aCopyE, myF, f, l);
257 aCopyE = BOPTools_AlgoTools::CopyEdge(aCopyE);
259 Standard_Integer iErr = 1;
262 // Attach pcurve from the original edge
264 BOPTools_AlgoTools::MakeSplitEdge(myEz, myV1, myT1,
266 iErr = BOPTools_AlgoTools2D::AttachExistingPCurve(aSpz,
272 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aCopyE, myF, myContext);
274 myNewC2d = BRep_Tool::CurveOnSurface(aCopyE, myF, f, l);
275 if (myNewC2d.IsNull())
277 AddError(new BOPAlgo_AlertBuildingPCurveFailed(TopoDS_Shape()));
281 myNewTol = BRep_Tool::Tolerance(aCopyE);
285 UpdateVertices(aCopyE, myF);
288 catch (Standard_Failure)
290 AddError(new BOPAlgo_AlertBuildingPCurveFailed(TopoDS_Shape()));
294 const Handle(Geom2d_Curve)& GetNewPCurve() const
299 Standard_Real GetNewTolerance() const
305 Standard_Boolean myFlag;
313 Handle(Geom2d_Curve) myNewC2d;
314 Standard_Real myNewTol;
316 Handle(IntTools_Context) myContext;
319 //=======================================================================
320 typedef BOPCol_NCVector
321 <BOPAlgo_MPC> BOPAlgo_VectorOfMPC;
323 typedef BOPCol_ContextFunctor
326 Handle(IntTools_Context),
327 IntTools_Context> BOPAlgo_MPCFunctor;
329 typedef BOPCol_ContextCnt
332 Handle(IntTools_Context)> BOPAlgo_MPCCnt;
334 //=======================================================================
335 //class : BOPAlgo_BPC
337 //=======================================================================
346 void SetFace(const TopoDS_Face& aF) {
350 void SetEdge(const TopoDS_Edge& aE) {
354 const TopoDS_Edge& GetEdge() const {
357 const TopoDS_Face& GetFace() const {
360 const Handle(Geom2d_Curve)& GetCurve2d() const {
363 Standard_Boolean IsToUpdate() const {
368 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (myE, myF, myCurve, myToUpdate);
374 Handle(Geom2d_Curve) myCurve;
375 Standard_Boolean myToUpdate;
377 //=======================================================================
378 typedef BOPCol_NCVector
379 <BOPAlgo_BPC> BOPAlgo_VectorOfBPC;
381 typedef BOPCol_Functor
383 BOPAlgo_VectorOfBPC> BOPAlgo_BPCFunctor;
387 BOPAlgo_VectorOfBPC> BOPAlgo_BPCCnt;
390 //=======================================================================
391 // function: MakeSplitEdges
393 //=======================================================================
394 void BOPAlgo_PaveFiller::MakeSplitEdges()
396 BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
397 Standard_Integer aNbPBP = aPBP.Extent();
402 Standard_Boolean bCB, bV1, bV2;
403 Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, aNbVBSE, k;
404 Standard_Real aT1, aT2;
405 BOPDS_ListIteratorOfListOfPaveBlock aItPB;
406 Handle(BOPDS_PaveBlock) aPB;
407 BOPDS_MapOfPaveBlock aMPB(100);
408 TopoDS_Vertex aV1, aV2;
410 BOPAlgo_VectorOfSplitEdge aVBSE;
413 UpdateCommonBlocksWithSDVertices();
415 aNbPBP=aPBP.Extent();
417 for (i=0; i<aNbPBP; ++i) {
418 BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
423 aPB->Indices(nV1, nV2);
424 bV1=myDS->IsNewShape(nV1);
425 bV2=myDS->IsNewShape(nV2);
426 bCB=myDS->IsCommonBlock(aPB);
428 if (!(bV1 || bV2)) { // no new vertices here
429 if (!myNonDestructive || !bCB) {
431 if (!aPB->HasEdge()) {
432 const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
433 nE = aCB->PaveBlock1()->OriginalEdge();
435 // Compute tolerance of the common block and update the edge
436 Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, myDS, myContext);
437 myDS->UpdateEdgeTolerance(nE, aTol);
441 nE = aPB->OriginalEdge();
449 aItPB.Initialize(aLPB);
450 for (; aItPB.More(); aItPB.Next()) {
452 nE=aPB->OriginalEdge();
453 const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
458 const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
461 aPB=aCB->PaveBlock1();
465 nE=aPB->OriginalEdge();
466 aPB->Indices(nV1, nV2);
467 aPB->Range(aT1, aT2);
469 aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
470 aE.Orientation(TopAbs_FORWARD);
472 aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
473 aV1.Orientation(TopAbs_FORWARD);
475 aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
476 aV2.Orientation(TopAbs_REVERSED);
478 BOPAlgo_SplitEdge& aBSE=aVBSE.Append1();
480 aBSE.SetData(aE, aV1, aT1, aV2, aT2);
481 aBSE.SetPaveBlock(aPB);
483 aBSE.SetCommonBlock(aCB);
486 aBSE.SetProgressIndicator(myProgressIndicator);
488 } // for (; aItPB.More(); aItPB.Next()) {
489 } // for (i=0; i<aNbPBP; ++i) {
491 aNbVBSE=aVBSE.Extent();
492 //======================================================
493 BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE, myContext);
494 //======================================================
498 aSI.SetShapeType(TopAbs_EDGE);
500 for (k=0; k < aNbVBSE; ++k) {
501 BOPAlgo_SplitEdge& aBSE=aVBSE(k);
503 const TopoDS_Edge& aSp=aBSE.SplitEdge();
504 const Bnd_Box& aBox=aBSE.Box();
506 Handle(BOPDS_PaveBlock) aPBk=aBSE.PaveBlock();
507 Handle(BOPDS_CommonBlock)& aCBk=aBSE.CommonBlock();
510 aSI.ChangeBox()=aBox;
512 nSp=myDS->Append(aSI);
514 if (!aCBk.IsNull()) {
515 myDS->UpdateEdgeTolerance(nSp, aBSE.Tolerance());
524 //=======================================================================
525 // function: SplitEdge
527 //=======================================================================
528 Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE,
529 const Standard_Integer nV1,
530 const Standard_Real aT1,
531 const Standard_Integer nV2,
532 const Standard_Real aT2)
534 Standard_Integer nSp;
535 TopoDS_Vertex aV1, aV2;
539 aSI.SetShapeType(TopAbs_EDGE);
541 aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
542 aE.Orientation(TopAbs_FORWARD);
544 aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
545 aV1.Orientation(TopAbs_FORWARD);
547 aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
548 aV2.Orientation(TopAbs_REVERSED);
550 BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);
554 Bnd_Box& aBox=aSI.ChangeBox();
555 BRepBndLib::Add(aSp, aBox);
556 aBox.SetGap(aBox.GetGap() + Precision::Confusion());
558 nSp=myDS->Append(aSI);
561 //=======================================================================
562 // function: MakePCurves
564 //=======================================================================
565 void BOPAlgo_PaveFiller::MakePCurves()
567 if (myAvoidBuildPCurve ||
568 (!mySectionAttribute.PCurveOnS1() && !mySectionAttribute.PCurveOnS2()))
570 Standard_Boolean bHasPC;
571 Standard_Integer i, nF1, aNbC, k, nE, aNbFF, aNbFI, nEx;
572 Standard_Integer j, aNbPBIn, aNbPBOn;
573 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
574 TopoDS_Face aF1F, aF2F;
575 BOPAlgo_VectorOfMPC aVMPC;
577 // 1. Process Common Blocks
578 const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool();
581 for (i=0; i<aNbFI; ++i) {
582 const BOPDS_FaceInfo& aFI=aFIP(i);
585 aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
586 aF1F.Orientation(TopAbs_FORWARD);
588 const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
589 aNbPBIn = aMPBIn.Extent();
590 for (j = 1; j <= aNbPBIn; ++j) {
591 const Handle(BOPDS_PaveBlock)& aPB = aMPBIn(j);
593 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
595 BOPAlgo_MPC& aMPC=aVMPC.Append1();
598 aMPC.SetProgressIndicator(myProgressIndicator);
602 const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
603 aNbPBOn = aMPBOn.Extent();
604 for (j = 1; j <= aNbPBOn; ++j) {
605 const Handle(BOPDS_PaveBlock)& aPB = aMPBOn(j);
607 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
608 bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF1F);
613 Handle(BOPDS_CommonBlock) aCB=myDS->CommonBlock(aPB);
618 const BOPDS_ListOfPaveBlock& aLPB=aCB->PaveBlocks();
619 if (aLPB.Extent()<2) {
623 BOPAlgo_MPC& aMPC=aVMPC.Append1();
625 aItLPB.Initialize(aLPB);
626 for(; aItLPB.More(); aItLPB.Next()) {
627 const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
632 nEx=aPBx->OriginalEdge();
633 const TopoDS_Edge& aEx=(*(TopoDS_Edge *)(&myDS->Shape(nEx)));
634 bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aEx, aF1F);
639 Standard_Integer nV1x, nV2x;
640 Standard_Real aT1x, aT2x;
641 TopoDS_Vertex aV1x, aV2x;
645 aEz.Orientation(TopAbs_FORWARD);
647 aPBx->Indices(nV1x, nV2x);
648 aPBx->Range(aT1x, aT2x);
650 aV1x=(*(TopoDS_Vertex *)(&myDS->Shape(nV1x)));
651 aV1x.Orientation(TopAbs_FORWARD);
653 aV2x=(*(TopoDS_Vertex *)(&myDS->Shape(nV2x)));
654 aV2x.Orientation(TopAbs_REVERSED);
656 aMPC.SetData(aEz, aV1x, aT1x, aV2x, aT2x);
663 aMPC.SetProgressIndicator(myProgressIndicator);
665 }// for (i=0; i<aNbFI; ++i) {
667 // 2. Process section edges. P-curves on them must already be computed.
668 // However, we must provide the call to UpdateVertices.
669 Standard_Boolean bPCurveOnS[2];
670 bPCurveOnS[0]=mySectionAttribute.PCurveOnS1();
671 bPCurveOnS[1]=mySectionAttribute.PCurveOnS2();
673 if (bPCurveOnS[0] || bPCurveOnS[1]) {
674 // container to remember already added edge-face pairs
675 BOPDS_MapOfPair anEFPairs;
676 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
678 for (i=0; i<aNbFF; ++i) {
679 const BOPDS_InterfFF& aFF=aFFs(i);
680 const BOPDS_VectorOfCurve& aVNC = aFF.Curves();
681 aNbC = aVNC.Extent();
684 Standard_Integer nF[2];
685 aFF.Indices(nF[0], nF[1]);
688 aFf[0] = (*(TopoDS_Face *)(&myDS->Shape(nF[0])));
689 aFf[0].Orientation(TopAbs_FORWARD);
691 aFf[1]=(*(TopoDS_Face *)(&myDS->Shape(nF[1])));
692 aFf[1].Orientation(TopAbs_FORWARD);
694 for (k=0; k<aNbC; ++k)
696 const BOPDS_Curve& aNC=aVNC(k);
697 const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks();
698 aItLPB.Initialize(aLPB);
699 for(; aItLPB.More(); aItLPB.Next())
701 const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
703 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
705 for (Standard_Integer m = 0; m<2; ++m)
707 if (bPCurveOnS[m] && anEFPairs.Add(BOPDS_Pair(nE, nF[m])))
709 BOPAlgo_MPC& aMPC = aVMPC.Append1();
711 aMPC.SetFace(aFf[m]);
712 aMPC.SetFlag(Standard_True);
713 aMPC.SetProgressIndicator(myProgressIndicator);
718 }// for (i=0; i<aNbFF; ++i) {
719 }//if (bPCurveOnS1 || bPCurveOnS2 ) {
721 //======================================================
722 BOPAlgo_MPCCnt::Perform(myRunParallel, aVMPC, myContext);
723 //======================================================
725 // Add warnings of the failed projections and update edges with new pcurves
726 Standard_Integer aNb = aVMPC.Extent();
727 for (i = 0; i < aNb; ++i)
729 const BOPAlgo_MPC& aMPC = aVMPC(i);
730 if (aMPC.HasErrors())
733 BRep_Builder().MakeCompound(aWC);
734 BRep_Builder().Add(aWC, aMPC.Edge());
735 BRep_Builder().Add(aWC, aMPC.Face());
736 AddWarning(new BOPAlgo_AlertBuildingPCurveFailed(aWC));
740 const Handle(Geom2d_Curve)& aNewPC = aMPC.GetNewPCurve();
741 // if aNewPC is null we do not need to update the edge because it already contains
742 // valid p-curve, and only vertices have been updated.
743 if (!aNewPC.IsNull())
744 BRep_Builder().UpdateEdge(aMPC.Edge(), aNewPC, aMPC.Face(), aMPC.GetNewTolerance());
748 //=======================================================================
749 //function : UpdateVertices
750 //purpose : update tolerances of vertices comparing extremities of
752 //=======================================================================
753 void UpdateVertices(const TopoDS_Edge& aE,
754 const TopoDS_Face& aF)
757 Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD;
760 Handle(Geom_Surface) aS;
761 Handle(Geom_Curve) aC3D;
762 Handle(Geom2d_Curve) aC2D;
768 aEf.Orientation(TopAbs_FORWARD);
770 TopExp::Vertices(aEf, aV[0], aV[1]);
772 aS=BRep_Tool::Surface(aF);
773 aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]);
774 aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]);
776 for (j=0; j<2; ++j) {
777 aTolV2=BRep_Tool::Tolerance(aV[j]);
778 aTolV2=aTolV2*aTolV2;
780 aC3D->D0(aT[j], aP3D);
781 aC2D->D0(aT[j], aP2Dx);
782 aP2Dx.Coord(aUx, aVx);
783 aS->D0(aUx, aVx, aP3Dx);
784 aD2=aP3D.SquareDistance(aP3Dx);
787 aBB.UpdateVertex(aV[j], aD);
791 //=======================================================================
794 //=======================================================================
795 void BOPAlgo_PaveFiller::Prepare()
797 if (myNonDestructive) {
798 // do not allow storing pcurves in original edges if non-destructive mode is on
801 TopAbs_ShapeEnum aType[] = {
806 Standard_Boolean bIsBasedOnPlane;
807 Standard_Integer i, aNb, n1, nF, aNbF;
808 TopExp_Explorer aExp;
809 BOPCol_IndexedMapOfShape aMF;
812 for(i=0; i<aNb; ++i) {
813 myIterator->Initialize(aType[i], aType[2]);
814 for (; myIterator->More(); myIterator->Next()) {
815 myIterator->Value(n1, nF);
816 const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF)));
818 bIsBasedOnPlane=IsBasedOnPlane(aF);
819 if (bIsBasedOnPlane) {
830 // Build pcurves of edges on planes; first collect pairs edge-face.
831 BOPAlgo_VectorOfBPC aVBPC;
833 for (i = 1; i <= aNbF; ++i) {
834 const TopoDS_Face& aF = *(TopoDS_Face*)&aMF(i);
835 aExp.Init(aF, aType[1]);
836 for (; aExp.More(); aExp.Next()) {
837 const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
838 BOPAlgo_BPC& aBPC=aVBPC.Append1();
844 //======================================================
845 BOPAlgo_BPCCnt::Perform(myRunParallel, aVBPC);
846 //======================================================
848 // pcurves are built, and now update edges
851 for (i = 0; i < aVBPC.Extent(); i++) {
852 const BOPAlgo_BPC& aBPC=aVBPC(i);
853 if (aBPC.IsToUpdate()) {
854 Standard_Real aTolE = BRep_Tool::Tolerance(aBPC.GetEdge());
855 aBB.UpdateEdge(aBPC.GetEdge(), aBPC.GetCurve2d(), aBPC.GetFace(), aTolE);
859 //=======================================================================
860 //function : IsBasedOnPlane
862 //=======================================================================
863 Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF)
865 TopLoc_Location aLoc;
866 Handle(Geom_RectangularTrimmedSurface) aGRTS;
867 Handle(Geom_Plane) aGP;
869 const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF, aLoc);
870 aGRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
871 if(!aGRTS.IsNull()) {
872 aGP = Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
875 aGP = Handle(Geom_Plane)::DownCast(aS);
878 return (!aGP.IsNull());