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 <BOPDS_CommonBlock.hxx>
23 #include <BOPDS_Curve.hxx>
24 #include <BOPDS_DS.hxx>
25 #include <BOPDS_FaceInfo.hxx>
26 #include <BOPDS_Interf.hxx>
27 #include <BOPDS_Iterator.hxx>
28 #include <BOPDS_ListOfPaveBlock.hxx>
29 #include <BOPDS_MapOfPair.hxx>
30 #include <BOPDS_MapOfPaveBlock.hxx>
31 #include <BOPDS_Pave.hxx>
32 #include <BOPDS_PaveBlock.hxx>
33 #include <BOPDS_ShapeInfo.hxx>
34 #include <BOPDS_VectorOfCurve.hxx>
35 #include <BOPDS_VectorOfFaceInfo.hxx>
36 #include <BOPDS_VectorOfInterfFF.hxx>
37 #include <BOPDS_VectorOfListOfPaveBlock.hxx>
38 #include <BOPTools_AlgoTools.hxx>
39 #include <BOPTools_AlgoTools2D.hxx>
40 #include <BOPTools_Parallel.hxx>
41 #include <BRepLib.hxx>
42 #include <BRep_Builder.hxx>
43 #include <BRep_Tool.hxx>
44 #include <BRepBndLib.hxx>
45 #include <Geom2d_Curve.hxx>
46 #include <Geom_Curve.hxx>
47 #include <Geom_Plane.hxx>
48 #include <Geom_RectangularTrimmedSurface.hxx>
49 #include <Geom_Surface.hxx>
50 #include <GeomAPI_ProjectPointOnCurve.hxx>
51 #include <GeomAPI_ProjectPointOnSurf.hxx>
53 #include <IntTools_Context.hxx>
54 #include <IntTools_Tools.hxx>
55 #include <NCollection_Vector.hxx>
57 #include <TopExp_Explorer.hxx>
59 #include <TopoDS_Edge.hxx>
60 #include <TopoDS_Face.hxx>
61 #include <TopoDS_Vertex.hxx>
62 #include <TopTools_IndexedMapOfShape.hxx>
66 Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF);
69 static void UpdateVertices(const TopoDS_Edge& aE,
70 const TopoDS_Face& aF);
72 //=======================================================================
73 //class : BOPAlgo_SplitEdge
75 //=======================================================================
76 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 Standard_Real Tolerance() const {
132 void SetDS(const BOPDS_PDS theDS) {
136 void SetContext(const Handle(IntTools_Context)& aContext) {
137 myContext = aContext;
140 virtual void Perform () {
141 BOPAlgo_Algo::UserBreak();
142 myTol = BOPAlgo_Tools::ComputeToleranceOfCB(myCB, myDS, myContext);
143 BOPTools_AlgoTools::MakeSplitEdge(myE,
147 BRepBndLib::Add(myESp, myBox);
148 myBox.SetGap(myBox.GetGap() + Precision::Confusion());
159 Handle(BOPDS_PaveBlock) myPB;
160 Handle(BOPDS_CommonBlock) myCB;
167 Handle(IntTools_Context) myContext;
170 //=======================================================================
171 typedef NCollection_Vector
172 <BOPAlgo_SplitEdge> BOPAlgo_VectorOfSplitEdge;
174 typedef BOPTools_ContextFunctor
176 BOPAlgo_VectorOfSplitEdge,
177 Handle(IntTools_Context),
178 IntTools_Context> BOPAlgo_SplitEdgeFunctor;
180 typedef BOPTools_ContextCnt
181 <BOPAlgo_SplitEdgeFunctor,
182 BOPAlgo_VectorOfSplitEdge,
183 Handle(IntTools_Context)> BOPAlgo_SplitEdgeCnt;
185 //=======================================================================
186 //class : BOPAlgo_MPC
188 //=======================================================================
189 class BOPAlgo_MPC : public BOPAlgo_Algo {
192 DEFINE_STANDARD_ALLOC
196 myFlag(Standard_False) {
199 virtual ~BOPAlgo_MPC(){
202 void SetEdge(const TopoDS_Edge& aE) {
206 const TopoDS_Edge& Edge() const {
210 void SetFace(const TopoDS_Face& aF) {
214 const TopoDS_Face& Face() const {
218 void SetFlag(const Standard_Boolean bFlag) {
222 Standard_Boolean Flag() const {
226 void SetData(const TopoDS_Edge& aEz,
227 const TopoDS_Vertex& aV1,
228 const Standard_Real aT1,
229 const TopoDS_Vertex& aV2,
230 const Standard_Real aT2) {
238 void SetContext(const Handle(IntTools_Context)& aContext) {
242 const Handle(IntTools_Context)& Context()const {
246 virtual void Perform() {
251 // Check if edge has pcurve. If no then make its copy to avoid data races,
252 // and use it to build pcurve.
253 TopoDS_Edge aCopyE = myE;
255 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(aCopyE, myF, f, l);
258 aCopyE = BOPTools_AlgoTools::CopyEdge(aCopyE);
260 Standard_Integer iErr = 1;
263 // Attach pcurve from the original edge
265 BOPTools_AlgoTools::MakeSplitEdge(myEz, myV1, myT1,
267 iErr = BOPTools_AlgoTools2D::AttachExistingPCurve(aSpz,
273 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aCopyE, myF, myContext);
275 myNewC2d = BRep_Tool::CurveOnSurface(aCopyE, myF, f, l);
276 if (myNewC2d.IsNull())
278 AddError(new BOPAlgo_AlertBuildingPCurveFailed(TopoDS_Shape()));
282 myNewTol = BRep_Tool::Tolerance(aCopyE);
286 const BRepAdaptor_Surface& aBAS = myContext->SurfaceAdaptor(myF);
287 if (aBAS.IsUPeriodic() || aBAS.IsVPeriodic())
289 // The curve already exists. Adjust it for periodic cases.
290 BOPTools_AlgoTools2D::AdjustPCurveOnSurf
291 (myContext->SurfaceAdaptor(myF), f, l, aC2d, myNewC2d);
292 if (myNewC2d != aC2d)
293 myNewTol = BRep_Tool::Tolerance(aCopyE);
300 UpdateVertices(aCopyE, myF);
303 catch (Standard_Failure)
305 AddError(new BOPAlgo_AlertBuildingPCurveFailed(TopoDS_Shape()));
309 const Handle(Geom2d_Curve)& GetNewPCurve() const
314 Standard_Real GetNewTolerance() const
320 Standard_Boolean myFlag;
328 Handle(Geom2d_Curve) myNewC2d;
329 Standard_Real myNewTol;
331 Handle(IntTools_Context) myContext;
334 //=======================================================================
335 typedef NCollection_Vector
336 <BOPAlgo_MPC> BOPAlgo_VectorOfMPC;
338 typedef BOPTools_ContextFunctor
341 Handle(IntTools_Context),
342 IntTools_Context> BOPAlgo_MPCFunctor;
344 typedef BOPTools_ContextCnt
347 Handle(IntTools_Context)> BOPAlgo_MPCCnt;
349 //=======================================================================
350 //class : BOPAlgo_BPC
352 //=======================================================================
361 void SetFace(const TopoDS_Face& aF) {
365 void SetEdge(const TopoDS_Edge& aE) {
369 const TopoDS_Edge& GetEdge() const {
372 const TopoDS_Face& GetFace() const {
375 const Handle(Geom2d_Curve)& GetCurve2d() const {
378 Standard_Boolean IsToUpdate() const {
383 BRepLib::BuildPCurveForEdgeOnPlane(myE, myF, myCurve, myToUpdate);
389 Handle(Geom2d_Curve) myCurve;
390 Standard_Boolean myToUpdate;
392 //=======================================================================
393 typedef NCollection_Vector
394 <BOPAlgo_BPC> BOPAlgo_VectorOfBPC;
396 typedef BOPTools_Functor
398 BOPAlgo_VectorOfBPC> BOPAlgo_BPCFunctor;
402 BOPAlgo_VectorOfBPC> BOPAlgo_BPCCnt;
405 //=======================================================================
406 // function: MakeSplitEdges
408 //=======================================================================
409 void BOPAlgo_PaveFiller::MakeSplitEdges()
411 BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
412 Standard_Integer aNbPBP = aPBP.Length();
417 Standard_Boolean bCB, bV1, bV2;
418 Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, aNbVBSE, k;
419 Standard_Real aT1, aT2;
420 BOPDS_ListIteratorOfListOfPaveBlock aItPB;
421 Handle(BOPDS_PaveBlock) aPB;
422 BOPDS_MapOfPaveBlock aMPB(100);
423 TopoDS_Vertex aV1, aV2;
425 BOPAlgo_VectorOfSplitEdge aVBSE;
428 UpdateCommonBlocksWithSDVertices();
430 aNbPBP=aPBP.Length();
432 for (i=0; i<aNbPBP; ++i) {
433 BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
438 aPB->Indices(nV1, nV2);
439 bV1=myDS->IsNewShape(nV1);
440 bV2=myDS->IsNewShape(nV2);
441 bCB=myDS->IsCommonBlock(aPB);
443 if (!(bV1 || bV2)) { // no new vertices here
444 if (!myNonDestructive || !bCB) {
446 if (!aPB->HasEdge()) {
447 const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
448 nE = aCB->PaveBlock1()->OriginalEdge();
450 // Compute tolerance of the common block and update the edge
451 Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, myDS, myContext);
452 myDS->UpdateEdgeTolerance(nE, aTol);
456 nE = aPB->OriginalEdge();
464 aItPB.Initialize(aLPB);
465 for (; aItPB.More(); aItPB.Next()) {
467 nE=aPB->OriginalEdge();
468 const BOPDS_ShapeInfo& aSIE=myDS->ShapeInfo(nE);
473 const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
476 aPB=aCB->PaveBlock1();
480 nE=aPB->OriginalEdge();
481 aPB->Indices(nV1, nV2);
482 aPB->Range(aT1, aT2);
484 aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
485 aE.Orientation(TopAbs_FORWARD);
487 aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
488 aV1.Orientation(TopAbs_FORWARD);
490 aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
491 aV2.Orientation(TopAbs_REVERSED);
493 BOPAlgo_SplitEdge& aBSE=aVBSE.Appended();
495 aBSE.SetData(aE, aV1, aT1, aV2, aT2);
496 aBSE.SetPaveBlock(aPB);
498 aBSE.SetCommonBlock(aCB);
501 aBSE.SetProgressIndicator(myProgressIndicator);
503 } // for (; aItPB.More(); aItPB.Next()) {
504 } // for (i=0; i<aNbPBP; ++i) {
506 aNbVBSE=aVBSE.Length();
507 //======================================================
508 BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE, myContext);
509 //======================================================
513 aSI.SetShapeType(TopAbs_EDGE);
515 for (k=0; k < aNbVBSE; ++k) {
516 BOPAlgo_SplitEdge& aBSE=aVBSE(k);
518 const TopoDS_Edge& aSp=aBSE.SplitEdge();
519 const Bnd_Box& aBox=aBSE.Box();
521 Handle(BOPDS_PaveBlock) aPBk=aBSE.PaveBlock();
522 Handle(BOPDS_CommonBlock)& aCBk=aBSE.CommonBlock();
525 aSI.ChangeBox()=aBox;
527 nSp=myDS->Append(aSI);
529 if (!aCBk.IsNull()) {
530 myDS->UpdateEdgeTolerance(nSp, aBSE.Tolerance());
539 //=======================================================================
540 // function: SplitEdge
542 //=======================================================================
543 Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE,
544 const Standard_Integer nV1,
545 const Standard_Real aT1,
546 const Standard_Integer nV2,
547 const Standard_Real aT2)
549 Standard_Integer nSp;
550 TopoDS_Vertex aV1, aV2;
554 aSI.SetShapeType(TopAbs_EDGE);
556 aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
557 aE.Orientation(TopAbs_FORWARD);
559 aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
560 aV1.Orientation(TopAbs_FORWARD);
562 aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
563 aV2.Orientation(TopAbs_REVERSED);
565 BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);
569 Bnd_Box& aBox=aSI.ChangeBox();
570 BRepBndLib::Add(aSp, aBox);
571 aBox.SetGap(aBox.GetGap() + Precision::Confusion());
573 nSp=myDS->Append(aSI);
576 //=======================================================================
577 // function: MakePCurves
579 //=======================================================================
580 void BOPAlgo_PaveFiller::MakePCurves()
582 if (myAvoidBuildPCurve ||
583 (!mySectionAttribute.PCurveOnS1() && !mySectionAttribute.PCurveOnS2()))
585 Standard_Boolean bHasPC;
586 Standard_Integer i, nF1, aNbC, k, nE, aNbFF, aNbFI, nEx;
587 Standard_Integer j, aNbPBIn, aNbPBOn;
588 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
589 TopoDS_Face aF1F, aF2F;
590 BOPAlgo_VectorOfMPC aVMPC;
592 // 1. Process Common Blocks
593 const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool();
596 for (i=0; i<aNbFI; ++i) {
597 const BOPDS_FaceInfo& aFI=aFIP(i);
600 aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
601 aF1F.Orientation(TopAbs_FORWARD);
603 const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
604 aNbPBIn = aMPBIn.Extent();
605 for (j = 1; j <= aNbPBIn; ++j) {
606 const Handle(BOPDS_PaveBlock)& aPB = aMPBIn(j);
608 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
610 BOPAlgo_MPC& aMPC=aVMPC.Appended();
613 aMPC.SetProgressIndicator(myProgressIndicator);
617 const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
618 aNbPBOn = aMPBOn.Extent();
619 for (j = 1; j <= aNbPBOn; ++j) {
620 const Handle(BOPDS_PaveBlock)& aPB = aMPBOn(j);
622 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
623 bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF1F);
628 Handle(BOPDS_CommonBlock) aCB=myDS->CommonBlock(aPB);
633 const BOPDS_ListOfPaveBlock& aLPB=aCB->PaveBlocks();
634 if (aLPB.Extent()<2) {
638 BOPAlgo_MPC& aMPC=aVMPC.Appended();
640 aItLPB.Initialize(aLPB);
641 for(; aItLPB.More(); aItLPB.Next()) {
642 const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
647 nEx=aPBx->OriginalEdge();
648 const TopoDS_Edge& aEx=(*(TopoDS_Edge *)(&myDS->Shape(nEx)));
649 bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aEx, aF1F);
654 Standard_Integer nV1x, nV2x;
655 Standard_Real aT1x, aT2x;
656 TopoDS_Vertex aV1x, aV2x;
660 aEz.Orientation(TopAbs_FORWARD);
662 aPBx->Indices(nV1x, nV2x);
663 aPBx->Range(aT1x, aT2x);
665 aV1x=(*(TopoDS_Vertex *)(&myDS->Shape(nV1x)));
666 aV1x.Orientation(TopAbs_FORWARD);
668 aV2x=(*(TopoDS_Vertex *)(&myDS->Shape(nV2x)));
669 aV2x.Orientation(TopAbs_REVERSED);
671 aMPC.SetData(aEz, aV1x, aT1x, aV2x, aT2x);
678 aMPC.SetProgressIndicator(myProgressIndicator);
680 }// for (i=0; i<aNbFI; ++i) {
682 // 2. Process section edges. P-curves on them must already be computed.
683 // However, we must provide the call to UpdateVertices.
684 Standard_Boolean bPCurveOnS[2];
685 bPCurveOnS[0]=mySectionAttribute.PCurveOnS1();
686 bPCurveOnS[1]=mySectionAttribute.PCurveOnS2();
688 if (bPCurveOnS[0] || bPCurveOnS[1]) {
689 // container to remember already added edge-face pairs
690 BOPDS_MapOfPair anEFPairs;
691 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
693 for (i=0; i<aNbFF; ++i) {
694 const BOPDS_InterfFF& aFF=aFFs(i);
695 const BOPDS_VectorOfCurve& aVNC = aFF.Curves();
696 aNbC = aVNC.Length();
699 Standard_Integer nF[2];
700 aFF.Indices(nF[0], nF[1]);
703 aFf[0] = (*(TopoDS_Face *)(&myDS->Shape(nF[0])));
704 aFf[0].Orientation(TopAbs_FORWARD);
706 aFf[1]=(*(TopoDS_Face *)(&myDS->Shape(nF[1])));
707 aFf[1].Orientation(TopAbs_FORWARD);
709 for (k=0; k<aNbC; ++k)
711 const BOPDS_Curve& aNC=aVNC(k);
712 const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks();
713 aItLPB.Initialize(aLPB);
714 for(; aItLPB.More(); aItLPB.Next())
716 const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
718 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
720 for (Standard_Integer m = 0; m<2; ++m)
722 if (bPCurveOnS[m] && anEFPairs.Add(BOPDS_Pair(nE, nF[m])))
724 BOPAlgo_MPC& aMPC = aVMPC.Appended();
726 aMPC.SetFace(aFf[m]);
727 aMPC.SetFlag(Standard_True);
728 aMPC.SetProgressIndicator(myProgressIndicator);
733 }// for (i=0; i<aNbFF; ++i) {
734 }//if (bPCurveOnS1 || bPCurveOnS2 ) {
736 //======================================================
737 BOPAlgo_MPCCnt::Perform(myRunParallel, aVMPC, myContext);
738 //======================================================
740 // Add warnings of the failed projections and update edges with new pcurves
741 Standard_Integer aNb = aVMPC.Length();
742 for (i = 0; i < aNb; ++i)
744 const BOPAlgo_MPC& aMPC = aVMPC(i);
745 if (aMPC.HasErrors())
748 BRep_Builder().MakeCompound(aWC);
749 BRep_Builder().Add(aWC, aMPC.Edge());
750 BRep_Builder().Add(aWC, aMPC.Face());
751 AddWarning(new BOPAlgo_AlertBuildingPCurveFailed(aWC));
755 const Handle(Geom2d_Curve)& aNewPC = aMPC.GetNewPCurve();
756 // if aNewPC is null we do not need to update the edge because it already contains
757 // valid p-curve, and only vertices have been updated.
758 if (!aNewPC.IsNull())
759 BRep_Builder().UpdateEdge(aMPC.Edge(), aNewPC, aMPC.Face(), aMPC.GetNewTolerance());
763 //=======================================================================
764 //function : UpdateVertices
765 //purpose : update tolerances of vertices comparing extremities of
767 //=======================================================================
768 void UpdateVertices(const TopoDS_Edge& aE,
769 const TopoDS_Face& aF)
772 Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD;
775 Handle(Geom_Surface) aS;
776 Handle(Geom_Curve) aC3D;
777 Handle(Geom2d_Curve) aC2D;
783 aEf.Orientation(TopAbs_FORWARD);
785 TopExp::Vertices(aEf, aV[0], aV[1]);
787 aS=BRep_Tool::Surface(aF);
788 aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]);
789 aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]);
791 for (j=0; j<2; ++j) {
792 aTolV2=BRep_Tool::Tolerance(aV[j]);
793 aTolV2=aTolV2*aTolV2;
795 aC3D->D0(aT[j], aP3D);
796 aC2D->D0(aT[j], aP2Dx);
797 aP2Dx.Coord(aUx, aVx);
798 aS->D0(aUx, aVx, aP3Dx);
799 aD2=aP3D.SquareDistance(aP3Dx);
802 aBB.UpdateVertex(aV[j], aD);
806 //=======================================================================
809 //=======================================================================
810 void BOPAlgo_PaveFiller::Prepare()
812 if (myNonDestructive) {
813 // do not allow storing pcurves in original edges if non-destructive mode is on
816 TopAbs_ShapeEnum aType[] = {
821 Standard_Boolean bIsBasedOnPlane;
822 Standard_Integer i, aNb, n1, nF, aNbF;
823 TopExp_Explorer aExp;
824 TopTools_IndexedMapOfShape aMF;
827 for(i=0; i<aNb; ++i) {
828 myIterator->Initialize(aType[i], aType[2]);
829 for (; myIterator->More(); myIterator->Next()) {
830 myIterator->Value(n1, nF);
831 const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF)));
833 bIsBasedOnPlane=IsBasedOnPlane(aF);
834 if (bIsBasedOnPlane) {
845 // Build pcurves of edges on planes; first collect pairs edge-face.
846 BOPAlgo_VectorOfBPC aVBPC;
848 for (i = 1; i <= aNbF; ++i) {
849 const TopoDS_Face& aF = *(TopoDS_Face*)&aMF(i);
850 aExp.Init(aF, aType[1]);
851 for (; aExp.More(); aExp.Next()) {
852 const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
853 BOPAlgo_BPC& aBPC=aVBPC.Appended();
859 //======================================================
860 BOPAlgo_BPCCnt::Perform(myRunParallel, aVBPC);
861 //======================================================
863 // pcurves are built, and now update edges
866 for (i = 0; i < aVBPC.Length(); i++) {
867 const BOPAlgo_BPC& aBPC=aVBPC(i);
868 if (aBPC.IsToUpdate()) {
869 Standard_Real aTolE = BRep_Tool::Tolerance(aBPC.GetEdge());
870 aBB.UpdateEdge(aBPC.GetEdge(), aBPC.GetCurve2d(), aBPC.GetFace(), aTolE);
874 //=======================================================================
875 //function : IsBasedOnPlane
877 //=======================================================================
878 Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF)
880 TopLoc_Location aLoc;
881 Handle(Geom_RectangularTrimmedSurface) aGRTS;
882 Handle(Geom_Plane) aGP;
884 const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF, aLoc);
885 aGRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
886 if(!aGRTS.IsNull()) {
887 aGP = Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
890 aGP = Handle(Geom_Plane)::DownCast(aS);
893 return (!aGP.IsNull());