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_TBB.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_TBBFunctor
158 BOPAlgo_VectorOfSplitEdge> BOPAlgo_SplitEdgeFunctor;
160 typedef BOPCol_TBBCnt
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 virtual void Perform() {
206 BOPAlgo_Algo::UserBreak();
207 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnFace(myE, myF);
209 UpdateVertices(myE, myF);
214 Standard_Boolean myFlag;
219 //=======================================================================
220 typedef BOPCol_NCVector
221 <BOPAlgo_MPC> BOPAlgo_VectorOfMPC;
223 typedef BOPCol_TBBFunctor
225 BOPAlgo_VectorOfMPC> BOPAlgo_MPCFunctor;
227 typedef BOPCol_TBBCnt
229 BOPAlgo_VectorOfMPC> BOPAlgo_MPCCnt;
231 //=======================================================================
232 //class : BOPAlgo_BPC
234 //=======================================================================
243 void SetFace(const TopoDS_Face& aF) {
247 void SetEdge(const TopoDS_Edge& aE) {
252 BOPTools_AlgoTools2D::BuildPCurveForEdgeOnPlane (myE, myF);
259 //=======================================================================
260 typedef BOPCol_NCVector
261 <BOPAlgo_BPC> BOPAlgo_VectorOfBPC;
263 typedef BOPCol_TBBFunctor
265 BOPAlgo_VectorOfBPC> BOPAlgo_BPCFunctor;
267 typedef BOPCol_TBBCnt
269 BOPAlgo_VectorOfBPC> BOPAlgo_BPCCnt;
272 //=======================================================================
273 // function: MakeSplitEdges
275 //=======================================================================
276 void BOPAlgo_PaveFiller::MakeSplitEdges()
278 Standard_Integer aNbPBP;
282 BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
283 aNbPBP=aPBP.Extent();
288 Standard_Boolean bCB, bV1, bV2;
289 Standard_Integer i, nE, nV1, nV2, nSp, aNbPB, aNbVBSE, k;
290 Standard_Real aT1, aT2;
291 BOPDS_ListIteratorOfListOfPaveBlock aItPB, aItPBCB;
292 Handle(BOPDS_PaveBlock) aPB;
293 BOPDS_MapOfPaveBlock aMPB(100);
294 TopoDS_Vertex aV1, aV2;
296 BOPAlgo_VectorOfSplitEdge aVBSE;
299 for (i=0; i<aNbPBP; ++i) {
300 BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
305 aPB->Indices(nV1, nV2);
306 bV1=myDS->IsNewShape(nV1);
307 bV2=myDS->IsNewShape(nV2);
310 nE=aPB->OriginalEdge();
316 aItPB.Initialize(aLPB);
317 for (; aItPB.More(); aItPB.Next()) {
319 const Handle(BOPDS_CommonBlock)& aCB=myDS->CommonBlock(aPB);
322 myDS->SortPaveBlocks(aCB);
323 aPB=aCB->PaveBlock1();
327 nE=aPB->OriginalEdge();
328 aPB->Indices(nV1, nV2);
329 aPB->Range(aT1, aT2);
331 aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
332 aE.Orientation(TopAbs_FORWARD);
334 aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
335 aV1.Orientation(TopAbs_FORWARD);
337 aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
338 aV2.Orientation(TopAbs_REVERSED);
340 BOPAlgo_SplitEdge& aBSE=aVBSE.Append1();
342 aBSE.SetData(aE, aV1, aT1, aV2, aT2);
343 aBSE.SetPaveBlock(aPB);
345 aBSE.SetCommonBlock(aCB);
347 aBSE.SetProgressIndicator(myProgressIndicator);
349 } // for (; aItPB.More(); aItPB.Next()) {
350 } // for (i=0; i<aNbPBP; ++i) {
352 aNbVBSE=aVBSE.Extent();
353 //======================================================
354 BOPAlgo_SplitEdgeCnt::Perform(myRunParallel, aVBSE);
355 //======================================================
359 aSI.SetShapeType(TopAbs_EDGE);
361 for (k=0; k < aNbVBSE; ++k) {
362 BOPAlgo_SplitEdge& aBSE=aVBSE(k);
364 const TopoDS_Edge& aSp=aBSE.SplitEdge();
365 const Bnd_Box& aBox=aBSE.Box();
367 Handle(BOPDS_PaveBlock) aPBk=aBSE.PaveBlock();
368 Handle(BOPDS_CommonBlock)& aCBk=aBSE.CommonBlock();
371 aSI.ChangeBox()=aBox;
373 nSp=myDS->Append(aSI);
375 if (!aCBk.IsNull()) {
383 //=======================================================================
384 // function: SplitEdge
386 //=======================================================================
387 Standard_Integer BOPAlgo_PaveFiller::SplitEdge(const Standard_Integer nE,
388 const Standard_Integer nV1,
389 const Standard_Real aT1,
390 const Standard_Integer nV2,
391 const Standard_Real aT2)
393 Standard_Integer nSp;
394 TopoDS_Vertex aV1, aV2;
398 aSI.SetShapeType(TopAbs_EDGE);
400 aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
401 aE.Orientation(TopAbs_FORWARD);
403 aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
404 aV1.Orientation(TopAbs_FORWARD);
406 aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
407 aV2.Orientation(TopAbs_REVERSED);
409 BOPTools_AlgoTools::MakeSplitEdge(aE, aV1, aT1, aV2, aT2, aSp);
413 Bnd_Box& aBox=aSI.ChangeBox();
414 BRepBndLib::Add(aSp, aBox);
416 nSp=myDS->Append(aSI);
419 //=======================================================================
420 // function: MakePCurves
422 //=======================================================================
423 void BOPAlgo_PaveFiller::MakePCurves()
426 Standard_Integer i, nF1, nF2, aNbC, k, nE, aNbFF, aNbFI;
427 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
428 BOPDS_MapIteratorOfMapOfPaveBlock aItMPB;
429 TopoDS_Face aF1F, aF2F;
430 BOPAlgo_VectorOfMPC aVMPC;
434 // 1. Process Common Blocks
435 const BOPDS_VectorOfFaceInfo& aFIP=myDS->FaceInfoPool();
438 for (i=0; i<aNbFI; ++i) {
439 const BOPDS_FaceInfo& aFI=aFIP(i);
442 aF1F=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
443 aF1F.Orientation(TopAbs_FORWARD);
445 const BOPDS_IndexedMapOfPaveBlock& aMPBIn=aFI.PaveBlocksIn();
446 aItMPB.Initialize(aMPBIn);
447 for(; aItMPB.More(); aItMPB.Next()) {
448 const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
450 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
452 BOPAlgo_MPC& aMPC=aVMPC.Append1();
455 aMPC.SetProgressIndicator(myProgressIndicator);
459 const BOPDS_IndexedMapOfPaveBlock& aMPBOn=aFI.PaveBlocksOn();
460 aItMPB.Initialize(aMPBOn);
461 for(; aItMPB.More(); aItMPB.Next()) {
462 const Handle(BOPDS_PaveBlock)& aPB=aItMPB.Value();
463 if (myDS->IsCommonBlockOnEdge(aPB)) {
465 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
467 BOPAlgo_MPC& aMPC=aVMPC.Append1();
470 aMPC.SetProgressIndicator(myProgressIndicator);
473 }// for (i=0; i<aNbFI; ++i) {
475 // 2. Process section edges
476 Standard_Boolean bPCurveOnS[2];
480 bPCurveOnS[0]=mySectionAttribute.PCurveOnS1();
481 bPCurveOnS[1]=mySectionAttribute.PCurveOnS2();
483 if (bPCurveOnS[0] || bPCurveOnS[1]) {
484 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
486 for (i=0; i<aNbFF; ++i) {
487 const BOPDS_InterfFF& aFF=aFFs(i);
488 aFF.Indices(nF1, nF2);
490 aFf[0]=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
491 aFf[0].Orientation(TopAbs_FORWARD);
493 aFf[1]=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
494 aFf[1].Orientation(TopAbs_FORWARD);
496 const BOPDS_VectorOfCurve& aVNC=aFF.Curves();
498 for (k=0; k<aNbC; ++k) {
499 const BOPDS_Curve& aNC=aVNC(k);
500 const BOPDS_ListOfPaveBlock& aLPB=aNC.PaveBlocks();
501 aItLPB.Initialize(aLPB);
502 for(; aItLPB.More(); aItLPB.Next()) {
503 const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
505 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE)));
507 for (m=0; m<2; ++m) {
509 BOPAlgo_MPC& aMPC=aVMPC.Append1();
511 aMPC.SetFace(aFf[m]);
512 aMPC.SetFlag(bPCurveOnS[m]);
513 aMPC.SetProgressIndicator(myProgressIndicator);
518 }// for (i=0; i<aNbFF; ++i) {
519 }//if (bPCurveOnS1 || bPCurveOnS2 ) {
521 //======================================================
522 BOPAlgo_MPCCnt::Perform(myRunParallel, aVMPC);
523 //======================================================
525 //=======================================================================
526 // function: RefineFaceInfoOn
528 //=======================================================================
529 void BOPAlgo_PaveFiller::RefineFaceInfoOn()
531 Standard_Integer aNbPBP;
535 BOPDS_VectorOfListOfPaveBlock& aPBP=myDS->ChangePaveBlocksPool();
536 aNbPBP=aPBP.Extent();
541 Standard_Boolean bV1, bV2;
542 Standard_Integer i, nV1, nV2, aNbPB;
543 Handle(BOPDS_PaveBlock) aPB;
545 for (i=0; i<aNbPBP; ++i) {
546 BOPDS_ListOfPaveBlock& aLPB=aPBP(i);
551 aPB->Indices(nV1, nV2);
552 bV1=myDS->IsNewShape(nV1);
553 bV2=myDS->IsNewShape(nV2);
556 if (!myDS->IsCommonBlock(aPB)) {
557 // the PB seems to be untouced
561 }//if (!(bV1 || bV2)) {
563 }//for (i=0; i<aNbPBP; ++i) {
564 myDS->RefineFaceInfoOn();
566 //=======================================================================
567 //function : UpdateVertices
568 //purpose : update tolerances of vertices comparing extremities of
570 //=======================================================================
571 void UpdateVertices(const TopoDS_Edge& aE,
572 const TopoDS_Face& aF)
575 Standard_Real aT[2], aUx, aVx, aTolV2, aD2, aD;
578 Handle(Geom_Surface) aS;
579 Handle(Geom_Curve) aC3D;
580 Handle(Geom2d_Curve) aC2D;
586 aEf.Orientation(TopAbs_FORWARD);
588 TopExp::Vertices(aEf, aV[0], aV[1]);
590 aS=BRep_Tool::Surface(aF);
591 aC3D=BRep_Tool::Curve(aEf, aT[0], aT[1]);
592 aC2D=BRep_Tool::CurveOnSurface(aEf, aF, aT[0], aT[1]);
594 for (j=0; j<2; ++j) {
595 aTolV2=BRep_Tool::Tolerance(aV[j]);
596 aTolV2=aTolV2*aTolV2;
598 aC3D->D0(aT[j], aP3D);
599 aC2D->D0(aT[j], aP2Dx);
600 aP2Dx.Coord(aUx, aVx);
601 aS->D0(aUx, aVx, aP3Dx);
602 aD2=aP3D.SquareDistance(aP3Dx);
605 aBB.UpdateVertex(aV[j], aD);
609 //=======================================================================
612 //=======================================================================
613 void BOPAlgo_PaveFiller::Prepare()
615 TopAbs_ShapeEnum aType[] = {
620 Standard_Boolean bJustAdd, bIsBasedOnPlane;
621 Standard_Integer i, aNb, n1, nF;
622 TopExp_Explorer aExp;
623 BOPCol_MapOfShape aMF;
624 BOPCol_MapIteratorOfMapOfShape aItMF;
629 for(i=0; i<aNb; ++i) {
630 myIterator->Initialize(aType[i], aType[2]);
631 for (; myIterator->More(); myIterator->Next()) {
632 myIterator->Value(n1, nF, bJustAdd);
633 const TopoDS_Face& aF=(*(TopoDS_Face *)(&myDS->Shape(nF)));
635 bIsBasedOnPlane=IsBasedOnPlane(aF);
636 if (bIsBasedOnPlane) {
646 BOPAlgo_VectorOfBPC aVBPC;
648 aItMF.Initialize(aMF);
649 for (; aItMF.More(); aItMF.Next()) {
650 const TopoDS_Face& aF=*((TopoDS_Face *)&aItMF.Key());
651 aExp.Init(aF, aType[1]);
652 for (; aExp.More(); aExp.Next()) {
653 const TopoDS_Edge& aE=*((TopoDS_Edge *)&aExp.Current());
654 BOPAlgo_BPC& aBPC=aVBPC.Append1();
660 //======================================================
661 BOPAlgo_BPCCnt::Perform(myRunParallel, aVBPC);
662 //======================================================
664 //=======================================================================
665 //function : IsBasedOnPlane
667 //=======================================================================
668 Standard_Boolean IsBasedOnPlane(const TopoDS_Face& aF)
670 TopLoc_Location aLoc;
671 Handle(Geom_RectangularTrimmedSurface) aGRTS;
672 Handle(Geom_Plane) aGP;
674 const Handle(Geom_Surface)& aS = BRep_Tool::Surface(aF, aLoc);
675 aGRTS = Handle(Geom_RectangularTrimmedSurface)::DownCast(aS);
676 if(!aGRTS.IsNull()) {
677 aGP = Handle(Geom_Plane)::DownCast(aGRTS->BasisSurface());
680 aGP = Handle(Geom_Plane)::DownCast(aS);
683 return (!aGP.IsNull());