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 <Bnd_Box.hxx>
19 #include <BOPAlgo_PaveFiller.hxx>
20 #include <BOPAlgo_SectionAttribute.hxx>
21 #include <BOPAlgo_Tools.hxx>
22 #include <BOPCol_DataMapOfIntegerReal.hxx>
23 #include <BOPCol_DataMapOfShapeInteger.hxx>
24 #include <BOPCol_ListOfInteger.hxx>
25 #include <BOPCol_ListOfShape.hxx>
26 #include <BOPCol_MapOfInteger.hxx>
27 #include <BOPCol_NCVector.hxx>
28 #include <BOPCol_Parallel.hxx>
29 #include <BOPDS_CommonBlock.hxx>
30 #include <BOPDS_CoupleOfPaveBlocks.hxx>
31 #include <BOPDS_Curve.hxx>
32 #include <BOPDS_DataMapOfPaveBlockListOfPaveBlock.hxx>
33 #include <BOPDS_DS.hxx>
34 #include <BOPDS_FaceInfo.hxx>
35 #include <BOPDS_Interf.hxx>
36 #include <BOPDS_Iterator.hxx>
37 #include <BOPDS_ListOfPave.hxx>
38 #include <BOPDS_ListOfPaveBlock.hxx>
39 #include <BOPDS_MapOfPaveBlock.hxx>
40 #include <BOPDS_PaveBlock.hxx>
41 #include <BOPDS_Point.hxx>
42 #include <BOPDS_ShapeInfo.hxx>
43 #include <BOPDS_VectorOfCurve.hxx>
44 #include <BOPDS_VectorOfPoint.hxx>
45 #include <BOPTools.hxx>
46 #include <BOPTools_AlgoTools.hxx>
47 #include <BOPTools_AlgoTools3D.hxx>
48 #include <BRep_Builder.hxx>
49 #include <BRep_Tool.hxx>
50 #include <BRep_TEdge.hxx>
51 #include <BRepAdaptor_Curve.hxx>
52 #include <BRepAdaptor_Surface.hxx>
53 #include <BRepBndLib.hxx>
54 #include <BRepBuilderAPI_MakeVertex.hxx>
55 #include <BRepTools.hxx>
56 #include <Geom2d_Curve.hxx>
57 #include <Geom_Curve.hxx>
58 #include <GeomAPI_ProjectPointOnCurve.hxx>
59 #include <GeomAPI_ProjectPointOnSurf.hxx>
61 #include <IntSurf_ListOfPntOn2S.hxx>
62 #include <IntSurf_PntOn2S.hxx>
63 #include <IntTools.hxx>
64 #include <IntTools_Context.hxx>
65 #include <IntTools_Curve.hxx>
66 #include <IntTools_EdgeFace.hxx>
67 #include <IntTools_FaceFace.hxx>
68 #include <IntTools_PntOn2Faces.hxx>
69 #include <IntTools_SequenceOfCurves.hxx>
70 #include <IntTools_SequenceOfPntOn2Faces.hxx>
71 #include <IntTools_ShrunkRange.hxx>
72 #include <IntTools_Tools.hxx>
73 #include <Precision.hxx>
75 #include <TopExp_Explorer.hxx>
77 #include <TopoDS_Compound.hxx>
78 #include <TopoDS_Edge.hxx>
79 #include <TopoDS_Face.hxx>
80 #include <TopoDS_Vertex.hxx>
83 static void ToleranceFF(const BRepAdaptor_Surface& aBAS1,
84 const BRepAdaptor_Surface& aBAS2,
85 Standard_Real& aTolFF);
87 /////////////////////////////////////////////////////////////////////////
88 //=======================================================================
89 //class : BOPAlgo_FaceFace
91 //=======================================================================
92 class BOPAlgo_FaceFace :
93 public IntTools_FaceFace,
102 myIF1(-1), myIF2(-1), myTolFF(1.e-7) {
105 virtual ~BOPAlgo_FaceFace() {
108 void SetIndices(const Standard_Integer nF1,
109 const Standard_Integer nF2) {
114 void Indices(Standard_Integer& nF1,
115 Standard_Integer& nF2) const {
120 void SetFaces(const TopoDS_Face& aF1,
121 const TopoDS_Face& aF2) {
126 const TopoDS_Face& Face1()const {
130 const TopoDS_Face& Face2()const {
134 void SetTolFF(const Standard_Real aTolFF) {
138 Standard_Real TolFF() const{
142 virtual void Perform() {
143 BOPAlgo_Algo::UserBreak();
144 IntTools_FaceFace::Perform(myF1, myF2);
148 Standard_Integer myIF1;
149 Standard_Integer myIF2;
150 Standard_Real myTolFF;
155 //=======================================================================
156 typedef BOPCol_NCVector
157 <BOPAlgo_FaceFace> BOPAlgo_VectorOfFaceFace;
159 typedef BOPCol_Functor
161 BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceFunctor;
164 <BOPAlgo_FaceFaceFunctor,
165 BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceCnt;
166 /////////////////////////////////////////////////////////////////////////
167 //=======================================================================
168 //function : PerformFF
170 //=======================================================================
171 void BOPAlgo_PaveFiller::PerformFF()
173 Standard_Integer iSize;
174 Standard_Boolean bValid;
178 myIterator->Initialize(TopAbs_FACE, TopAbs_FACE);
179 iSize=myIterator->ExpectedLength();
184 Standard_Boolean bJustAdd, bApp, bCompC2D1, bCompC2D2, bIsDone;
185 Standard_Boolean bToSplit, bTangentFaces;
186 Standard_Integer nF1, nF2, aNbCurves, aNbPoints, i, aNbLP;
187 Standard_Integer aNbFaceFace, k;
188 Standard_Real aApproxTol, aTolR3D, aTolR2D, aTolFF, aTolReal;
189 BRepAdaptor_Surface aBAS1, aBAS2;
190 BOPCol_MapOfInteger aMI;
191 BOPAlgo_VectorOfFaceFace aVFaceFace;
193 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
194 aFFs.SetIncrement(iSize);
196 bApp=mySectionAttribute.Approximation();
197 bCompC2D1=mySectionAttribute.PCurveOnS1();
198 bCompC2D2=mySectionAttribute.PCurveOnS2();
200 bToSplit = Standard_False;
202 for (; myIterator->More(); myIterator->Next()) {
203 myIterator->Value(nF1, nF2, bJustAdd);
208 const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
209 const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
212 myDS->UpdateFaceInfoOn(nF1);
213 myDS->UpdateFaceInfoIn(nF1);
216 myDS->UpdateFaceInfoOn(nF2);
217 myDS->UpdateFaceInfoIn(nF2);
220 aBAS1.Initialize(aF1, Standard_False);
221 aBAS2.Initialize(aF2, Standard_False);
222 if (aBAS1.GetType() == GeomAbs_Plane &&
223 aBAS2.GetType() == GeomAbs_Plane) {
224 Standard_Boolean bToIntersect;
226 bToIntersect = CheckPlanes(nF1, nF2);
228 myDS->AddInterf(nF1, nF2);
229 BOPDS_InterfFF& aFF=aFFs.Append1();
230 aFF.SetIndices(nF1, nF2);
236 ToleranceFF(aBAS1, aBAS2, aTolFF);
238 BOPAlgo_FaceFace& aFaceFace=aVFaceFace.Append1();
240 aFaceFace.SetIndices(nF1, nF2);
241 aFaceFace.SetFaces(aF1, aF2);
242 aFaceFace.SetTolFF(aTolFF);
244 IntSurf_ListOfPntOn2S aListOfPnts;
245 GetEFPnts(nF1, nF2, aListOfPnts);
246 aNbLP = aListOfPnts.Extent();
248 aFaceFace.SetList(aListOfPnts);
251 aFaceFace.SetParameters(bApp, bCompC2D1, bCompC2D2, aApproxTol);
252 aFaceFace.SetProgressIndicator(myProgressIndicator);
253 }//for (; myIterator->More(); myIterator->Next()) {
255 aNbFaceFace=aVFaceFace.Extent();
256 //======================================================
257 BOPAlgo_FaceFaceCnt::Perform(myRunParallel, aVFaceFace);
258 //======================================================
260 for (k=0; k < aNbFaceFace; ++k) {
261 BOPAlgo_FaceFace& aFaceFace=aVFaceFace(k);
263 aFaceFace.Indices(nF1, nF2);
264 aTolFF=aFaceFace.TolFF();
266 bIsDone=aFaceFace.IsDone();
268 aTolR3D=aFaceFace.TolReached3d();
269 aTolR2D=aFaceFace.TolReached2d();
270 aTolReal = aFaceFace.TolReal();
271 bTangentFaces=aFaceFace.TangentFaces();
273 if (aTolR3D < aTolFF){
276 if (aTolReal < aTolFF) {
279 if (aTolR2D < 1.e-7){
283 aFaceFace.PrepareLines3D(bToSplit);
285 const IntTools_SequenceOfCurves& aCvsX=aFaceFace.Lines();
286 const IntTools_SequenceOfPntOn2Faces& aPntsX=aFaceFace.Points();
288 aNbCurves=aCvsX.Length();
289 aNbPoints=aPntsX.Length();
291 if (aNbCurves || aNbPoints) {
292 myDS->AddInterf(nF1, nF2);
295 BOPDS_InterfFF& aFF=aFFs.Append1();
296 aFF.SetIndices(nF1, nF2);
298 aFF.SetTolR3D(aTolR3D);
299 aFF.SetTolR2D(aTolR2D);
300 aFF.SetTolReal(aTolReal);
301 aFF.SetTangentFaces(bTangentFaces);
304 aFF.Init(aNbCurves, aNbPoints);
308 // Fix bounding box expanding coefficient.
309 Standard_Real aBoxExpandValue = aTolR3D;
312 // Modify geometric expanding coefficient by topology value,
313 // since this bounging box used in sharing (vertex or edge).
314 Standard_Real aMaxVertexTol = Max (BRep_Tool::MaxTolerance(aFaceFace.Face1(), TopAbs_VERTEX),
315 BRep_Tool::MaxTolerance(aFaceFace.Face2(), TopAbs_VERTEX));
316 aBoxExpandValue += aMaxVertexTol;
319 BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
320 for (i=1; i<=aNbCurves; ++i) {
323 const IntTools_Curve& aIC=aCvsX(i);
324 const Handle(Geom_Curve)& aC3D= aIC.Curve();
325 bValid=IntTools_Tools::CheckCurve(aC3D, aBoxExpandValue, aBox);
327 BOPDS_Curve& aNC=aVNC.Append1();
334 BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
335 for (i=1; i<=aNbPoints; ++i) {
336 const IntTools_PntOn2Faces& aPi=aPntsX(i);
337 const gp_Pnt& aP=aPi.P1().Pnt();
339 BOPDS_Point& aNP=aVNP.Append1();
342 //}// if (aNbCs || aNbPs)
345 BOPDS_InterfFF& aFF=aFFs.Append1();
346 aFF.SetIndices(nF1, nF2);
349 aFF.Init(aNbCurves, aNbPoints);
351 }// for (k=0; k < aNbFaceFace; ++k) {
353 //=======================================================================
354 //function : MakeBlocks
356 //=======================================================================
357 void BOPAlgo_PaveFiller::MakeBlocks()
359 Standard_Integer aNbFF;
363 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
369 Standard_Boolean bExist, bValid2D;
370 Standard_Integer i, nF1, nF2, aNbC, aNbP, j;
371 Standard_Integer nV1, nV2;
372 Standard_Real aTolR3D, aT1, aT2, aTol;
373 Handle(NCollection_BaseAllocator) aAllocator;
374 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
376 Handle(BOPDS_PaveBlock) aPBOut;
378 //-----------------------------------------------------scope f
380 NCollection_BaseAllocator::CommonBaseAllocator();
382 BOPCol_ListOfInteger aLSE(aAllocator), aLBV(aAllocator);
383 BOPCol_MapOfInteger aMVOnIn(100, aAllocator), aMF(100, aAllocator),
384 aMVStick(100,aAllocator), aMVEF(100, aAllocator),
385 aMI(100, aAllocator), aMVBounds(100, aAllocator);
386 BOPDS_IndexedMapOfPaveBlock aMPBOnIn(100, aAllocator);
387 BOPDS_MapOfPaveBlock aMPBAdd(100, aAllocator);
388 BOPDS_ListOfPaveBlock aLPB(aAllocator);
389 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMSCPB(100, aAllocator);
390 BOPCol_DataMapOfShapeInteger aMVI(100, aAllocator);
391 BOPDS_DataMapOfPaveBlockListOfPaveBlock aDMExEdges(100, aAllocator);
392 BOPCol_DataMapOfIntegerReal aMVTol(100, aAllocator);
393 BOPCol_DataMapOfIntegerInteger aDMI(100, aAllocator);
394 BOPCol_DataMapOfIntegerListOfInteger aDMBV(100, aAllocator);
395 BOPCol_DataMapIteratorOfDataMapOfIntegerReal aItMV;
396 BOPCol_IndexedMapOfShape aMicroEdges(100, aAllocator);
398 for (i=0; i<aNbFF; ++i) {
402 BOPDS_InterfFF& aFF=aFFs(i);
403 aFF.Indices(nF1, nF2);
405 BOPDS_VectorOfPoint& aVP=aFF.ChangePoints();
407 BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
409 if (!aNbP && !aNbC) {
413 const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
414 const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
416 aTolR3D=aFF.TolR3D();
420 myDS->UpdateFaceInfoOn(nF1);
421 myDS->UpdateFaceInfoIn(nF1);
424 myDS->UpdateFaceInfoOn(nF2);
425 myDS->UpdateFaceInfoIn(nF2);
428 BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
429 BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
436 myDS->VerticesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn);
437 myDS->SharedEdges(nF1, nF2, aLSE, aAllocator);
440 for (j=0; j<aNbP; ++j) {
442 BOPDS_CoupleOfPaveBlocks aCPB;
444 BOPDS_Point& aNP=aVP.ChangeValue(j);
445 const gp_Pnt& aP=aNP.Pnt();
447 bExist=IsExistingVertex(aP, aTolR3D, aMVOnIn);
449 BOPTools_AlgoTools::MakeNewVertex(aP, aTolR3D, aV);
451 aCPB.SetIndexInterf(i);
453 aMSCPB.Add(aV, aCPB);
460 GetStickVertices(nF1, nF2, aMVStick, aMVEF, aMI);
462 for (j=0; j<aNbC; ++j) {
463 BOPDS_Curve& aNC=aVC.ChangeValue(j);
464 const IntTools_Curve& aIC=aNC.Curve();
466 aNC.InitPaveBlock1();
468 PutPavesOnCurve(aMVOnIn, aTolR3D, aNC, nF1, nF2, aMI, aMVEF, aMVTol);
470 PutStickPavesOnCurve(aF1, aF2, aMI, aNC, aMVStick, aMVTol);
473 PutEFPavesOnCurve(aNC, aMI, aMVEF, aMVTol);
476 if (aIC.HasBounds()) {
479 PutBoundPaveOnCurve(aF1, aF2, aTolR3D, aNC, aLBV);
481 if (!aLBV.IsEmpty()) {
483 BOPCol_ListIteratorOfListOfInteger aItI(aLBV);
484 for (; aItI.More(); aItI.Next()) {
485 aMVBounds.Add(aItI.Value());
489 }//for (j=0; j<aNbC; ++j) {
491 // Put closing pave if needed
492 for (j=0; j<aNbC; ++j) {
493 BOPDS_Curve& aNC=aVC.ChangeValue(j);
494 PutClosingPaveOnCurve (aNC);
497 // 3. Make section edges
498 for (j=0; j<aNbC; ++j) {
499 BOPDS_Curve& aNC=aVC.ChangeValue(j);
500 const IntTools_Curve& aIC=aNC.Curve();
502 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
503 Handle(BOPDS_PaveBlock)& aPB1=aNC.ChangePaveBlock1();
506 aPB1->Update(aLPB, Standard_False);
508 aItLPB.Initialize(aLPB);
509 for (; aItLPB.More(); aItLPB.Next()) {
510 Handle(BOPDS_PaveBlock)& aPB=aItLPB.ChangeValue();
511 aPB->Indices(nV1, nV2);
512 aPB->Range (aT1, aT2);
514 if (fabs(aT1 - aT2) < Precision::PConfusion()) {
518 bValid2D=myContext->IsValidBlockForFaces(aT1, aT2, aIC,
524 bExist=IsExistingPaveBlock(aPB, aNC, aLSE);
529 const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
530 const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
533 BOPTools_AlgoTools::MakeEdge (aIC, aV1, aT1, aV2, aT2, aTolR3D, aES);
535 // check for micro edge
536 if (BOPTools_AlgoTools::IsMicroEdge(aES, myContext, Standard_False)) {
537 // If the section edge is a micro edge, i.e. the whole edge is
538 // covered by the tolerance spheres of its vertices, it will be
539 // passed into post treatment process to fuse its vertices.
540 // The edge itself will not be kept.
541 if (!aMVBounds.Contains(nV1) && !aMVBounds.Contains(nV2)) {
542 aMicroEdges.Add(aES);
543 // keep vertices for post treatment
550 Standard_Real aTolNew;
551 bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aPBOut, aTolNew);
553 if (aMPBAdd.Add(aPBOut)) {
554 Standard_Boolean bInBothFaces = Standard_True;
555 if (!myDS->IsCommonBlock(aPBOut)) {
560 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(nE);
561 aTolE = BRep_Tool::Tolerance(aE);
562 if (aTolNew < aFF.TolReal())
563 aTolNew = aFF.TolReal(); // use real tolerance of intersection
564 if (aTolNew > aTolE) {
565 UpdateEdgeTolerance(nE, aTolNew);
567 bInBothFaces = Standard_False;
570 bInBothFaces = (aFI1.PaveBlocksOn().Contains(aPBOut) ||
571 aFI1.PaveBlocksIn().Contains(aPBOut))&&
572 (aFI2.PaveBlocksOn().Contains(aPBOut) ||
573 aFI2.PaveBlocksIn().Contains(aPBOut));
576 PreparePostTreatFF(i, j, aPBOut, aMSCPB, aMVI, aLPBC);
583 BOPTools_AlgoTools::MakePCurve(aES, aF1, aF2, aIC,
584 mySectionAttribute.PCurveOnS1(),
585 mySectionAttribute.PCurveOnS2());
587 // Append the Pave Block to the Curve j
590 // Keep info for post treatment
591 BOPDS_CoupleOfPaveBlocks aCPB;
592 aCPB.SetIndexInterf(i);
594 aCPB.SetPaveBlock1(aPB);
596 aMSCPB.Add(aES, aCPB);
605 }//for (j=0; j<aNbC; ++j) {
606 //back to previous tolerance values for unused vertices
607 aItMV.Initialize(aMVTol);
608 for (; aItMV.More(); aItMV.Next()) {
610 aTol = aItMV.Value();
612 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV1);
613 const Handle(BRep_TVertex)& TV =
614 *((Handle(BRep_TVertex)*)&aV.TShape());
618 ProcessExistingPaveBlocks(i, aMPBOnIn, aDMBV, aMSCPB, aMVI, aMPBAdd);
619 }//for (i=0; i<aNbFF; ++i) {
622 myErrorStatus=PostTreatFF(aMSCPB, aMVI, aDMExEdges, aDMI, aMicroEdges, aAllocator);
626 // reduce tolerances of section edges where it is appropriate
627 CorrectToleranceOfSE();
630 UpdateFaceInfo(aDMExEdges, aDMI);
631 //Update all pave blocks
632 UpdatePaveBlocks(aDMI);
633 //-----------------------------------------------------scope t
643 //=======================================================================
644 //function : PostTreatFF
646 //=======================================================================
647 Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
648 (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
649 BOPCol_DataMapOfShapeInteger& aMVI,
650 BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges,
651 BOPCol_DataMapOfIntegerInteger& aDMI,
652 const BOPCol_IndexedMapOfShape& theMicroEdges,
653 const Handle(NCollection_BaseAllocator)& theAllocator)
655 Standard_Integer iRet, aNbS;
658 aNbS=theMSCPB.Extent();
663 Standard_Boolean bHasPaveBlocks, bOld;
664 Standard_Integer iErr, nSx, nVSD, iX, iP, iC, j, nV, iV = 0, iE, k;
665 Standard_Integer aNbLPBx;
666 TopAbs_ShapeEnum aType;
668 BOPCol_ListIteratorOfListOfShape aItLS;
669 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
671 Handle(BOPDS_PaveBlock) aPB1;
675 BOPCol_ListOfShape aLS(theAllocator);
676 BOPAlgo_PaveFiller aPF(theAllocator);
677 aPF.SetIsPrimary(Standard_False);
678 aPF.SetNonDestructive(myNonDestructive);
680 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
682 Standard_Integer aNbME = theMicroEdges.Extent();
684 if (aNbS==1 && (aNbME == 0)) {
685 const TopoDS_Shape& aS=theMSCPB.FindKey(1);
686 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromIndex(1);
688 aType=aS.ShapeType();
689 if (aType==TopAbs_VERTEX) {
690 aSI.SetShapeType(aType);
692 iV=myDS->Append(aSI);
694 iX=aCPB.IndexInterf();
696 BOPDS_InterfFF& aFF=aFFs(iX);
697 BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
698 BOPDS_Point& aNP=aVNP(iP);
701 else if (aType==TopAbs_EDGE) {
702 aPB1=aCPB.PaveBlock1();
704 if (aPB1->HasEdge()) {
705 BOPDS_ListOfPaveBlock aLPBx;
707 aDMExEdges.Bind(aPB1, aLPBx);
709 aSI.SetShapeType(aType);
711 iE=myDS->Append(aSI);
719 // 1 prepare arguments
720 for (k=1; k<=aNbS; ++k) {
721 const TopoDS_Shape& aS=theMSCPB.FindKey(k);
725 // The section edges considered as a micro should be
726 // specially treated - their vertices should be united and
727 // the edge itself should be removed. Thus, we add only
728 // its vertices into operation.
731 for (k = 1; k <= aNbME; ++k) {
732 const TopoDS_Edge& aE = TopoDS::Edge(theMicroEdges(k));
734 TopoDS_Vertex aV1, aV2;
735 TopExp::Vertices(aE, aV1, aV2);
740 // make sure these vertices will be united
741 const gp_Pnt& aP1 = BRep_Tool::Pnt(aV1);
742 const gp_Pnt& aP2 = BRep_Tool::Pnt(aV2);
744 Standard_Real aDist = aP1.Distance(aP2);
745 Standard_Real aTolV1 = BRep_Tool::Tolerance(aV1);
746 Standard_Real aTolV2 = BRep_Tool::Tolerance(aV2);
748 aDist -= (aTolV1 + aTolV2);
751 aBB.UpdateVertex(aV1, aTolV1 + aDist);
752 aBB.UpdateVertex(aV2, aTolV2 + aDist);
757 aPF.SetProgressIndicator(myProgressIndicator);
758 aPF.SetRunParallel(myRunParallel);
759 aPF.SetArguments(aLS);
761 iErr=aPF.ErrorStatus();
767 aItLS.Initialize(aLS);
768 for (; aItLS.More(); aItLS.Next()) {
769 const TopoDS_Shape& aSx=aItLS.Value();
770 nSx=aPDS->Index(aSx);
771 const BOPDS_ShapeInfo& aSIx=aPDS->ShapeInfo(nSx);
773 aType=aSIx.ShapeType();
775 if (aType==TopAbs_VERTEX) {
776 Standard_Boolean bIntersectionPoint = theMSCPB.Contains(aSx);
778 if (aPDS->HasShapeSD(nSx, nVSD)) {
779 aV=aPDS->Shape(nVSD);
784 // index of new vertex in theDS -> iV
785 if (!aMVI.IsBound(aV)) {
786 aSI.SetShapeType(aType);
788 iV=myDS->Append(aSI);
796 if (!bIntersectionPoint) {
797 // save SD connection
798 nSx = aMVI.Find(aSx);
800 myDS->AddShapeSD(nSx, iV);
803 // update FF interference
804 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
805 iX=aCPB.IndexInterf();
807 BOPDS_InterfFF& aFF=aFFs(iX);
808 BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
809 BOPDS_Point& aNP=aVNP(iP);
812 }//if (aType==TopAbs_VERTEX) {
814 else if (aType==TopAbs_EDGE) {
815 bHasPaveBlocks=aPDS->HasPaveBlocks(nSx);
816 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
817 iX=aCPB.IndexInterf();
819 aPB1=aCPB.PaveBlock1();
821 bOld = aPB1->HasEdge();
823 BOPDS_ListOfPaveBlock aLPBx;
824 aDMExEdges.Bind(aPB1, aLPBx);
827 if (!bHasPaveBlocks) {
829 aDMExEdges.ChangeFind(aPB1).Append(aPB1);
832 aSI.SetShapeType(aType);
834 iE = myDS->Append(aSI);
840 BOPDS_InterfFF& aFF=aFFs(iX);
841 BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
842 BOPDS_Curve& aNC=aVNC(iC);
843 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
845 // check if edge occured to be micro edge;
846 // note we check not the edge aSx itself, but its image in aPDS
847 const BOPDS_ListOfPaveBlock& aLPBx = aPDS->PaveBlocks(nSx);
848 aNbLPBx = aLPBx.Extent();
849 if (aPDS->HasPaveBlocks(nSx) &&
850 (aNbLPBx == 0 || (aNbLPBx == 1 && !aLPBx.First()->HasShrunkData()))) {
851 BOPDS_ListIteratorOfListOfPaveBlock it(aLPBC);
852 for (; it.More(); it.Next()) {
853 if (it.Value() == aPB1) {
861 if (bOld && !aNbLPBx) {
862 aDMExEdges.ChangeFind(aPB1).Append(aPB1);
867 aItLPB.Initialize(aLPBC);
868 for (; aItLPB.More(); aItLPB.Next()) {
869 const Handle(BOPDS_PaveBlock)& aPBC=aItLPB.Value();
871 aLPBC.Remove(aItLPB);
880 if (!aMVI.IsBound(aE)) {
881 aSI.SetShapeType(aType);
883 iE=myDS->Append(aSI);
889 // append new PaveBlock to aLPBC
895 aItLPB.Initialize(aLPBx);
896 for (; aItLPB.More(); aItLPB.Next()) {
897 const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
898 const Handle(BOPDS_PaveBlock) aPBRx=aPDS->RealPaveBlock(aPBx);
900 // update vertices of paves
901 aPave[0]=aPBx->Pave1();
902 aPave[1]=aPBx->Pave2();
903 for (j=0; j<2; ++j) {
904 nV = aPave[j].Index();
905 aV = aPDS->Shape(nV);
907 if (!aMVI.IsBound(aV)) {
908 // index of new vertex in theDS -> iV
909 aSI.SetShapeType(TopAbs_VERTEX);
911 iV = myDS->Append(aSI);
917 const BOPDS_Pave& aP1 = !j ? aPB1->Pave1() : aPB1->Pave2();
918 if (aP1.Parameter() == aPave[j].Parameter() &&
920 aDMI.Bind(aP1.Index(), iV);
921 myDS->AddShapeSD(aP1.Index(), iV);
924 aPave[j].SetIndex(iV);
928 aE=aPDS->Shape(aPBRx->Edge());
930 if (!aMVI.IsBound(aE)) {
931 aSI.SetShapeType(aType);
933 iE=myDS->Append(aSI);
935 // update real edge tolerance according to distances in common block if any
936 if (aPDS->IsCommonBlock(aPBx)) {
937 const Handle(BOPDS_CommonBlock)& aCB = aPDS->CommonBlock(aPBx);
938 Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, aPDS, aPF.Context());
939 if (aFF.TolReal() < aTol) {
940 aFF.SetTolReal(aTol);
947 // append new PaveBlock to aLPBC
948 Handle(BOPDS_PaveBlock) aPBC=new BOPDS_PaveBlock();
950 aPBC->SetPave1(aPave[0]);
951 aPBC->SetPave2(aPave[1]);
954 aPBC->SetOriginalEdge(aPB1->OriginalEdge());
955 aDMExEdges.ChangeFind(aPB1).Append(aPBC);
963 }//else if (aType==TopAbs_EDGE)
964 }//for (; aItLS.More(); aItLS.Next()) {
968 //=======================================================================
969 //function : UpdateFaceInfo
971 //=======================================================================
972 void BOPAlgo_PaveFiller::UpdateFaceInfo
973 (BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDME,
974 const BOPCol_DataMapOfIntegerInteger& theDMV)
976 Standard_Integer i, j, nV1, nF1, nF2,
978 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
979 BOPCol_MapOfInteger aMF;
981 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
984 //1. Sections (curves, points);
985 for (i=0; i<aNbFF; ++i) {
986 BOPDS_InterfFF& aFF=aFFs(i);
987 aFF.Indices(nF1, nF2);
989 BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
990 BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
992 // 1.1. Section edges
993 BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
995 for (j=0; j<aNbC; ++j) {
996 BOPDS_Curve& aNC=aVNC(j);
997 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
999 // Add section edges to face info
1000 aItLPB.Initialize(aLPBC);
1001 for (; aItLPB.More(); ) {
1002 const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
1004 // Treat existing pave blocks
1005 if (theDME.IsBound(aPB)) {
1006 BOPDS_ListOfPaveBlock& aLPB=theDME.ChangeFind(aPB);
1007 UpdateExistingPaveBlocks(aPB, aLPB, nF1, nF2);
1008 aLPBC.Remove(aItLPB);
1012 aFI1.ChangePaveBlocksSc().Add(aPB);
1013 aFI2.ChangePaveBlocksSc().Add(aPB);
1018 // 1.2. Section vertices
1019 const BOPDS_VectorOfPoint& aVNP=aFF.Points();
1021 for (j=0; j<aNbP; ++j) {
1022 const BOPDS_Point& aNP=aVNP(j);
1027 aFI1.ChangeVerticesSc().Add(nV1);
1028 aFI2.ChangeVerticesSc().Add(nV1);
1035 Standard_Boolean bVerts, bEdges;
1037 bVerts = theDMV.Extent() > 0;
1038 bEdges = theDME.Extent() > 0;
1040 if (!bVerts && !bEdges) {
1044 // 2. Update Face Info information with new vertices and new
1045 // pave blocks created in PostTreatFF from existing ones
1046 Standard_Integer nV2, aNbPB;
1047 BOPCol_MapIteratorOfMapOfInteger aItMF;
1048 BOPCol_DataMapIteratorOfDataMapOfIntegerInteger aItMV;
1050 aItMF.Initialize(aMF);
1051 for (; aItMF.More(); aItMF.Next()) {
1052 nF1 = aItMF.Value();
1054 BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF1);
1056 // 2.1. Update information about vertices
1058 BOPCol_MapOfInteger& aMVOn = aFI.ChangeVerticesOn();
1059 BOPCol_MapOfInteger& aMVIn = aFI.ChangeVerticesIn();
1061 aItMV.Initialize(theDMV);
1062 for (; aItMV.More(); aItMV.Next()) {
1064 nV2 = aItMV.Value();
1066 if (aMVOn.Remove(nV1)) {
1070 if (aMVIn.Remove(nV1)) {
1073 } // for (; aItMV.More(); aItMV.Next()) {
1076 // 2.2. Update information about pave blocks
1078 BOPDS_IndexedMapOfPaveBlock& aMPBOn = aFI.ChangePaveBlocksOn();
1079 BOPDS_IndexedMapOfPaveBlock& aMPBIn = aFI.ChangePaveBlocksIn();
1081 BOPDS_IndexedMapOfPaveBlock aMPBCopy;
1082 for (i = 0; i < 2; ++i) {
1083 BOPDS_IndexedMapOfPaveBlock& aMPBOnIn = !i ? aMPBOn : aMPBIn;
1084 aMPBCopy = aMPBOnIn;
1087 aNbPB = aMPBCopy.Extent();
1088 for (j = 1; j <= aNbPB; ++j) {
1089 const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(j);
1090 if (theDME.IsBound(aPB)) {
1091 const BOPDS_ListOfPaveBlock& aLPB = theDME.Find(aPB);
1092 if (aLPB.IsEmpty()) {
1097 aItLPB.Initialize(aLPB);
1098 for (; aItLPB.More(); aItLPB.Next()) {
1099 const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB.Value();
1106 } // for (j = 1; j <= aNbPB; ++j) {
1107 } // for (i = 0; i < 2; ++i) {
1111 //=======================================================================
1112 //function : IsExistingVertex
1114 //=======================================================================
1115 Standard_Boolean BOPAlgo_PaveFiller::IsExistingVertex
1117 const Standard_Real theTolR3D,
1118 const BOPCol_MapOfInteger& aMVOnIn)const
1120 Standard_Boolean bRet;
1121 Standard_Integer nV, iFlag;
1124 BOPCol_MapIteratorOfMapOfInteger aIt;
1129 aBoxP.Enlarge(theTolR3D);
1131 aIt.Initialize(aMVOnIn);
1132 for (; aIt.More(); aIt.Next()) {
1134 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1135 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aSIV.Shape()));
1136 const Bnd_Box& aBoxV=aSIV.Box();
1138 if (!aBoxP.IsOut(aBoxV)) {
1139 iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP, theTolR3D);
1147 //=======================================================================
1148 //function : IsExistingPaveBlock
1150 //=======================================================================
1151 Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
1152 (const Handle(BOPDS_PaveBlock)& thePB,
1153 const BOPDS_Curve& theNC,
1154 const BOPCol_ListOfInteger& theLSE)
1156 Standard_Boolean bRet=Standard_True;
1158 if (theLSE.IsEmpty()) {
1162 Standard_Real aT1, aT2, aTm, aTx, aTol, aDist;
1163 Standard_Integer nE, iFlag, nV1, nV2;
1166 BOPCol_ListIteratorOfListOfInteger aItLI;
1168 thePB->Range(aT1, aT2);
1169 thePB->Indices(nV1, nV2);
1170 const TopoDS_Vertex &aV1 = TopoDS::Vertex(myDS->Shape(nV1)),
1171 &aV2 = TopoDS::Vertex(myDS->Shape(nV2));
1172 const Standard_Real aTolV1 = BRep_Tool::Tolerance(aV1),
1173 aTolV2 = BRep_Tool::Tolerance(aV2);
1175 aTol = Max(aTolV1, aTolV2);
1177 aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
1178 theNC.Curve().D0(aTm, aPm);
1180 aBoxPm.Enlarge(aTol);
1182 aItLI.Initialize(theLSE);
1183 for (; aItLI.More(); aItLI.Next()) {
1187 const BOPDS_ShapeInfo& aSIE=myDS->ChangeShapeInfo(nE);
1188 const Bnd_Box& aBoxE=aSIE.Box();
1189 if (!aBoxE.IsOut(aBoxPm)) {
1190 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
1191 const Standard_Real aTol1 = Max(BRep_Tool::Tolerance(aE), aTol);
1192 iFlag=myContext->ComputePE(aPm, aTol1, aE, aTx, aDist);
1201 //=======================================================================
1202 //function : IsExistingPaveBlock
1204 //=======================================================================
1205 Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
1206 (const Handle(BOPDS_PaveBlock)& thePB,
1207 const BOPDS_Curve& theNC,
1208 const Standard_Real theTolR3D,
1209 const BOPDS_IndexedMapOfPaveBlock& theMPBOnIn,
1210 Handle(BOPDS_PaveBlock)& aPBOut,
1211 Standard_Real& theTolNew)
1213 Standard_Boolean bRet;
1214 Standard_Real aT1, aT2, aTm, aTx;
1215 Standard_Integer nSp, iFlag1, iFlag2, nV11, nV12, nV21, nV22, i, aNbPB;
1216 gp_Pnt aP1, aPm, aP2;
1217 Bnd_Box aBoxP1, aBoxPm, aBoxP2, aBoxTmp;
1219 bRet=Standard_False;
1220 const IntTools_Curve& aIC=theNC.Curve();
1222 thePB->Range(aT1, aT2);
1223 thePB->Indices(nV11, nV12);
1224 const Standard_Real aTolV11 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV11)));
1225 const Standard_Real aTolV12 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV12)));
1226 const Standard_Real aTolV1 = Max(aTolV11, aTolV12);
1231 aBoxP1.Enlarge(aTolV11);
1232 //intermediate point
1233 aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
1239 aBoxP2.Enlarge(aTolV12);
1242 aNbPB = theMPBOnIn.Extent();
1243 for (i = 1; i <= aNbPB; ++i) {
1244 const Handle(BOPDS_PaveBlock)& aPB = theMPBOnIn(i);
1245 aPB->Indices(nV21, nV22);
1246 const Standard_Real aTolV21 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV21)));
1247 const Standard_Real aTolV22 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV22)));
1248 const Standard_Real aTolV2 = Max(aTolV21, aTolV22);
1252 const BOPDS_ShapeInfo& aSISp=myDS->ChangeShapeInfo(nSp);
1253 const TopoDS_Edge& aSp=(*(TopoDS_Edge *)(&aSISp.Shape()));
1254 const Bnd_Box& aBoxSp=aSISp.Box();
1256 iFlag1 = (nV11 == nV21 || nV11 == nV22) ? 2 :
1257 (!aBoxSp.IsOut(aBoxP1) ? 1 : 0);
1258 iFlag2 = (nV12 == nV21 || nV12 == nV22) ? 2 :
1259 (!aBoxSp.IsOut(aBoxP2) ? 1 : 0);
1260 if (iFlag1 && iFlag2) {
1261 Standard_Real aDist;
1263 const Standard_Real aRealTol = myDS->IsCommonBlock(aPB) ?
1264 Max(aTolV1, aTolV2) : theTolR3D;
1267 aBoxTmp.Enlarge(aRealTol);
1269 if (aBoxSp.IsOut(aBoxTmp) || myContext->ComputePE(aPm,
1277 iFlag1 = !myContext->ComputePE(aP1, aRealTol, aSp, aTx, aDist);
1278 if (theTolNew < aDist)
1283 iFlag2 = !myContext->ComputePE(aP2, aRealTol, aSp, aTx, aDist);
1284 if (theTolNew < aDist)
1288 if (iFlag1 && iFlag2) {
1297 //=======================================================================
1298 //function : PutBoundPaveOnCurve
1300 //=======================================================================
1301 void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1,
1302 const TopoDS_Face& aF2,
1303 const Standard_Real aTolR3D,
1305 BOPCol_ListOfInteger& aLVB)
1307 Standard_Boolean bVF;
1308 Standard_Integer nV, iFlag, nVn, j, aNbEP;
1309 Standard_Real aT[2], aTmin, aTmax, aTV, aTol, aTolVnew;
1312 BOPDS_ListIteratorOfListOfPave aItLP;
1313 BOPDS_Pave aPn, aPMM[2];
1315 aTolVnew = Precision::Confusion();
1317 const IntTools_Curve& aIC=aNC.Curve();
1318 aIC.Bounds(aT[0], aT[1], aP[0], aP[1]);
1320 Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
1321 const BOPDS_ListOfPave& aLP=aPB->ExtPaves();
1328 aItLP.Initialize(aLP);
1329 for (; aItLP.More(); aItLP.Next()) {
1330 const BOPDS_Pave& aPv=aItLP.Value();
1331 aPv.Contents(nV, aTV);
1343 for (j=0; j<2; ++j) {
1344 //if curve is closed, process only one bound
1345 if (j && aP[1].IsEqual(aP[0], aTolVnew)) {
1355 aTol = aTolR3D+Precision::Confusion();
1356 aBoxP.Enlarge(aTol);
1357 const BOPDS_Pave& aPV=aPMM[j];
1359 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1360 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aSIV.Shape()));
1361 const Bnd_Box& aBoxV=aSIV.Box();
1362 if (!aBoxP.IsOut(aBoxV)){
1363 iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP[j], aTol);
1368 bVF=myContext->IsValidPointForFaces (aP[j], aF1, aF2, aTolR3D);
1373 BOPDS_ShapeInfo aSIVn;
1375 BOPTools_AlgoTools::MakeNewVertex(aP[j], aTolR3D, aVn);
1376 aSIVn.SetShapeType(TopAbs_VERTEX);
1377 aSIVn.SetShape(aVn);
1379 nVn=myDS->Append(aSIVn);
1382 aPn.SetParameter(aT[j]);
1383 aPB->AppendExtPave(aPn);
1385 aVn=(*(TopoDS_Vertex *)(&myDS->Shape(nVn)));
1386 BOPTools_AlgoTools::UpdateVertex (aIC, aT[j], aVn);
1388 aTolVnew = BRep_Tool::Tolerance(aVn);
1390 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nVn);
1391 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
1392 BRepBndLib::Add(aVn, aBoxDS);
1393 aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
1400 //=======================================================================
1401 //function : PutPavesOnCurve
1403 //=======================================================================
1404 void BOPAlgo_PaveFiller::PutPavesOnCurve
1405 (const BOPCol_MapOfInteger& aMVOnIn,
1406 const Standard_Real aTolR3D,
1408 const Standard_Integer nF1,
1409 const Standard_Integer nF2,
1410 const BOPCol_MapOfInteger& aMI,
1411 const BOPCol_MapOfInteger& aMVEF,
1412 BOPCol_DataMapOfIntegerReal& aMVTol)
1414 Standard_Boolean bInBothFaces;
1415 Standard_Integer nV;
1416 BOPCol_MapIteratorOfMapOfInteger aIt;
1418 const Bnd_Box& aBoxC=aNC.Box();
1420 //Put EF vertices first
1421 aIt.Initialize(aMVEF);
1422 for (; aIt.More(); aIt.Next()) {
1424 PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, 2);
1426 //Put all other vertices
1427 aIt.Initialize(aMVOnIn);
1428 for (; aIt.More(); aIt.Next()) {
1430 if (aMVEF.Contains(nV)) {
1434 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1435 const Bnd_Box& aBoxV=aSIV.Box();
1437 if (aBoxC.IsOut(aBoxV)){
1440 if (!myDS->IsNewShape(nV)) {
1441 const BOPDS_FaceInfo& aFI1 = myDS->FaceInfo(nF1);
1442 const BOPDS_FaceInfo& aFI2 = myDS->FaceInfo(nF2);
1444 bInBothFaces = (aFI1.VerticesOn().Contains(nV) ||
1445 aFI1.VerticesIn().Contains(nV))&&
1446 (aFI2.VerticesOn().Contains(nV) ||
1447 aFI2.VerticesIn().Contains(nV));
1448 if (!bInBothFaces) {
1453 PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, 1);
1457 //=======================================================================
1458 //function : ExtendedTolerance
1460 //=======================================================================
1461 Standard_Boolean BOPAlgo_PaveFiller::ExtendedTolerance
1462 (const Standard_Integer nV,
1463 const BOPCol_MapOfInteger& aMI,
1464 Standard_Real& aTolVExt,
1465 const Standard_Integer aType)
1467 Standard_Boolean bFound = Standard_False;
1468 if (!(myDS->IsNewShape(nV))) {
1472 Standard_Integer i, k, aNbLines, aNbInt;
1473 Standard_Real aT11, aT12, aD1, aD2, aD;
1475 gp_Pnt aPV, aP11, aP12;
1481 } else if (aType == 2) {
1485 aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1486 aPV=BRep_Tool::Pnt(aV);
1488 BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
1489 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1491 for (; k<aNbInt; ++k) {
1492 aNbLines = !k ? aEEs.Extent() : aEFs.Extent();
1493 for (i = 0; i < aNbLines; ++i) {
1494 BOPDS_Interf *aInt = !k ? (BOPDS_Interf*) (&aEEs(i)) :
1495 (BOPDS_Interf*) (&aEFs(i));
1496 if (aInt->IndexNew() == nV) {
1497 if (aMI.Contains(aInt->Index1()) &&
1498 aMI.Contains(aInt->Index2())) {
1499 const IntTools_CommonPrt& aComPrt = !k ? aEEs(i).CommonPart() :
1500 aEFs(i).CommonPart();
1502 const TopoDS_Edge& aE1=aComPrt.Edge1();
1503 aComPrt.Range1(aT11, aT12);
1504 BOPTools_AlgoTools::PointOnEdge(aE1, aT11, aP11);
1505 BOPTools_AlgoTools::PointOnEdge(aE1, aT12, aP12);
1506 aD1=aPV.Distance(aP11);
1507 aD2=aPV.Distance(aP12);
1508 aD=(aD1>aD2)? aD1 : aD2;
1513 }//if (aMI.Contains(aEF.Index1()) && aMI.Contains(aEF.Index2())) {
1514 }//if (aInt->IndexNew() == nV) {
1515 }//for (i = 0; i < aNbLines; ++i) {
1516 }//for (k=0; k<2; ++k) {
1520 //=======================================================================
1521 //function : GetEFPnts
1523 //=======================================================================
1524 void BOPAlgo_PaveFiller::GetEFPnts
1525 (const Standard_Integer nF1,
1526 const Standard_Integer nF2,
1527 IntSurf_ListOfPntOn2S& aListOfPnts)
1529 Standard_Integer nE, nF, nFOpposite, aNbEFs, i;
1530 Standard_Real U1, U2, V1, V2, f, l;
1531 BOPCol_MapOfInteger aMI;
1533 //collect indexes of all shapes from nF1 and nF2.
1534 GetFullShapeMap(nF1, aMI);
1535 GetFullShapeMap(nF2, aMI);
1537 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1538 aNbEFs = aEFs.Extent();
1540 for(i = 0; i < aNbEFs; ++i) {
1541 const BOPDS_InterfEF& aEF = aEFs(i);
1542 if (aEF.HasIndexNew()) {
1543 aEF.Indices(nE, nFOpposite);
1544 if(aMI.Contains(nE) && aMI.Contains(nFOpposite)) {
1545 const IntTools_CommonPrt& aCP = aEF.CommonPart();
1546 Standard_Real aPar = aCP.VertexParameter1();
1547 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&myDS->Shape(nE)));
1548 const TopoDS_Face& aFOpposite =
1549 (*(TopoDS_Face*)(&myDS->Shape(nFOpposite)));
1551 const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(aE, f, l);
1553 nF = (nFOpposite == nF1) ? nF2 : nF1;
1554 const TopoDS_Face& aF = (*(TopoDS_Face*)(&myDS->Shape(nF)));
1555 Handle(Geom2d_Curve) aPCurve =
1556 BRep_Tool::CurveOnSurface(aE, aF, f, l);
1558 GeomAPI_ProjectPointOnSurf& aProj=myContext->ProjPS(aFOpposite);
1561 aCurve->D0(aPar, aPoint);
1562 IntSurf_PntOn2S aPnt;
1563 if(!aPCurve.IsNull()) {
1564 gp_Pnt2d aP2d = aPCurve->Value(aPar);
1565 aProj.Perform(aPoint);
1566 if(aProj.IsDone()) {
1567 aProj.LowerDistanceParameters(U1,V1);
1569 aPnt.SetValue(aP2d.X(),aP2d.Y(),U1,V1);
1571 aPnt.SetValue(U1,V1,aP2d.X(),aP2d.Y());
1573 aListOfPnts.Append(aPnt);
1577 GeomAPI_ProjectPointOnSurf& aProj1 = myContext->ProjPS(aF);
1578 aProj1.Perform(aPoint);
1579 aProj.Perform(aPoint);
1580 if(aProj1.IsDone() && aProj.IsDone()){
1581 aProj1.LowerDistanceParameters(U1,V1);
1582 aProj.LowerDistanceParameters(U2,V2);
1584 aPnt.SetValue(U1,V1,U2,V2);
1586 aPnt.SetValue(U2,V2,U1,V1);
1588 aListOfPnts.Append(aPnt);
1596 //=======================================================================
1597 //function : ProcessUnUsedVertices
1599 //=======================================================================
1600 void BOPAlgo_PaveFiller::PutEFPavesOnCurve
1602 const BOPCol_MapOfInteger& aMI,
1603 const BOPCol_MapOfInteger& aMVEF,
1604 BOPCol_DataMapOfIntegerReal& aMVTol)
1606 if (!aMVEF.Extent()) {
1610 const IntTools_Curve& aIC=aNC.Curve();
1611 GeomAbs_CurveType aTypeC;
1613 if (!(aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve)) {
1617 Standard_Integer nV;
1618 BOPCol_MapOfInteger aMV;
1621 RemoveUsedVertices(aNC, aMV);
1622 if (!aMV.Extent()) {
1626 Standard_Real aDist;
1629 const Handle(Geom_Curve)& aC3D=aIC.Curve();
1630 GeomAPI_ProjectPointOnCurve& aProjPT = myContext->ProjPT(aC3D);
1632 BOPCol_MapIteratorOfMapOfInteger aItMI;
1633 aItMI.Initialize(aMV);
1634 for (; aItMI.More(); aItMI.Next()) {
1636 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1637 gp_Pnt aPV = BRep_Tool::Pnt(aV);
1638 aProjPT.Perform(aPV);
1639 Standard_Integer aNbPoints = aProjPT.NbPoints();
1641 aDist = aProjPT.LowerDistance();
1642 PutPaveOnCurve(nV, aDist, aNC, aMI, aMVTol);
1647 //=======================================================================
1648 //function : ProcessUnUsedVertices
1650 //=======================================================================
1651 void BOPAlgo_PaveFiller::PutStickPavesOnCurve
1652 (const TopoDS_Face& aF1,
1653 const TopoDS_Face& aF2,
1654 const BOPCol_MapOfInteger& aMI,
1656 const BOPCol_MapOfInteger& aMVStick,
1657 BOPCol_DataMapOfIntegerReal& aMVTol)
1659 BOPCol_MapOfInteger aMV;
1660 aMV.Assign(aMVStick);
1661 RemoveUsedVertices(aNC, aMV);
1663 if (!aMV.Extent()) {
1667 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
1668 Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2);
1670 const IntTools_Curve& aIC=aNC.Curve();
1671 //if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) {
1672 Handle(Geom2d_Curve) aC2D[2];
1674 aC2D[0]=aIC.FirstCurve2d();
1675 aC2D[1]=aIC.SecondCurve2d();
1676 if (!aC2D[0].IsNull() && !aC2D[1].IsNull()) {
1677 Standard_Integer nV, m, n;
1678 Standard_Real aTC[2], aD, aD2, u, v, aDT2, aScPr, aDScPr;
1682 BOPCol_MapIteratorOfMapOfInteger aItMI, aItMI1;
1684 aDT2=2e-7; // the rich criteria
1685 aDScPr=5.e-9; // the creasing criteria
1686 aIC.Bounds(aTC[0], aTC[1], aPC[0], aPC[1]);
1688 aItMI.Initialize(aMV);
1689 for (; aItMI.More(); aItMI.Next()) {
1691 const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&myDS->Shape(nV));
1692 aPV=BRep_Tool::Pnt(aV);
1694 for (m=0; m<2; ++m) {
1695 aD2=aPC[m].SquareDistance(aPV);
1696 if (aD2>aDT2) {// no rich
1700 for (n=0; n<2; ++n) {
1701 Handle(Geom_Surface)& aS=(!n)? aS1 : aS2;
1702 aC2D[n]->D0(aTC[m], aP2D);
1704 BOPTools_AlgoTools3D::GetNormalToSurface(aS, u, v, aDN[n]);
1707 aScPr=aDN[0]*aDN[1];
1717 // The intersection curve aIC is vanishing curve (the crease)
1720 PutPaveOnCurve(nV, aD, aNC, aMI, aMVTol);
1722 }//for (jVU=1; jVU=aNbVU; ++jVU) {
1724 //}//if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) {
1725 //}//if(aType1==GeomAbs_Torus || aType2==GeomAbs_Torus) {
1728 //=======================================================================
1729 //function : GetStickVertices
1731 //=======================================================================
1732 void BOPAlgo_PaveFiller::GetStickVertices(const Standard_Integer nF1,
1733 const Standard_Integer nF2,
1734 BOPCol_MapOfInteger& aMVStick,
1735 BOPCol_MapOfInteger& aMVEF,
1736 BOPCol_MapOfInteger& aMI)
1738 Standard_Integer nS1, nS2, nVNew, aTypeInt, i;
1740 BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV();
1741 BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
1742 BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
1743 BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
1744 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1746 Standard_Integer aNbLines[5] = {
1747 aVVs.Extent(), aVEs.Extent(), aEEs.Extent(),
1748 aVFs.Extent(), aEFs.Extent()
1750 //collect indices of all shapes from nF1 and nF2.
1752 GetFullShapeMap(nF1, aMI);
1753 GetFullShapeMap(nF2, aMI);
1755 //collect VV, VE, EE, VF interferences
1756 for (aTypeInt = 0; aTypeInt < 4; ++aTypeInt) {
1757 for (i = 0; i < aNbLines[aTypeInt]; ++i) {
1758 BOPDS_Interf* aInt = (aTypeInt==0) ? (BOPDS_Interf*)(&aVVs(i)) :
1759 ((aTypeInt==1) ? (BOPDS_Interf*)(&aVEs(i)) :
1760 ((aTypeInt==2) ? (BOPDS_Interf*)(&aEEs(i)) :
1761 (BOPDS_Interf*)(&aVFs(i))));
1762 if (aInt->HasIndexNew()) {
1763 aInt->Indices(nS1, nS2);
1764 if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
1765 nVNew = aInt->IndexNew();
1766 aMVStick.Add(nVNew);
1771 //collect EF interferences
1772 for (i = 0; i < aNbLines[4]; ++i) {
1773 const BOPDS_InterfEF& aInt = aEFs(i);
1774 if (aInt.HasIndexNew()) {
1775 aInt.Indices(nS1, nS2);
1776 if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
1777 nVNew = aInt.IndexNew();
1778 aMVStick.Add(nVNew);
1785 //=======================================================================
1786 // function: GetFullShapeMap
1788 //=======================================================================
1789 void BOPAlgo_PaveFiller::GetFullShapeMap(const Standard_Integer nF,
1790 BOPCol_MapOfInteger& aMI)
1792 BOPCol_ListIteratorOfListOfInteger aIt;
1793 Standard_Integer nS;
1795 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF);
1796 const BOPCol_ListOfInteger& aLI = aSI.SubShapes();
1799 aIt.Initialize(aLI);
1800 for (; aIt.More(); aIt.Next()) {
1806 //=======================================================================
1807 // function: RemoveUsedVertices
1809 //=======================================================================
1810 void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC,
1811 BOPCol_MapOfInteger& aMV)
1813 if (!aMV.Extent()) {
1816 Standard_Integer nV;
1818 BOPDS_ListIteratorOfListOfPave aItLP;
1820 Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
1821 const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
1822 aItLP.Initialize(aLP);
1823 for (;aItLP.More();aItLP.Next()) {
1824 aPave = aItLP.Value();
1830 //=======================================================================
1831 //function : PutPaveOnCurve
1833 //=======================================================================
1834 void BOPAlgo_PaveFiller::PutPaveOnCurve
1835 (const Standard_Integer nV,
1836 const Standard_Real aTolR3D,
1838 const BOPCol_MapOfInteger& aMI,
1839 BOPCol_DataMapOfIntegerReal& aMVTol,
1840 const Standard_Integer iCheckExtend)
1842 Standard_Boolean bIsVertexOnLine;
1843 Standard_Real aT, aTolV;
1845 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1846 Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
1847 const IntTools_Curve& aIC = aNC.Curve();
1849 bIsVertexOnLine=myContext->IsVertexOnLine(aV, aIC, aTolR3D, aT);
1850 if (!bIsVertexOnLine && iCheckExtend) {
1851 aTolV = BRep_Tool::Tolerance(aV);
1853 ExtendedTolerance(nV, aMI, aTolV, iCheckExtend);
1854 bIsVertexOnLine=myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D, aT);
1857 if (bIsVertexOnLine) {
1858 // check if aPB contains the parameter aT
1859 Standard_Boolean bExist;
1860 Standard_Integer nVToUpdate;
1861 Standard_Real aPTol, aDist, aTolVNew, aTolV2, aDTol;
1862 TopoDS_Vertex aVToUpdate;
1868 GeomAdaptor_Curve aGAC(aIC.Curve());
1869 aPTol = aGAC.Resolution(aTolR3D);
1871 bExist = aPB->ContainsParameter(aT, aPTol, nVToUpdate);
1873 // use existing pave
1874 aP1 = BRep_Tool::Pnt(aV);
1875 aTolV2 = BRep_Tool::Tolerance(aV);
1876 aVToUpdate = (*(TopoDS_Vertex *)(&myDS->Shape(nVToUpdate)));
1882 aPave.SetParameter(aT);
1883 aPB->AppendExtPave(aPave);
1885 aP1 = aGAC.Value(aT);
1890 aTolV = BRep_Tool::Tolerance(aVToUpdate);
1891 aP2 = BRep_Tool::Pnt(aVToUpdate);
1892 aDist = aP1.Distance(aP2);
1893 aTolVNew = Max(aDist - aTolV2, aTolR3D);
1895 if (aTolVNew > aTolV) {
1897 aBB.UpdateVertex(aVToUpdate, aTolVNew+aDTol);
1899 if (!aMVTol.IsBound(nVToUpdate)) {
1900 aMVTol.Bind(nVToUpdate, aTolV);
1903 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nVToUpdate);
1904 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
1905 BRepBndLib::Add(aVToUpdate, aBoxDS);
1906 aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
1911 //=======================================================================
1912 //function : ProcessOldPaveBlocks
1914 //=======================================================================
1915 void BOPAlgo_PaveFiller::ProcessExistingPaveBlocks
1916 (const Standard_Integer theInt,
1917 const BOPDS_IndexedMapOfPaveBlock& aMPBOnIn,
1918 const BOPCol_DataMapOfIntegerListOfInteger& aDMBV,
1919 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
1920 BOPCol_DataMapOfShapeInteger& aMVI,
1921 BOPDS_MapOfPaveBlock& aMPB)
1923 if (aDMBV.IsEmpty()) {
1927 Standard_Real aT, dummy;
1928 Standard_Integer i, nV, nE, iC, aNbPB, iFlag;
1929 BOPCol_ListIteratorOfListOfInteger aItLI;
1930 BOPCol_DataMapIteratorOfDataMapOfIntegerListOfInteger aItBV;
1932 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
1933 BOPDS_InterfFF& aFF = aFFs(theInt);
1934 BOPDS_VectorOfCurve& aVC = aFF.ChangeCurves();
1936 aNbPB = aMPBOnIn.Extent();
1938 aItBV.Initialize(aDMBV);
1939 for (; aItBV.More(); aItBV.Next()) {
1941 const BOPCol_ListOfInteger& aLBV = aItBV.Value();
1943 BOPDS_Curve& aNC = aVC.ChangeValue(iC);
1944 BOPDS_ListOfPaveBlock& aLPBC = aNC.ChangePaveBlocks();
1946 aItLI.Initialize(aLBV);
1947 for (; aItLI.More(); aItLI.Next()) {
1949 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1950 const Bnd_Box& aBoxV=aSIV.Box();
1951 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aSIV.Shape();
1952 if (!aMVI.IsBound(aV)) {
1956 for (i = 1; i <= aNbPB; ++i) {
1957 const Handle(BOPDS_PaveBlock)& aPB = aMPBOnIn(i);
1958 if (aPB->Pave1().Index() == nV || aPB->Pave2().Index() == nV) {
1962 if (aMPB.Contains(aPB)) {
1965 if (myDS->ShapeInfo(aPB->OriginalEdge()).HasFlag()) { // skip degenerated edges
1970 const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE);
1971 const Bnd_Box& aBoxE = aSIE.Box();
1973 if (aBoxV.IsOut(aBoxE)) {
1977 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aSIE.Shape();
1979 iFlag = myContext->ComputeVE(aV, aE, aT, dummy);
1982 PreparePostTreatFF(theInt, iC, aPB, aMSCPB, aMVI, aLPBC);
1988 //=======================================================================
1989 //function : UpdateExistingPaveBlocks
1991 //=======================================================================
1992 void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks
1993 (const Handle(BOPDS_PaveBlock)& aPBf,
1994 BOPDS_ListOfPaveBlock& aLPB,
1995 const Standard_Integer nF1,
1996 const Standard_Integer nF2)
1998 if (!aLPB.Extent()) {
2002 Standard_Integer nE;
2003 Standard_Boolean bCB;
2004 Handle(BOPDS_PaveBlock) aPB, aPB1, aPB2, aPB2n;
2005 Handle(BOPDS_CommonBlock) aCB;
2006 BOPDS_ListIteratorOfListOfPaveBlock aIt, aIt1, aIt2;
2008 BOPDS_FaceInfo& aFI1 = myDS->ChangeFaceInfo(nF1);
2009 BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2);
2011 BOPDS_IndexedMapOfPaveBlock& aMPBOn1 = aFI1.ChangePaveBlocksOn();
2012 BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.ChangePaveBlocksIn();
2013 BOPDS_IndexedMapOfPaveBlock& aMPBOn2 = aFI2.ChangePaveBlocksOn();
2014 BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.ChangePaveBlocksIn();
2016 // 1. Remove old pave blocks
2017 const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPBf);
2018 bCB = !aCB1.IsNull();
2019 BOPDS_ListOfPaveBlock aLPB1;
2022 aLPB1.Assign(aCB1->PaveBlocks());
2026 aIt1.Initialize(aLPB1);
2027 for (; aIt1.More(); aIt1.Next()) {
2028 aPB1 = aIt1.Value();
2029 nE = aPB1->OriginalEdge();
2031 BOPDS_ListOfPaveBlock& aLPB2 = myDS->ChangePaveBlocks(nE);
2032 aIt2.Initialize(aLPB2);
2033 for (; aIt2.More(); aIt2.Next()) {
2034 aPB2 = aIt2.Value();
2042 // 2. Update pave blocks
2044 //create new common blocks
2045 BOPDS_ListOfPaveBlock aLPBNew;
2046 const BOPCol_ListOfInteger& aFaces = aCB1->Faces();
2047 aIt.Initialize(aLPB);
2048 for (; aIt.More(); aIt.Next()) {
2049 const Handle(BOPDS_PaveBlock)& aPBValue = aIt.Value();
2051 aCB = new BOPDS_CommonBlock;
2052 aIt1.Initialize(aLPB1);
2053 for (; aIt1.More(); aIt1.Next()) {
2054 aPB2 = aIt1.Value();
2055 nE = aPB2->OriginalEdge();
2057 aPB2n = new BOPDS_PaveBlock;
2058 aPB2n->SetPave1(aPBValue->Pave1());
2059 aPB2n->SetPave2(aPBValue->Pave2());
2060 aPB2n->SetEdge(aPBValue->Edge());
2061 aPB2n->SetOriginalEdge(nE);
2062 aCB->AddPaveBlock(aPB2n);
2063 myDS->SetCommonBlock(aPB2n, aCB);
2064 myDS->ChangePaveBlocks(nE).Append(aPB2n);
2066 aCB->SetFaces(aFaces);
2067 myDS->SortPaveBlocks(aCB);
2069 const Handle(BOPDS_PaveBlock)& aPBNew = aCB->PaveBlocks().First();
2070 aLPBNew.Append(aPBNew);
2076 nE = aPBf->OriginalEdge();
2077 BOPDS_ListOfPaveBlock& aLPBE = myDS->ChangePaveBlocks(nE);
2078 aIt.Initialize(aLPB);
2079 for (; aIt.More(); aIt.Next()) {
2085 Standard_Boolean bIn1, bIn2;
2087 bIn1 = aMPBOn1.Contains(aPBf) || aMPBIn1.Contains(aPBf);
2088 bIn2 = aMPBOn2.Contains(aPBf) || aMPBIn2.Contains(aPBf);
2094 // 3. Check new pave blocks for coincidence
2095 // with the opposite face.
2096 // In case of coincidence create common blocks
2097 Standard_Integer nF;
2098 Standard_Real aTolE, aTolF;
2100 nF = bIn1 ? nF2 : nF1;
2101 const TopoDS_Face& aF = *(TopoDS_Face*)&myDS->Shape(nF);
2102 BOPDS_IndexedMapOfPaveBlock& aMPBIn = bIn1 ? aMPBIn2 : aMPBIn1;
2103 aTolF = BRep_Tool::Tolerance(aF);
2105 aIt.Initialize(aLPB);
2106 for (; aIt.More(); aIt.Next()) {
2107 Handle(BOPDS_PaveBlock)& aPBChangeValue = aIt.ChangeValue();
2108 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPBChangeValue->Edge());
2109 aTolE = BRep_Tool::Tolerance(aE);
2111 IntTools_EdgeFace anEF;
2114 anEF.SetTolE(aTolE);
2115 anEF.SetTolF(aTolF);
2116 anEF.SetRange(aPBChangeValue->Pave1().Parameter(), aPBChangeValue->Pave2().Parameter());
2117 anEF.SetContext(myContext);
2120 const IntTools_SequenceOfCommonPrts& aCPrts=anEF.CommonParts();
2121 if (aCPrts.Length() == 1) {
2122 Standard_Boolean bCoinc = (aCPrts(1).Type() == TopAbs_EDGE);
2125 aCB = myDS->CommonBlock(aPBChangeValue);
2127 aCB = new BOPDS_CommonBlock;
2128 aCB->AddPaveBlock(aPBChangeValue);
2129 myDS->SetCommonBlock(aPBChangeValue, aCB);
2133 aMPBIn.Add(aPBChangeValue);
2138 //=======================================================================
2139 // function: PutClosingPaveOnCurve
2141 //=======================================================================
2142 void BOPAlgo_PaveFiller::PutClosingPaveOnCurve(BOPDS_Curve& aNC)
2144 Standard_Boolean bIsClosed, bHasBounds, bAdded;
2145 Standard_Integer nVC, j;
2146 Standard_Real aT[2], aTC, dT, aTx;
2149 BOPDS_ListIteratorOfListOfPave aItLP;
2151 const IntTools_Curve& aIC=aNC.Curve();
2152 const Handle(Geom_Curve)& aC3D=aIC.Curve();
2157 bIsClosed=IntTools_Tools::IsClosed(aC3D);
2162 bHasBounds=aIC.HasBounds ();
2167 bAdded=Standard_False;
2168 dT=Precision::PConfusion();
2169 aIC.Bounds (aT[0], aT[1], aP[0], aP[1]);
2171 Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
2172 BOPDS_ListOfPave& aLP=aPB->ChangeExtPaves();
2174 aItLP.Initialize(aLP);
2175 for (; aItLP.More() && !bAdded; aItLP.Next()) {
2176 const BOPDS_Pave& aPC=aItLP.Value();
2178 aTC=aPC.Parameter();
2180 for (j=0; j<2; ++j) {
2181 if (fabs(aTC-aT[j]) < dT) {
2182 aTx=(!j) ? aT[1] : aT[0];
2184 aPVx.SetParameter(aTx);
2187 bAdded=Standard_True;
2193 //=======================================================================
2194 //function : PreparePostTreatFF
2196 //=======================================================================
2197 void BOPAlgo_PaveFiller::PreparePostTreatFF
2198 (const Standard_Integer aInt,
2199 const Standard_Integer aCur,
2200 const Handle(BOPDS_PaveBlock)& aPB,
2201 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
2202 BOPCol_DataMapOfShapeInteger& aMVI,
2203 BOPDS_ListOfPaveBlock& aLPBC)
2205 Standard_Integer nV1, nV2;
2209 aPB->Indices(nV1, nV2);
2210 const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
2211 const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
2212 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPB->Edge());
2213 // Keep info for post treatment
2214 BOPDS_CoupleOfPaveBlocks aCPB;
2215 aCPB.SetIndexInterf(aInt);
2216 aCPB.SetIndex(aCur);
2217 aCPB.SetPaveBlock1(aPB);
2219 aMSCPB.Add(aE, aCPB);
2220 aMVI.Bind(aV1, nV1);
2221 aMVI.Bind(aV2, nV2);
2224 //=======================================================================
2225 //function : CheckPlanes
2227 //=======================================================================
2228 Standard_Boolean BOPAlgo_PaveFiller::CheckPlanes
2229 (const Standard_Integer nF1,
2230 const Standard_Integer nF2)const
2232 Standard_Boolean bToIntersect;
2233 Standard_Integer i, nV2, iCnt;
2234 BOPCol_MapIteratorOfMapOfInteger aIt;
2236 bToIntersect=Standard_False;
2238 const BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
2239 const BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
2241 const BOPCol_MapOfInteger& aMVIn1=aFI1.VerticesIn();
2242 const BOPCol_MapOfInteger& aMVOn1=aFI1.VerticesOn();
2245 for (i=0; (i<2 && !bToIntersect); ++i) {
2246 const BOPCol_MapOfInteger& aMV2=(!i) ? aFI2.VerticesIn()
2247 : aFI2.VerticesOn();
2249 aIt.Initialize(aMV2);
2250 for (; aIt.More(); aIt.Next()) {
2252 if (aMVIn1.Contains(nV2) || aMVOn1.Contains(nV2)) {
2255 bToIntersect=!bToIntersect;
2262 return bToIntersect;
2264 //=======================================================================
2265 //function : UpdatePaveBlocks
2267 //=======================================================================
2268 void BOPAlgo_PaveFiller::UpdatePaveBlocks
2269 (const BOPCol_DataMapOfIntegerInteger& aDMI)
2271 if (aDMI.IsEmpty()) {
2275 Standard_Integer nSp, aNbPBP, nV[2], i, j;
2276 Standard_Real aT[2];
2277 Standard_Boolean bCB, bRebuild;
2278 BOPDS_ListIteratorOfListOfPaveBlock aItPB;
2279 BOPDS_MapOfPaveBlock aMPB;
2280 BOPCol_MapOfInteger aMicroEdges;
2282 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
2283 aNbPBP = aPBP.Extent();
2284 for (i = 0; i < aNbPBP; ++i) {
2285 BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2287 aItPB.Initialize(aLPB);
2288 for (; aItPB.More(); aItPB.Next()) {
2289 Handle(BOPDS_PaveBlock) aPB = aItPB.Value();
2290 const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
2291 bCB = !aCB.IsNull();
2293 aPB = aCB->PaveBlock1();
2296 if (aMPB.Add(aPB)) {
2297 bRebuild = Standard_False;
2298 aPB->Indices(nV[0], nV[1]);
2299 aPB->Range(aT[0], aT[1]);
2300 // remember the fact if the edge had different vertices before substitution
2301 Standard_Boolean wasRegularEdge = (nV[0] != nV[1]);
2303 for (j = 0; j < 2; ++j) {
2304 if (aDMI.IsBound(nV[j])) {
2307 nV[j] = aDMI.Find(nV[j]);
2308 aPave.SetIndex(nV[j]);
2309 aPave.SetParameter(aT[j]);
2311 bRebuild = Standard_True;
2313 aPB->SetPave1(aPave);
2316 aPB->SetPave2(aPave);
2322 Standard_Boolean isDegEdge = myDS->ShapeInfo(aPB->Edge()).HasFlag();
2323 if (wasRegularEdge && !isDegEdge && nV[0] == nV[1]) {
2324 // now edge has the same vertex on both ends;
2325 // check if it is not a regular closed curve.
2326 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(aPB->Edge()));
2327 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV[0]));
2328 Standard_Real aLength = IntTools::Length(aE);
2329 Standard_Real aTolV = BRep_Tool::Tolerance(aV);
2330 if (aLength <= aTolV * 2.) {
2331 // micro edge, so mark it for removal
2332 aMicroEdges.Add(aPB->Edge());
2336 nSp = SplitEdge(aPB->OriginalEdge(), nV[0], aT[0], nV[1], aT[1]);
2344 }// if (aMPB.Add(aPB)) {
2345 }// for (; aItPB.More(); aItPB.Next()) {
2346 }// for (i=0; i<aNbPBP; ++i) {
2349 if (aMicroEdges.Extent())
2350 RemovePaveBlocks(aMicroEdges);
2352 //=======================================================================
2353 //function : RemovePaveBlocks
2355 //=======================================================================
2356 void BOPAlgo_PaveFiller::RemovePaveBlocks(const BOPCol_MapOfInteger theEdges)
2358 // Remove all pave blocks referring to input edges:
2360 // 1. from the Pave Blocks Pool
2361 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
2362 Standard_Integer aNbPBP = aPBP.Extent(), i;
2363 for (i = 0; i < aNbPBP; ++i) {
2364 BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2366 BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
2367 while (aItPB.More()) {
2368 const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
2369 if (theEdges.Contains(aPB->Edge()))
2376 // 2. from Face Info and section curves
2377 BOPCol_MapOfInteger aMPassed;
2378 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2379 Standard_Integer aNbFF = aFFs.Extent(), j;
2380 for (i = 0; i < aNbFF; ++i) {
2381 BOPDS_InterfFF& aFF = aFFs(i);
2382 Standard_Integer nF1, nF2;
2383 aFF.Indices(nF1, nF2);
2385 // rebuild pave block maps of face info
2386 for (j = 0; j < 2; j++) {
2387 Standard_Integer nF = (j == 0 ? nF1 : nF2);
2388 if (!aMPassed.Add(nF))
2390 BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF);
2391 BOPDS_IndexedMapOfPaveBlock* aIMPB[] = { &aFI.ChangePaveBlocksIn(),
2392 &aFI.ChangePaveBlocksOn(), &aFI.ChangePaveBlocksSc() };
2393 for (Standard_Integer k = 0; k < 3; k++) {
2394 Standard_Integer aNbPB = aIMPB[k]->Extent(), m;
2395 for (m = 1; m <= aNbPB; ++m) {
2396 const Handle(BOPDS_PaveBlock)& aPB = aIMPB[k]->FindKey(m);
2397 if (theEdges.Contains(aPB->Edge()))
2401 BOPDS_IndexedMapOfPaveBlock aMPBCopy = *aIMPB[k];
2403 for (m = 1; m <= aNbPB; ++m) {
2404 const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(m);
2405 if (!theEdges.Contains(aPB->Edge()))
2411 // remove from Section pave blocks
2412 BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
2413 Standard_Integer aNbC = aVNC.Extent();
2414 for (j = 0; j < aNbC; ++j) {
2415 BOPDS_Curve& aNC = aVNC(j);
2416 BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
2417 BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
2418 while (aItPB.More()) {
2419 const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
2420 if (theEdges.Contains(aPB->Edge()))
2429 //=======================================================================
2430 //function : ToleranceFF
2431 //purpose : Computes the TolFF according to the tolerance value and
2432 // types of the faces.
2433 //=======================================================================
2434 void ToleranceFF(const BRepAdaptor_Surface& aBAS1,
2435 const BRepAdaptor_Surface& aBAS2,
2436 Standard_Real& aTolFF)
2438 Standard_Real aTol1, aTol2;
2439 Standard_Boolean isAna1, isAna2;
2441 aTol1 = aBAS1.Tolerance();
2442 aTol2 = aBAS2.Tolerance();
2443 aTolFF = Max(aTol1, aTol2);
2445 isAna1 = (aBAS1.GetType() == GeomAbs_Plane ||
2446 aBAS1.GetType() == GeomAbs_Cylinder ||
2447 aBAS1.GetType() == GeomAbs_Cone ||
2448 aBAS1.GetType() == GeomAbs_Sphere ||
2449 aBAS1.GetType() == GeomAbs_Torus);
2451 isAna2 = (aBAS2.GetType() == GeomAbs_Plane ||
2452 aBAS2.GetType() == GeomAbs_Cylinder ||
2453 aBAS2.GetType() == GeomAbs_Cone ||
2454 aBAS2.GetType() == GeomAbs_Sphere ||
2455 aBAS2.GetType() == GeomAbs_Torus);
2457 if (!isAna1 || !isAna2) {
2458 aTolFF = Max(aTolFF, 5.e-6);
2461 //=======================================================================
2462 //function : UpdateBlocksWithSharedVertices
2464 //=======================================================================
2465 void BOPAlgo_PaveFiller::UpdateBlocksWithSharedVertices()
2467 if (!myNonDestructive) {
2473 Standard_Integer aNbFF;
2475 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
2476 aNbFF=aFFs.Extent();
2481 Standard_Boolean bOnCurve, bHasShapeSD;
2482 Standard_Integer i, nF1, nF2, aNbC, j, nV, nVSD;
2483 Standard_Real aTolR3D, aTolV;
2484 BOPCol_MapOfInteger aMF;
2486 for (i=0; i<aNbFF; ++i) {
2487 BOPDS_InterfFF& aFF=aFFs(i);
2489 BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
2495 aFF.Indices(nF1, nF2);
2496 aTolR3D=aFF.TolR3D();
2499 myDS->UpdateFaceInfoOn(nF1);
2502 myDS->UpdateFaceInfoOn(nF2);
2505 // Collect old vertices that are shared for nF1, nF2 ->aMI;
2506 BOPCol_MapOfInteger aMI;
2507 BOPCol_MapIteratorOfMapOfInteger aItMI;
2509 BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
2510 BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
2512 const BOPCol_MapOfInteger& aMVOn1=aFI1.VerticesOn();
2513 const BOPCol_MapOfInteger& aMVIn1=aFI1.VerticesIn();
2514 const BOPCol_MapOfInteger& aMVOn2=aFI2.VerticesOn();
2515 const BOPCol_MapOfInteger& aMVIn2=aFI2.VerticesIn();
2517 for (j=0; j<2; ++j) {
2518 const BOPCol_MapOfInteger& aMV1=(!j) ? aMVOn1 : aMVIn1;
2519 aItMI.Initialize(aMV1);
2520 for (; aItMI.More(); aItMI.Next()) {
2522 if (myDS->IsNewShape(nV)) {
2525 if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV)) {
2531 // Try to put vertices aMI on curves
2532 for (j=0; j<aNbC; ++j) {
2533 BOPDS_Curve& aNC=aVC.ChangeValue(j);
2534 //const IntTools_Curve& aIC=aNC.Curve();
2536 aItMI.Initialize(aMI);
2537 for (; aItMI.More(); aItMI.Next()) {
2540 bHasShapeSD=myDS->HasShapeSD(nV, nVSD);
2545 bOnCurve=EstimatePaveOnCurve(nV, aNC, aTolR3D);
2550 const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV));
2551 aTolV=BRep_Tool::Tolerance(aV);
2553 UpdateVertex(nV, aTolV);
2555 }//for (j=0; j<aNbC; ++j) {
2556 }//for (i=0; i<aNbFF; ++i) {
2558 UpdateCommonBlocksWithSDVertices();
2560 //=======================================================================
2561 //function : EstimatePaveOnCurve
2563 //=======================================================================
2564 Standard_Boolean BOPAlgo_PaveFiller::EstimatePaveOnCurve
2565 (const Standard_Integer nV,
2566 const BOPDS_Curve& aNC,
2567 const Standard_Real aTolR3D)
2569 Standard_Boolean bIsVertexOnLine;
2572 const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV));
2573 const IntTools_Curve& aIC=aNC.Curve();
2575 bIsVertexOnLine=myContext->IsVertexOnLine(aV, aIC, aTolR3D, aT);
2576 return bIsVertexOnLine;
2579 //=======================================================================
2580 //function : CorrectToleranceOfSE
2582 //=======================================================================
2583 void BOPAlgo_PaveFiller::CorrectToleranceOfSE()
2585 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2586 NCollection_IndexedDataMap<Standard_Integer,BOPDS_ListOfPaveBlock> aMVIPBs;
2587 BOPCol_MapOfInteger aMVIToReduce;
2589 // 1. iterate on all sections F-F
2590 Standard_Integer aNb = aFFs.Extent(), i;
2591 for (i = 0; i < aNb; ++i) {
2592 BOPDS_InterfFF& aFF = aFFs(i);
2593 Standard_Real aTolR3D = aFF.TolR3D();
2594 Standard_Real aTolReal = aFF.TolReal();
2595 Standard_Boolean bToReduce = aTolReal < aTolR3D;
2596 // tolerance of intersection has been increased, so process this intersection
2597 BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
2598 Standard_Integer aNbC = aVNC.Extent(), k;
2599 for (k = 0; k < aNbC; ++k) {
2600 BOPDS_Curve& aNC = aVNC(k);
2601 BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
2602 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
2603 for (; aItLPB.More(); ) {
2604 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
2605 Standard_Integer nE;
2606 if (!aPB->HasEdge(nE)) {
2607 aLPB.Remove(aItLPB);
2611 Standard_Boolean bIsReduced = Standard_False;
2612 if (bToReduce && (aPB->OriginalEdge() < 0)) {
2613 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
2614 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
2615 if (aTolReal < aTolE) {
2616 // reduce edge tolerance
2617 reinterpret_cast<BRep_TEdge*>(aE.TShape().operator->())->Tolerance(aTolReal);
2618 bIsReduced = Standard_True;
2622 // fill in the map vertex index - pave blocks
2623 for (Standard_Integer j=0; j < 2; j++) {
2624 Standard_Integer nV = (j == 0 ? aPB->Pave1().Index() : aPB->Pave2().Index());
2625 BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV);
2627 pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock()));
2629 pPBList->Append(aPB);
2631 aMVIToReduce.Add(nV);
2639 if (aMVIToReduce.IsEmpty()) {
2643 // 2. try to reduce tolerances of connected vertices
2644 // 2.1 find all other edges containing these connected vertices to avoid
2645 // reducing the tolerance to the value less than the tolerances of edges,
2646 // i.e. minimal tolerance for the vertex is the max tolerance of the
2647 // edges containing this vertex
2648 BOPCol_DataMapOfIntegerReal aMVITol;
2649 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
2650 aNb = aPBP.Extent();
2651 for (i = 0; i < aNb; ++i) {
2652 const BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2653 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
2654 for (; aItLPB.More(); aItLPB.Next()) {
2655 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
2656 Standard_Integer nE;
2657 if (!aPB->HasEdge(nE)) {
2660 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
2661 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
2663 Standard_Integer nV[2];
2664 aPB->Indices(nV[0], nV[1]);
2666 for (Standard_Integer j = 0; j < 2; j++) {
2667 if (aMVIToReduce.Contains(nV[j])) {
2668 Standard_Real *aMaxTol = aMVITol.ChangeSeek(nV[j]);
2670 aMVITol.Bind(nV[j], aTolE);
2672 else if (aTolE > *aMaxTol) {
2680 // 2.2 reduce tolerances if possible
2681 aNb = aMVIPBs.Extent();
2682 for (i = 1; i <= aNb; ++i) {
2683 Standard_Integer nV = aMVIPBs.FindKey(i);
2684 if (!aMVIToReduce.Contains(nV)) {
2688 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
2689 Standard_Real aTolV = BRep_Tool::Tolerance(aV);
2690 Standard_Real aMaxTol = aMVITol.IsBound(nV) ? aMVITol.Find(nV) : 0.;
2691 // it makes no sense to compute the real tolerance if it is
2692 // impossible to reduce the tolerance at least 0.1% of the current value
2693 if (aTolV - aMaxTol < 0.001 * aTolV) {
2697 // compute the maximal distance from the vertex to the adjacent edges
2698 gp_Pnt aP = BRep_Tool::Pnt(aV);
2700 const BOPDS_ListOfPaveBlock& aLPB = aMVIPBs.FindFromIndex(i);
2701 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
2702 for (; aItLPB.More(); aItLPB.Next()) {
2703 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
2704 Standard_Integer nE = aPB->Edge();
2705 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
2706 const BOPDS_Pave& aPave = (aPB->Pave1().Index() == nV ? aPB->Pave1() : aPB->Pave2());
2707 BRepAdaptor_Curve aC(aE);
2708 gp_Pnt aPonE = aC.Value(aPave.Parameter());
2709 Standard_Real aDist = aP.Distance(aPonE);
2710 aDist += BRep_Tool::Tolerance(aE);
2711 if (aDist > aMaxTol) {
2716 if (aMaxTol < aTolV) {
2717 reinterpret_cast<BRep_TVertex*>(aV.TShape().operator->())->Tolerance(aMaxTol);