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_MapOfCommonBlock.hxx>
30 #include <BOPDS_MapOfPair.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 <BOPTools_Parallel.hxx>
42 #include <BRepLib.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>
56 #include <NCollection_Vector.hxx>
58 #include <TopExp_Explorer.hxx>
60 #include <TopoDS_Edge.hxx>
61 #include <TopoDS_Face.hxx>
62 #include <TopoDS_Vertex.hxx>
63 #include <TopTools_IndexedMapOfShape.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 {
89 virtual ~BOPAlgo_SplitEdge() {
92 void SetData(const TopoDS_Edge& aE,
93 const TopoDS_Vertex& aV1,
94 const Standard_Real aT1,
95 const TopoDS_Vertex& aV2,
96 const Standard_Real aT2) {
105 void SetPaveBlock(const Handle(BOPDS_PaveBlock)& aPB) {
109 Handle(BOPDS_PaveBlock)& PaveBlock() {
113 void SetCommonBlock(const Handle(BOPDS_CommonBlock)& aCB) {
117 Handle(BOPDS_CommonBlock)& CommonBlock() {
121 const TopoDS_Edge& SplitEdge() const {
125 const Bnd_Box Box() {
129 Standard_Real Tolerance() const {
133 void SetDS(const BOPDS_PDS theDS) {
137 void SetContext(const Handle(IntTools_Context)& aContext) {
138 myContext = aContext;
141 virtual void Perform () {
142 BOPAlgo_Algo::UserBreak();
143 myTol = BOPAlgo_Tools::ComputeToleranceOfCB(myCB, myDS, myContext);
144 BOPTools_AlgoTools::MakeSplitEdge(myE,
148 BRepBndLib::Add(myESp, myBox);
149 myBox.SetGap(myBox.GetGap() + Precision::Confusion());
160 Handle(BOPDS_PaveBlock) myPB;
161 Handle(BOPDS_CommonBlock) myCB;
168 Handle(IntTools_Context) myContext;
171 //=======================================================================
172 typedef NCollection_Vector
173 <BOPAlgo_SplitEdge> BOPAlgo_VectorOfSplitEdge;
175 typedef BOPTools_ContextFunctor
177 BOPAlgo_VectorOfSplitEdge,
178 Handle(IntTools_Context),
179 IntTools_Context> BOPAlgo_SplitEdgeFunctor;
181 typedef BOPTools_ContextCnt
182 <BOPAlgo_SplitEdgeFunctor,
183 BOPAlgo_VectorOfSplitEdge,
184 Handle(IntTools_Context)> BOPAlgo_SplitEdgeCnt;
186 //=======================================================================
187 //class : BOPAlgo_MPC
189 //=======================================================================
190 class BOPAlgo_MPC : public BOPAlgo_Algo {
193 DEFINE_STANDARD_ALLOC
197 myFlag(Standard_False) {
200 virtual ~BOPAlgo_MPC(){
203 void SetEdge(const TopoDS_Edge& aE) {
207 const TopoDS_Edge& Edge() const {
211 void SetFace(const TopoDS_Face& aF) {
215 const TopoDS_Face& Face() const {
219 void SetFlag(const Standard_Boolean bFlag) {
223 Standard_Boolean Flag() const {
227 void SetData(const TopoDS_Edge& aEz,
228 const TopoDS_Vertex& aV1,
229 const Standard_Real aT1,
230 const TopoDS_Vertex& aV2,
231 const Standard_Real aT2) {
239 void SetContext(const Handle(IntTools_Context)& aContext) {
243 const Handle(IntTools_Context)& Context()const {
247 virtual void Perform() {
252 // Check if edge has pcurve. If no then make its copy to avoid data races,
253 // and use it to build pcurve.
254 TopoDS_Edge aCopyE = myE;
256 Handle(Geom2d_Curve) aC2d = BRep_Tool::CurveOnSurface(aCopyE, myF, f, l);
259 aCopyE = BOPTools_AlgoTools::CopyEdge(aCopyE);
261 Standard_Integer iErr = 1;
264 // Attach pcurve from the original edge
266 BOPTools_AlgoTools::MakeSplitEdge(myEz, myV1, myT1,
268 iErr = BOPTools_AlgoTools2D::AttachExistingPCurve(aSpz,
274 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(aCopyE, myF, myContext);
276 myNewC2d = BRep_Tool::CurveOnSurface(aCopyE, myF, f, l);
277 if (myNewC2d.IsNull())
279 AddError(new BOPAlgo_AlertBuildingPCurveFailed(TopoDS_Shape()));
283 myNewTol = BRep_Tool::Tolerance(aCopyE);
287 const BRepAdaptor_Surface& aBAS = myContext->SurfaceAdaptor(myF);
288 if (aBAS.IsUPeriodic() || aBAS.IsVPeriodic())
290 // The curve already exists. Adjust it for periodic cases.
291 BOPTools_AlgoTools2D::AdjustPCurveOnSurf
292 (myContext->SurfaceAdaptor(myF), f, l, aC2d, myNewC2d);
293 if (myNewC2d != aC2d)
294 myNewTol = BRep_Tool::Tolerance(aCopyE);
301 UpdateVertices(aCopyE, myF);
304 catch (Standard_Failure)
306 AddError(new BOPAlgo_AlertBuildingPCurveFailed(TopoDS_Shape()));
310 const Handle(Geom2d_Curve)& GetNewPCurve() const
315 Standard_Real GetNewTolerance() const
321 Standard_Boolean myFlag;
329 Handle(Geom2d_Curve) myNewC2d;
330 Standard_Real myNewTol;
332 Handle(IntTools_Context) myContext;
335 //=======================================================================
336 typedef NCollection_Vector
337 <BOPAlgo_MPC> BOPAlgo_VectorOfMPC;
339 typedef BOPTools_ContextFunctor
342 Handle(IntTools_Context),
343 IntTools_Context> BOPAlgo_MPCFunctor;
345 typedef BOPTools_ContextCnt
348 Handle(IntTools_Context)> BOPAlgo_MPCCnt;
350 //=======================================================================
351 //class : BOPAlgo_BPC
353 //=======================================================================
362 void SetFace(const TopoDS_Face& aF) {
366 void SetEdge(const TopoDS_Edge& aE) {
370 const TopoDS_Edge& GetEdge() const {
373 const TopoDS_Face& GetFace() const {
376 const Handle(Geom2d_Curve)& GetCurve2d() const {
379 Standard_Boolean IsToUpdate() const {
384 BRepLib::BuildPCurveForEdgeOnPlane(myE, myF, myCurve, myToUpdate);
390 Handle(Geom2d_Curve) myCurve;
391 Standard_Boolean myToUpdate;
393 //=======================================================================
394 typedef NCollection_Vector
395 <BOPAlgo_BPC> BOPAlgo_VectorOfBPC;
397 typedef BOPTools_Functor
399 BOPAlgo_VectorOfBPC> BOPAlgo_BPCFunctor;
403 BOPAlgo_VectorOfBPC> BOPAlgo_BPCCnt;
406 //=======================================================================
407 // function: MakeSplitEdges
409 //=======================================================================
410 void BOPAlgo_PaveFiller::MakeSplitEdges()
412 BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
413 Standard_Integer aNbPBP = aPBP.Length();
418 Standard_Integer i, nE, nV1, nV2, nSp, aNbVBSE, k;
419 Standard_Real aT1, aT2;
420 BOPDS_ListIteratorOfListOfPaveBlock aItPB;
421 Handle(BOPDS_PaveBlock) aPB;
422 BOPDS_MapOfCommonBlock aMCB(100);
423 TopoDS_Vertex aV1, aV2;
425 BOPAlgo_VectorOfSplitEdge aVBSE;
428 UpdateCommonBlocksWithSDVertices();
430 aNbPBP=aPBP.Length();
432 for (i = 0; i < aNbPBP; ++i)
434 BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
436 aItPB.Initialize(aLPB);
437 for (; aItPB.More(); aItPB.Next()) {
439 nE = aPB->OriginalEdge();
440 const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE);
443 // Skip degenerated edges
447 const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
448 Standard_Boolean bCB = !aCB.IsNull();
449 if (bCB && !aMCB.Add(aCB))
452 aPB->Indices(nV1, nV2);
453 // Check if it is necessary to make the split of the edge
455 Standard_Boolean bV1 = myDS->IsNewShape(nV1);
456 Standard_Boolean bV2 = myDS->IsNewShape(nV2);
458 Standard_Boolean bToSplit = Standard_True;
459 if (!bV1 && !bV2) // no new vertices here
461 if (!myNonDestructive || !bCB)
465 // Find the edge with these vertices
466 BOPDS_ListIteratorOfListOfPaveBlock it(aCB->PaveBlocks());
467 for (; it.More(); it.Next())
469 nE = it.Value()->OriginalEdge();
470 if (myDS->PaveBlocks(nE).Extent() == 1)
475 // The pave block is found
476 bToSplit = Standard_False;
477 aCB->SetRealPaveBlock(it.Value());
479 // Compute tolerance of the common block and update the edge
480 Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, myDS, myContext);
481 UpdateEdgeTolerance(nE, aTol);
484 else if (aLPB.Extent() == 1)
486 bToSplit = Standard_False;
498 aPB = aCB->PaveBlock1();
499 nE = aPB->OriginalEdge();
500 aPB->Indices(nV1, nV2);
502 aPB->Range(aT1, aT2);
504 aE = (*(TopoDS_Edge *)(&myDS->Shape(nE)));
505 aE.Orientation(TopAbs_FORWARD);
507 aV1 = (*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
508 aV1.Orientation(TopAbs_FORWARD);
510 aV2 = (*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
511 aV2.Orientation(TopAbs_REVERSED);
513 BOPAlgo_SplitEdge& aBSE = aVBSE.Appended();
515 aBSE.SetData(aE, aV1, aT1, aV2, aT2);
516 aBSE.SetPaveBlock(aPB);
518 aBSE.SetCommonBlock(aCB);
521 aBSE.SetProgressIndicator(myProgressIndicator);
522 } // for (; aItPB.More(); aItPB.Next()) {
523 } // for (i=0; i<aNbPBP; ++i) {
525 aNbVBSE=aVBSE.Length();
526 //======================================================
527 BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE, myContext);
528 //======================================================
530 for (k=0; k < aNbVBSE; ++k) {
531 BOPAlgo_SplitEdge& aBSE=aVBSE(k);
533 const TopoDS_Edge& aSp=aBSE.SplitEdge();
534 const Bnd_Box& aBox=aBSE.Box();
536 Handle(BOPDS_PaveBlock) aPBk=aBSE.PaveBlock();
537 Handle(BOPDS_CommonBlock)& aCBk=aBSE.CommonBlock();
540 aSI.SetShapeType(TopAbs_EDGE);
542 aSI.ChangeBox()=aBox;
543 TColStd_ListOfInteger& aSubShapes = aSI.ChangeSubShapes();
544 aSubShapes.Append(aPBk->Pave1().Index());
545 aSubShapes.Append(aPBk->Pave2().Index());
547 nSp=myDS->Append(aSI);
549 if (!aCBk.IsNull()) {
550 UpdateEdgeTolerance(nSp, aBSE.Tolerance());
559 //=======================================================================
560 // function: SplitEdge
562 //=======================================================================
563 Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE,
564 const Standard_Integer nV1,
565 const Standard_Real aT1,
566 const Standard_Integer nV2,
567 const Standard_Real aT2)
569 Standard_Integer nSp;
570 TopoDS_Vertex aV1, aV2;
574 aSI.SetShapeType(TopAbs_EDGE);
576 aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
577 aE.Orientation(TopAbs_FORWARD);
579 aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
580 aV1.Orientation(TopAbs_FORWARD);
582 aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
583 aV2.Orientation(TopAbs_REVERSED);
585 BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);
589 Bnd_Box& aBox=aSI.ChangeBox();
590 BRepBndLib::Add(aSp, aBox);
591 aBox.SetGap(aBox.GetGap() + Precision::Confusion());
593 nSp=myDS->Append(aSI);
596 //=======================================================================
597 // function: MakePCurves
599 //=======================================================================
600 void BOPAlgo_PaveFiller::MakePCurves()
602 if (myAvoidBuildPCurve ||
603 (!mySectionAttribute.PCurveOnS1() && !mySectionAttribute.PCurveOnS2()))
605 Standard_Boolean bHasPC;
606 Standard_Integer i, nF1, aNbC, k, nE, aNbFF, aNbFI, nEx;
607 Standard_Integer j, aNbPBIn, aNbPBOn;
608 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
609 TopoDS_Face aF1F, aF2F;
610 BOPAlgo_VectorOfMPC aVMPC;
612 // 1. Process Common Blocks
613 const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool();
616 for (i=0; i<aNbFI; ++i) {
617 const BOPDS_FaceInfo& aFI=aFIP(i);
620 aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
621 aF1F.Orientation(TopAbs_FORWARD);
623 const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
624 aNbPBIn = aMPBIn.Extent();
625 for (j = 1; j <= aNbPBIn; ++j) {
626 const Handle(BOPDS_PaveBlock)& aPB = aMPBIn(j);
628 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
630 BOPAlgo_MPC& aMPC=aVMPC.Appended();
633 aMPC.SetProgressIndicator(myProgressIndicator);
637 const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
638 aNbPBOn = aMPBOn.Extent();
639 for (j = 1; j <= aNbPBOn; ++j) {
640 const Handle(BOPDS_PaveBlock)& aPB = aMPBOn(j);
642 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
643 bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aE, aF1F);
648 BOPAlgo_MPC& aMPC = aVMPC.Appended();
650 Handle(BOPDS_CommonBlock) aCB = myDS->CommonBlock(aPB);
654 const BOPDS_ListOfPaveBlock& aLPB = aCB->PaveBlocks();
655 if (aLPB.Extent() >= 2)
657 aItLPB.Initialize(aLPB);
658 for(; aItLPB.More(); aItLPB.Next()) {
659 const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
664 nEx=aPBx->OriginalEdge();
665 const TopoDS_Edge& aEx=(*(TopoDS_Edge *)(&myDS->Shape(nEx)));
666 bHasPC=BOPTools_AlgoTools2D::HasCurveOnSurface (aEx, aF1F);
671 Standard_Integer nV1x, nV2x;
672 Standard_Real aT1x, aT2x;
673 TopoDS_Vertex aV1x, aV2x;
677 aEz.Orientation(TopAbs_FORWARD);
679 aPBx->Indices(nV1x, nV2x);
680 aPBx->Range(aT1x, aT2x);
682 aV1x=(*(TopoDS_Vertex *)(&myDS->Shape(nV1x)));
683 aV1x.Orientation(TopAbs_FORWARD);
685 aV2x=(*(TopoDS_Vertex *)(&myDS->Shape(nV2x)));
686 aV2x.Orientation(TopAbs_REVERSED);
688 aMPC.SetData(aEz, aV1x, aT1x, aV2x, aT2x);
697 aMPC.SetProgressIndicator(myProgressIndicator);
699 }// for (i=0; i<aNbFI; ++i) {
701 // 2. Process section edges. P-curves on them must already be computed.
702 // However, we must provide the call to UpdateVertices.
703 Standard_Boolean bPCurveOnS[2];
704 bPCurveOnS[0]=mySectionAttribute.PCurveOnS1();
705 bPCurveOnS[1]=mySectionAttribute.PCurveOnS2();
707 if (bPCurveOnS[0] || bPCurveOnS[1]) {
708 // container to remember already added edge-face pairs
709 BOPDS_MapOfPair anEFPairs;
710 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
712 for (i=0; i<aNbFF; ++i) {
713 const BOPDS_InterfFF& aFF=aFFs(i);
714 const BOPDS_VectorOfCurve& aVNC = aFF.Curves();
715 aNbC = aVNC.Length();
718 Standard_Integer nF[2];
719 aFF.Indices(nF[0], nF[1]);
722 aFf[0] = (*(TopoDS_Face *)(&myDS->Shape(nF[0])));
723 aFf[0].Orientation(TopAbs_FORWARD);
725 aFf[1]=(*(TopoDS_Face *)(&myDS->Shape(nF[1])));
726 aFf[1].Orientation(TopAbs_FORWARD);
728 for (k=0; k<aNbC; ++k)
730 const BOPDS_Curve& aNC=aVNC(k);
731 const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks();
732 aItLPB.Initialize(aLPB);
733 for(; aItLPB.More(); aItLPB.Next())
735 const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
737 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
739 for (Standard_Integer m = 0; m<2; ++m)
741 if (bPCurveOnS[m] && anEFPairs.Add(BOPDS_Pair(nE, nF[m])))
743 BOPAlgo_MPC& aMPC = aVMPC.Appended();
745 aMPC.SetFace(aFf[m]);
746 aMPC.SetFlag(Standard_True);
747 aMPC.SetProgressIndicator(myProgressIndicator);
752 }// for (i=0; i<aNbFF; ++i) {
753 }//if (bPCurveOnS1 || bPCurveOnS2 ) {
755 //======================================================
756 BOPAlgo_MPCCnt::Perform(myRunParallel, aVMPC, myContext);
757 //======================================================
759 // Add warnings of the failed projections and update edges with new pcurves
760 Standard_Integer aNb = aVMPC.Length();
761 for (i = 0; i < aNb; ++i)
763 const BOPAlgo_MPC& aMPC = aVMPC(i);
764 if (aMPC.HasErrors())
767 BRep_Builder().MakeCompound(aWC);
768 BRep_Builder().Add(aWC, aMPC.Edge());
769 BRep_Builder().Add(aWC, aMPC.Face());
770 AddWarning(new BOPAlgo_AlertBuildingPCurveFailed(aWC));
774 const Handle(Geom2d_Curve)& aNewPC = aMPC.GetNewPCurve();
775 // if aNewPC is null we do not need to update the edge because it already contains
776 // valid p-curve, and only vertices have been updated.
777 if (!aNewPC.IsNull())
778 BRep_Builder().UpdateEdge(aMPC.Edge(), aNewPC, aMPC.Face(), aMPC.GetNewTolerance());
782 //=======================================================================
783 //function : UpdateVertices
784 //purpose : update tolerances of vertices comparing extremities of
786 //=======================================================================
787 void UpdateVertices(const TopoDS_Edge& aE,
788 const TopoDS_Face& aF)
791 Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD;
794 Handle(Geom_Surface) aS;
795 Handle(Geom_Curve) aC3D;
796 Handle(Geom2d_Curve) aC2D;
802 aEf.Orientation(TopAbs_FORWARD);
804 TopExp::Vertices(aEf, aV[0], aV[1]);
806 aS=BRep_Tool::Surface(aF);
807 aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]);
808 aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]);
810 for (j=0; j<2; ++j) {
811 aTolV2=BRep_Tool::Tolerance(aV[j]);
812 aTolV2=aTolV2*aTolV2;
814 aC3D->D0(aT[j], aP3D);
815 aC2D->D0(aT[j], aP2Dx);
816 aP2Dx.Coord(aUx, aVx);
817 aS->D0(aUx, aVx, aP3Dx);
818 aD2=aP3D.SquareDistance(aP3Dx);
821 aBB.UpdateVertex(aV[j], aD);
825 //=======================================================================
828 //=======================================================================
829 void BOPAlgo_PaveFiller::Prepare()
831 if (myNonDestructive) {
832 // do not allow storing pcurves in original edges if non-destructive mode is on
835 TopAbs_ShapeEnum aType[] = {
840 Standard_Boolean bIsBasedOnPlane;
841 Standard_Integer i, aNb, n1, nF, aNbF;
842 TopExp_Explorer aExp;
843 TopTools_IndexedMapOfShape aMF;
846 for(i=0; i<aNb; ++i) {
847 myIterator->Initialize(aType[i], aType[2]);
848 for (; myIterator->More(); myIterator->Next()) {
849 myIterator->Value(n1, nF);
850 const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF)));
852 bIsBasedOnPlane=IsBasedOnPlane(aF);
853 if (bIsBasedOnPlane) {
864 // Build pcurves of edges on planes; first collect pairs edge-face.
865 BOPAlgo_VectorOfBPC aVBPC;
867 for (i = 1; i <= aNbF; ++i) {
868 const TopoDS_Face& aF = *(TopoDS_Face*)&aMF(i);
869 aExp.Init(aF, aType[1]);
870 for (; aExp.More(); aExp.Next()) {
871 const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
872 BOPAlgo_BPC& aBPC=aVBPC.Appended();
878 //======================================================
879 BOPAlgo_BPCCnt::Perform(myRunParallel, aVBPC);
880 //======================================================
882 // pcurves are built, and now update edges
885 for (i = 0; i < aVBPC.Length(); i++) {
886 const BOPAlgo_BPC& aBPC=aVBPC(i);
887 if (aBPC.IsToUpdate()) {
888 Standard_Real aTolE = BRep_Tool::Tolerance(aBPC.GetEdge());
889 aBB.UpdateEdge(aBPC.GetEdge(), aBPC.GetCurve2d(), aBPC.GetFace(), aTolE);
893 //=======================================================================
894 //function : IsBasedOnPlane
896 //=======================================================================
897 Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF)
899 TopLoc_Location aLoc;
900 Handle(Geom_RectangularTrimmedSurface) aGRTS;
901 Handle(Geom_Plane) aGP;
903 const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF, aLoc);
904 aGRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
905 if(!aGRTS.IsNull()) {
906 aGP = Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
909 aGP = Handle(Geom_Plane)::DownCast(aS);
912 return (!aGP.IsNull());