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 <BOPAlgo_Alerts.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 Standard_Real ToleranceFF(const BRepAdaptor_Surface& aBAS1,
84 const BRepAdaptor_Surface& aBAS2);
86 /////////////////////////////////////////////////////////////////////////
87 //=======================================================================
88 //class : BOPAlgo_FaceFace
90 //=======================================================================
91 class BOPAlgo_FaceFace :
92 public IntTools_FaceFace,
101 myIF1(-1), myIF2(-1), myTolFF(1.e-7) {
104 virtual ~BOPAlgo_FaceFace() {
107 void SetIndices(const Standard_Integer nF1,
108 const Standard_Integer nF2) {
113 void Indices(Standard_Integer& nF1,
114 Standard_Integer& nF2) const {
119 void SetFaces(const TopoDS_Face& aF1,
120 const TopoDS_Face& aF2) {
125 const TopoDS_Face& Face1()const {
129 const TopoDS_Face& Face2()const {
133 void SetTolFF(const Standard_Real aTolFF) {
137 Standard_Real TolFF() const{
141 void SetFuzzyValue(const Standard_Real theFuzz) {
142 IntTools_FaceFace::SetFuzzyValue(theFuzz);
145 virtual void Perform() {
146 BOPAlgo_Algo::UserBreak();
151 IntTools_FaceFace::Perform(myF1, myF2);
153 catch (Standard_Failure)
155 AddError(new BOPAlgo_AlertIntersectionFailed);
160 Standard_Integer myIF1;
161 Standard_Integer myIF2;
162 Standard_Real myTolFF;
167 //=======================================================================
168 typedef BOPCol_NCVector
169 <BOPAlgo_FaceFace> BOPAlgo_VectorOfFaceFace;
171 typedef BOPCol_Functor
173 BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceFunctor;
176 <BOPAlgo_FaceFaceFunctor,
177 BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceCnt;
178 /////////////////////////////////////////////////////////////////////////
179 //=======================================================================
180 //function : PerformFF
182 //=======================================================================
183 void BOPAlgo_PaveFiller::PerformFF()
185 myIterator->Initialize(TopAbs_FACE, TopAbs_FACE);
186 Standard_Integer iSize = myIterator->ExpectedLength();
191 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
192 aFFs.SetIncrement(iSize);
194 // Options for the intersection algorithm
195 Standard_Boolean bApprox = mySectionAttribute.Approximation(),
196 bCompC2D1 = mySectionAttribute.PCurveOnS1(),
197 bCompC2D2 = mySectionAttribute.PCurveOnS2();
198 Standard_Real anApproxTol = 1.e-7;
199 // Post-processing options
200 Standard_Boolean bSplitCurve = Standard_False;
202 // Fence map to store faces with updated FaceInfo structure
203 BOPCol_MapOfInteger aMIFence;
204 // Prepare the pairs of faces for intersection
205 BOPAlgo_VectorOfFaceFace aVFaceFace;
206 Standard_Integer nF1, nF2;
208 for (; myIterator->More(); myIterator->Next()) {
209 myIterator->Value(nF1, nF2);
211 // Update/Initialize FaceInfo structure for first face
212 if (myDS->HasFaceInfo(nF1))
214 if (aMIFence.Add(nF1))
216 myDS->UpdateFaceInfoOn(nF1);
217 myDS->UpdateFaceInfoIn(nF1);
220 else if (myDS->HasInterfShapeSubShapes(nF2, nF1))
222 myDS->ChangeFaceInfo(nF1);
226 // Update/Initialize FaceInfo structure for second face
227 if (myDS->HasFaceInfo(nF2))
229 if (aMIFence.Add(nF2))
231 myDS->UpdateFaceInfoOn(nF2);
232 myDS->UpdateFaceInfoIn(nF2);
235 else if (myDS->HasInterfShapeSubShapes(nF1, nF2))
237 myDS->ChangeFaceInfo(nF2);
241 if (myGlue == BOPAlgo_GlueOff)
243 const TopoDS_Face& aF1 = (*(TopoDS_Face *)(&myDS->Shape(nF1)));
244 const TopoDS_Face& aF2 = (*(TopoDS_Face *)(&myDS->Shape(nF2)));
246 const BRepAdaptor_Surface& aBAS1 = myContext->SurfaceAdaptor(aF1);
247 const BRepAdaptor_Surface& aBAS2 = myContext->SurfaceAdaptor(aF2);
248 if (aBAS1.GetType() == GeomAbs_Plane &&
249 aBAS2.GetType() == GeomAbs_Plane) {
250 // Check if the planes are really interfering
251 Standard_Boolean bToIntersect = CheckPlanes(nF1, nF2);
253 BOPDS_InterfFF& aFF = aFFs.Append1();
254 aFF.SetIndices(nF1, nF2);
260 BOPAlgo_FaceFace& aFaceFace=aVFaceFace.Append1();
262 aFaceFace.SetIndices(nF1, nF2);
263 aFaceFace.SetFaces(aF1, aF2);
264 // compute minimal tolerance for the curves
265 Standard_Real aTolFF = ToleranceFF(aBAS1, aBAS2);
266 aFaceFace.SetTolFF(aTolFF);
268 IntSurf_ListOfPntOn2S aListOfPnts;
269 GetEFPnts(nF1, nF2, aListOfPnts);
270 Standard_Integer aNbLP = aListOfPnts.Extent();
272 aFaceFace.SetList(aListOfPnts);
275 aFaceFace.SetParameters(bApprox, bCompC2D1, bCompC2D2, anApproxTol);
276 aFaceFace.SetFuzzyValue(myFuzzyValue);
277 aFaceFace.SetProgressIndicator(myProgressIndicator);
280 // for the Glue mode just add all interferences of that type
281 BOPDS_InterfFF& aFF = aFFs.Append1();
282 aFF.SetIndices(nF1, nF2);
283 aFF.SetTangentFaces(Standard_False);
286 }//for (; myIterator->More(); myIterator->Next()) {
288 //======================================================
289 // Perform intersection
290 BOPAlgo_FaceFaceCnt::Perform(myRunParallel, aVFaceFace);
291 //======================================================
292 // Treatment of the results
293 Standard_Integer k, aNbFaceFace = aVFaceFace.Extent();
294 for (k = 0; k < aNbFaceFace; ++k) {
295 BOPAlgo_FaceFace& aFaceFace = aVFaceFace(k);
296 aFaceFace.Indices(nF1, nF2);
297 if (!aFaceFace.IsDone() || aFaceFace.HasErrors()) {
298 BOPDS_InterfFF& aFF = aFFs.Append1();
299 aFF.SetIndices(nF1, nF2);
301 // Warn about failed intersection of faces
302 AddIntersectionFailedWarning(aFaceFace.Face1(), aFaceFace.Face2());
306 Standard_Boolean bTangentFaces = aFaceFace.TangentFaces();
307 Standard_Real aTolFF = aFaceFace.TolFF();
309 aFaceFace.PrepareLines3D(bSplitCurve);
311 const IntTools_SequenceOfCurves& aCvsX = aFaceFace.Lines();
312 const IntTools_SequenceOfPntOn2Faces& aPntsX = aFaceFace.Points();
314 Standard_Integer aNbCurves = aCvsX.Length();
315 Standard_Integer aNbPoints = aPntsX.Length();
317 if (aNbCurves || aNbPoints) {
318 myDS->AddInterf(nF1, nF2);
321 BOPDS_InterfFF& aFF = aFFs.Append1();
322 aFF.SetIndices(nF1, nF2);
323 aFF.SetTangentFaces(bTangentFaces);
324 aFF.Init(aNbCurves, aNbPoints);
327 // Fix bounding box expanding coefficient.
328 Standard_Real aBoxExpandValue = aTolFF;
331 // Modify geometric expanding coefficient by topology value,
332 // since this bounding box used in sharing (vertex or edge).
333 Standard_Real aMaxVertexTol = Max(BRep_Tool::MaxTolerance(aFaceFace.Face1(), TopAbs_VERTEX),
334 BRep_Tool::MaxTolerance(aFaceFace.Face2(), TopAbs_VERTEX));
335 aBoxExpandValue += aMaxVertexTol;
338 BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
339 for (Standard_Integer i = 1; i <= aNbCurves; ++i) {
341 const IntTools_Curve& aIC = aCvsX(i);
342 Standard_Boolean bIsValid = IntTools_Tools::CheckCurve(aIC, aBox);
344 BOPDS_Curve& aNC = aVNC.Append1();
346 // make sure that the bounding box has the maximal gap
347 aBox.Enlarge(aBoxExpandValue);
349 aNC.SetTolerance(Max(aIC.Tolerance(), aTolFF));
354 BOPDS_VectorOfPoint& aVNP = aFF.ChangePoints();
355 for (Standard_Integer i = 1; i <= aNbPoints; ++i) {
356 const IntTools_PntOn2Faces& aPi = aPntsX(i);
357 const gp_Pnt& aP = aPi.P1().Pnt();
359 BOPDS_Point& aNP = aVNP.Append1();
364 //=======================================================================
365 //function : MakeBlocks
367 //=======================================================================
368 void BOPAlgo_PaveFiller::MakeBlocks()
370 if (myGlue != BOPAlgo_GlueOff) {
374 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
375 Standard_Integer aNbFF = aFFs.Extent();
380 Standard_Boolean bExist, bValid2D;
381 Standard_Integer i, nF1, nF2, aNbC, aNbP, j;
382 Standard_Integer nV1, nV2;
383 Standard_Real aT1, aT2;
384 Handle(NCollection_BaseAllocator) aAllocator;
385 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
387 Handle(BOPDS_PaveBlock) aPBOut;
389 //-----------------------------------------------------scope f
391 NCollection_BaseAllocator::CommonBaseAllocator();
393 BOPCol_ListOfInteger aLSE(aAllocator), aLBV(aAllocator);
394 BOPCol_MapOfInteger aMVOnIn(100, aAllocator),
395 aMVStick(100,aAllocator), aMVEF(100, aAllocator),
396 aMI(100, aAllocator), aMVBounds(100, aAllocator);
397 BOPDS_IndexedMapOfPaveBlock aMPBOnIn(100, aAllocator);
398 BOPDS_MapOfPaveBlock aMPBAdd(100, aAllocator), aMPBCommon;
399 BOPDS_ListOfPaveBlock aLPB(aAllocator);
400 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMSCPB(100, aAllocator);
401 BOPCol_DataMapOfShapeInteger aMVI(100, aAllocator);
402 BOPDS_DataMapOfPaveBlockListOfPaveBlock aDMExEdges(100, aAllocator);
403 BOPCol_DataMapOfIntegerReal aMVTol(100, aAllocator);
404 BOPCol_DataMapOfIntegerInteger aDMNewSD(100, aAllocator);
405 BOPCol_DataMapOfIntegerListOfInteger aDMVLV;
406 BOPCol_DataMapOfIntegerListOfInteger aDMBV(100, aAllocator);
407 BOPCol_DataMapIteratorOfDataMapOfIntegerReal aItMV;
408 BOPCol_IndexedMapOfShape aMicroEdges(100, aAllocator);
409 BOPCol_IndexedMapOfShape aVertsOnRejectedPB;
411 for (i=0; i<aNbFF; ++i) {
415 BOPDS_InterfFF& aFF=aFFs(i);
416 aFF.Indices(nF1, nF2);
418 BOPDS_VectorOfPoint& aVP=aFF.ChangePoints();
420 BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
422 if (!aNbP && !aNbC) {
426 const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
427 const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
429 Standard_Real aTolFF = Max(BRep_Tool::Tolerance(aF1), BRep_Tool::Tolerance(aF2));
431 BOPDS_FaceInfo& aFI1 = myDS->ChangeFaceInfo(nF1);
432 BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2);
441 myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn, aMPBCommon);
442 myDS->SharedEdges(nF1, nF2, aLSE, aAllocator);
444 Standard_Boolean bHasRealSectionEdge = Standard_False;
446 for (j=0; j<aNbP; ++j) {
448 BOPDS_CoupleOfPaveBlocks aCPB;
450 BOPDS_Point& aNP=aVP.ChangeValue(j);
451 const gp_Pnt& aP=aNP.Pnt();
453 bExist=IsExistingVertex(aP, aTolFF, aMVOnIn);
455 BOPTools_AlgoTools::MakeNewVertex(aP, aTolFF, aV);
457 aCPB.SetIndexInterf(i);
459 aMSCPB.Add(aV, aCPB);
466 GetStickVertices(nF1, nF2, aMVStick, aMVEF, aMI);
468 for (j = 0; j < aNbC; ++j) {
469 BOPDS_Curve& aNC = aVC.ChangeValue(j);
471 aNC.InitPaveBlock1();
473 PutPavesOnCurve(aMVOnIn, aNC, nF1, nF2, aMI, aMVEF, aMVTol, aDMVLV);
476 // if some E-F vertex was put on a curve due to large E-F intersection range,
477 // and it also was put on another curve correctly then remove this vertex from
478 // the first curve. Detect such case if the distance to curve exceeds aTolR3D.
479 FilterPavesOnCurves(aVC);
481 for (j = 0; j<aNbC; ++j) {
482 BOPDS_Curve& aNC=aVC.ChangeValue(j);
483 const IntTools_Curve& aIC=aNC.Curve();
485 PutStickPavesOnCurve(aF1, aF2, aMI, aNC, aMVStick, aMVTol, aDMVLV);
488 PutEFPavesOnCurve(aNC, aMI, aMVEF, aMVTol, aDMVLV);
491 if (aIC.HasBounds()) {
494 PutBoundPaveOnCurve(aF1, aF2, aNC, aLBV);
496 if (!aLBV.IsEmpty()) {
498 BOPCol_ListIteratorOfListOfInteger aItI(aLBV);
499 for (; aItI.More(); aItI.Next()) {
500 aMVBounds.Add(aItI.Value());
504 }//for (j=0; j<aNbC; ++j) {
506 // Put closing pave if needed
507 for (j=0; j<aNbC; ++j) {
508 BOPDS_Curve& aNC=aVC.ChangeValue(j);
509 PutClosingPaveOnCurve (aNC);
512 // 3. Make section edges
513 for (j=0; j<aNbC; ++j) {
514 BOPDS_Curve& aNC=aVC.ChangeValue(j);
515 const IntTools_Curve& aIC=aNC.Curve();
516 Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
518 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
519 Handle(BOPDS_PaveBlock)& aPB1=aNC.ChangePaveBlock1();
522 aPB1->Update(aLPB, Standard_False);
524 aItLPB.Initialize(aLPB);
525 for (; aItLPB.More(); aItLPB.Next()) {
526 Handle(BOPDS_PaveBlock)& aPB=aItLPB.ChangeValue();
527 aPB->Indices(nV1, nV2);
528 aPB->Range (aT1, aT2);
530 if (fabs(aT1 - aT2) < Precision::PConfusion()) {
534 bValid2D=myContext->IsValidBlockForFaces(aT1, aT2, aIC,
540 bExist=IsExistingPaveBlock(aPB, aNC, aLSE);
545 const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
546 const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
549 BOPTools_AlgoTools::MakeEdge (aIC, aV1, aT1, aV2, aT2, aTolR3D, aES);
551 // check for micro edge
552 if (BOPTools_AlgoTools::IsMicroEdge(aES, myContext, Standard_False)) {
553 // If the section edge is a micro edge, i.e. the whole edge is
554 // covered by the tolerance spheres of its vertices, it will be
555 // passed into post treatment process to fuse its vertices.
556 // The edge itself will not be kept.
557 if (!aMVBounds.Contains(nV1) && !aMVBounds.Contains(nV2)) {
558 aMicroEdges.Add(aES);
559 // keep vertices for post treatment
566 Standard_Real aTolNew;
567 bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aMPBCommon, aPBOut, aTolNew);
569 if (!aMPBAdd.Contains(aPBOut)) {
570 Standard_Boolean bInBothFaces = Standard_True;
571 if (!myDS->IsCommonBlock(aPBOut)) {
576 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(nE);
577 aTolE = BRep_Tool::Tolerance(aE);
578 if (aTolNew < aNC.Tolerance())
579 aTolNew = aNC.Tolerance(); // use real tolerance of intersection
580 if (aTolNew > aTolE) {
581 UpdateEdgeTolerance(nE, aTolNew);
583 bInBothFaces = Standard_False;
586 bInBothFaces = (aFI1.PaveBlocksOn().Contains(aPBOut) ||
587 aFI1.PaveBlocksIn().Contains(aPBOut))&&
588 (aFI2.PaveBlocksOn().Contains(aPBOut) ||
589 aFI2.PaveBlocksIn().Contains(aPBOut));
593 PreparePostTreatFF(i, j, aPBOut, aMSCPB, aMVI, aLPBC);
594 // Try fusing the vertices of the existing pave block
595 // with the vertices put on the real section curve (except
596 // for technological vertices, which will be removed)
597 Standard_Integer nVOut1, nVOut2;
598 aPBOut->Indices(nVOut1, nVOut2);
599 if (nV1 != nVOut1 && nV1 != nVOut2 && !aMVBounds.Contains(nV1))
601 aVertsOnRejectedPB.Add(aV1);
603 if (nV2 != nVOut1 && nV2 != nVOut2 && !aMVBounds.Contains(nV2))
605 aVertsOnRejectedPB.Add(aV2);
613 BOPTools_AlgoTools::MakePCurve(aES, aF1, aF2, aIC,
614 mySectionAttribute.PCurveOnS1(),
615 mySectionAttribute.PCurveOnS2(),
618 // Append the Pave Block to the Curve j
621 // Keep info for post treatment
622 BOPDS_CoupleOfPaveBlocks aCPB;
623 aCPB.SetIndexInterf(i);
625 aCPB.SetPaveBlock1(aPB);
627 aMSCPB.Add(aES, aCPB);
634 bHasRealSectionEdge = Standard_True;
638 }//for (j=0; j<aNbC; ++j) {
640 //back to previous tolerance values for unused vertices
641 //and forget about SD groups of such vertices
642 aItMV.Initialize(aMVTol);
643 for (; aItMV.More(); aItMV.Next()) {
645 Standard_Real aTol = aItMV.Value();
647 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV1);
648 const Handle(BRep_TVertex)& TV =
649 *((Handle(BRep_TVertex)*)&aV.TShape());
652 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV1);
653 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
655 BRepBndLib::Add(aV, aBoxDS);
656 aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
658 if (aDMVLV.IsBound(nV1))
662 ProcessExistingPaveBlocks(i, aMPBOnIn, aDMBV, aMSCPB, aMVI, aMPBAdd);
664 // If the pair of faces has produced any real section edges
665 // it is necessary to check if these edges do not intersect
666 // any common IN edges of the faces. For that, all such edges
667 // are added for Post Treatment along with sections edges.
668 if (bHasRealSectionEdge) {
669 const BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.PaveBlocksIn();
670 const BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.PaveBlocksIn();
672 // For simplicity add all IN edges into the first set of section curves.
673 // These existing edges will be removed from the set on the post treatment
674 // stage in the UpdateFaceInfo function.
675 BOPDS_ListOfPaveBlock& aLPBC = aVC.ChangeValue(0).ChangePaveBlocks();
677 Standard_Integer aNbIn1 = aMPBIn1.Extent();
678 for (j = 1; j <= aNbIn1; ++j) {
679 const Handle(BOPDS_PaveBlock)& aPB = aMPBIn1(j);
680 if (aMPBIn2.Contains(aPB) && aMPBAdd.Add(aPB)) {
681 PreparePostTreatFF(i, 0, aPB, aMSCPB, aMVI, aLPBC);
685 }//for (i=0; i<aNbFF; ++i) {
688 MakeSDVerticesFF(aDMVLV, aDMNewSD);
689 PostTreatFF(aMSCPB, aDMExEdges, aDMNewSD, aMicroEdges, aVertsOnRejectedPB, aAllocator);
693 // reduce tolerances of section edges where it is appropriate
694 CorrectToleranceOfSE();
697 UpdateFaceInfo(aDMExEdges, aDMNewSD);
698 //Update all pave blocks
699 UpdatePaveBlocks(aDMNewSD);
701 // Treat possible common zones by trying to put each section edge
702 // into all faces, not participated in creation of that edge, as IN edge
705 //-----------------------------------------------------scope t
714 //=======================================================================
715 //function : MakeSDVerticesFF
717 //=======================================================================
718 void BOPAlgo_PaveFiller::MakeSDVerticesFF
719 (const BOPCol_DataMapOfIntegerListOfInteger& theDMVLV,
720 BOPCol_DataMapOfIntegerInteger& theDMNewSD)
722 // Create a new SD vertex for each group of coinciding vertices
723 // and put new substitutions to theDMNewSD.
724 BOPCol_DataMapIteratorOfDataMapOfIntegerListOfInteger aItG(theDMVLV);
725 for (; aItG.More(); aItG.Next()) {
726 const BOPCol_ListOfInteger& aList = aItG.Value();
727 // make SD vertices w/o creation of interfs
728 Standard_Integer nSD = MakeSDVertices(aList, Standard_False);
730 BOPCol_ListIteratorOfListOfInteger aItL(aList);
731 for (; aItL.More(); aItL.Next()) {
732 Standard_Integer nV = aItL.Value();
733 theDMNewSD.Bind(nV, nSD);
738 //=======================================================================
739 //function : PostTreatFF
741 //=======================================================================
742 void BOPAlgo_PaveFiller::PostTreatFF
743 (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
744 BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges,
745 BOPCol_DataMapOfIntegerInteger& aDMNewSD,
746 const BOPCol_IndexedMapOfShape& theMicroEdges,
747 const BOPCol_IndexedMapOfShape& theVertsOnRejectedPB,
748 const Handle(NCollection_BaseAllocator)& theAllocator)
750 Standard_Integer aNbS = theMSCPB.Extent();
755 Standard_Boolean bHasPaveBlocks, bOld;
756 Standard_Integer nSx, nVSD, iX, iP, iC, j, nV, iV = 0, iE, k;
757 Standard_Integer aNbLPBx;
758 TopAbs_ShapeEnum aType;
760 BOPCol_ListIteratorOfListOfShape aItLS;
761 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
763 Handle(BOPDS_PaveBlock) aPB1;
767 BOPCol_ListOfShape aLS(theAllocator);
768 BOPAlgo_PaveFiller aPF(theAllocator);
769 aPF.SetIsPrimary(Standard_False);
770 aPF.SetNonDestructive(myNonDestructive);
772 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
774 Standard_Integer aNbME = theMicroEdges.Extent();
775 Standard_Integer aNbVOnRPB = theVertsOnRejectedPB.Extent();
777 if (aNbS==1 && (aNbME == 0) && (aNbVOnRPB == 0)) {
778 const TopoDS_Shape& aS=theMSCPB.FindKey(1);
779 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromIndex(1);
781 aType=aS.ShapeType();
782 if (aType==TopAbs_VERTEX) {
783 aSI.SetShapeType(aType);
785 iV=myDS->Append(aSI);
787 iX=aCPB.IndexInterf();
789 BOPDS_InterfFF& aFF=aFFs(iX);
790 BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
791 BOPDS_Point& aNP=aVNP(iP);
794 else if (aType==TopAbs_EDGE) {
795 aPB1=aCPB.PaveBlock1();
797 if (aPB1->HasEdge()) {
798 BOPDS_ListOfPaveBlock aLPBx;
800 aDMExEdges.Bind(aPB1, aLPBx);
802 aSI.SetShapeType(aType);
804 iE=myDS->Append(aSI);
812 // 1 prepare arguments
813 BOPCol_MapOfShape anAddedSD;
814 for (k=1; k<=aNbS; ++k) {
815 const TopoDS_Shape& aS=theMSCPB.FindKey(k);
817 // add vertices-candidates for SD from the map aDMNewSD,
818 // so that they took part in fuse operation.
819 TopoDS_Iterator itV(aS);
820 for (; itV.More(); itV.Next())
822 const TopoDS_Shape& aVer = itV.Value();
823 Standard_Integer iVer = myDS->Index(aVer);
824 const Standard_Integer* pSD = aDMNewSD.Seek(iVer);
827 const TopoDS_Shape& aVSD = myDS->Shape(*pSD);
828 if (anAddedSD.Add(aVSD))
834 // The section edges considered as a micro should be
835 // specially treated - their vertices should be united and
836 // the edge itself should be removed. Thus, we add only
837 // its vertices into operation.
840 for (k = 1; k <= aNbME; ++k) {
841 const TopoDS_Edge& aEM = TopoDS::Edge(theMicroEdges(k));
843 TopoDS_Vertex aVerts[2];
844 TopExp::Vertices(aEM, aVerts[0], aVerts[1]);
845 for (Standard_Integer i = 0; i < 2; ++i) {
846 nV = myDS->Index(aVerts[i]);
847 const Standard_Integer* pSD = aDMNewSD.Seek(nV);
849 aVerts[i] = TopoDS::Vertex(myDS->Shape(*pSD));
852 if (anAddedSD.Add(aVerts[i])) {
853 aLS.Append(aVerts[i]);
857 if (aVerts[0].IsSame(aVerts[1])) {
861 // make sure these vertices will be united
862 const gp_Pnt& aP1 = BRep_Tool::Pnt(aVerts[0]);
863 const gp_Pnt& aP2 = BRep_Tool::Pnt(aVerts[1]);
865 Standard_Real aDist = aP1.Distance(aP2);
866 Standard_Real aTolV1 = BRep_Tool::Tolerance(aVerts[0]);
867 Standard_Real aTolV2 = BRep_Tool::Tolerance(aVerts[1]);
869 aDist -= (aTolV1 + aTolV2);
872 aBB.UpdateVertex(aVerts[0], aTolV1 + aDist);
873 aBB.UpdateVertex(aVerts[1], aTolV2 + aDist);
877 // Add vertices put on the real section curves to unify them with the
878 // vertices of the edges, by which these sections curves have been rejected
879 for (Standard_Integer i = 1; i <= aNbVOnRPB; ++i)
881 TopoDS_Shape aVer = theVertsOnRejectedPB(i);
882 Standard_Integer iVer = myDS->Index(aVer);
883 const Standard_Integer* pSD = aDMNewSD.Seek(iVer);
885 aVer = myDS->Shape(*pSD);
887 if (anAddedSD.Add(aVer))
892 aPF.SetProgressIndicator(myProgressIndicator);
893 aPF.SetRunParallel(myRunParallel);
894 aPF.SetArguments(aLS);
896 if (aPF.HasErrors()) {
897 AddError (new BOPAlgo_AlertPostTreatFF);
902 // Map to store the real tolerance of the common block
903 // and avoid repeated computation of it
904 NCollection_DataMap<Handle(BOPDS_CommonBlock),
906 TColStd_MapTransientHasher> aMCBTol;
907 // Map to avoid creation of different pave blocks for
908 // the same intersection edge
909 NCollection_DataMap<Standard_Integer, Handle(BOPDS_PaveBlock)> aMEPB;
911 aItLS.Initialize(aLS);
912 for (; aItLS.More(); aItLS.Next()) {
913 const TopoDS_Shape& aSx=aItLS.Value();
914 nSx=aPDS->Index(aSx);
915 const BOPDS_ShapeInfo& aSIx=aPDS->ShapeInfo(nSx);
917 aType=aSIx.ShapeType();
919 if (aType==TopAbs_VERTEX) {
920 Standard_Boolean bIntersectionPoint = theMSCPB.Contains(aSx);
922 if (aPDS->HasShapeSD(nSx, nVSD)) {
923 aV=aPDS->Shape(nVSD);
928 // index of new vertex in theDS -> iV
929 iV = myDS->Index(aV);
931 aSI.SetShapeType(aType);
933 iV=myDS->Append(aSI);
936 if (!bIntersectionPoint) {
937 // save SD connection
938 nSx = myDS->Index(aSx);
939 aDMNewSD.Bind(nSx, iV);
940 myDS->AddShapeSD(nSx, iV);
943 // update FF interference
944 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
945 iX=aCPB.IndexInterf();
947 BOPDS_InterfFF& aFF=aFFs(iX);
948 BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
949 BOPDS_Point& aNP=aVNP(iP);
952 }//if (aType==TopAbs_VERTEX) {
954 else if (aType==TopAbs_EDGE) {
955 bHasPaveBlocks=aPDS->HasPaveBlocks(nSx);
956 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
957 iX=aCPB.IndexInterf();
959 aPB1=aCPB.PaveBlock1();
961 bOld = aPB1->HasEdge();
963 BOPDS_ListOfPaveBlock aLPBx;
964 aDMExEdges.Bind(aPB1, aLPBx);
967 if (!bHasPaveBlocks) {
969 aDMExEdges.ChangeFind(aPB1).Append(aPB1);
972 aSI.SetShapeType(aType);
974 iE = myDS->Append(aSI);
980 BOPDS_InterfFF& aFF=aFFs(iX);
981 BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
982 BOPDS_Curve& aNC=aVNC(iC);
983 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
985 // check if edge occured to be micro edge;
986 // note we check not the edge aSx itself, but its image in aPDS
987 const BOPDS_ListOfPaveBlock& aLPBx = aPDS->PaveBlocks(nSx);
988 aNbLPBx = aLPBx.Extent();
989 if (aPDS->HasPaveBlocks(nSx) &&
990 (aNbLPBx == 0 || (aNbLPBx == 1 && !aLPBx.First()->HasShrunkData()))) {
991 BOPDS_ListIteratorOfListOfPaveBlock it(aLPBC);
992 for (; it.More(); it.Next()) {
993 if (it.Value() == aPB1) {
1001 if (bOld && !aNbLPBx) {
1002 aDMExEdges.ChangeFind(aPB1).Append(aPB1);
1007 aItLPB.Initialize(aLPBC);
1008 for (; aItLPB.More(); aItLPB.Next()) {
1009 const Handle(BOPDS_PaveBlock)& aPBC=aItLPB.Value();
1011 aLPBC.Remove(aItLPB);
1018 aItLPB.Initialize(aLPBx);
1019 for (; aItLPB.More(); aItLPB.Next()) {
1020 const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
1021 const Handle(BOPDS_PaveBlock) aPBRx=aPDS->RealPaveBlock(aPBx);
1023 // update vertices of paves
1024 aPave[0] = aPBx->Pave1();
1025 aPave[1] = aPBx->Pave2();
1026 for (j=0; j<2; ++j) {
1027 nV = aPave[j].Index();
1028 aV = aPDS->Shape(nV);
1029 // index of new vertex in myDS -> iV
1030 iV = myDS->Index(aV);
1032 aSI.SetShapeType(TopAbs_VERTEX);
1034 iV = myDS->Append(aSI);
1036 const BOPDS_Pave& aP1 = !j ? aPB1->Pave1() : aPB1->Pave2();
1037 if (aP1.Index() != iV) {
1038 if (aP1.Parameter() == aPave[j].Parameter()) {
1039 aDMNewSD.Bind(aP1.Index(), iV);
1040 myDS->AddShapeSD(aP1.Index(), iV);
1043 // check aPDS to have the SD connection between these vertices
1044 const TopoDS_Shape& aVPave = myDS->Shape(aP1.Index());
1045 Standard_Integer nVnewSD, nVnew = aPDS->Index(aVPave);
1046 if (aPDS->HasShapeSD(nVnew, nVnewSD)) {
1047 if (nVnewSD == nV) {
1048 aDMNewSD.Bind(aP1.Index(), iV);
1049 myDS->AddShapeSD(aP1.Index(), iV);
1055 aPave[j].SetIndex(iV);
1059 aE=aPDS->Shape(aPBRx->Edge());
1060 iE = myDS->Index(aE);
1062 aSI.SetShapeType(aType);
1064 iE=myDS->Append(aSI);
1067 // update real edge tolerance according to distances in common block if any
1068 if (aPDS->IsCommonBlock(aPBRx)) {
1069 const Handle(BOPDS_CommonBlock)& aCB = aPDS->CommonBlock(aPBRx);
1070 Standard_Real *pTol = aMCBTol.ChangeSeek(aCB);
1072 Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, aPDS, aPF.Context());
1073 pTol = aMCBTol.Bound(aCB, aTol);
1076 if (aNC.Tolerance() < *pTol) {
1077 aNC.SetTolerance(*pTol);
1080 // append new PaveBlock to aLPBC
1081 Handle(BOPDS_PaveBlock) *pPBC = aMEPB.ChangeSeek(iE);
1083 pPBC = aMEPB.Bound(iE, new BOPDS_PaveBlock());
1084 BOPDS_Pave aPaveR1, aPaveR2;
1085 aPaveR1 = aPBRx->Pave1();
1086 aPaveR2 = aPBRx->Pave2();
1087 aPaveR1.SetIndex(myDS->Index(aPDS->Shape(aPaveR1.Index())));
1088 aPaveR2.SetIndex(myDS->Index(aPDS->Shape(aPaveR2.Index())));
1090 (*pPBC)->SetPave1(aPaveR1);
1091 (*pPBC)->SetPave2(aPaveR2);
1092 (*pPBC)->SetEdge(iE);
1096 (*pPBC)->SetOriginalEdge(aPB1->OriginalEdge());
1097 aDMExEdges.ChangeFind(aPB1).Append(*pPBC);
1100 aLPBC.Append(*pPBC);
1105 }//else if (aType==TopAbs_EDGE)
1106 }//for (; aItLS.More(); aItLS.Next()) {
1108 // Update SD for vertices that did not participate in operation
1109 BOPCol_DataMapOfIntegerInteger::Iterator itDM(aDMNewSD);
1110 for (; itDM.More(); itDM.Next())
1112 const Standard_Integer* pSD = aDMNewSD.Seek(itDM.Value());
1115 itDM.ChangeValue() = *pSD;
1116 myDS->AddShapeSD(itDM.Key(), *pSD);
1122 //=======================================================================
1123 //function : UpdateFaceInfo
1125 //=======================================================================
1126 void BOPAlgo_PaveFiller::UpdateFaceInfo
1127 (BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDME,
1128 const BOPCol_DataMapOfIntegerInteger& theDMV)
1130 Standard_Integer i, j, nV1, nF1, nF2,
1132 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
1133 BOPCol_MapOfInteger aMF;
1135 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
1136 aNbFF=aFFs.Extent();
1138 //1. Sections (curves, points);
1139 for (i=0; i<aNbFF; ++i) {
1140 BOPDS_InterfFF& aFF=aFFs(i);
1141 aFF.Indices(nF1, nF2);
1143 BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
1144 BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
1146 // 1.1. Section edges
1147 BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
1149 for (j=0; j<aNbC; ++j) {
1150 BOPDS_Curve& aNC=aVNC(j);
1151 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
1153 // Add section edges to face info
1154 aItLPB.Initialize(aLPBC);
1155 for (; aItLPB.More(); ) {
1156 const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
1158 // Treat existing pave blocks
1159 if (theDME.IsBound(aPB)) {
1160 BOPDS_ListOfPaveBlock& aLPB=theDME.ChangeFind(aPB);
1161 UpdateExistingPaveBlocks(aPB, aLPB, nF1, nF2);
1162 aLPBC.Remove(aItLPB);
1166 aFI1.ChangePaveBlocksSc().Add(aPB);
1167 aFI2.ChangePaveBlocksSc().Add(aPB);
1172 // 1.2. Section vertices
1173 const BOPDS_VectorOfPoint& aVNP=aFF.Points();
1175 for (j=0; j<aNbP; ++j) {
1176 const BOPDS_Point& aNP=aVNP(j);
1181 aFI1.ChangeVerticesSc().Add(nV1);
1182 aFI2.ChangeVerticesSc().Add(nV1);
1189 Standard_Boolean bVerts, bEdges;
1191 bVerts = theDMV.Extent() > 0;
1192 bEdges = theDME.Extent() > 0;
1194 if (!bVerts && !bEdges) {
1198 // 2. Update Face Info information with new vertices and new
1199 // pave blocks created in PostTreatFF from existing ones
1200 Standard_Integer nV2, aNbPB;
1201 BOPCol_MapIteratorOfMapOfInteger aItMF;
1202 BOPCol_DataMapIteratorOfDataMapOfIntegerInteger aItMV;
1204 aItMF.Initialize(aMF);
1205 for (; aItMF.More(); aItMF.Next()) {
1206 nF1 = aItMF.Value();
1208 BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF1);
1210 // 2.1. Update information about vertices
1212 BOPCol_MapOfInteger& aMVOn = aFI.ChangeVerticesOn();
1213 BOPCol_MapOfInteger& aMVIn = aFI.ChangeVerticesIn();
1215 aItMV.Initialize(theDMV);
1216 for (; aItMV.More(); aItMV.Next()) {
1218 nV2 = aItMV.Value();
1220 if (aMVOn.Remove(nV1)) {
1224 if (aMVIn.Remove(nV1)) {
1227 } // for (; aItMV.More(); aItMV.Next()) {
1230 // 2.2. Update information about pave blocks
1232 BOPDS_IndexedMapOfPaveBlock& aMPBOn = aFI.ChangePaveBlocksOn();
1233 BOPDS_IndexedMapOfPaveBlock& aMPBIn = aFI.ChangePaveBlocksIn();
1235 BOPDS_IndexedMapOfPaveBlock aMPBCopy;
1236 for (i = 0; i < 2; ++i) {
1237 BOPDS_IndexedMapOfPaveBlock& aMPBOnIn = !i ? aMPBOn : aMPBIn;
1238 aMPBCopy = aMPBOnIn;
1241 aNbPB = aMPBCopy.Extent();
1242 for (j = 1; j <= aNbPB; ++j) {
1243 const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(j);
1244 if (theDME.IsBound(aPB)) {
1245 const BOPDS_ListOfPaveBlock& aLPB = theDME.Find(aPB);
1246 if (aLPB.IsEmpty()) {
1251 aItLPB.Initialize(aLPB);
1252 for (; aItLPB.More(); aItLPB.Next()) {
1253 const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB.Value();
1260 } // for (j = 1; j <= aNbPB; ++j) {
1261 } // for (i = 0; i < 2; ++i) {
1265 //=======================================================================
1266 //function : IsExistingVertex
1268 //=======================================================================
1269 Standard_Boolean BOPAlgo_PaveFiller::IsExistingVertex
1271 const Standard_Real theTolR3D,
1272 const BOPCol_MapOfInteger& aMVOnIn)const
1274 Standard_Boolean bRet;
1275 Standard_Integer nV, iFlag;
1276 Standard_Real aTolCheck;
1279 BOPCol_MapIteratorOfMapOfInteger aIt;
1281 aTolCheck = theTolR3D + myFuzzyValue;
1285 aBoxP.Enlarge(theTolR3D);
1287 aIt.Initialize(aMVOnIn);
1288 for (; aIt.More(); aIt.Next()) {
1290 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1291 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aSIV.Shape()));
1292 const Bnd_Box& aBoxV=aSIV.Box();
1294 if (!aBoxP.IsOut(aBoxV)) {
1295 iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP, aTolCheck);
1303 //=======================================================================
1304 //function : IsExistingPaveBlock
1306 //=======================================================================
1307 Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
1308 (const Handle(BOPDS_PaveBlock)& thePB,
1309 const BOPDS_Curve& theNC,
1310 const BOPCol_ListOfInteger& theLSE)
1312 Standard_Boolean bRet=Standard_True;
1314 if (theLSE.IsEmpty()) {
1318 Standard_Real aT1, aT2, aTm, aTx, aTolE, aTolCheck, aTol, aDist;
1319 Standard_Integer nE, iFlag, nV1, nV2;
1322 BOPCol_ListIteratorOfListOfInteger aItLI;
1324 thePB->Range(aT1, aT2);
1325 thePB->Indices(nV1, nV2);
1326 const TopoDS_Vertex &aV1 = TopoDS::Vertex(myDS->Shape(nV1)),
1327 &aV2 = TopoDS::Vertex(myDS->Shape(nV2));
1328 const Standard_Real aTolV1 = BRep_Tool::Tolerance(aV1),
1329 aTolV2 = BRep_Tool::Tolerance(aV2);
1331 aTol = Max(aTolV1, aTolV2);
1333 aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
1334 theNC.Curve().D0(aTm, aPm);
1336 aBoxPm.Enlarge(aTol);
1338 aItLI.Initialize(theLSE);
1339 for (; aItLI.More(); aItLI.Next()) {
1343 const BOPDS_ShapeInfo& aSIE=myDS->ChangeShapeInfo(nE);
1344 const Bnd_Box& aBoxE=aSIE.Box();
1345 if (!aBoxE.IsOut(aBoxPm)) {
1346 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
1347 aTolE = BRep_Tool::Tolerance(aE);
1348 aTolCheck = Max(aTolE, aTol) + myFuzzyValue;
1349 iFlag = myContext->ComputePE(aPm, aTolCheck, aE, aTx, aDist);
1358 //=======================================================================
1359 //function : IsExistingPaveBlock
1361 //=======================================================================
1362 Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
1363 (const Handle(BOPDS_PaveBlock)& thePB,
1364 const BOPDS_Curve& theNC,
1365 const Standard_Real theTolR3D,
1366 const BOPDS_IndexedMapOfPaveBlock& theMPBOnIn,
1367 const BOPDS_MapOfPaveBlock& theMPBCommon,
1368 Handle(BOPDS_PaveBlock)& aPBOut,
1369 Standard_Real& theTolNew)
1371 Standard_Boolean bRet;
1372 Standard_Real aT1, aT2, aTm, aTx, aTolCheck;
1373 Standard_Integer nSp, iFlag1, iFlag2, nV11, nV12, nV21, nV22, i, aNbPB;
1374 gp_Pnt aP1, aPm, aP2;
1375 Bnd_Box aBoxP1, aBoxPm, aBoxP2, aBoxTmp;
1377 bRet=Standard_False;
1378 aTolCheck = theTolR3D + myFuzzyValue;
1379 const IntTools_Curve& aIC=theNC.Curve();
1381 thePB->Range(aT1, aT2);
1382 thePB->Indices(nV11, nV12);
1383 const Standard_Real aTolV11 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV11)));
1384 const Standard_Real aTolV12 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV12)));
1385 const Standard_Real aTolV1 = Max(aTolV11, aTolV12) + myFuzzyValue;
1390 aBoxP1.Enlarge(aTolV11);
1391 //intermediate point
1392 aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
1398 aBoxP2.Enlarge(aTolV12);
1401 aNbPB = theMPBOnIn.Extent();
1402 for (i = 1; i <= aNbPB; ++i) {
1403 const Handle(BOPDS_PaveBlock)& aPB = theMPBOnIn(i);
1404 aPB->Indices(nV21, nV22);
1405 const Standard_Real aTolV21 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV21)));
1406 const Standard_Real aTolV22 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV22)));
1407 const Standard_Real aTolV2 = Max(aTolV21, aTolV22) + myFuzzyValue;
1411 const BOPDS_ShapeInfo& aSISp=myDS->ChangeShapeInfo(nSp);
1412 const TopoDS_Edge& aSp=(*(TopoDS_Edge *)(&aSISp.Shape()));
1413 const Bnd_Box& aBoxSp=aSISp.Box();
1415 iFlag1 = (nV11 == nV21 || nV11 == nV22) ? 2 :
1416 (!aBoxSp.IsOut(aBoxP1) ? 1 : 0);
1417 iFlag2 = (nV12 == nV21 || nV12 == nV22) ? 2 :
1418 (!aBoxSp.IsOut(aBoxP2) ? 1 : 0);
1419 if (iFlag1 && iFlag2) {
1420 Standard_Real aDist = 0.;
1422 Standard_Real aRealTol = aTolCheck;
1423 if (myDS->IsCommonBlock(aPB))
1425 aRealTol = Max(aRealTol, Max(aTolV1, aTolV2));
1426 if (theMPBCommon.Contains(aPB))
1427 // for an edge, which is a common block with a face,
1428 // increase the chance to coincide with section curve
1433 aBoxTmp.Enlarge(aRealTol);
1435 if (aBoxSp.IsOut(aBoxTmp) || myContext->ComputePE(aPm,
1443 iFlag1 = !myContext->ComputePE(aP1, aRealTol, aSp, aTx, aDist);
1444 if (iFlag1 && theTolNew < aDist)
1449 iFlag2 = !myContext->ComputePE(aP2, aRealTol, aSp, aTx, aDist);
1450 if (iFlag2 && theTolNew < aDist)
1454 if (iFlag1 && iFlag2) {
1463 //=======================================================================
1464 //function : PutBoundPaveOnCurve
1466 //=======================================================================
1467 void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1,
1468 const TopoDS_Face& aF2,
1470 BOPCol_ListOfInteger& aLVB)
1472 Standard_Boolean bVF;
1473 Standard_Integer nV, iFlag, nVn, j, aNbEP;
1474 Standard_Real aT[2], aTmin, aTmax, aTV, aTol, aTolVnew;
1477 BOPDS_ListIteratorOfListOfPave aItLP;
1478 BOPDS_Pave aPn, aPMM[2];
1480 aTolVnew = Precision::Confusion();
1482 const IntTools_Curve& aIC=aNC.Curve();
1483 aIC.Bounds(aT[0], aT[1], aP[0], aP[1]);
1484 Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
1486 Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
1487 const BOPDS_ListOfPave& aLP=aPB->ExtPaves();
1494 aItLP.Initialize(aLP);
1495 for (; aItLP.More(); aItLP.Next()) {
1496 const BOPDS_Pave& aPv=aItLP.Value();
1497 aPv.Contents(nV, aTV);
1509 for (j=0; j<2; ++j) {
1510 //if curve is closed, process only one bound
1511 if (j && aP[1].IsEqual(aP[0], aTolVnew)) {
1521 aTol = aTolR3D+Precision::Confusion();
1522 aBoxP.Enlarge(aTol);
1523 const BOPDS_Pave& aPV=aPMM[j];
1525 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1526 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aSIV.Shape()));
1527 const Bnd_Box& aBoxV=aSIV.Box();
1528 if (!aBoxP.IsOut(aBoxV)){
1529 iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP[j], aTol);
1534 bVF=myContext->IsValidPointForFaces (aP[j], aF1, aF2, aTolR3D);
1539 BOPDS_ShapeInfo aSIVn;
1541 BOPTools_AlgoTools::MakeNewVertex(aP[j], aTolR3D, aVn);
1542 aSIVn.SetShapeType(TopAbs_VERTEX);
1543 aSIVn.SetShape(aVn);
1545 nVn=myDS->Append(aSIVn);
1548 aPn.SetParameter(aT[j]);
1549 aPB->AppendExtPave(aPn);
1551 aVn=(*(TopoDS_Vertex *)(&myDS->Shape(nVn)));
1552 BOPTools_AlgoTools::UpdateVertex (aIC, aT[j], aVn);
1554 aTolVnew = BRep_Tool::Tolerance(aVn);
1556 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nVn);
1557 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
1558 BRepBndLib::Add(aVn, aBoxDS);
1559 aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
1566 //=======================================================================
1567 //function : PutPavesOnCurve
1569 //=======================================================================
1570 void BOPAlgo_PaveFiller::PutPavesOnCurve
1571 (const BOPCol_MapOfInteger& aMVOnIn,
1573 const Standard_Integer nF1,
1574 const Standard_Integer nF2,
1575 const BOPCol_MapOfInteger& aMI,
1576 const BOPCol_MapOfInteger& aMVEF,
1577 BOPCol_DataMapOfIntegerReal& aMVTol,
1578 BOPCol_DataMapOfIntegerListOfInteger& aDMVLV)
1580 Standard_Boolean bInBothFaces;
1581 Standard_Integer nV;
1582 BOPCol_MapIteratorOfMapOfInteger aIt;
1584 const Bnd_Box& aBoxC=aNC.Box();
1585 Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
1587 //Put EF vertices first
1588 aIt.Initialize(aMVEF);
1589 for (; aIt.More(); aIt.Next()) {
1591 PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 2);
1593 //Put all other vertices
1594 aIt.Initialize(aMVOnIn);
1595 for (; aIt.More(); aIt.Next()) {
1597 if (aMVEF.Contains(nV)) {
1601 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1602 const Bnd_Box& aBoxV=aSIV.Box();
1604 if (aBoxC.IsOut(aBoxV)){
1607 if (!myDS->IsNewShape(nV)) {
1608 const BOPDS_FaceInfo& aFI1 = myDS->FaceInfo(nF1);
1609 const BOPDS_FaceInfo& aFI2 = myDS->FaceInfo(nF2);
1611 bInBothFaces = (aFI1.VerticesOn().Contains(nV) ||
1612 aFI1.VerticesIn().Contains(nV))&&
1613 (aFI2.VerticesOn().Contains(nV) ||
1614 aFI2.VerticesIn().Contains(nV));
1615 if (!bInBothFaces) {
1620 PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 1);
1624 //=======================================================================
1625 //function : FilterPavesOnCurves
1627 //=======================================================================
1629 struct PaveBlockDist {
1630 Handle(BOPDS_PaveBlock) PB;
1631 Standard_Real Dist; // square distance from vertex to the paveblock
1632 Standard_Real SinAngle; // sinus of angle between projection vector
1633 // and tangent at projection point
1634 Standard_Real Tolerance; // tolerance of the section curve
1637 void BOPAlgo_PaveFiller::FilterPavesOnCurves(const BOPDS_VectorOfCurve& theVNC)
1639 // For each vertex found in ExtPaves of pave blocks of section curves
1640 // collect list of pave blocks with distance to the curve
1641 NCollection_IndexedDataMap<Standard_Integer,NCollection_List<PaveBlockDist> > aIDMVertPBs;
1643 const Standard_Real anEps = gp::Resolution();
1644 for (i = 0; i < theVNC.Extent(); ++i)
1646 const BOPDS_Curve& aNC = theVNC(i);
1647 const IntTools_Curve& aIC = aNC.Curve();
1648 const Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
1649 GeomAdaptor_Curve aGAC(aIC.Curve());
1650 const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First();
1651 const BOPDS_ListOfPave& aPaves = aPB->ExtPaves();
1652 BOPDS_ListOfPave::Iterator itPaves(aPaves);
1653 for (; itPaves.More(); itPaves.Next())
1655 const BOPDS_Pave& aPave = itPaves.Value();
1656 Standard_Integer nV = aPave.Index();
1657 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
1658 // compute distance from vertex to the point on curve with vertex parameter
1659 gp_Pnt aPV = BRep_Tool::Pnt(aV);
1660 Standard_Real aPar = aPave.Parameter();
1663 aGAC.D1(aPar, aPonC, aD1);
1664 gp_Vec aProjVec(aPV, aPonC);
1665 Standard_Real aSqDist = aProjVec.SquareMagnitude();
1666 Standard_Real aSqD1Mod = aD1.SquareMagnitude();
1667 Standard_Real aSin = aProjVec.CrossSquareMagnitude(aD1);
1668 if (aSqDist > anEps && aSqD1Mod > anEps)
1669 aSin = sqrt(aSin / aSqDist / aSqD1Mod);
1670 NCollection_List<PaveBlockDist>* pList = aIDMVertPBs.ChangeSeek(nV);
1672 pList = &aIDMVertPBs.ChangeFromIndex(aIDMVertPBs.Add(nV, NCollection_List<PaveBlockDist>()));
1673 PaveBlockDist aPBD = { aPB, aSqDist, aSin, aTolR3D };
1674 pList->Append(aPBD);
1678 // Process each vertex
1679 const Standard_Real aSinAngleMin = 0.5; // angle below which projection is suspicious
1680 for (i = 1; i <= aIDMVertPBs.Extent(); i++)
1682 Standard_Integer nV = aIDMVertPBs.FindKey(i);
1683 const NCollection_List<PaveBlockDist>& aList = aIDMVertPBs(i);
1684 // Find a pave with minimal distance
1685 Standard_Real aMinDist = RealLast();
1686 Handle(BOPDS_PaveBlock) aPBMinDist;
1687 NCollection_List<PaveBlockDist>::Iterator itL(aList);
1688 for (; itL.More(); itL.Next())
1690 const PaveBlockDist& aPBD = itL.Value();
1691 if (aPBD.Dist < aMinDist)
1693 aMinDist = aPBD.Dist;
1694 aPBMinDist = aPBD.PB;
1697 // Remove a vertex from a pave block if the distance is greater than the tolerance
1698 // and there are other pave blocks for which the distance is less than the current.
1699 // Do not remove a vertex if it is projected on the curve with quite large angle
1700 // (see test bugs modalg_6 bug27761).
1701 for (itL.Init(aList); itL.More(); itL.Next())
1703 const PaveBlockDist& aPBD = itL.Value();
1704 Standard_Real aCheckDist = 100. * Max(aPBD.Tolerance*aPBD.Tolerance, aMinDist);
1705 if (aPBD.Dist > aCheckDist && aPBD.SinAngle < aSinAngleMin)
1707 aPBD.PB->RemoveExtPave(nV);
1713 //=======================================================================
1714 //function : ExtendedTolerance
1716 //=======================================================================
1717 Standard_Boolean BOPAlgo_PaveFiller::ExtendedTolerance
1718 (const Standard_Integer nV,
1719 const BOPCol_MapOfInteger& aMI,
1720 Standard_Real& aTolVExt,
1721 const Standard_Integer aType)
1723 Standard_Boolean bFound = Standard_False;
1724 if (!(myDS->IsNewShape(nV))) {
1728 Standard_Integer i, k, aNbLines, aNbInt;
1729 Standard_Real aT11, aT12, aD1, aD2, aD;
1731 gp_Pnt aPV, aP11, aP12;
1737 } else if (aType == 2) {
1741 aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1742 aPV=BRep_Tool::Pnt(aV);
1744 BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
1745 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1747 for (; k<aNbInt; ++k) {
1748 aNbLines = !k ? aEEs.Extent() : aEFs.Extent();
1749 for (i = 0; i < aNbLines; ++i) {
1750 BOPDS_Interf *aInt = !k ? (BOPDS_Interf*) (&aEEs(i)) :
1751 (BOPDS_Interf*) (&aEFs(i));
1752 if (aInt->IndexNew() == nV) {
1753 if (aMI.Contains(aInt->Index1()) &&
1754 aMI.Contains(aInt->Index2())) {
1755 const IntTools_CommonPrt& aComPrt = !k ? aEEs(i).CommonPart() :
1756 aEFs(i).CommonPart();
1758 const TopoDS_Edge& aE1=aComPrt.Edge1();
1759 aComPrt.Range1(aT11, aT12);
1760 BOPTools_AlgoTools::PointOnEdge(aE1, aT11, aP11);
1761 BOPTools_AlgoTools::PointOnEdge(aE1, aT12, aP12);
1762 aD1=aPV.Distance(aP11);
1763 aD2=aPV.Distance(aP12);
1764 aD=(aD1>aD2)? aD1 : aD2;
1769 }//if (aMI.Contains(aEF.Index1()) && aMI.Contains(aEF.Index2())) {
1770 }//if (aInt->IndexNew() == nV) {
1771 }//for (i = 0; i < aNbLines; ++i) {
1772 }//for (k=0; k<2; ++k) {
1776 //=======================================================================
1777 //function : GetEFPnts
1779 //=======================================================================
1780 void BOPAlgo_PaveFiller::GetEFPnts
1781 (const Standard_Integer nF1,
1782 const Standard_Integer nF2,
1783 IntSurf_ListOfPntOn2S& aListOfPnts)
1785 Standard_Integer nE, nF, nFOpposite, aNbEFs, i;
1786 Standard_Real U1, U2, V1, V2, f, l;
1787 BOPCol_MapOfInteger aMI;
1789 //collect indexes of all shapes from nF1 and nF2.
1790 GetFullShapeMap(nF1, aMI);
1791 GetFullShapeMap(nF2, aMI);
1793 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1794 aNbEFs = aEFs.Extent();
1796 for(i = 0; i < aNbEFs; ++i) {
1797 const BOPDS_InterfEF& aEF = aEFs(i);
1798 if (aEF.HasIndexNew()) {
1799 aEF.Indices(nE, nFOpposite);
1800 if(aMI.Contains(nE) && aMI.Contains(nFOpposite)) {
1801 const IntTools_CommonPrt& aCP = aEF.CommonPart();
1802 Standard_Real aPar = aCP.VertexParameter1();
1803 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&myDS->Shape(nE)));
1804 const TopoDS_Face& aFOpposite =
1805 (*(TopoDS_Face*)(&myDS->Shape(nFOpposite)));
1807 const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(aE, f, l);
1809 nF = (nFOpposite == nF1) ? nF2 : nF1;
1810 const TopoDS_Face& aF = (*(TopoDS_Face*)(&myDS->Shape(nF)));
1811 Handle(Geom2d_Curve) aPCurve =
1812 BRep_Tool::CurveOnSurface(aE, aF, f, l);
1814 GeomAPI_ProjectPointOnSurf& aProj=myContext->ProjPS(aFOpposite);
1817 aCurve->D0(aPar, aPoint);
1818 IntSurf_PntOn2S aPnt;
1819 if(!aPCurve.IsNull()) {
1820 gp_Pnt2d aP2d = aPCurve->Value(aPar);
1821 aProj.Perform(aPoint);
1822 if(aProj.IsDone()) {
1823 aProj.LowerDistanceParameters(U1,V1);
1825 aPnt.SetValue(aP2d.X(),aP2d.Y(),U1,V1);
1827 aPnt.SetValue(U1,V1,aP2d.X(),aP2d.Y());
1829 aListOfPnts.Append(aPnt);
1833 GeomAPI_ProjectPointOnSurf& aProj1 = myContext->ProjPS(aF);
1834 aProj1.Perform(aPoint);
1835 aProj.Perform(aPoint);
1836 if(aProj1.IsDone() && aProj.IsDone()){
1837 aProj1.LowerDistanceParameters(U1,V1);
1838 aProj.LowerDistanceParameters(U2,V2);
1840 aPnt.SetValue(U1,V1,U2,V2);
1842 aPnt.SetValue(U2,V2,U1,V1);
1844 aListOfPnts.Append(aPnt);
1852 //=======================================================================
1853 //function : PutEFPavesOnCurve
1855 //=======================================================================
1856 void BOPAlgo_PaveFiller::PutEFPavesOnCurve
1858 const BOPCol_MapOfInteger& aMI,
1859 const BOPCol_MapOfInteger& aMVEF,
1860 BOPCol_DataMapOfIntegerReal& aMVTol,
1861 BOPCol_DataMapOfIntegerListOfInteger& aDMVLV)
1863 if (!aMVEF.Extent()) {
1867 const IntTools_Curve& aIC=aNC.Curve();
1868 GeomAbs_CurveType aTypeC;
1870 if (!(aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve)) {
1874 Standard_Integer nV;
1875 BOPCol_MapOfInteger aMV;
1878 RemoveUsedVertices(aNC, aMV);
1879 if (!aMV.Extent()) {
1883 Standard_Real aDist;
1886 const Handle(Geom_Curve)& aC3D=aIC.Curve();
1887 GeomAPI_ProjectPointOnCurve& aProjPT = myContext->ProjPT(aC3D);
1889 BOPCol_MapIteratorOfMapOfInteger aItMI;
1890 aItMI.Initialize(aMV);
1891 for (; aItMI.More(); aItMI.Next()) {
1893 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1894 gp_Pnt aPV = BRep_Tool::Pnt(aV);
1895 aProjPT.Perform(aPV);
1896 Standard_Integer aNbPoints = aProjPT.NbPoints();
1898 aDist = aProjPT.LowerDistance();
1899 PutPaveOnCurve(nV, aDist, aNC, aMI, aMVTol, aDMVLV);
1904 //=======================================================================
1905 //function : ProcessUnUsedVertices
1907 //=======================================================================
1908 void BOPAlgo_PaveFiller::PutStickPavesOnCurve
1909 (const TopoDS_Face& aF1,
1910 const TopoDS_Face& aF2,
1911 const BOPCol_MapOfInteger& aMI,
1913 const BOPCol_MapOfInteger& aMVStick,
1914 BOPCol_DataMapOfIntegerReal& aMVTol,
1915 BOPCol_DataMapOfIntegerListOfInteger& aDMVLV)
1917 BOPCol_MapOfInteger aMV;
1918 aMV.Assign(aMVStick);
1919 RemoveUsedVertices(aNC, aMV);
1921 if (!aMV.Extent()) {
1925 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
1926 Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2);
1928 const IntTools_Curve& aIC=aNC.Curve();
1929 //if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) {
1930 Handle(Geom2d_Curve) aC2D[2];
1932 aC2D[0]=aIC.FirstCurve2d();
1933 aC2D[1]=aIC.SecondCurve2d();
1934 if (!aC2D[0].IsNull() && !aC2D[1].IsNull()) {
1935 Standard_Integer nV, m, n;
1936 Standard_Real aTC[2], aD, aD2, u, v, aDT2, aScPr, aDScPr;
1940 BOPCol_MapIteratorOfMapOfInteger aItMI, aItMI1;
1942 aDT2=2e-7; // the rich criteria
1943 aDScPr=5.e-9; // the creasing criteria
1944 aIC.Bounds(aTC[0], aTC[1], aPC[0], aPC[1]);
1946 aItMI.Initialize(aMV);
1947 for (; aItMI.More(); aItMI.Next()) {
1949 const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&myDS->Shape(nV));
1950 aPV=BRep_Tool::Pnt(aV);
1952 for (m=0; m<2; ++m) {
1953 aD2=aPC[m].SquareDistance(aPV);
1954 if (aD2>aDT2) {// no rich
1958 for (n=0; n<2; ++n) {
1959 Handle(Geom_Surface)& aS=(!n)? aS1 : aS2;
1960 aC2D[n]->D0(aTC[m], aP2D);
1962 BOPTools_AlgoTools3D::GetNormalToSurface(aS, u, v, aDN[n]);
1965 aScPr=aDN[0]*aDN[1];
1975 // The intersection curve aIC is vanishing curve (the crease)
1978 PutPaveOnCurve(nV, aD, aNC, aMI, aMVTol, aDMVLV);
1980 }//for (jVU=1; jVU=aNbVU; ++jVU) {
1982 //}//if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) {
1983 //}//if(aType1==GeomAbs_Torus || aType2==GeomAbs_Torus) {
1986 //=======================================================================
1987 //function : GetStickVertices
1989 //=======================================================================
1990 void BOPAlgo_PaveFiller::GetStickVertices(const Standard_Integer nF1,
1991 const Standard_Integer nF2,
1992 BOPCol_MapOfInteger& aMVStick,
1993 BOPCol_MapOfInteger& aMVEF,
1994 BOPCol_MapOfInteger& aMI)
1996 Standard_Integer nS1, nS2, nVNew, aTypeInt, i;
1998 BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV();
1999 BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
2000 BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
2001 BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
2002 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
2004 Standard_Integer aNbLines[5] = {
2005 aVVs.Extent(), aVEs.Extent(), aEEs.Extent(),
2006 aVFs.Extent(), aEFs.Extent()
2008 //collect indices of all shapes from nF1 and nF2.
2010 GetFullShapeMap(nF1, aMI);
2011 GetFullShapeMap(nF2, aMI);
2013 //collect VV, VE, EE, VF interferences
2014 for (aTypeInt = 0; aTypeInt < 4; ++aTypeInt) {
2015 for (i = 0; i < aNbLines[aTypeInt]; ++i) {
2016 BOPDS_Interf* aInt = (aTypeInt==0) ? (BOPDS_Interf*)(&aVVs(i)) :
2017 ((aTypeInt==1) ? (BOPDS_Interf*)(&aVEs(i)) :
2018 ((aTypeInt==2) ? (BOPDS_Interf*)(&aEEs(i)) :
2019 (BOPDS_Interf*)(&aVFs(i))));
2020 if (aInt->HasIndexNew()) {
2021 aInt->Indices(nS1, nS2);
2022 if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
2023 nVNew = aInt->IndexNew();
2024 aMVStick.Add(nVNew);
2029 //collect EF interferences
2030 for (i = 0; i < aNbLines[4]; ++i) {
2031 const BOPDS_InterfEF& aInt = aEFs(i);
2032 if (aInt.HasIndexNew()) {
2033 aInt.Indices(nS1, nS2);
2034 if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
2035 nVNew = aInt.IndexNew();
2036 aMVStick.Add(nVNew);
2043 //=======================================================================
2044 // function: GetFullShapeMap
2046 //=======================================================================
2047 void BOPAlgo_PaveFiller::GetFullShapeMap(const Standard_Integer nF,
2048 BOPCol_MapOfInteger& aMI)
2050 BOPCol_ListIteratorOfListOfInteger aIt;
2051 Standard_Integer nS;
2053 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF);
2054 const BOPCol_ListOfInteger& aLI = aSI.SubShapes();
2057 aIt.Initialize(aLI);
2058 for (; aIt.More(); aIt.Next()) {
2064 //=======================================================================
2065 // function: RemoveUsedVertices
2067 //=======================================================================
2068 void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC,
2069 BOPCol_MapOfInteger& aMV)
2071 if (!aMV.Extent()) {
2074 Standard_Integer nV;
2076 BOPDS_ListIteratorOfListOfPave aItLP;
2078 Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
2079 const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
2080 aItLP.Initialize(aLP);
2081 for (;aItLP.More();aItLP.Next()) {
2082 aPave = aItLP.Value();
2088 //=======================================================================
2089 //function : PutPaveOnCurve
2091 //=======================================================================
2092 void BOPAlgo_PaveFiller::PutPaveOnCurve
2093 (const Standard_Integer nV,
2094 const Standard_Real aTolR3D,
2095 const BOPDS_Curve& aNC,
2096 const BOPCol_MapOfInteger& aMI,
2097 BOPCol_DataMapOfIntegerReal& aMVTol,
2098 BOPCol_DataMapOfIntegerListOfInteger& aDMVLV,
2099 const Standard_Integer iCheckExtend)
2101 Standard_Boolean bIsVertexOnLine;
2104 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
2105 const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First();
2106 const IntTools_Curve& aIC = aNC.Curve();
2108 Standard_Real aTolV = (aMVTol.IsBound(nV) ? aMVTol(nV) : BRep_Tool::Tolerance(aV));
2110 bIsVertexOnLine = myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D + myFuzzyValue, aT);
2111 if (!bIsVertexOnLine && iCheckExtend) {
2112 ExtendedTolerance(nV, aMI, aTolV, iCheckExtend);
2113 bIsVertexOnLine = myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D + myFuzzyValue, aT);
2116 if (bIsVertexOnLine) {
2117 // check if aPB contains the parameter aT
2118 Standard_Boolean bExist;
2119 Standard_Integer nVUsed;
2120 Standard_Real aPTol, aDTol;
2124 GeomAdaptor_Curve aGAC(aIC.Curve());
2125 aPTol = aGAC.Resolution(Max(aTolR3D, aTolV));
2127 bExist = aPB->ContainsParameter(aT, aPTol, nVUsed);
2129 // use existing pave
2130 BOPCol_ListOfInteger* pList = aDMVLV.ChangeSeek(nVUsed);
2132 pList = aDMVLV.Bound(nVUsed, BOPCol_ListOfInteger());
2133 pList->Append(nVUsed);
2134 if (!aMVTol.IsBound(nVUsed)) {
2135 const TopoDS_Vertex& aVUsed = (*(TopoDS_Vertex *)(&myDS->Shape(nVUsed)));
2136 aTolV = BRep_Tool::Tolerance(aVUsed);
2137 aMVTol.Bind(nVUsed, aTolV);
2140 // avoid repeated elements in the list
2141 BOPCol_ListIteratorOfListOfInteger aItLI(*pList);
2142 for (; aItLI.More(); aItLI.Next()) {
2143 if (aItLI.Value() == nV) {
2147 if (!aItLI.More()) {
2150 // save initial tolerance for the vertex
2151 if (!aMVTol.IsBound(nV)) {
2152 aTolV = BRep_Tool::Tolerance(aV);
2153 aMVTol.Bind(nV, aTolV);
2160 aPave.SetParameter(aT);
2161 aPB->AppendExtPave(aPave);
2163 gp_Pnt aP1 = aGAC.Value(aT);
2164 aTolV = BRep_Tool::Tolerance(aV);
2165 gp_Pnt aP2 = BRep_Tool::Pnt(aV);
2166 Standard_Real aDist = aP1.Distance(aP2);
2167 if (aDist > aTolV) {
2168 BRep_Builder().UpdateVertex(aV, aDist + aDTol);
2170 if (!aMVTol.IsBound(nV)) {
2171 aMVTol.Bind(nV, aTolV);
2174 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV);
2175 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
2176 BRepBndLib::Add(aV, aBoxDS);
2177 aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
2183 //=======================================================================
2184 //function : ProcessExistingPaveBlocks
2186 //=======================================================================
2187 void BOPAlgo_PaveFiller::ProcessExistingPaveBlocks
2188 (const Standard_Integer theInt,
2189 const BOPDS_IndexedMapOfPaveBlock& aMPBOnIn,
2190 const BOPCol_DataMapOfIntegerListOfInteger& aDMBV,
2191 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
2192 BOPCol_DataMapOfShapeInteger& aMVI,
2193 BOPDS_MapOfPaveBlock& aMPB)
2195 if (aDMBV.IsEmpty()) {
2199 Standard_Real aT, dummy;
2200 Standard_Integer i, nV, nE, iC, aNbPB, iFlag;
2201 BOPCol_ListIteratorOfListOfInteger aItLI;
2202 BOPCol_DataMapIteratorOfDataMapOfIntegerListOfInteger aItBV;
2204 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2205 BOPDS_InterfFF& aFF = aFFs(theInt);
2206 BOPDS_VectorOfCurve& aVC = aFF.ChangeCurves();
2208 aNbPB = aMPBOnIn.Extent();
2210 aItBV.Initialize(aDMBV);
2211 for (; aItBV.More(); aItBV.Next()) {
2213 const BOPCol_ListOfInteger& aLBV = aItBV.Value();
2215 BOPDS_Curve& aNC = aVC.ChangeValue(iC);
2216 BOPDS_ListOfPaveBlock& aLPBC = aNC.ChangePaveBlocks();
2218 aItLI.Initialize(aLBV);
2219 for (; aItLI.More(); aItLI.Next()) {
2221 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
2222 const Bnd_Box& aBoxV=aSIV.Box();
2223 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aSIV.Shape();
2224 if (!aMVI.IsBound(aV)) {
2228 for (i = 1; i <= aNbPB; ++i) {
2229 const Handle(BOPDS_PaveBlock)& aPB = aMPBOnIn(i);
2230 if (aPB->Pave1().Index() == nV || aPB->Pave2().Index() == nV) {
2234 if (aMPB.Contains(aPB)) {
2237 if (myDS->ShapeInfo(aPB->OriginalEdge()).HasFlag()) { // skip degenerated edges
2242 const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE);
2243 const Bnd_Box& aBoxE = aSIE.Box();
2245 if (aBoxV.IsOut(aBoxE)) {
2249 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aSIE.Shape();
2251 iFlag = myContext->ComputeVE(aV, aE, aT, dummy, myFuzzyValue);
2254 PreparePostTreatFF(theInt, iC, aPB, aMSCPB, aMVI, aLPBC);
2260 //=======================================================================
2261 //function : UpdateExistingPaveBlocks
2263 //=======================================================================
2264 void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks
2265 (const Handle(BOPDS_PaveBlock)& aPBf,
2266 BOPDS_ListOfPaveBlock& aLPB,
2267 const Standard_Integer nF1,
2268 const Standard_Integer nF2)
2270 if (!aLPB.Extent()) {
2274 Standard_Integer nE;
2275 Standard_Boolean bCB;
2276 Handle(BOPDS_PaveBlock) aPB, aPB1, aPB2, aPB2n;
2277 Handle(BOPDS_CommonBlock) aCB;
2278 BOPDS_ListIteratorOfListOfPaveBlock aIt, aIt1, aIt2;
2280 BOPDS_FaceInfo& aFI1 = myDS->ChangeFaceInfo(nF1);
2281 BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2);
2283 BOPDS_IndexedMapOfPaveBlock& aMPBOn1 = aFI1.ChangePaveBlocksOn();
2284 BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.ChangePaveBlocksIn();
2285 BOPDS_IndexedMapOfPaveBlock& aMPBOn2 = aFI2.ChangePaveBlocksOn();
2286 BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.ChangePaveBlocksIn();
2288 // 1. Remove old pave blocks
2289 const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPBf);
2290 bCB = !aCB1.IsNull();
2291 BOPDS_ListOfPaveBlock aLPB1;
2294 aLPB1.Assign(aCB1->PaveBlocks());
2298 aIt1.Initialize(aLPB1);
2299 for (; aIt1.More(); aIt1.Next()) {
2300 aPB1 = aIt1.Value();
2301 nE = aPB1->OriginalEdge();
2303 BOPDS_ListOfPaveBlock& aLPB2 = myDS->ChangePaveBlocks(nE);
2304 aIt2.Initialize(aLPB2);
2305 for (; aIt2.More(); aIt2.Next()) {
2306 aPB2 = aIt2.Value();
2314 // 2. Update pave blocks
2316 // Create new common blocks
2317 BOPDS_ListOfPaveBlock aLPBNew;
2318 const BOPCol_ListOfInteger& aFaces = aCB1->Faces();
2319 aIt.Initialize(aLPB);
2320 for (; aIt.More(); aIt.Next()) {
2321 const Handle(BOPDS_PaveBlock)& aPBValue = aIt.Value();
2322 BOPDS_Pave aPBValuePaves[2] = {aPBValue->Pave1(), aPBValue->Pave2()};
2324 aCB = new BOPDS_CommonBlock;
2325 aIt1.Initialize(aLPB1);
2326 for (; aIt1.More(); aIt1.Next()) {
2327 aPB2 = aIt1.Value();
2328 nE = aPB2->OriginalEdge();
2330 // Create new pave block
2331 aPB2n = new BOPDS_PaveBlock;
2332 if (aPBValue->OriginalEdge() == nE) {
2333 aPB2n->SetPave1(aPBValuePaves[0]);
2334 aPB2n->SetPave2(aPBValuePaves[1]);
2337 // For the different original edge compute the parameters of paves
2338 BOPDS_Pave aPave[2];
2339 for (Standard_Integer i = 0; i < 2; ++i) {
2340 Standard_Integer nV = aPBValuePaves[i].Index();
2341 aPave[i].SetIndex(nV);
2342 if (nV == aPB2->Pave1().Index()) {
2343 aPave[i].SetParameter(aPB2->Pave1().Parameter());
2345 else if (nV == aPB2->Pave2().Index()) {
2346 aPave[i].SetParameter(aPB2->Pave2().Parameter());
2349 // Compute the parameter by projecting the point
2350 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
2351 const TopoDS_Edge& aEOr = TopoDS::Edge(myDS->Shape(nE));
2352 Standard_Real aTOut, aDist;
2353 Standard_Integer iErr = myContext->ComputeVE(aV, aEOr, aTOut, aDist, myFuzzyValue);
2355 aPave[i].SetParameter(aTOut);
2358 // Unable to project - set the parameter of the closest boundary
2359 const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(aPB2->Pave1().Index()));
2360 const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(aPB2->Pave2().Index()));
2362 gp_Pnt aP = BRep_Tool::Pnt(aV);
2363 gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
2364 gp_Pnt aP2 = BRep_Tool::Pnt(aV2);
2366 Standard_Real aDist1 = aP.SquareDistance(aP1);
2367 Standard_Real aDist2 = aP.SquareDistance(aP2);
2369 aPave[i].SetParameter(aDist1 < aDist2 ? aPB2->Pave1().Parameter() : aPB2->Pave2().Parameter());
2374 if (aPave[1].Parameter() < aPave[0].Parameter()) {
2375 BOPDS_Pave aPaveTmp = aPave[0];
2376 aPave[0] = aPave[1];
2377 aPave[1] = aPaveTmp;
2380 aPB2n->SetPave1(aPave[0]);
2381 aPB2n->SetPave2(aPave[1]);
2384 aPB2n->SetEdge(aPBValue->Edge());
2385 aPB2n->SetOriginalEdge(nE);
2386 aCB->AddPaveBlock(aPB2n);
2387 myDS->SetCommonBlock(aPB2n, aCB);
2388 myDS->ChangePaveBlocks(nE).Append(aPB2n);
2390 aCB->SetFaces(aFaces);
2392 const Handle(BOPDS_PaveBlock)& aPBNew = aCB->PaveBlocks().First();
2393 aLPBNew.Append(aPBNew);
2399 nE = aPBf->OriginalEdge();
2400 BOPDS_ListOfPaveBlock& aLPBE = myDS->ChangePaveBlocks(nE);
2401 aIt.Initialize(aLPB);
2402 for (; aIt.More(); aIt.Next()) {
2408 Standard_Boolean bIn1, bIn2;
2410 bIn1 = aMPBOn1.Contains(aPBf) || aMPBIn1.Contains(aPBf);
2411 bIn2 = aMPBOn2.Contains(aPBf) || aMPBIn2.Contains(aPBf);
2417 // 3. Check new pave blocks for coincidence
2418 // with the opposite face.
2419 // In case of coincidence create common blocks
2420 Standard_Integer nF;
2422 nF = bIn1 ? nF2 : nF1;
2423 const TopoDS_Face& aF = *(TopoDS_Face*)&myDS->Shape(nF);
2424 BOPDS_IndexedMapOfPaveBlock& aMPBIn = bIn1 ? aMPBIn2 : aMPBIn1;
2426 aIt.Initialize(aLPB);
2427 for (; aIt.More(); aIt.Next()) {
2428 Handle(BOPDS_PaveBlock)& aPBChangeValue = aIt.ChangeValue();
2429 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPBChangeValue->Edge());
2431 IntTools_EdgeFace anEF;
2434 anEF.SetFuzzyValue(myFuzzyValue);
2435 anEF.SetRange(aPBChangeValue->Pave1().Parameter(), aPBChangeValue->Pave2().Parameter());
2436 anEF.SetContext(myContext);
2439 const IntTools_SequenceOfCommonPrts& aCPrts=anEF.CommonParts();
2440 if (aCPrts.Length() == 1) {
2441 Standard_Boolean bCoinc = (aCPrts(1).Type() == TopAbs_EDGE);
2444 aCB = myDS->CommonBlock(aPBChangeValue);
2446 aCB = new BOPDS_CommonBlock;
2447 aCB->AddPaveBlock(aPBChangeValue);
2448 myDS->SetCommonBlock(aPBChangeValue, aCB);
2452 aMPBIn.Add(aPBChangeValue);
2457 //=======================================================================
2458 // function: PutClosingPaveOnCurve
2460 //=======================================================================
2461 void BOPAlgo_PaveFiller::PutClosingPaveOnCurve(BOPDS_Curve& aNC)
2463 Standard_Boolean bIsClosed, bHasBounds, bAdded;
2464 Standard_Integer nVC, j;
2465 Standard_Real aT[2], aTC, dT, aTx;
2468 BOPDS_ListIteratorOfListOfPave aItLP;
2470 const IntTools_Curve& aIC=aNC.Curve();
2471 const Handle(Geom_Curve)& aC3D=aIC.Curve();
2476 bIsClosed=IntTools_Tools::IsClosed(aC3D);
2481 bHasBounds=aIC.HasBounds ();
2486 bAdded=Standard_False;
2487 dT=Precision::PConfusion();
2488 aIC.Bounds (aT[0], aT[1], aP[0], aP[1]);
2490 Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
2491 BOPDS_ListOfPave& aLP=aPB->ChangeExtPaves();
2493 aItLP.Initialize(aLP);
2494 for (; aItLP.More() && !bAdded; aItLP.Next()) {
2495 const BOPDS_Pave& aPC=aItLP.Value();
2497 aTC=aPC.Parameter();
2499 for (j=0; j<2; ++j) {
2500 if (fabs(aTC-aT[j]) < dT) {
2501 aTx=(!j) ? aT[1] : aT[0];
2503 aPVx.SetParameter(aTx);
2506 bAdded=Standard_True;
2512 //=======================================================================
2513 //function : PreparePostTreatFF
2515 //=======================================================================
2516 void BOPAlgo_PaveFiller::PreparePostTreatFF
2517 (const Standard_Integer aInt,
2518 const Standard_Integer aCur,
2519 const Handle(BOPDS_PaveBlock)& aPB,
2520 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
2521 BOPCol_DataMapOfShapeInteger& aMVI,
2522 BOPDS_ListOfPaveBlock& aLPBC)
2524 Standard_Integer nV1, nV2;
2528 aPB->Indices(nV1, nV2);
2529 const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
2530 const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
2531 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPB->Edge());
2532 // Keep info for post treatment
2533 BOPDS_CoupleOfPaveBlocks aCPB;
2534 aCPB.SetIndexInterf(aInt);
2535 aCPB.SetIndex(aCur);
2536 aCPB.SetPaveBlock1(aPB);
2538 aMSCPB.Add(aE, aCPB);
2539 aMVI.Bind(aV1, nV1);
2540 aMVI.Bind(aV2, nV2);
2543 //=======================================================================
2544 //function : CheckPlanes
2546 //=======================================================================
2547 Standard_Boolean BOPAlgo_PaveFiller::CheckPlanes
2548 (const Standard_Integer nF1,
2549 const Standard_Integer nF2)const
2551 Standard_Boolean bToIntersect;
2552 Standard_Integer i, nV2, iCnt;
2553 BOPCol_MapIteratorOfMapOfInteger aIt;
2555 bToIntersect=Standard_False;
2557 const BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
2558 const BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
2560 const BOPCol_MapOfInteger& aMVIn1=aFI1.VerticesIn();
2561 const BOPCol_MapOfInteger& aMVOn1=aFI1.VerticesOn();
2564 for (i=0; (i<2 && !bToIntersect); ++i) {
2565 const BOPCol_MapOfInteger& aMV2=(!i) ? aFI2.VerticesIn()
2566 : aFI2.VerticesOn();
2568 aIt.Initialize(aMV2);
2569 for (; aIt.More(); aIt.Next()) {
2571 if (aMVIn1.Contains(nV2) || aMVOn1.Contains(nV2)) {
2574 bToIntersect=!bToIntersect;
2581 return bToIntersect;
2583 //=======================================================================
2584 //function : UpdatePaveBlocks
2586 //=======================================================================
2587 void BOPAlgo_PaveFiller::UpdatePaveBlocks
2588 (const BOPCol_DataMapOfIntegerInteger& aDMNewSD)
2590 if (aDMNewSD.IsEmpty()) {
2594 Standard_Integer nSp, aNbPBP, nV[2], i, j;
2595 Standard_Real aT[2];
2596 Standard_Boolean bCB, bRebuild;
2597 BOPDS_ListIteratorOfListOfPaveBlock aItPB;
2598 BOPDS_MapOfPaveBlock aMPB;
2599 BOPCol_MapOfInteger aMicroEdges;
2601 BOPDS_ListOfPaveBlock anAllPBs;
2603 // Get pave blocks of section edges
2604 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2605 Standard_Integer aNbFF = aFFs.Extent();
2606 for (i = 0; i < aNbFF; ++i)
2608 const BOPDS_InterfFF& aFF = aFFs(i);
2609 const BOPDS_VectorOfCurve& aVNC = aFF.Curves();
2610 Standard_Integer aNbC = aVNC.Extent();
2611 for (j = 0; j < aNbC; ++j)
2613 const BOPDS_Curve& aNC = aVNC(j);
2614 const BOPDS_ListOfPaveBlock& aLPBC = aNC.PaveBlocks();
2615 aItPB.Initialize(aLPBC);
2616 for (; aItPB.More(); aItPB.Next())
2617 anAllPBs.Append(aItPB.Value());
2621 // Get pave blocks from the pool
2622 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
2623 aNbPBP = aPBP.Extent();
2624 for (i = 0; i < aNbPBP; ++i) {
2625 BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2626 aItPB.Initialize(aLPB);
2627 for (; aItPB.More(); aItPB.Next())
2628 anAllPBs.Append(aItPB.Value());
2631 // Process all pave blocks
2632 aItPB.Initialize(anAllPBs);
2633 for (; aItPB.More(); aItPB.Next())
2635 Handle(BOPDS_PaveBlock) aPB = aItPB.Value();
2636 const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
2637 bCB = !aCB.IsNull();
2639 aPB = aCB->PaveBlock1();
2642 if (aMPB.Add(aPB)) {
2643 bRebuild = Standard_False;
2644 aPB->Indices(nV[0], nV[1]);
2645 aPB->Range(aT[0], aT[1]);
2646 // remember the fact if the edge had different vertices before substitution
2647 Standard_Boolean wasRegularEdge = (nV[0] != nV[1]);
2649 for (j = 0; j < 2; ++j) {
2650 if (aDMNewSD.IsBound(nV[j])) {
2653 nV[j] = aDMNewSD.Find(nV[j]);
2654 aPave.SetIndex(nV[j]);
2655 aPave.SetParameter(aT[j]);
2657 bRebuild = Standard_True;
2659 aPB->SetPave1(aPave);
2662 aPB->SetPave2(aPave);
2668 Standard_Integer nE = aPB->Edge();
2669 // Check if the Pave Block has the edge set
2672 nE = aPB->OriginalEdge();
2674 Standard_Boolean isDegEdge = myDS->ShapeInfo(nE).HasFlag();
2675 if (wasRegularEdge && !isDegEdge && nV[0] == nV[1]) {
2676 // now edge has the same vertex on both ends;
2677 // check if it is not a regular closed curve.
2678 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
2679 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV[0]));
2680 Standard_Real aLength = IntTools::Length(aE);
2681 Standard_Real aTolV = BRep_Tool::Tolerance(aV);
2682 if (aLength <= aTolV * 2.) {
2683 // micro edge, so mark it for removal
2684 aMicroEdges.Add(nE);
2688 nSp = SplitEdge(nE, nV[0], aT[0], nV[1], aT[1]);
2694 }// if (aMPB.Add(aPB)) {
2695 }// for (; aItPB.More(); aItPB.Next()) {
2698 if (aMicroEdges.Extent())
2699 RemovePaveBlocks(aMicroEdges);
2701 //=======================================================================
2702 //function : RemovePaveBlocks
2704 //=======================================================================
2705 void BOPAlgo_PaveFiller::RemovePaveBlocks(const BOPCol_MapOfInteger theEdges)
2707 // Remove all pave blocks referring to input edges:
2709 // 1. from the Pave Blocks Pool
2710 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
2711 Standard_Integer aNbPBP = aPBP.Extent(), i;
2712 for (i = 0; i < aNbPBP; ++i) {
2713 BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2715 BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
2716 while (aItPB.More()) {
2717 const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
2718 if (theEdges.Contains(aPB->Edge()))
2725 // 2. from Face Info and section curves
2726 BOPCol_MapOfInteger aMPassed;
2727 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2728 Standard_Integer aNbFF = aFFs.Extent(), j;
2729 for (i = 0; i < aNbFF; ++i) {
2730 BOPDS_InterfFF& aFF = aFFs(i);
2731 Standard_Integer nF1, nF2;
2732 aFF.Indices(nF1, nF2);
2734 // rebuild pave block maps of face info
2735 for (j = 0; j < 2; j++) {
2736 Standard_Integer nF = (j == 0 ? nF1 : nF2);
2737 if (!aMPassed.Add(nF))
2739 BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF);
2740 BOPDS_IndexedMapOfPaveBlock* aIMPB[] = { &aFI.ChangePaveBlocksIn(),
2741 &aFI.ChangePaveBlocksOn(), &aFI.ChangePaveBlocksSc() };
2742 for (Standard_Integer k = 0; k < 3; k++) {
2743 Standard_Integer aNbPB = aIMPB[k]->Extent(), m;
2744 for (m = 1; m <= aNbPB; ++m) {
2745 const Handle(BOPDS_PaveBlock)& aPB = aIMPB[k]->FindKey(m);
2746 if (theEdges.Contains(aPB->Edge()))
2750 BOPDS_IndexedMapOfPaveBlock aMPBCopy = *aIMPB[k];
2752 for (m = 1; m <= aNbPB; ++m) {
2753 const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(m);
2754 if (!theEdges.Contains(aPB->Edge()))
2760 // remove from Section pave blocks
2761 BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
2762 Standard_Integer aNbC = aVNC.Extent();
2763 for (j = 0; j < aNbC; ++j) {
2764 BOPDS_Curve& aNC = aVNC(j);
2765 BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
2766 BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
2767 while (aItPB.More()) {
2768 const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
2769 if (theEdges.Contains(aPB->Edge()))
2777 //=======================================================================
2778 //function : ToleranceFF
2779 //purpose : Computes the TolFF according to the tolerance value and
2780 // types of the faces.
2781 //=======================================================================
2782 Standard_Real ToleranceFF(const BRepAdaptor_Surface& aBAS1,
2783 const BRepAdaptor_Surface& aBAS2)
2785 Standard_Real aTol1 = aBAS1.Tolerance();
2786 Standard_Real aTol2 = aBAS2.Tolerance();
2787 Standard_Real aTolFF = Max(aTol1, aTol2);
2789 Standard_Boolean isAna1, isAna2;
2790 isAna1 = (aBAS1.GetType() == GeomAbs_Plane ||
2791 aBAS1.GetType() == GeomAbs_Cylinder ||
2792 aBAS1.GetType() == GeomAbs_Cone ||
2793 aBAS1.GetType() == GeomAbs_Sphere ||
2794 aBAS1.GetType() == GeomAbs_Torus);
2796 isAna2 = (aBAS2.GetType() == GeomAbs_Plane ||
2797 aBAS2.GetType() == GeomAbs_Cylinder ||
2798 aBAS2.GetType() == GeomAbs_Cone ||
2799 aBAS2.GetType() == GeomAbs_Sphere ||
2800 aBAS2.GetType() == GeomAbs_Torus);
2802 if (!isAna1 || !isAna2) {
2803 aTolFF = Max(aTolFF, 5.e-6);
2807 //=======================================================================
2808 //function : UpdateBlocksWithSharedVertices
2810 //=======================================================================
2811 void BOPAlgo_PaveFiller::UpdateBlocksWithSharedVertices()
2813 if (!myNonDestructive) {
2817 Standard_Integer aNbFF;
2819 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
2820 aNbFF=aFFs.Extent();
2825 Standard_Boolean bOnCurve, bHasShapeSD;
2826 Standard_Integer i, nF1, nF2, aNbC, j, nV, nVSD;
2827 Standard_Real aTolV;
2828 BOPCol_MapOfInteger aMF;
2830 for (i=0; i<aNbFF; ++i) {
2831 BOPDS_InterfFF& aFF=aFFs(i);
2833 BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
2839 aFF.Indices(nF1, nF2);
2842 myDS->UpdateFaceInfoOn(nF1);
2845 myDS->UpdateFaceInfoOn(nF2);
2848 // Collect old vertices that are shared for nF1, nF2 ->aMI;
2849 BOPCol_MapOfInteger aMI;
2850 BOPCol_MapIteratorOfMapOfInteger aItMI;
2852 BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
2853 BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
2855 const BOPCol_MapOfInteger& aMVOn1=aFI1.VerticesOn();
2856 const BOPCol_MapOfInteger& aMVIn1=aFI1.VerticesIn();
2857 const BOPCol_MapOfInteger& aMVOn2=aFI2.VerticesOn();
2858 const BOPCol_MapOfInteger& aMVIn2=aFI2.VerticesIn();
2860 for (j=0; j<2; ++j) {
2861 const BOPCol_MapOfInteger& aMV1=(!j) ? aMVOn1 : aMVIn1;
2862 aItMI.Initialize(aMV1);
2863 for (; aItMI.More(); aItMI.Next()) {
2865 if (myDS->IsNewShape(nV)) {
2868 if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV)) {
2874 // Try to put vertices aMI on curves
2875 for (j=0; j<aNbC; ++j) {
2876 BOPDS_Curve& aNC=aVC.ChangeValue(j);
2877 Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
2879 aItMI.Initialize(aMI);
2880 for (; aItMI.More(); aItMI.Next()) {
2883 bHasShapeSD=myDS->HasShapeSD(nV, nVSD);
2888 bOnCurve=EstimatePaveOnCurve(nV, aNC, aTolR3D);
2893 const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV));
2894 aTolV=BRep_Tool::Tolerance(aV);
2896 UpdateVertex(nV, aTolV);
2898 }//for (j=0; j<aNbC; ++j) {
2899 }//for (i=0; i<aNbFF; ++i) {
2901 UpdateCommonBlocksWithSDVertices();
2903 //=======================================================================
2904 //function : EstimatePaveOnCurve
2906 //=======================================================================
2907 Standard_Boolean BOPAlgo_PaveFiller::EstimatePaveOnCurve
2908 (const Standard_Integer nV,
2909 const BOPDS_Curve& aNC,
2910 const Standard_Real aTolR3D)
2912 Standard_Boolean bIsVertexOnLine;
2915 const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV));
2916 const IntTools_Curve& aIC=aNC.Curve();
2918 bIsVertexOnLine=myContext->IsVertexOnLine(aV, aIC, aTolR3D, aT);
2919 return bIsVertexOnLine;
2922 //=======================================================================
2923 //function : CorrectToleranceOfSE
2925 //=======================================================================
2926 void BOPAlgo_PaveFiller::CorrectToleranceOfSE()
2928 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2929 NCollection_IndexedDataMap<Standard_Integer,BOPDS_ListOfPaveBlock> aMVIPBs;
2930 BOPCol_MapOfInteger aMVIToReduce;
2931 // Fence map to avoid repeated checking of the same edge
2932 BOPDS_MapOfPaveBlock aMPB;
2934 // 1. iterate on all sections F-F
2935 Standard_Integer aNb = aFFs.Extent(), i;
2936 for (i = 0; i < aNb; ++i) {
2937 BOPDS_InterfFF& aFF = aFFs(i);
2939 BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
2940 Standard_Integer aNbC = aVNC.Extent(), k;
2941 for (k = 0; k < aNbC; ++k) {
2942 BOPDS_Curve& aNC = aVNC(k);
2943 BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
2944 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
2945 for (; aItLPB.More(); ) {
2946 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
2947 Standard_Integer nE;
2948 if (!aPB->HasEdge(nE)) {
2949 aLPB.Remove(aItLPB);
2953 if (!aMPB.Add(aPB)) {
2958 Standard_Boolean bIsReduced = Standard_False;
2959 if (aPB->OriginalEdge() < 0) {
2960 // It is possible that due to small angle between faces the
2961 // common zone between faces can be large and the tangential
2962 // tolerance of the curve will be large as well.
2963 // Here we're trying to reduce the tolerance of the section
2964 // edge using the valid tolerance of the edge.
2965 // Note, that if the pave block has created common block with
2966 // other edges its valid tolerance could have been changed to
2967 // cover all edges in common block (see PostTreatFF() method).
2968 Standard_Real aTolC = aNC.Tolerance();
2969 Standard_Real aTolTang = aNC.TangentialTolerance();
2970 if (aTolC < aTolTang) {
2971 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
2972 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
2973 if (aTolC < aTolE) {
2974 // reduce edge tolerance
2975 reinterpret_cast<BRep_TEdge*>(aE.TShape().operator->())->Tolerance(aTolC);
2976 bIsReduced = Standard_True;
2981 // fill in the map vertex index - pave blocks
2982 for (Standard_Integer j=0; j < 2; j++) {
2983 Standard_Integer nV = (j == 0 ? aPB->Pave1().Index() : aPB->Pave2().Index());
2984 myDS->HasShapeSD(nV, nV);
2985 BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV);
2987 pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock()));
2989 pPBList->Append(aPB);
2991 aMVIToReduce.Add(nV);
2999 if (aMVIToReduce.IsEmpty()) {
3003 // 2. try to reduce tolerances of connected vertices
3004 // 2.1 find all other edges containing these connected vertices to avoid
3005 // reducing the tolerance to the value less than the tolerances of edges,
3006 // i.e. minimal tolerance for the vertex is the max tolerance of the
3007 // edges containing this vertex
3008 BOPCol_DataMapOfIntegerReal aMVITol;
3009 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
3010 aNb = aPBP.Extent();
3011 for (i = 0; i < aNb; ++i) {
3012 const BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
3013 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
3014 for (; aItLPB.More(); aItLPB.Next()) {
3015 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
3016 Standard_Integer nE;
3017 if (!aPB->HasEdge(nE)) {
3020 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
3021 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
3023 Standard_Integer nV[2];
3024 aPB->Indices(nV[0], nV[1]);
3026 for (Standard_Integer j = 0; j < 2; j++) {
3027 if (aMVIToReduce.Contains(nV[j])) {
3028 Standard_Real *aMaxTol = aMVITol.ChangeSeek(nV[j]);
3030 aMVITol.Bind(nV[j], aTolE);
3032 else if (aTolE > *aMaxTol) {
3040 // 2.2 reduce tolerances if possible
3041 aNb = aMVIPBs.Extent();
3042 for (i = 1; i <= aNb; ++i) {
3043 Standard_Integer nV = aMVIPBs.FindKey(i);
3044 if (!aMVIToReduce.Contains(nV)) {
3048 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
3049 Standard_Real aTolV = BRep_Tool::Tolerance(aV);
3050 Standard_Real aMaxTol = aMVITol.IsBound(nV) ? aMVITol.Find(nV) : 0.;
3051 // it makes no sense to compute the real tolerance if it is
3052 // impossible to reduce the tolerance at least 0.1% of the current value
3053 if (aTolV - aMaxTol < 0.001 * aTolV) {
3057 // compute the maximal distance from the vertex to the adjacent edges
3058 gp_Pnt aP = BRep_Tool::Pnt(aV);
3060 // Avoid repeated checks
3061 BOPDS_MapOfPaveBlock aMPBFence;
3063 const BOPDS_ListOfPaveBlock& aLPB = aMVIPBs.FindFromIndex(i);
3064 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
3065 for (; aItLPB.More(); aItLPB.Next()) {
3066 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
3067 if (!aMPBFence.Add(aPB)) {
3070 Standard_Integer nE = aPB->Edge();
3071 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
3072 BRepAdaptor_Curve aC(aE);
3073 for (Standard_Integer iPave = 0; iPave < 2; ++iPave) {
3074 const BOPDS_Pave& aPave = !iPave ? aPB->Pave1() : aPB->Pave2();
3075 Standard_Integer nVSD = aPave.Index();
3076 myDS->HasShapeSD(nVSD, nVSD);
3081 gp_Pnt aPonE = aC.Value(aPave.Parameter());
3082 Standard_Real aDist = aP.Distance(aPonE);
3083 aDist += BRep_Tool::Tolerance(aE);
3084 if (aDist > aMaxTol) {
3090 if (aMaxTol < aTolV) {
3091 reinterpret_cast<BRep_TVertex*>(aV.TShape().operator->())->Tolerance(aMaxTol);
3096 //=======================================================================
3097 //function : PutSEInOtherFaces
3099 //=======================================================================
3100 void BOPAlgo_PaveFiller::PutSEInOtherFaces()
3102 // Try to intersect each section edge with the faces
3103 // not participated in its creation
3105 // 1. Get all section edges
3106 BOPDS_IndexedMapOfPaveBlock aMPBScAll;
3108 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
3109 Standard_Integer i, j, aNbFF = aFFs.Extent();
3111 for (i = 0; i < aNbFF; ++i) {
3112 const BOPDS_VectorOfCurve& aVNC = aFFs(i).Curves();
3113 Standard_Integer aNbC = aVNC.Extent();
3114 for (j = 0; j < aNbC; ++j) {
3115 const BOPDS_ListOfPaveBlock& aLPBC = aVNC(j).PaveBlocks();
3116 BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPBC);
3117 for (; aItPB.More(); aItPB.Next()) {
3118 aMPBScAll.Add(aItPB.Value());
3123 Standard_Integer aNbPBSc = aMPBScAll.Extent();
3125 // 2. Loop for all faces and check each section curve
3126 Standard_Integer aNbS = myDS->NbSourceShapes();
3127 for (i = 0; i < aNbS; ++i) {
3128 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
3129 if (aSI.ShapeType() != TopAbs_FACE) {
3133 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aSI.Shape()));
3134 BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(i);
3136 // IN edges to add new ones
3137 BOPDS_IndexedMapOfPaveBlock& aMFPBIn = aFI.ChangePaveBlocksIn();
3138 // Section edges to check the participation of the face
3139 const BOPDS_IndexedMapOfPaveBlock& aMFPBSc = aFI.PaveBlocksSc();
3141 // Get vertices of the face to check that vertices of the
3142 // processed section edge belong to the face
3143 BOPCol_MapOfInteger aMFVerts;
3144 // Get vertices from ON, IN and Sc pave blocks of the face
3145 for (j = 0; j < 3; ++j) {
3146 const BOPDS_IndexedMapOfPaveBlock& aMPB =
3147 !j ? aFI.PaveBlocksOn() : (j == 1 ? aMFPBIn : aMFPBSc);
3148 Standard_Integer aNbPB = aMPB.Extent();
3149 for (Standard_Integer k = 1; k <= aNbPB; ++k) {
3150 const Handle(BOPDS_PaveBlock)& aPB = aMPB(k);
3151 aMFVerts.Add(aPB->Pave1().Index());
3152 aMFVerts.Add(aPB->Pave2().Index());
3155 // Add ON, IN and Sc vertices of the face
3156 for (j = 0; j < 3; ++j) {
3157 const BOPCol_MapOfInteger& aMFV = !j ? aFI.VerticesOn() :
3158 (j == 1 ? aFI.VerticesIn() : aFI.VerticesSc());
3159 BOPCol_MapIteratorOfMapOfInteger aItMI(aMFV);
3160 for (; aItMI.More(); aItMI.Next()) {
3161 aMFVerts.Add(aItMI.Value());
3165 // Check each section edge for possible belonging to the face
3166 for (j = 1; j <= aNbPBSc; ++j) {
3167 const Handle(BOPDS_PaveBlock)& aPB = aMPBScAll(j);
3168 if (aMFPBSc.Contains(aPB)) {
3172 // Both vertices of the section edge should belong to the face
3173 if (!aMFVerts.Contains(aPB->Pave1().Index()) ||
3174 !aMFVerts.Contains(aPB->Pave2().Index())) {
3178 // Perform intersection
3179 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(aPB->Edge()));
3181 IntTools_EdgeFace anEFInt;
3182 anEFInt.SetEdge(aE);
3183 anEFInt.SetFace(aF);
3184 anEFInt.SetFuzzyValue(myFuzzyValue);
3185 anEFInt.SetRange(aPB->Pave1().Parameter(), aPB->Pave2().Parameter());
3186 anEFInt.SetContext(myContext);
3187 anEFInt.UseQuickCoincidenceCheck(Standard_True);
3190 const IntTools_SequenceOfCommonPrts& aCPrts = anEFInt.CommonParts();
3191 if ((aCPrts.Length() == 1) && (aCPrts(1).Type() == TopAbs_EDGE)) {
3192 Handle(BOPDS_CommonBlock) aCB;
3193 if (myDS->IsCommonBlock(aPB)) {
3194 aCB = myDS->CommonBlock(aPB);
3197 aCB = new BOPDS_CommonBlock;
3198 aCB->AddPaveBlock(aPB);