1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 // EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
7 // This file is part of Open CASCADE Technology software library.
9 // This library is free software; you can redistribute it and/or modify it under
10 // the terms of the GNU Lesser General Public License version 2.1 as published
11 // by the Free Software Foundation, with special exception defined in the file
12 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 // distribution for complete text of the license and disclaimer of any warranty.
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
18 #include <BOPAlgo_PaveFiller.hxx>
19 #include <Bnd_Box.hxx>
20 #include <BOPAlgo_Alerts.hxx>
21 #include <BOPAlgo_SectionAttribute.hxx>
22 #include <BOPAlgo_Tools.hxx>
23 #include <BOPDS_CoupleOfPaveBlocks.hxx>
24 #include <BOPDS_Curve.hxx>
25 #include <BOPDS_DataMapOfPaveBlockListOfPaveBlock.hxx>
26 #include <BOPDS_DS.hxx>
27 #include <BOPDS_FaceInfo.hxx>
28 #include <BOPDS_Interf.hxx>
29 #include <BOPDS_Iterator.hxx>
30 #include <BOPDS_ListOfPave.hxx>
31 #include <BOPDS_ListOfPaveBlock.hxx>
32 #include <BOPDS_MapOfPaveBlock.hxx>
33 #include <BOPDS_PaveBlock.hxx>
34 #include <BOPDS_Point.hxx>
35 #include <BOPDS_ShapeInfo.hxx>
36 #include <BOPDS_VectorOfCurve.hxx>
37 #include <BOPDS_VectorOfPoint.hxx>
38 #include <BOPTools_AlgoTools.hxx>
39 #include <BOPTools_AlgoTools3D.hxx>
40 #include <BOPTools_BoxSelector.hxx>
41 #include <BOPTools_Parallel.hxx>
42 #include <Bnd_Tools.hxx>
43 #include <BRep_Builder.hxx>
44 #include <BRep_TEdge.hxx>
45 #include <BRep_Tool.hxx>
46 #include <BRepBndLib.hxx>
47 #include <BRepLib.hxx>
48 #include <BRepTools.hxx>
49 #include <Geom_Curve.hxx>
50 #include <Geom2d_Curve.hxx>
51 #include <GeomAPI_ProjectPointOnCurve.hxx>
52 #include <GeomAPI_ProjectPointOnSurf.hxx>
54 #include <IntSurf_ListOfPntOn2S.hxx>
55 #include <IntSurf_PntOn2S.hxx>
56 #include <IntTools.hxx>
57 #include <IntTools_Context.hxx>
58 #include <IntTools_Curve.hxx>
59 #include <IntTools_EdgeFace.hxx>
60 #include <IntTools_FaceFace.hxx>
61 #include <IntTools_PntOn2Faces.hxx>
62 #include <IntTools_SequenceOfCurves.hxx>
63 #include <IntTools_SequenceOfPntOn2Faces.hxx>
64 #include <IntTools_Tools.hxx>
65 #include <NCollection_Vector.hxx>
66 #include <Precision.hxx>
67 #include <TColStd_ListOfInteger.hxx>
68 #include <TColStd_MapOfInteger.hxx>
69 #include <TopExp_Explorer.hxx>
71 #include <TopoDS_Compound.hxx>
72 #include <TopoDS_Edge.hxx>
73 #include <TopoDS_Face.hxx>
74 #include <TopoDS_Vertex.hxx>
75 #include <TopTools_DataMapOfShapeInteger.hxx>
76 #include <TopTools_ListOfShape.hxx>
79 static Standard_Real ToleranceFF(const BRepAdaptor_Surface& aBAS1,
80 const BRepAdaptor_Surface& aBAS2);
82 /////////////////////////////////////////////////////////////////////////
83 //=======================================================================
84 //class : BOPAlgo_FaceFace
86 //=======================================================================
87 class BOPAlgo_FaceFace :
88 public IntTools_FaceFace,
89 public BOPAlgo_ParallelAlgo {
96 BOPAlgo_ParallelAlgo(),
97 myIF1(-1), myIF2(-1), myTolFF(1.e-7) {
100 virtual ~BOPAlgo_FaceFace() {
103 void SetIndices(const Standard_Integer nF1,
104 const Standard_Integer nF2) {
109 void Indices(Standard_Integer& nF1,
110 Standard_Integer& nF2) const {
115 void SetFaces(const TopoDS_Face& aF1,
116 const TopoDS_Face& aF2) {
121 void SetBoxes(const Bnd_Box& theBox1,
122 const Bnd_Box& theBox2) {
127 const TopoDS_Face& Face1()const {
131 const TopoDS_Face& Face2()const {
135 void SetTolFF(const Standard_Real aTolFF) {
139 Standard_Real TolFF() const{
143 void SetFuzzyValue(const Standard_Real theFuzz) {
144 IntTools_FaceFace::SetFuzzyValue(theFuzz);
147 const gp_Trsf& Trsf() const { return myTrsf; }
149 virtual void Perform() {
150 Message_ProgressScope aPS(myProgressRange, NULL, 1);
160 TopoDS_Face aF1 = myF1, aF2 = myF2;
161 if (BOPAlgo_Tools::TrsfToPoint (myBox1, myBox2, aTrsf))
163 // Shapes are located far from origin, move the shapes to the origin,
164 // to increase the accuracy of intersection.
165 TopLoc_Location aLoc (aTrsf);
169 // The starting point is initialized only with the UV parameters
170 // on the faces - 3D point is not set (see GetEFPnts method),
171 // so no need to transform anything.
172 //for (IntSurf_ListOfPntOn2S::Iterator it (myListOfPnts); it.More(); it.Next())
174 // IntSurf_PntOn2S& aP2S = it.ChangeValue();
175 // aP2S.SetValue (aP2S.Value().Transformed (aTrsf));
178 myTrsf = aTrsf.Inverted();
181 IntTools_FaceFace::Perform (aF1, aF2, myRunParallel);
183 catch (Standard_Failure const&)
185 AddError(new BOPAlgo_AlertIntersectionFailed);
194 for (Standard_Integer i = 1; i <= mySeqOfCurve.Length(); ++i)
196 IntTools_Curve& aIC = mySeqOfCurve (i);
197 aIC.Curve()->Transform (myTrsf);
200 for (Standard_Integer i = 1; i <= myPnts.Length(); ++i)
202 IntTools_PntOn2Faces& aP2F = myPnts (i);
203 IntTools_PntOnFace aPOnF1 = aP2F.P1(), aPOnF2 = aP2F.P2();
204 aPOnF1.SetPnt (aPOnF1.Pnt().Transformed (myTrsf));
205 aPOnF2.SetPnt (aPOnF2.Pnt().Transformed (myTrsf));
214 Standard_Integer myIF1;
215 Standard_Integer myIF2;
216 Standard_Real myTolFF;
224 //=======================================================================
225 typedef NCollection_Vector<BOPAlgo_FaceFace> BOPAlgo_VectorOfFaceFace;
227 /////////////////////////////////////////////////////////////////////////
228 //=======================================================================
229 //function : PerformFF
231 //=======================================================================
232 void BOPAlgo_PaveFiller::PerformFF(const Message_ProgressRange& theRange)
234 // Update face info for all Face/Face intersection pairs
235 // and also for the rest of the faces with FaceInfo already initialized,
236 // i.e. anyhow touched faces.
237 myIterator->Initialize(TopAbs_FACE, TopAbs_FACE);
238 Standard_Integer iSize = myIterator->ExpectedLength();
240 // Collect faces from intersection pairs
241 TColStd_MapOfInteger aMIFence;
242 Standard_Integer nF1, nF2;
243 for (; myIterator->More(); myIterator->Next())
245 myIterator->Value(nF1, nF2);
249 // Collect the rest of the touched faces
250 for (Standard_Integer i = 0; i < myDS->NbSourceShapes(); ++i)
252 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo (i);
253 if (aSI.ShapeType() == TopAbs_FACE && aSI.HasReference())
259 myDS->UpdateFaceInfoOn (aMIFence);
260 myDS->UpdateFaceInfoIn (aMIFence);
264 // no intersection pairs found
268 Message_ProgressScope aPSOuter(theRange, NULL, 1);
270 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
271 aFFs.SetIncrement(iSize);
273 // Options for the intersection algorithm
274 Standard_Boolean bApprox = mySectionAttribute.Approximation(),
275 bCompC2D1 = mySectionAttribute.PCurveOnS1(),
276 bCompC2D2 = mySectionAttribute.PCurveOnS2();
277 Standard_Real anApproxTol = 1.e-7;
278 // Post-processing options
279 Standard_Boolean bSplitCurve = Standard_False;
281 // Collect all pairs of Edge/Edge interferences to check if
282 // some faces have to be moved to obtain more precise intersection
283 NCollection_DataMap<BOPDS_Pair, TColStd_ListOfInteger, BOPDS_PairMapHasher> aEEMap;
284 const BOPDS_VectorOfInterfEE& aVEEs = myDS->InterfEE();
285 for (Standard_Integer iEE = 0; iEE < aVEEs.Size(); ++iEE)
287 const BOPDS_Interf& aEE = aVEEs(iEE);
288 if (!aEE.HasIndexNew())
292 Standard_Integer nE1, nE2;
293 aEE.Indices(nE1, nE2);
295 const Standard_Integer nVN = aEE.IndexNew();
297 BOPDS_Pair aPair(nE1, nE2);
298 TColStd_ListOfInteger* pPoints = aEEMap.ChangeSeek(aPair);
301 pPoints->Append(nVN);
305 pPoints = aEEMap.Bound(BOPDS_Pair(nE1, nE2), TColStd_ListOfInteger());
306 pPoints->Append(nVN);
310 // Prepare the pairs of faces for intersection
311 BOPAlgo_VectorOfFaceFace aVFaceFace;
312 myIterator->Initialize(TopAbs_FACE, TopAbs_FACE);
313 for (; myIterator->More(); myIterator->Next()) {
314 if (UserBreak(aPSOuter))
318 myIterator->Value(nF1, nF2);
320 if (myGlue == BOPAlgo_GlueOff)
322 const TopoDS_Face& aF1 = (*(TopoDS_Face *)(&myDS->Shape(nF1)));
323 const TopoDS_Face& aF2 = (*(TopoDS_Face *)(&myDS->Shape(nF2)));
325 const BRepAdaptor_Surface& aBAS1 = myContext->SurfaceAdaptor(aF1);
326 const BRepAdaptor_Surface& aBAS2 = myContext->SurfaceAdaptor(aF2);
327 if (aBAS1.GetType() == GeomAbs_Plane &&
328 aBAS2.GetType() == GeomAbs_Plane) {
329 // Check if the planes are really interfering
330 Standard_Boolean bToIntersect = CheckPlanes(nF1, nF2);
332 BOPDS_InterfFF& aFF = aFFs.Appended();
333 aFF.SetIndices(nF1, nF2);
339 // Check if there is an intersection between edges of the faces.
340 // If there is an intersection, check if there is a shift between the edges
341 // (intersection point is on some distance from the edges), and move one of
342 // the faces to the point of exact edges intersection. This should allow
343 // obtaining more precise intersection curves between the faces
344 // (at least the curves should reach the boundary).
345 // Note, that currently this check considers only closed edges (seam edges).
346 TopoDS_Face aFShifted1 = aF1, aFShifted2 = aF2;
347 // Keep shift value to use it as the tolerance for intersection curves
348 Standard_Real aShiftValue = 0.;
350 if (aBAS1.GetType() != GeomAbs_Plane ||
351 aBAS2.GetType() != GeomAbs_Plane) {
353 Standard_Boolean isFound = Standard_False;
354 for (TopExp_Explorer aExp1(aF1, TopAbs_EDGE); !isFound && aExp1.More(); aExp1.Next())
356 const TopoDS_Edge& aE1 = TopoDS::Edge(aExp1.Current());
357 const Standard_Integer nE1 = myDS->Index(aE1);
359 for (TopExp_Explorer aExp2(aF2, TopAbs_EDGE); !isFound && aExp2.More(); aExp2.Next())
361 const TopoDS_Edge& aE2 = TopoDS::Edge(aExp2.Current());
362 const Standard_Integer nE2 = myDS->Index(aE2);
364 Standard_Boolean bIsClosed1 = BRep_Tool::IsClosed(aE1, aF1);
365 Standard_Boolean bIsClosed2 = BRep_Tool::IsClosed(aE2, aF2);
366 if (!bIsClosed1 && !bIsClosed2)
371 const TColStd_ListOfInteger* pPoints = aEEMap.Seek(BOPDS_Pair(nE1, nE2));
377 for (TColStd_ListOfInteger::Iterator itEEP(*pPoints); itEEP.More(); itEEP.Next())
379 const Standard_Integer& nVN = itEEP.Value();
380 const TopoDS_Vertex& aVN = TopoDS::Vertex(myDS->Shape(nVN));
381 const gp_Pnt& aPnt = BRep_Tool::Pnt(aVN);
383 // Compute points exactly on the edges
384 GeomAPI_ProjectPointOnCurve& aProjPC1 = myContext->ProjPC(aE1);
385 GeomAPI_ProjectPointOnCurve& aProjPC2 = myContext->ProjPC(aE2);
386 aProjPC1.Perform(aPnt);
387 aProjPC2.Perform(aPnt);
388 if (!aProjPC1.NbPoints() && !aProjPC2.NbPoints())
392 gp_Pnt aP1 = aProjPC1.NbPoints() > 0 ? aProjPC1.NearestPoint() : aPnt;
393 gp_Pnt aP2 = aProjPC2.NbPoints() > 0 ? aProjPC2.NearestPoint() : aPnt;
395 Standard_Real aShiftDist = aP1.Distance(aP2);
396 if (aShiftDist > BRep_Tool::Tolerance(aVN))
398 // Move one of the faces to the point of exact intersection of edges
400 aTrsf.SetTranslation(bIsClosed1 ? gp_Vec(aP1, aP2) : gp_Vec(aP2, aP1));
401 TopLoc_Location aLoc(aTrsf);
402 (bIsClosed1 ? &aFShifted1 : &aFShifted2)->Move(aLoc);
403 aShiftValue = aShiftDist;
404 isFound = Standard_True;
411 BOPAlgo_FaceFace& aFaceFace=aVFaceFace.Appended();
413 aFaceFace.SetRunParallel (myRunParallel);
414 aFaceFace.SetIndices(nF1, nF2);
415 aFaceFace.SetFaces(aFShifted1, aFShifted2);
416 aFaceFace.SetBoxes (myDS->ShapeInfo (nF1).Box(), myDS->ShapeInfo (nF2).Box());
417 // Note: in case of faces with closed edges it should not be less than value of the shift
418 Standard_Real aTolFF = Max(aShiftValue, ToleranceFF(aBAS1, aBAS2));
419 aFaceFace.SetTolFF(aTolFF);
421 IntSurf_ListOfPntOn2S aListOfPnts;
422 GetEFPnts(nF1, nF2, aListOfPnts);
423 Standard_Integer aNbLP = aListOfPnts.Extent();
425 aFaceFace.SetList(aListOfPnts);
428 aFaceFace.SetParameters(bApprox, bCompC2D1, bCompC2D2, anApproxTol);
429 aFaceFace.SetFuzzyValue(myFuzzyValue);
432 // for the Glue mode just add all interferences of that type
433 BOPDS_InterfFF& aFF = aFFs.Appended();
434 aFF.SetIndices(nF1, nF2);
435 aFF.SetTangentFaces(Standard_False);
438 }//for (; myIterator->More(); myIterator->Next()) {
440 Standard_Integer k, aNbFaceFace = aVFaceFace.Length();;
441 Message_ProgressScope aPS(aPSOuter.Next(), "Performing Face-Face intersection", aNbFaceFace);
442 for (k = 0; k < aNbFaceFace; k++)
444 BOPAlgo_FaceFace& aFaceFace = aVFaceFace.ChangeValue(k);
445 aFaceFace.SetProgressRange(aPS.Next());
447 //======================================================
448 // Perform intersection
449 BOPTools_Parallel::Perform (myRunParallel, aVFaceFace);
450 if (UserBreak(aPSOuter))
454 //======================================================
455 // Treatment of the results
457 for (k = 0; k < aNbFaceFace; ++k) {
458 if (UserBreak(aPSOuter))
462 BOPAlgo_FaceFace& aFaceFace = aVFaceFace(k);
463 aFaceFace.Indices(nF1, nF2);
464 if (!aFaceFace.IsDone() || aFaceFace.HasErrors()) {
465 BOPDS_InterfFF& aFF = aFFs.Appended();
466 aFF.SetIndices(nF1, nF2);
468 // Warn about failed intersection of faces
469 AddIntersectionFailedWarning(aFaceFace.Face1(), aFaceFace.Face2());
473 Standard_Boolean bTangentFaces = aFaceFace.TangentFaces();
474 Standard_Real aTolFF = aFaceFace.TolFF();
476 aFaceFace.PrepareLines3D(bSplitCurve);
478 aFaceFace.ApplyTrsf();
480 const IntTools_SequenceOfCurves& aCvsX = aFaceFace.Lines();
481 const IntTools_SequenceOfPntOn2Faces& aPntsX = aFaceFace.Points();
483 Standard_Integer aNbCurves = aCvsX.Length();
484 Standard_Integer aNbPoints = aPntsX.Length();
486 if (aNbCurves || aNbPoints) {
487 myDS->AddInterf(nF1, nF2);
490 BOPDS_InterfFF& aFF = aFFs.Appended();
491 aFF.SetIndices(nF1, nF2);
492 aFF.SetTangentFaces(bTangentFaces);
493 aFF.Init(aNbCurves, aNbPoints);
496 // Fix bounding box expanding coefficient.
497 Standard_Real aBoxExpandValue = aTolFF;
500 // Modify geometric expanding coefficient by topology value,
501 // since this bounding box used in sharing (vertex or edge).
502 Standard_Real aMaxVertexTol = Max(BRep_Tool::MaxTolerance(aFaceFace.Face1(), TopAbs_VERTEX),
503 BRep_Tool::MaxTolerance(aFaceFace.Face2(), TopAbs_VERTEX));
504 aBoxExpandValue += aMaxVertexTol;
507 BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
508 for (Standard_Integer i = 1; i <= aNbCurves; ++i) {
509 if (UserBreak(aPSOuter))
514 const IntTools_Curve& aIC = aCvsX(i);
515 Standard_Boolean bIsValid = IntTools_Tools::CheckCurve(aIC, aBox);
517 BOPDS_Curve& aNC = aVNC.Appended();
519 // make sure that the bounding box has the maximal gap
520 aBox.Enlarge(aBoxExpandValue);
522 aNC.SetTolerance(Max(aIC.Tolerance(), aTolFF));
527 BOPDS_VectorOfPoint& aVNP = aFF.ChangePoints();
528 for (Standard_Integer i = 1; i <= aNbPoints; ++i) {
529 const IntTools_PntOn2Faces& aPi = aPntsX(i);
530 const gp_Pnt& aP = aPi.P1().Pnt();
532 BOPDS_Point& aNP = aVNP.Appended();
538 //=======================================================================
539 //function : UpdateSavedTolerance
540 //purpose : Updates the saved tolerance of the vertices of the edge
541 // with new tolerance of edge
542 //=======================================================================
543 static void UpdateSavedTolerance(const BOPDS_PDS& theDS,
544 const Standard_Integer theNE,
545 const Standard_Real theTolNew,
546 TColStd_DataMapOfIntegerReal& theMVTol)
548 const TColStd_ListOfInteger& aSubShapes = theDS->ShapeInfo(theNE).SubShapes();
549 TColStd_ListIteratorOfListOfInteger itSS(aSubShapes);
550 for (; itSS.More(); itSS.Next())
552 const Standard_Integer nV = itSS.Value();
553 Standard_Real *pTolSaved = theMVTol.ChangeSeek(nV);
554 if (pTolSaved && *pTolSaved < theTolNew)
555 *pTolSaved = theTolNew;
559 //=======================================================================
560 //function : MakeBlocks
562 //=======================================================================
563 void BOPAlgo_PaveFiller::MakeBlocks(const Message_ProgressRange& theRange)
565 Message_ProgressScope aPSOuter(theRange, NULL, 4);
566 if (myGlue != BOPAlgo_GlueOff) {
570 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
571 Standard_Integer aNbFF = aFFs.Length();
572 Message_ProgressScope aPS(aPSOuter.Next(), "Building section edges", aNbFF);
577 Standard_Boolean bExist, bValid2D;
578 Standard_Integer i, nF1, nF2, aNbC, aNbP, j;
579 Standard_Integer nV1, nV2;
580 Standard_Real aT1, aT2;
581 Handle(NCollection_BaseAllocator) aAllocator;
582 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
584 Handle(BOPDS_PaveBlock) aPBOut;
586 //-----------------------------------------------------scope f
588 NCollection_BaseAllocator::CommonBaseAllocator();
590 TColStd_ListOfInteger aLSE(aAllocator), aLBV(aAllocator);
591 TColStd_MapOfInteger aMVOnIn(100, aAllocator), aMVCommon(100, aAllocator),
592 aMVStick(100,aAllocator), aMVEF(100, aAllocator),
593 aMI(100, aAllocator), aMVBounds(100, aAllocator);
594 BOPDS_IndexedMapOfPaveBlock aMPBOnIn(100, aAllocator);
595 BOPDS_MapOfPaveBlock aMPBAdd(100, aAllocator), aMPBCommon;
596 BOPDS_ListOfPaveBlock aLPB(aAllocator);
597 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMSCPB(100, aAllocator);
598 TopTools_DataMapOfShapeInteger aMVI(100, aAllocator);
599 BOPDS_DataMapOfPaveBlockListOfPaveBlock aDMExEdges(100, aAllocator);
600 TColStd_DataMapOfIntegerReal aMVTol(100, aAllocator);
601 TColStd_DataMapOfIntegerInteger aDMNewSD(100, aAllocator);
602 TColStd_DataMapOfIntegerListOfInteger aDMVLV;
603 TColStd_DataMapOfIntegerListOfInteger aDMBV(100, aAllocator);
604 TColStd_DataMapIteratorOfDataMapOfIntegerReal aItMV;
605 BOPDS_IndexedMapOfPaveBlock aMicroPB(100, aAllocator);
606 TopTools_IndexedMapOfShape aVertsOnRejectedPB;
607 // Map of PaveBlocks with the faces to which it has to be added
608 BOPAlgo_DataMapOfPaveBlockListOfInteger aPBFacesMap;
610 for (i=0; i<aNbFF; ++i, aPS.Next()) {
616 BOPDS_InterfFF& aFF=aFFs(i);
617 aFF.Indices(nF1, nF2);
619 BOPDS_VectorOfPoint& aVP=aFF.ChangePoints();
621 BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
623 if (!aNbP && !aNbC) {
627 const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
628 const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
630 Standard_Real aTolFF = Max(BRep_Tool::Tolerance(aF1), BRep_Tool::Tolerance(aF2));
632 BOPDS_FaceInfo& aFI1 = myDS->ChangeFaceInfo(nF1);
633 BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2);
643 myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMVCommon, aMPBOnIn, aMPBCommon);
644 myDS->SharedEdges(nF1, nF2, aLSE, aAllocator);
647 for (j=0; j<aNbP; ++j) {
649 BOPDS_CoupleOfPaveBlocks aCPB;
651 BOPDS_Point& aNP=aVP.ChangeValue(j);
652 const gp_Pnt& aP=aNP.Pnt();
654 bExist=IsExistingVertex(aP, aTolFF, aMVOnIn);
656 BOPTools_AlgoTools::MakeNewVertex(aP, aTolFF, aV);
658 aCPB.SetIndexInterf(i);
660 aMSCPB.Add(aV, aCPB);
667 GetStickVertices(nF1, nF2, aMVStick, aMVEF, aMI);
669 for (j = 0; j < aNbC; ++j) {
670 BOPDS_Curve& aNC = aVC.ChangeValue(j);
672 aNC.InitPaveBlock1();
674 // In order to avoid problems connected with
675 // extending tolerance of vertex while putting
676 // (e.g. see "bugs modalg_6 bug26789_1" test case),
677 // all not-common vertices will be checked by
678 // BndBoxes before putting. For common-vertices,
679 // filtering by BndBoxes is not necessary.
680 PutPavesOnCurve(aMVOnIn, aMVCommon, aNC, aMI, aMVEF, aMVTol, aDMVLV);
683 // if some E-F vertex was put on a curve due to large E-F intersection range,
684 // and it also was put on another curve correctly then remove this vertex from
685 // the first curve. Detect such case if the distance to curve exceeds aTolR3D.
686 FilterPavesOnCurves(aVC, aMVTol);
688 for (j = 0; j<aNbC; ++j) {
689 BOPDS_Curve& aNC=aVC.ChangeValue(j);
690 const IntTools_Curve& aIC=aNC.Curve();
692 PutStickPavesOnCurve(aF1, aF2, aMI, aVC, j, aMVStick, aMVTol, aDMVLV);
695 PutEFPavesOnCurve(aVC, j, aMI, aMVEF, aMVTol, aDMVLV);
698 if (aIC.HasBounds()) {
701 PutBoundPaveOnCurve(aF1, aF2, aNC, aLBV);
703 if (!aLBV.IsEmpty()) {
705 TColStd_ListIteratorOfListOfInteger aItI(aLBV);
706 for (; aItI.More(); aItI.Next()) {
707 aMVBounds.Add(aItI.Value());
711 }//for (j=0; j<aNbC; ++j) {
713 // Put closing pave if needed
714 for (j=0; j<aNbC; ++j) {
715 BOPDS_Curve& aNC=aVC.ChangeValue(j);
716 PutClosingPaveOnCurve (aNC);
720 BOPTools_BoxTree aPBTree;
722 // Fill the tree with boxes of pave blocks ON/IN
723 // Tree will be build on first selection from the tree.
724 const Standard_Integer aNbPB = aMPBOnIn.Extent();
725 aPBTree.SetSize (aNbPB);
726 for (Standard_Integer iPB = 1; iPB <= aNbPB; ++iPB)
728 const Handle(BOPDS_PaveBlock)& aPB = aMPBOnIn (iPB);
732 if (myDS->ShapeInfo (aPB->OriginalEdge()).HasFlag())
735 aPBTree.Add (iPB, Bnd_Tools::Bnd2BVH (myDS->ShapeInfo (aPB->Edge()).Box()));
740 // 3. Make section edges
741 for (j=0; j<aNbC; ++j) {
742 BOPDS_Curve& aNC=aVC.ChangeValue(j);
743 const IntTools_Curve& aIC=aNC.Curve();
744 Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
746 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
747 Handle(BOPDS_PaveBlock)& aPB1=aNC.ChangePaveBlock1();
750 aPB1->Update(aLPB, Standard_False);
752 aItLPB.Initialize(aLPB);
753 for (; aItLPB.More(); aItLPB.Next()) {
754 Handle(BOPDS_PaveBlock)& aPB=aItLPB.ChangeValue();
755 aPB->Indices(nV1, nV2);
756 aPB->Range (aT1, aT2);
758 if (fabs(aT1 - aT2) < Precision::PConfusion()) {
762 // Check validity of the block for the faces:
763 // classify bounding and middle points on the curve
764 // relatively both faces
765 bValid2D=myContext->IsValidBlockForFaces(aT1, aT2, aIC,
771 Standard_Integer nEOut;
772 Standard_Real aTolNew = -1.;
773 bExist = IsExistingPaveBlock(aPB, aNC, aLSE, nEOut, aTolNew);
776 // Update edge with new tolerance
777 UpdateEdgeTolerance(nEOut, aTolNew);
778 // Update aMVTol map with new tolerances of vertices
779 UpdateSavedTolerance(myDS, nEOut, aTolNew, aMVTol);
783 const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
784 const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
786 // check if the pave block has a valid range
787 Standard_Real aFirst, aLast;
788 if (!BRepLib::FindValidRange(GeomAdaptor_Curve(aIC.Curve()), aTolR3D,
789 aT1, BRep_Tool::Pnt(aV1), Max (aTolR3D, BRep_Tool::Tolerance(aV1)),
790 aT2, BRep_Tool::Pnt(aV2), Max (aTolR3D, BRep_Tool::Tolerance(aV2)),
793 // If the pave block does not have valid range, i.e. it is completely
794 // covered by the tolerance spheres of its vertices, it will be
795 // passed into post treatment process to fuse its vertices.
796 // The pave block itself will not be kept.
797 if (!aMVBounds.Contains(nV1) && !aMVBounds.Contains(nV2)) {
799 // keep vertices for post treatment
806 bExist = IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aPBTree, aMPBCommon, aPBOut, aTolNew);
809 Standard_Boolean bInF1 = (aFI1.PaveBlocksOn().Contains(aPBOut) ||
810 aFI1.PaveBlocksIn().Contains(aPBOut));
811 Standard_Boolean bInF2 = (aFI2.PaveBlocksOn().Contains(aPBOut) ||
812 aFI2.PaveBlocksIn().Contains(aPBOut));
813 if (!bInF1 || !bInF2)
815 // Update edge to touch both faces
816 Standard_Integer nE = aPBOut->Edge();
817 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(nE);
818 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
819 if (aTolNew < aNC.Tolerance())
820 aTolNew = aNC.Tolerance(); // use real tolerance of intersection
821 if (aTolNew > aTolE) {
822 UpdateEdgeTolerance(nE, aTolNew);
823 // Update aMVTol map with new tolerances of vertices
824 UpdateSavedTolerance(myDS, nE, aTolNew, aMVTol);
827 // Face without pave block
828 const Standard_Integer nF = bInF1 ? nF2 : nF1;
829 TColStd_ListOfInteger* pFaces = aPBFacesMap.ChangeSeek(aPBOut);
831 pFaces = aPBFacesMap.Bound(aPBOut, TColStd_ListOfInteger());
832 // List is expected to be short, so we allow the check here
833 if (pFaces->IsEmpty() || !pFaces->Contains(nF))
836 // Try fusing the vertices of the existing pave block
837 // with the vertices put on the real section curve (except
838 // for technological vertices, which will be removed)
839 Standard_Integer nVOut1, nVOut2;
840 aPBOut->Indices(nVOut1, nVOut2);
841 if (nV1 != nVOut1 && nV1 != nVOut2 && !aMVBounds.Contains(nV1))
843 aVertsOnRejectedPB.Add(aV1);
845 if (nV2 != nVOut1 && nV2 != nVOut2 && !aMVBounds.Contains(nV2))
847 aVertsOnRejectedPB.Add(aV2);
850 if (aMPBAdd.Add(aPBOut))
852 // Add edge for processing as the section edge
853 PreparePostTreatFF(i, j, aPBOut, aMSCPB, aMVI, aLPBC);
860 BOPTools_AlgoTools::MakeEdge (aIC, aV1, aT1, aV2, aT2, aTolR3D, aES);
862 BOPTools_AlgoTools::MakePCurve(aES, aF1, aF2, aIC,
863 mySectionAttribute.PCurveOnS1(),
864 mySectionAttribute.PCurveOnS2(),
867 // Append the Pave Block to the Curve j
870 // Keep info for post treatment
871 BOPDS_CoupleOfPaveBlocks aCPB;
872 aCPB.SetIndexInterf(i);
874 aCPB.SetPaveBlock1(aPB);
876 aMSCPB.Add(aES, aCPB);
883 // Add existing pave blocks for post treatment
884 ProcessExistingPaveBlocks (i, j, nF1, nF2, aES, aMPBOnIn, aPBTree,
885 aMSCPB, aMVI, aLPBC, aPBFacesMap, aMPBAdd);
889 }//for (j=0; j<aNbC; ++j) {
891 //back to previous tolerance values for unused vertices
892 //and forget about SD groups of such vertices
893 aItMV.Initialize(aMVTol);
894 for (; aItMV.More(); aItMV.Next()) {
896 Standard_Real aTol = aItMV.Value();
898 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV1);
899 const Handle(BRep_TVertex)& TV =
900 *((Handle(BRep_TVertex)*)&aV.TShape());
903 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV1);
904 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
906 BRepBndLib::Add(aV, aBoxDS);
907 aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
909 if (aDMVLV.IsBound(nV1))
913 ProcessExistingPaveBlocks(i, nF1, nF2, aMPBOnIn, aPBTree, aDMBV, aMSCPB, aMVI, aPBFacesMap, aMPBAdd);
914 }//for (i=0; i<aNbFF; ++i) {
916 // Remove "micro" section edges
917 RemoveMicroSectionEdges(aMSCPB, aMicroPB);
920 MakeSDVerticesFF(aDMVLV, aDMNewSD);
921 PostTreatFF(aMSCPB, aDMExEdges, aDMNewSD, aMicroPB, aVertsOnRejectedPB, aAllocator, aPSOuter.Next(2));
925 // reduce tolerances of section edges where it is appropriate
926 CorrectToleranceOfSE();
929 UpdateFaceInfo(aDMExEdges, aDMNewSD, aPBFacesMap);
930 //Update all pave blocks
931 UpdatePaveBlocks(aDMNewSD);
933 // Treat possible common zones by trying to put each section edge
934 // into all faces, not participated in creation of that edge, as IN edge
936 PutSEInOtherFaces(aPSOuter.Next());
938 //-----------------------------------------------------scope t
948 //=======================================================================
949 //function : MakeSDVerticesFF
951 //=======================================================================
952 void BOPAlgo_PaveFiller::MakeSDVerticesFF
953 (const TColStd_DataMapOfIntegerListOfInteger& theDMVLV,
954 TColStd_DataMapOfIntegerInteger& theDMNewSD)
956 // Create a new SD vertex for each group of coinciding vertices
957 // and put new substitutions to theDMNewSD.
958 TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger aItG(theDMVLV);
959 for (; aItG.More(); aItG.Next()) {
960 const TColStd_ListOfInteger& aList = aItG.Value();
961 // make SD vertices w/o creation of interfs
962 Standard_Integer nSD = MakeSDVertices(aList, Standard_False);
964 TColStd_ListIteratorOfListOfInteger aItL(aList);
965 for (; aItL.More(); aItL.Next()) {
966 Standard_Integer nV = aItL.Value();
967 theDMNewSD.Bind(nV, nSD);
972 //=======================================================================
973 //function : PostTreatFF
975 //=======================================================================
976 void BOPAlgo_PaveFiller::PostTreatFF
977 (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
978 BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges,
979 TColStd_DataMapOfIntegerInteger& aDMNewSD,
980 const BOPDS_IndexedMapOfPaveBlock& theMicroPB,
981 const TopTools_IndexedMapOfShape& theVertsOnRejectedPB,
982 const Handle(NCollection_BaseAllocator)& theAllocator,
983 const Message_ProgressRange& theRange)
985 Standard_Integer aNbS = theMSCPB.Extent();
990 Standard_Boolean bHasPaveBlocks, bOld;
991 Standard_Integer nSx, nVSD, iX, iP, iC, j, nV, iV = 0, iE, k;
992 Standard_Integer aNbLPBx;
993 TopAbs_ShapeEnum aType;
995 TopTools_ListIteratorOfListOfShape aItLS;
996 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
998 Handle(BOPDS_PaveBlock) aPB1;
1000 BOPDS_ShapeInfo aSI;
1002 TopTools_ListOfShape aLS(theAllocator);
1003 BOPAlgo_PaveFiller aPF(theAllocator);
1004 aPF.SetIsPrimary(Standard_False);
1005 aPF.SetNonDestructive(myNonDestructive);
1007 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
1008 Standard_Integer aNbFF = aFFs.Length();
1011 //Find unused vertices
1012 TopTools_IndexedMapOfShape VertsUnused;
1013 TColStd_MapOfInteger IndMap;
1014 for (Standard_Integer i = 0; i < aNbFF; i++)
1016 BOPDS_InterfFF& aFF = aFFs(i);
1017 Standard_Integer nF1, nF2;
1018 aFF.Indices(nF1, nF2);
1020 TColStd_MapOfInteger aMV, aMVEF, aMI;
1021 GetStickVertices(nF1, nF2, aMV, aMVEF, aMI);
1022 BOPDS_VectorOfCurve& aVC = aFF.ChangeCurves();
1023 RemoveUsedVertices (aVC, aMV);
1025 TColStd_MapIteratorOfMapOfInteger itmap(aMV);
1026 for(; itmap.More(); itmap.Next())
1028 Standard_Integer indV = itmap.Value();
1029 const TopoDS_Shape& aVertex = myDS->Shape(indV);
1030 if (IndMap.Add(indV))
1031 VertsUnused.Add(aVertex);
1033 VertsUnused.RemoveKey(aVertex);
1036 /////////////////////
1038 Standard_Integer aNbME = theMicroPB.Extent();
1039 Standard_Integer aNbVOnRPB = theVertsOnRejectedPB.Extent();
1041 if (aNbS==1 && (aNbME == 0) && (aNbVOnRPB == 0) && VertsUnused.IsEmpty()) {
1042 const TopoDS_Shape& aS=theMSCPB.FindKey(1);
1043 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromIndex(1);
1045 aType=aS.ShapeType();
1046 if (aType==TopAbs_VERTEX) {
1047 aSI.SetShapeType(aType);
1049 iV=myDS->Append(aSI);
1051 iX=aCPB.IndexInterf();
1053 BOPDS_InterfFF& aFF=aFFs(iX);
1054 BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
1055 BOPDS_Point& aNP=aVNP(iP);
1058 else if (aType==TopAbs_EDGE) {
1059 aPB1=aCPB.PaveBlock1();
1061 if (aPB1->HasEdge()) {
1062 BOPDS_ListOfPaveBlock aLPBx;
1064 aDMExEdges.Bind(aPB1, aLPBx);
1066 aSI.SetShapeType(aType);
1068 iE=myDS->Append(aSI);
1076 // 1 prepare arguments
1077 // Avoid intersection of existing edges among themselves
1078 TopoDS_Compound anExistingEdges;
1079 BRep_Builder().MakeCompound (anExistingEdges);
1080 TopTools_MapOfShape anAddedSD;
1081 for (k = aNbS; k > 0; --k) {
1082 const TopoDS_Shape& aS=theMSCPB.FindKey(k);
1083 const Handle(BOPDS_PaveBlock)& aPB = theMSCPB (k).PaveBlock1();
1084 if (!aPB.IsNull() && aPB->HasEdge())
1085 BRep_Builder().Add (anExistingEdges, aS);
1088 // add vertices-candidates for SD from the map aDMNewSD,
1089 // so that they took part in fuse operation.
1090 TopoDS_Iterator itV(aS);
1091 for (; itV.More(); itV.Next())
1093 const TopoDS_Shape& aVer = itV.Value();
1094 Standard_Integer iVer = myDS->Index(aVer);
1095 const Standard_Integer* pSD = aDMNewSD.Seek(iVer);
1098 const TopoDS_Shape& aVSD = myDS->Shape(*pSD);
1099 if (anAddedSD.Add(aVSD))
1104 if (anExistingEdges.NbChildren() > 0)
1105 aLS.Append (anExistingEdges);
1107 // The section edges considered as a micro should be
1108 // specially treated - their vertices should be united and
1109 // the edge itself should be removed. Thus, we add only
1110 // its vertices into operation.
1113 for (k = 1; k <= aNbME; ++k) {
1114 Standard_Integer nVerts[2];
1115 theMicroPB(k)->Indices(nVerts[0], nVerts[1]);
1116 TopoDS_Vertex aVerts[2];
1117 for (Standard_Integer i = 0; i < 2; ++i) {
1118 const Standard_Integer* pSD = aDMNewSD.Seek(nVerts[i]);
1119 aVerts[i] = TopoDS::Vertex(myDS->Shape(pSD ? *pSD : nVerts[i]));
1120 if (anAddedSD.Add(aVerts[i]))
1121 aLS.Append(aVerts[i]);
1124 if (aVerts[0].IsSame(aVerts[1])) {
1128 // make sure these vertices will be united
1129 const gp_Pnt& aP1 = BRep_Tool::Pnt(aVerts[0]);
1130 const gp_Pnt& aP2 = BRep_Tool::Pnt(aVerts[1]);
1132 Standard_Real aDist = aP1.Distance(aP2);
1133 Standard_Real aTolV1 = BRep_Tool::Tolerance(aVerts[0]);
1134 Standard_Real aTolV2 = BRep_Tool::Tolerance(aVerts[1]);
1136 aDist -= (aTolV1 + aTolV2);
1139 aBB.UpdateVertex(aVerts[0], aTolV1 + aDist);
1140 aBB.UpdateVertex(aVerts[1], aTolV2 + aDist);
1144 // Add vertices put on the real section curves to unify them with the
1145 // vertices of the edges, by which these sections curves have been rejected
1146 // and with unused vertices
1147 const TopTools_IndexedMapOfShape* VerMap [2] = {&theVertsOnRejectedPB, &VertsUnused};
1148 for (Standard_Integer imap = 0; imap < 2; imap++)
1150 Standard_Integer NbVer = VerMap[imap]->Extent();
1151 for (Standard_Integer i = 1; i <= NbVer; ++i)
1153 TopoDS_Shape aVer = VerMap[imap]->FindKey(i);
1154 Standard_Integer iVer = myDS->Index(aVer);
1155 const Standard_Integer* pSD = aDMNewSD.Seek(iVer);
1157 aVer = myDS->Shape(*pSD);
1159 if (anAddedSD.Add(aVer))
1164 Message_ProgressScope aPS(theRange, "Intersection of section edges", 1);
1167 aPF.SetRunParallel(myRunParallel);
1168 aPF.SetArguments(aLS);
1169 aPF.Perform(aPS.Next());
1170 if (aPF.HasErrors()) {
1171 AddError (new BOPAlgo_AlertPostTreatFF);
1176 // Map to store the real tolerance of the common block
1177 // and avoid repeated computation of it
1178 NCollection_DataMap<Handle(BOPDS_CommonBlock),
1180 TColStd_MapTransientHasher> aMCBTol;
1181 // Map to avoid creation of different pave blocks for
1182 // the same intersection edge
1183 NCollection_DataMap<Standard_Integer, Handle(BOPDS_PaveBlock)> aMEPB;
1185 aItLS.Initialize(aLS);
1186 for (; aItLS.More(); aItLS.Next()) {
1187 const TopoDS_Shape& aSx=aItLS.Value();
1188 if (aSx.ShapeType() == TopAbs_COMPOUND)
1190 for (TopoDS_Iterator itC (aSx); itC.More(); itC.Next())
1191 aLS.Append (itC.Value());
1194 nSx=aPDS->Index(aSx);
1195 const BOPDS_ShapeInfo& aSIx=aPDS->ShapeInfo(nSx);
1197 aType=aSIx.ShapeType();
1199 if (aType==TopAbs_VERTEX) {
1200 Standard_Boolean bIntersectionPoint = theMSCPB.Contains(aSx);
1202 if (aPDS->HasShapeSD(nSx, nVSD)) {
1203 aV=aPDS->Shape(nVSD);
1208 // index of new vertex in theDS -> iV
1209 iV = myDS->Index(aV);
1211 aSI.SetShapeType(aType);
1213 iV=myDS->Append(aSI);
1216 if (!bIntersectionPoint) {
1217 // save SD connection
1218 nSx = myDS->Index(aSx);
1221 aDMNewSD.Bind(nSx, iV);
1222 myDS->AddShapeSD(nSx, iV);
1226 // update FF interference
1227 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
1228 iX=aCPB.IndexInterf();
1230 BOPDS_InterfFF& aFF=aFFs(iX);
1231 BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
1232 BOPDS_Point& aNP=aVNP(iP);
1235 }//if (aType==TopAbs_VERTEX) {
1237 else if (aType==TopAbs_EDGE) {
1238 bHasPaveBlocks=aPDS->HasPaveBlocks(nSx);
1239 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
1240 iX=aCPB.IndexInterf();
1242 aPB1=aCPB.PaveBlock1();
1244 bOld = aPB1->HasEdge();
1246 BOPDS_ListOfPaveBlock aLPBx;
1247 aDMExEdges.Bind(aPB1, aLPBx);
1250 if (!bHasPaveBlocks) {
1252 aDMExEdges.ChangeFind(aPB1).Append(aPB1);
1255 aSI.SetShapeType(aType);
1257 iE = myDS->Append(aSI);
1263 BOPDS_InterfFF& aFF=aFFs(iX);
1264 BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
1265 BOPDS_Curve& aNC=aVNC(iC);
1266 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
1268 // check if edge occurred to be micro edge;
1269 // note we check not the edge aSx itself, but its image in aPDS
1270 const BOPDS_ListOfPaveBlock& aLPBx = aPDS->PaveBlocks(nSx);
1271 aNbLPBx = aLPBx.Extent();
1272 if (aNbLPBx == 0 || (aNbLPBx == 1 && !aLPBx.First()->HasShrunkData())) {
1273 BOPDS_ListIteratorOfListOfPaveBlock it(aLPBC);
1274 for (; it.More(); it.Next()) {
1275 if (it.Value() == aPB1) {
1281 // The edge became micro edge, check vertices for SD
1282 TopoDS_Iterator itV(aSx);
1283 for (; itV.More(); itV.Next())
1284 aLS.Append(itV.Value());
1289 if (bOld && !aNbLPBx) {
1290 aDMExEdges.ChangeFind(aPB1).Append(aPB1);
1295 aItLPB.Initialize(aLPBC);
1296 for (; aItLPB.More(); aItLPB.Next()) {
1297 const Handle(BOPDS_PaveBlock)& aPBC=aItLPB.Value();
1299 aLPBC.Remove(aItLPB);
1306 aItLPB.Initialize(aLPBx);
1307 for (; aItLPB.More(); aItLPB.Next()) {
1308 const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
1309 const Handle(BOPDS_PaveBlock) aPBRx=aPDS->RealPaveBlock(aPBx);
1311 // update vertices of paves
1312 aPave[0] = aPBx->Pave1();
1313 aPave[1] = aPBx->Pave2();
1314 for (j=0; j<2; ++j) {
1315 nV = aPave[j].Index();
1316 aV = aPDS->Shape(nV);
1317 // index of new vertex in myDS -> iV
1318 iV = myDS->Index(aV);
1320 aSI.SetShapeType(TopAbs_VERTEX);
1322 iV = myDS->Append(aSI);
1324 const BOPDS_Pave& aP1 = !j ? aPB1->Pave1() : aPB1->Pave2();
1325 if (aP1.Index() != iV) {
1326 if (aP1.Parameter() == aPave[j].Parameter()) {
1327 aDMNewSD.Bind(aP1.Index(), iV);
1328 myDS->AddShapeSD(aP1.Index(), iV);
1331 // check aPDS to have the SD connection between these vertices
1332 const TopoDS_Shape& aVPave = myDS->Shape(aP1.Index());
1333 Standard_Integer nVnewSD, nVnew = aPDS->Index(aVPave);
1334 if (aPDS->HasShapeSD(nVnew, nVnewSD)) {
1335 if (nVnewSD == nV) {
1336 aDMNewSD.Bind(aP1.Index(), iV);
1337 myDS->AddShapeSD(aP1.Index(), iV);
1343 aPave[j].SetIndex(iV);
1347 aE=aPDS->Shape(aPBRx->Edge());
1348 iE = myDS->Index(aE);
1350 aSI.SetShapeType(aType);
1352 iE=myDS->Append(aSI);
1355 // update real edge tolerance according to distances in common block if any
1356 if (aPDS->IsCommonBlock(aPBRx)) {
1357 const Handle(BOPDS_CommonBlock)& aCB = aPDS->CommonBlock(aPBRx);
1358 Standard_Real *pTol = aMCBTol.ChangeSeek(aCB);
1360 Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, aPDS, aPF.Context());
1361 pTol = aMCBTol.Bound(aCB, aTol);
1364 if (aNC.Tolerance() < *pTol) {
1365 aNC.SetTolerance(*pTol);
1368 // append new PaveBlock to aLPBC
1369 Handle(BOPDS_PaveBlock) *pPBC = aMEPB.ChangeSeek(iE);
1371 pPBC = aMEPB.Bound(iE, new BOPDS_PaveBlock());
1372 BOPDS_Pave aPaveR1, aPaveR2;
1373 aPaveR1 = aPBRx->Pave1();
1374 aPaveR2 = aPBRx->Pave2();
1375 aPaveR1.SetIndex(myDS->Index(aPDS->Shape(aPaveR1.Index())));
1376 aPaveR2.SetIndex(myDS->Index(aPDS->Shape(aPaveR2.Index())));
1378 (*pPBC)->SetPave1(aPaveR1);
1379 (*pPBC)->SetPave2(aPaveR2);
1380 (*pPBC)->SetEdge(iE);
1384 (*pPBC)->SetOriginalEdge(aPB1->OriginalEdge());
1385 aDMExEdges.ChangeFind(aPB1).Append(*pPBC);
1388 aLPBC.Append(*pPBC);
1393 }//else if (aType==TopAbs_EDGE)
1394 }//for (; aItLS.More(); aItLS.Next()) {
1396 // Update SD for vertices that did not participate in operation
1397 TColStd_DataMapOfIntegerInteger::Iterator itDM(aDMNewSD);
1398 for (; itDM.More(); itDM.Next())
1400 const Standard_Integer* pSD = aDMNewSD.Seek(itDM.Value());
1403 itDM.ChangeValue() = *pSD;
1404 myDS->AddShapeSD(itDM.Key(), *pSD);
1410 //=======================================================================
1411 //function : UpdateFaceInfo
1413 //=======================================================================
1414 void BOPAlgo_PaveFiller::UpdateFaceInfo
1415 (BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDME,
1416 const TColStd_DataMapOfIntegerInteger& theDMV,
1417 const BOPAlgo_DataMapOfPaveBlockListOfInteger& thePBFacesMap)
1419 Standard_Integer i, j, nV1, nF1, nF2,
1421 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
1422 TColStd_MapOfInteger aMF;
1424 // Unify pave blocks of the existing edges united on the post-treat stage
1425 NCollection_DataMap<Standard_Integer, BOPDS_ListOfPaveBlock> anEdgeLPB;
1427 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
1428 aNbFF=aFFs.Length();
1429 //1. Sections (curves, points);
1430 for (i=0; i<aNbFF; ++i) {
1431 BOPDS_InterfFF& aFF=aFFs(i);
1432 aFF.Indices(nF1, nF2);
1434 BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
1435 BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
1437 // 1.1. Section edges
1438 BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
1440 for (j=0; j<aNbC; ++j) {
1441 BOPDS_Curve& aNC=aVNC(j);
1442 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
1444 // Add section edges to face info
1445 aItLPB.Initialize(aLPBC);
1446 for (; aItLPB.More(); ) {
1447 const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
1449 // Treat existing pave blocks
1450 if (theDME.IsBound(aPB)) {
1451 BOPDS_ListOfPaveBlock& aLPB=theDME.ChangeFind(aPB);
1452 UpdateExistingPaveBlocks(aPB, aLPB, thePBFacesMap);
1454 BOPDS_ListIteratorOfListOfPaveBlock itLPB(aLPB);
1455 for (; itLPB.More(); itLPB.Next())
1457 const Standard_Integer nE = itLPB.Value()->Edge();
1458 BOPDS_ListOfPaveBlock* pLPBOnE = anEdgeLPB.ChangeSeek(nE);
1460 pLPBOnE = anEdgeLPB.Bound(nE, BOPDS_ListOfPaveBlock());
1461 pLPBOnE->Append(itLPB.Value());
1464 aLPBC.Remove(aItLPB);
1468 aFI1.ChangePaveBlocksSc().Add(aPB);
1469 aFI2.ChangePaveBlocksSc().Add(aPB);
1470 // Add edge-PB connection
1471 const Standard_Integer nE = aPB->Edge();
1472 BOPDS_ListOfPaveBlock* pLPBOnE = anEdgeLPB.ChangeSeek(nE);
1474 pLPBOnE = anEdgeLPB.Bound(nE, BOPDS_ListOfPaveBlock());
1475 pLPBOnE->Append(aPB);
1481 // 1.2. Section vertices
1482 const BOPDS_VectorOfPoint& aVNP=aFF.Points();
1484 for (j=0; j<aNbP; ++j) {
1485 const BOPDS_Point& aNP=aVNP(j);
1490 aFI1.ChangeVerticesSc().Add(nV1);
1491 aFI2.ChangeVerticesSc().Add(nV1);
1498 Standard_Boolean bNewCB = Standard_False;
1500 // Unify pave blocks of the existing edges united on the post-treat stage
1501 // by making new Common blocks from them
1502 NCollection_DataMap<Standard_Integer,
1503 BOPDS_ListOfPaveBlock>::Iterator itDM(anEdgeLPB);
1504 for (; itDM.More(); itDM.Next())
1506 const BOPDS_ListOfPaveBlock& aLPB = itDM.Value();
1507 if (aLPB.Extent() == 1)
1510 bNewCB = Standard_True;
1512 // Find or create common block
1513 Handle(BOPDS_CommonBlock) aCB;
1514 // Collect all faces attached to common blocks
1515 TColStd_MapOfInteger aMFaces;
1516 // Collect all pave blocks attached to common blocks
1517 BOPDS_IndexedMapOfPaveBlock aMPaveBlocks;
1519 BOPDS_ListIteratorOfListOfPaveBlock itLPB(aLPB);
1520 for (; itLPB.More(); itLPB.Next())
1522 const Handle(BOPDS_PaveBlock)& aPB = itLPB.Value();
1523 aMPaveBlocks.Add(aPB);
1525 if (myDS->IsCommonBlock(aPB))
1527 Handle(BOPDS_CommonBlock) aPBCB = myDS->CommonBlock(aPB);
1529 const BOPDS_ListOfPaveBlock& aLPBOnCB = aPBCB->PaveBlocks();
1530 for (BOPDS_ListOfPaveBlock::Iterator it(aLPBOnCB); it.More(); it.Next())
1531 aMPaveBlocks.Add(it.Value());
1534 const TColStd_ListOfInteger& aLFacesOnCB = aPBCB->Faces();
1535 for (TColStd_ListOfInteger::Iterator it(aLFacesOnCB); it.More(); it.Next())
1536 aMFaces.Add(it.Value());
1545 // None of the pave blocks in the list is a common block,
1546 // so create the new one.
1547 aCB = new BOPDS_CommonBlock;
1548 aCB->SetPaveBlocks(aLPB);
1549 itLPB.Initialize(aLPB);
1550 for (; itLPB.More(); itLPB.Next())
1552 const Handle(BOPDS_PaveBlock)& aPB = itLPB.Value();
1553 myDS->SetCommonBlock(aPB, aCB);
1558 // Update common block with new pave blocks
1559 BOPDS_ListOfPaveBlock aLPBNew;
1561 const Standard_Integer aNbPB = aMPaveBlocks.Extent();
1562 for (Standard_Integer iPB = 1; iPB <= aNbPB; ++iPB)
1564 const Handle(BOPDS_PaveBlock)& aPB = aMPaveBlocks(iPB);
1565 myDS->SetCommonBlock(aPB, aCB);
1566 aLPBNew.Append(aPB);
1569 aCB->SetPaveBlocks(aLPBNew);
1571 // Update faces of the common block
1572 TColStd_ListOfInteger aLFaces;
1573 for (TColStd_MapOfInteger::Iterator it(aMFaces); it.More(); it.Next())
1574 aLFaces.Append(it.Value());
1575 aCB->SetFaces(aLFaces);
1580 Standard_Boolean bVerts = theDMV.Extent() > 0;
1581 Standard_Boolean bEdges = theDME.Extent() > 0 || bNewCB;
1583 if (!bVerts && !bEdges) {
1587 // 2. Update Face Info information with new vertices and new
1588 // pave blocks created in PostTreatFF from existing ones
1589 Standard_Integer nV2;
1590 TColStd_MapIteratorOfMapOfInteger aItMF;
1591 TColStd_DataMapIteratorOfDataMapOfIntegerInteger aItMV;
1593 aItMF.Initialize(aMF);
1594 for (; aItMF.More(); aItMF.Next()) {
1595 nF1 = aItMF.Value();
1597 BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF1);
1599 // 2.1. Update information about vertices
1602 TColStd_MapOfInteger& aMVOn = aFI.ChangeVerticesOn();
1603 TColStd_MapOfInteger& aMVIn = aFI.ChangeVerticesIn();
1605 aItMV.Initialize(theDMV);
1606 for (; aItMV.More(); aItMV.Next())
1609 nV2 = aItMV.Value();
1611 if (aMVOn.Remove(nV1))
1614 if (aMVIn.Remove(nV1))
1616 } // for (; aItMV.More(); aItMV.Next()) {
1619 // 2.2. Update information about pave blocks
1622 BOPDS_MapOfPaveBlock aMPBFence;
1623 BOPDS_IndexedMapOfPaveBlock* pMPB[] = { &aFI.ChangePaveBlocksOn(),
1624 &aFI.ChangePaveBlocksIn(),
1625 &aFI.ChangePaveBlocksSc() };
1626 for (i = 0; i < 3; ++i)
1628 BOPDS_IndexedMapOfPaveBlock aMPBCopy = *pMPB[i];
1630 const Standard_Integer aNbPB = aMPBCopy.Extent();
1631 for (j = 1; j <= aNbPB; ++j)
1633 const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(j);
1634 const BOPDS_ListOfPaveBlock* pLPB = theDME.Seek(aPB);
1635 if (pLPB && !pLPB->IsEmpty())
1637 aItLPB.Initialize(*pLPB);
1638 for (; aItLPB.More(); aItLPB.Next())
1640 const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB.Value();
1641 const Handle(BOPDS_PaveBlock)& aPBR = myDS->RealPaveBlock(aPB1);
1642 if (aMPBFence.Add(aPBR))
1648 const Handle(BOPDS_PaveBlock)& aPBR = myDS->RealPaveBlock(aPB);
1649 if (aMPBFence.Add(aPBR))
1652 } // for (j = 1; j <= aNbPB; ++j) {
1653 } // for (i = 0; i < 2; ++i) {
1657 //=======================================================================
1658 //function : IsExistingVertex
1660 //=======================================================================
1661 Standard_Boolean BOPAlgo_PaveFiller::IsExistingVertex
1663 const Standard_Real theTolR3D,
1664 const TColStd_MapOfInteger& aMVOnIn)const
1666 Standard_Boolean bRet;
1667 Standard_Integer nV, iFlag;
1668 Standard_Real aTolCheck;
1671 TColStd_MapIteratorOfMapOfInteger aIt;
1673 aTolCheck = theTolR3D + myFuzzyValue;
1677 aBoxP.Enlarge(theTolR3D);
1679 aIt.Initialize(aMVOnIn);
1680 for (; aIt.More(); aIt.Next()) {
1682 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1683 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aSIV.Shape()));
1684 const Bnd_Box& aBoxV=aSIV.Box();
1686 if (!aBoxP.IsOut(aBoxV)) {
1687 iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP, aTolCheck);
1695 //=======================================================================
1696 //function : IsExistingPaveBlock
1698 //=======================================================================
1699 Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
1700 (const Handle(BOPDS_PaveBlock)& thePB,
1701 const BOPDS_Curve& theNC,
1702 const TColStd_ListOfInteger& theLSE,
1703 Standard_Integer& theNEOut,
1704 Standard_Real& theTolNew)
1706 if (theLSE.IsEmpty())
1707 return Standard_False;
1709 Standard_Real aT1, aT2, aTm, aTx, aTolE, aTolCheck, aTol, aDist;
1710 Standard_Integer nE, iFlag, nV1, nV2;
1713 TColStd_ListIteratorOfListOfInteger aItLI;
1715 thePB->Range(aT1, aT2);
1716 thePB->Indices(nV1, nV2);
1717 const TopoDS_Vertex &aV1 = TopoDS::Vertex(myDS->Shape(nV1)),
1718 &aV2 = TopoDS::Vertex(myDS->Shape(nV2));
1719 const Standard_Real aTolV1 = BRep_Tool::Tolerance(aV1),
1720 aTolV2 = BRep_Tool::Tolerance(aV2);
1722 aTol = Max(aTolV1, aTolV2);
1724 aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
1725 theNC.Curve().D0(aTm, aPm);
1727 aBoxPm.Enlarge(aTol);
1729 aItLI.Initialize(theLSE);
1730 for (; aItLI.More(); aItLI.Next()) {
1734 const BOPDS_ShapeInfo& aSIE=myDS->ChangeShapeInfo(nE);
1735 const Bnd_Box& aBoxE=aSIE.Box();
1736 if (!aBoxE.IsOut(aBoxPm)) {
1737 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
1738 aTolE = BRep_Tool::Tolerance(aE);
1739 aTolCheck = Max(aTolE, aTol) + myFuzzyValue;
1740 iFlag = myContext->ComputePE(aPm, aTolCheck, aE, aTx, aDist);
1745 return Standard_True;
1749 return Standard_False;
1752 //=======================================================================
1753 //function : IsExistingPaveBlock
1755 //=======================================================================
1756 Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
1757 (const Handle(BOPDS_PaveBlock)& thePB,
1758 const BOPDS_Curve& theNC,
1759 const Standard_Real theTolR3D,
1760 const BOPDS_IndexedMapOfPaveBlock& theMPBOnIn,
1761 BOPTools_BoxTree& thePBTree,
1762 const BOPDS_MapOfPaveBlock& theMPBCommon,
1763 Handle(BOPDS_PaveBlock)& aPBOut,
1764 Standard_Real& theTolNew)
1766 const IntTools_Curve& aIC=theNC.Curve();
1768 Standard_Real aT1, aT2;
1769 thePB->Range(aT1, aT2);
1771 Standard_Integer nV11, nV12;
1772 thePB->Indices (nV11, nV12);
1779 const Standard_Real aTolV11 = BRep_Tool::Tolerance (TopoDS::Vertex (myDS->Shape (nV11)));
1780 aBoxP1.Enlarge (aTolV11);
1782 // Find edges intersecting by AABB with the first point
1783 BOPTools_BoxTreeSelector aSelector;
1784 aSelector.SetBox (Bnd_Tools::Bnd2BVH (aBoxP1));
1785 aSelector.SetBVHSet (&thePBTree);
1786 if (!aSelector.Select())
1787 return Standard_False;
1789 //intermediate point
1791 Standard_Real aTm = IntTools_Tools::IntermediatePoint (aT1, aT2);
1794 const Handle(Geom_Curve)& aC3d = aIC.Curve();
1795 aC3d->D1(aTm, aPm, aVTgt1);
1797 Standard_Boolean isVtgt1Valid = aVTgt1.SquareMagnitude() > gp::Resolution();
1806 const Standard_Real aTolV12 = BRep_Tool::Tolerance (TopoDS::Vertex (myDS->Shape (nV12)));
1807 aBoxP2.Enlarge (aTolV12);
1809 const Standard_Real aTolV1 = Max(aTolV11, aTolV12) + myFuzzyValue;
1811 Standard_Real aTolCheck = theTolR3D + myFuzzyValue;
1813 //Some limit values to define "thin" face when iflag1=iflag2=2 and
1814 //edge has no common block with any face
1815 Standard_Real aMaxTolAdd = 0.001; //Maximal tolerance of edge allowed
1816 const Standard_Real aCoeffTolAdd = 10.; //Coeff to define max. tolerance with help of aTolCheck
1817 aMaxTolAdd = Min(aMaxTolAdd, aCoeffTolAdd * aTolCheck);
1819 // Look for the existing pave block closest to the section curve
1820 Standard_Boolean bFound = Standard_False;
1821 theTolNew = ::RealLast();
1823 for (TColStd_ListOfInteger::Iterator it (aSelector.Indices()); it.More(); it.Next())
1825 const Handle (BOPDS_PaveBlock)& aPB = theMPBOnIn (it.Value());
1827 Standard_Integer nV21, nV22;
1828 aPB->Indices (nV21, nV22);
1830 const Standard_Real aTolV21 = BRep_Tool::Tolerance (TopoDS::Vertex (myDS->Shape (nV21)));
1831 const Standard_Real aTolV22 = BRep_Tool::Tolerance (TopoDS::Vertex (myDS->Shape (nV22)));
1832 const Standard_Real aTolV2 = Max (aTolV21, aTolV22) + myFuzzyValue;
1834 const BOPDS_ShapeInfo& aSISp = myDS->ChangeShapeInfo (aPB->Edge());
1835 const TopoDS_Edge& aSp = (*(TopoDS_Edge *)(&aSISp.Shape()));
1836 const Bnd_Box& aBoxSp = aSISp.Box();
1838 Standard_Integer iFlag1 = (nV11 == nV21 || nV11 == nV22) ? 2 : 1;
1839 Standard_Integer iFlag2 = (nV12 == nV21 || nV12 == nV22) ? 2 : (!aBoxSp.IsOut (aBoxP2) ? 1 : 0);
1843 Standard_Real aDist = 0.;
1844 Standard_Real aCoeff = 1.; //Coeff for taking in account deflections between edge and theNC
1845 //when aPB is not common block
1846 Standard_Real aDistm1m2 = 0.;
1847 Standard_Integer aPEStatus = 1;
1849 Standard_Real aRealTol = aTolCheck;
1850 if (myDS->IsCommonBlock(aPB))
1852 aRealTol = Max(aRealTol, Max(aTolV1, aTolV2));
1853 if (theMPBCommon.Contains(aPB))
1854 // for an edge, which is a common block with a face,
1855 // increase the chance to coincide with section curve
1858 else if (iFlag1 == 2 && iFlag2 == 2)
1860 //Check, if edge could be common block with section curve
1861 // and increase the chance to coincide with section curve
1862 //skip processing if one edge is closed, but other is not closed
1863 //such configurations can give iFlag1 == 2 && iFlag2 == 2
1864 Standard_Boolean bSkipProcessing = ((nV11 == nV12) && (nV21 != nV22)) || ((nV11 != nV12) && (nV21 == nV22));
1866 if (!bSkipProcessing)
1871 BRepAdaptor_Curve aBAC2(aSp);
1872 if (aIC.Type() != GeomAbs_Line ||
1873 aBAC2.GetType() != GeomAbs_Line)
1875 Standard_Real aTldp;
1876 Standard_Real aTolAdd = 2. * Min(aMaxTolAdd, Max(aRealTol, Max(aTolV1, aTolV2)));
1877 aPEStatus = myContext->ComputePE(aPm, aTolAdd, aSp,
1880 if (aPEStatus == 0 )
1884 aBAC2.D1(aTldp, aPm2, aVTgt2);
1885 if (aVTgt2.SquareMagnitude() > gp::Resolution())
1887 // The angle should be close to zero
1888 Standard_Real aCos = aVTgt1.Dot(aVTgt2.Normalized());
1889 if (Abs(aCos) >= 0.9063)
1901 Bnd_Box aBoxTmp = aBoxPm;
1902 aBoxTmp.Enlarge(aRealTol);
1904 Standard_Real aDistToSp = 0.;
1906 if (aBoxSp.IsOut(aBoxTmp) || aPEStatus < 0)
1910 else if(aPEStatus == 0) //aPEStatus == 0 for case iflag1 == iflag2 == 2
1912 aDistToSp = aDistm1m2;
1914 else if (aPEStatus == 1) //Projection has not been done yet
1916 aPEStatus = myContext->ComputePE(aPm, aRealTol, aSp,
1923 iFlag1 = !myContext->ComputePE(aP1, aRealTol, aSp, aTx, aDist);
1924 if (iFlag1 && aDistToSp < aDist)
1929 iFlag2 = !myContext->ComputePE(aP2, aRealTol, aSp, aTx, aDist);
1930 if (iFlag2 && aDistToSp < aDist)
1934 if (iFlag1 && iFlag2)
1936 if (aDistToSp < theTolNew)
1939 theTolNew = aCoeff * aDistToSp;
1940 bFound = Standard_True;
1947 //=======================================================================
1950 //=======================================================================
1951 static void getBoundPaves(const BOPDS_DS* theDS,
1952 const BOPDS_Curve& theNC,
1953 Standard_Integer theNV[2])
1955 theNV[0] = theNV[1] = -1;
1957 // get extreme paves
1958 const Handle(BOPDS_PaveBlock)& aPB = theNC.PaveBlocks().First();
1959 const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
1960 Standard_Integer aNbEP = aLP.Extent();
1963 Standard_Real aTmin = RealLast();
1964 Standard_Real aTmax = -aTmin;
1965 for (BOPDS_ListIteratorOfListOfPave aItLP(aLP); aItLP.More(); aItLP.Next())
1967 const BOPDS_Pave& aPv = aItLP.Value();
1968 Standard_Integer nV;
1970 aPv.Contents(nV, aTV);
1972 theNV[0] = aPv.Index();
1976 theNV[1] = aPv.Index();
1981 // compare extreme vertices with ends of the curve
1982 const IntTools_Curve& aIC = theNC.Curve();
1983 Standard_Real aT[2];
1985 aIC.Bounds(aT[0], aT[1], aP[0], aP[1]);
1986 Standard_Real aTol = Max(theNC.Tolerance(), theNC.TangentialTolerance());
1987 aTol += Precision::Confusion();
1988 for (Standard_Integer j = 0; j < 2; ++j)
1990 const BOPDS_ShapeInfo& aSIV = theDS->ShapeInfo(theNV[j]);
1991 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&aSIV.Shape()));
1992 Standard_Integer iFlag = BOPTools_AlgoTools::ComputeVV(aV, aP[j], aTol);
1998 //=======================================================================
1999 //function : PutBoundPaveOnCurve
2001 //=======================================================================
2002 void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1,
2003 const TopoDS_Face& aF2,
2005 TColStd_ListOfInteger& aLVB)
2007 const IntTools_Curve& aIC=aNC.Curve();
2008 Standard_Real aT[2];
2010 aIC.Bounds(aT[0], aT[1], aP[0], aP[1]);
2011 Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
2012 Handle(BOPDS_PaveBlock)& aPB = aNC.ChangePaveBlock1();
2013 // Get numbers of vertices assigned to the ends of the curve
2014 Standard_Integer aBndNV[2];
2015 getBoundPaves(myDS, aNC, aBndNV);
2017 Standard_Real aTolVnew = Precision::Confusion();
2018 Standard_Boolean isClosed = aP[1].IsEqual (aP[0], aTolVnew);
2019 if (isClosed && (aBndNV[0] > 0 || aBndNV[1] > 0))
2022 for (Standard_Integer j = 0; j<2; ++j)
2026 // no vertex on this end
2027 if (j && isClosed) {
2028 //if curve is closed, process only one bound
2031 Standard_Boolean bVF = myContext->IsValidPointForFaces(aP[j], aF1, aF2, aTolR3D);
2036 BOPTools_AlgoTools::MakeNewVertex(aP[j], aTolR3D, aVn);
2037 BOPTools_AlgoTools::UpdateVertex(aIC, aT[j], aVn);
2038 aTolVnew = BRep_Tool::Tolerance(aVn);
2040 BOPDS_ShapeInfo aSIVn;
2041 aSIVn.SetShapeType(TopAbs_VERTEX);
2042 aSIVn.SetShape(aVn);
2044 Bnd_Box& aBox = aSIVn.ChangeBox();
2045 BRepBndLib::Add(aVn, aBox);
2046 aBox.SetGap(aBox.GetGap() + Precision::Confusion());
2048 Standard_Integer nVn = myDS->Append(aSIVn);
2052 aPn.SetParameter(aT[j]);
2053 aPB->AppendExtPave(aPn);
2060 //=======================================================================
2061 //function : PutPavesOnCurve
2063 //=======================================================================
2064 void BOPAlgo_PaveFiller::PutPavesOnCurve(const TColStd_MapOfInteger& theMVOnIn,
2065 const TColStd_MapOfInteger& theMVCommon,
2067 const TColStd_MapOfInteger& theMI,
2068 const TColStd_MapOfInteger& theMVEF,
2069 TColStd_DataMapOfIntegerReal& theMVTol,
2070 TColStd_DataMapOfIntegerListOfInteger& theDMVLV)
2072 Standard_Integer nV;
2073 TColStd_MapIteratorOfMapOfInteger aIt;
2075 const Bnd_Box& aBoxC = theNC.Box();
2076 const Standard_Real aTolR3D = Max(theNC.Tolerance(), theNC.TangentialTolerance());
2078 //Put EF vertices first
2079 aIt.Initialize(theMVEF);
2080 for (; aIt.More(); aIt.Next())
2083 PutPaveOnCurve(nV, aTolR3D, theNC, theMI, theMVTol, theDMVLV, 2);
2086 //Put all other vertices
2087 aIt.Initialize(theMVOnIn);
2088 for (; aIt.More(); aIt.Next())
2091 if (theMVEF.Contains(nV))
2096 if (!theMVCommon.Contains(nV))
2098 const BOPDS_ShapeInfo& aSIV = myDS->ShapeInfo(nV);
2099 const Bnd_Box& aBoxV = aSIV.Box();
2101 if (aBoxC.IsOut(aBoxV))
2105 if (!myDS->IsNewShape(nV))
2111 PutPaveOnCurve(nV, aTolR3D, theNC, theMI, theMVTol, theDMVLV, 1);
2115 //=======================================================================
2116 //function : FilterPavesOnCurves
2118 //=======================================================================
2120 struct PaveBlockDist {
2121 Handle(BOPDS_PaveBlock) PB;
2122 Standard_Real SquareDist; // square distance from vertex to the paveblock
2123 Standard_Real SinAngle; // sinus of angle between projection vector
2124 // and tangent at projection point
2125 Standard_Real Tolerance; // tolerance of the section curve
2128 void BOPAlgo_PaveFiller::FilterPavesOnCurves(const BOPDS_VectorOfCurve& theVNC,
2129 TColStd_DataMapOfIntegerReal& theMVTol)
2131 // For each vertex found in ExtPaves of pave blocks of section curves
2132 // collect list of pave blocks with distance to the curve
2133 NCollection_IndexedDataMap<Standard_Integer,NCollection_List<PaveBlockDist> > aIDMVertPBs;
2135 const Standard_Real anEps = gp::Resolution();
2136 for (i = 0; i < theVNC.Length(); ++i)
2138 const BOPDS_Curve& aNC = theVNC(i);
2139 const IntTools_Curve& aIC = aNC.Curve();
2140 const Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
2141 GeomAdaptor_Curve aGAC(aIC.Curve());
2142 const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First();
2143 const BOPDS_ListOfPave& aPaves = aPB->ExtPaves();
2144 BOPDS_ListOfPave::Iterator itPaves(aPaves);
2145 for (; itPaves.More(); itPaves.Next())
2147 const BOPDS_Pave& aPave = itPaves.Value();
2148 Standard_Integer nV = aPave.Index();
2149 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
2150 // compute distance from vertex to the point on curve with vertex parameter
2151 gp_Pnt aPV = BRep_Tool::Pnt(aV);
2152 Standard_Real aPar = aPave.Parameter();
2155 aGAC.D1(aPar, aPonC, aD1);
2156 gp_Vec aProjVec(aPV, aPonC);
2157 Standard_Real aSqDist = aProjVec.SquareMagnitude();
2158 Standard_Real aSqD1Mod = aD1.SquareMagnitude();
2159 Standard_Real aSin = aProjVec.CrossSquareMagnitude(aD1);
2160 if (aSqDist > anEps && aSqD1Mod > anEps)
2161 aSin = sqrt(aSin / aSqDist / aSqD1Mod);
2162 NCollection_List<PaveBlockDist>* pList = aIDMVertPBs.ChangeSeek(nV);
2164 pList = &aIDMVertPBs.ChangeFromIndex(aIDMVertPBs.Add(nV, NCollection_List<PaveBlockDist>()));
2165 PaveBlockDist aPBD = { aPB, aSqDist, aSin, aTolR3D };
2166 pList->Append(aPBD);
2170 // Process each vertex
2171 const Standard_Real aSinAngleMin = 0.5; // angle below which projection is suspicious
2172 for (i = 1; i <= aIDMVertPBs.Extent(); i++)
2174 Standard_Integer nV = aIDMVertPBs.FindKey(i);
2175 const NCollection_List<PaveBlockDist>& aList = aIDMVertPBs(i);
2176 // Find a pave with minimal distance
2177 Standard_Real aMinDist = RealLast();
2178 Handle(BOPDS_PaveBlock) aPBMinDist;
2179 NCollection_List<PaveBlockDist>::Iterator itL(aList);
2180 for (; itL.More(); itL.Next())
2182 const PaveBlockDist& aPBD = itL.Value();
2183 if (aPBD.SquareDist < aMinDist)
2185 aMinDist = aPBD.SquareDist;
2186 aPBMinDist = aPBD.PB;
2189 // Remove a vertex from a pave block if the distance is greater than the tolerance
2190 // and there are other pave blocks for which the distance is less than the current.
2191 // Do not remove a vertex if it is projected on the curve with quite large angle
2192 // (see test bugs modalg_6 bug27761).
2194 // Reduce tolerance for the vertex to the value of maximal distance to
2195 // to section curve on which it will be kept.
2196 Standard_Real aMaxDistKept = -1;
2197 Standard_Boolean isRemoved = Standard_False;
2198 for (itL.Init(aList); itL.More(); itL.Next())
2200 const PaveBlockDist& aPBD = itL.Value();
2201 Standard_Real aCheckDist = 100. * Max(aPBD.Tolerance*aPBD.Tolerance, aMinDist);
2202 if (aPBD.SquareDist > aCheckDist && aPBD.SinAngle < aSinAngleMin)
2204 aPBD.PB->RemoveExtPave(nV);
2205 isRemoved = Standard_True;
2207 else if (aPBD.SquareDist > aMaxDistKept)
2208 aMaxDistKept = aPBD.SquareDist;
2211 if (isRemoved && aMaxDistKept > 0)
2213 const Standard_Real* pTol = theMVTol.Seek(nV);
2216 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV);
2217 const Standard_Real aRealTol = Max(*pTol, sqrt(aMaxDistKept) + Precision::Confusion());
2218 (*(Handle(BRep_TVertex)*)&aV.TShape())->Tolerance(aRealTol);
2224 //=======================================================================
2225 //function : ExtendedTolerance
2227 //=======================================================================
2228 Standard_Boolean BOPAlgo_PaveFiller::ExtendedTolerance
2229 (const Standard_Integer nV,
2230 const TColStd_MapOfInteger& aMI,
2231 Standard_Real& aTolVExt,
2232 const Standard_Integer aType)
2234 Standard_Boolean bFound = Standard_False;
2235 if (!(myDS->IsNewShape(nV))) {
2239 Standard_Integer i, k, aNbLines, aNbInt;
2240 Standard_Real aT11, aT12, aD1, aD2, aD;
2242 gp_Pnt aPV, aP11, aP12;
2248 } else if (aType == 2) {
2252 aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
2253 aPV=BRep_Tool::Pnt(aV);
2255 BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
2256 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
2258 for (; k<aNbInt; ++k) {
2259 aNbLines = !k ? aEEs.Length() : aEFs.Length();
2260 for (i = 0; i < aNbLines; ++i) {
2261 BOPDS_Interf *aInt = !k ? (BOPDS_Interf*) (&aEEs(i)) :
2262 (BOPDS_Interf*) (&aEFs(i));
2263 if (aInt->IndexNew() == nV) {
2264 if (aMI.Contains(aInt->Index1()) &&
2265 aMI.Contains(aInt->Index2())) {
2266 const IntTools_CommonPrt& aComPrt = !k ? aEEs(i).CommonPart() :
2267 aEFs(i).CommonPart();
2269 const TopoDS_Edge& aE1=aComPrt.Edge1();
2270 aComPrt.Range1(aT11, aT12);
2271 BOPTools_AlgoTools::PointOnEdge(aE1, aT11, aP11);
2272 BOPTools_AlgoTools::PointOnEdge(aE1, aT12, aP12);
2273 aD1=aPV.Distance(aP11);
2274 aD2=aPV.Distance(aP12);
2275 aD=(aD1>aD2)? aD1 : aD2;
2280 }//if (aMI.Contains(aEF.Index1()) && aMI.Contains(aEF.Index2())) {
2281 }//if (aInt->IndexNew() == nV) {
2282 }//for (i = 0; i < aNbLines; ++i) {
2283 }//for (k=0; k<2; ++k) {
2287 //=======================================================================
2288 //function : GetEFPnts
2290 //=======================================================================
2291 void BOPAlgo_PaveFiller::GetEFPnts
2292 (const Standard_Integer nF1,
2293 const Standard_Integer nF2,
2294 IntSurf_ListOfPntOn2S& aListOfPnts)
2296 Standard_Integer nE, nF, nFOpposite, aNbEFs, i;
2297 Standard_Real U1, U2, V1, V2, f, l;
2298 TColStd_MapOfInteger aMI;
2300 //collect indexes of all shapes from nF1 and nF2.
2301 GetFullShapeMap(nF1, aMI);
2302 GetFullShapeMap(nF2, aMI);
2304 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
2305 aNbEFs = aEFs.Length();
2307 for(i = 0; i < aNbEFs; ++i) {
2308 const BOPDS_InterfEF& aEF = aEFs(i);
2309 if (aEF.HasIndexNew()) {
2310 aEF.Indices(nE, nFOpposite);
2311 if(aMI.Contains(nE) && aMI.Contains(nFOpposite)) {
2312 const IntTools_CommonPrt& aCP = aEF.CommonPart();
2313 Standard_Real aPar = aCP.VertexParameter1();
2314 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&myDS->Shape(nE)));
2315 const TopoDS_Face& aFOpposite =
2316 (*(TopoDS_Face*)(&myDS->Shape(nFOpposite)));
2318 const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(aE, f, l);
2320 nF = (nFOpposite == nF1) ? nF2 : nF1;
2321 const TopoDS_Face& aF = (*(TopoDS_Face*)(&myDS->Shape(nF)));
2322 Handle(Geom2d_Curve) aPCurve =
2323 BRep_Tool::CurveOnSurface(aE, aF, f, l);
2325 GeomAPI_ProjectPointOnSurf& aProj=myContext->ProjPS(aFOpposite);
2328 aCurve->D0(aPar, aPoint);
2329 IntSurf_PntOn2S aPnt;
2330 if(!aPCurve.IsNull()) {
2331 gp_Pnt2d aP2d = aPCurve->Value(aPar);
2332 aProj.Perform(aPoint);
2333 if(aProj.IsDone()) {
2334 aProj.LowerDistanceParameters(U1,V1);
2336 aPnt.SetValue(aP2d.X(),aP2d.Y(),U1,V1);
2338 aPnt.SetValue(U1,V1,aP2d.X(),aP2d.Y());
2340 aListOfPnts.Append(aPnt);
2344 GeomAPI_ProjectPointOnSurf& aProj1 = myContext->ProjPS(aF);
2345 aProj1.Perform(aPoint);
2346 aProj.Perform(aPoint);
2347 if(aProj1.IsDone() && aProj.IsDone()){
2348 aProj1.LowerDistanceParameters(U1,V1);
2349 aProj.LowerDistanceParameters(U2,V2);
2351 aPnt.SetValue(U1,V1,U2,V2);
2353 aPnt.SetValue(U2,V2,U1,V1);
2355 aListOfPnts.Append(aPnt);
2363 //=======================================================================
2364 //function : PutEFPavesOnCurve
2366 //=======================================================================
2367 void BOPAlgo_PaveFiller::PutEFPavesOnCurve
2368 (const BOPDS_VectorOfCurve& theVC,
2369 const Standard_Integer theIndex,
2370 const TColStd_MapOfInteger& aMI,
2371 const TColStd_MapOfInteger& aMVEF,
2372 TColStd_DataMapOfIntegerReal& aMVTol,
2373 TColStd_DataMapOfIntegerListOfInteger& aDMVLV)
2375 if (!aMVEF.Extent()) {
2379 const BOPDS_Curve& aNC = theVC.Value(theIndex);
2380 const IntTools_Curve& aIC=aNC.Curve();
2381 GeomAbs_CurveType aTypeC;
2383 if (!(aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve)) {
2387 Standard_Integer nV;
2388 TColStd_MapOfInteger aMV;
2391 RemoveUsedVertices(theVC, aMV);
2392 if (!aMV.Extent()) {
2396 Standard_Real aDist;
2399 const Handle(Geom_Curve)& aC3D=aIC.Curve();
2400 GeomAPI_ProjectPointOnCurve& aProjPT = myContext->ProjPT(aC3D);
2402 TColStd_MapIteratorOfMapOfInteger aItMI;
2403 aItMI.Initialize(aMV);
2404 for (; aItMI.More(); aItMI.Next()) {
2406 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
2407 gp_Pnt aPV = BRep_Tool::Pnt(aV);
2408 aProjPT.Perform(aPV);
2409 Standard_Integer aNbPoints = aProjPT.NbPoints();
2411 aDist = aProjPT.LowerDistance();
2412 PutPaveOnCurve(nV, aDist, aNC, aMI, aMVTol, aDMVLV);
2417 //=======================================================================
2418 //function : PutStickPavesOnCurve
2420 //=======================================================================
2421 void BOPAlgo_PaveFiller::PutStickPavesOnCurve
2422 (const TopoDS_Face& aF1,
2423 const TopoDS_Face& aF2,
2424 const TColStd_MapOfInteger& aMI,
2425 const BOPDS_VectorOfCurve& theVC,
2426 const Standard_Integer theIndex,
2427 const TColStd_MapOfInteger& aMVStick,
2428 TColStd_DataMapOfIntegerReal& aMVTol,
2429 TColStd_DataMapOfIntegerListOfInteger& aDMVLV)
2431 const BOPDS_Curve& aNC = theVC.Value(theIndex);
2432 // Get numbers of vertices assigned to the ends of the curve
2433 Standard_Integer aBndNV[2];
2434 getBoundPaves(myDS, aNC, aBndNV);
2435 if (aBndNV[0] >= 0 && aBndNV[1] >= 0)
2437 // both curve ends already have assigned vertices
2440 TColStd_MapOfInteger aMV;
2441 aMV.Assign(aMVStick);
2442 RemoveUsedVertices(theVC, aMV);
2444 if (!aMV.Extent()) {
2448 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
2449 Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2);
2451 const IntTools_Curve& aIC=aNC.Curve();
2452 Handle(Geom2d_Curve) aC2D[2];
2454 aC2D[0]=aIC.FirstCurve2d();
2455 aC2D[1]=aIC.SecondCurve2d();
2456 if (!aC2D[0].IsNull() && !aC2D[1].IsNull()) {
2457 Standard_Integer nV, m, n;
2458 Standard_Real aTC[2], aD, aD2, u, v, aDT2, aScPr, aDScPr;
2462 TColStd_MapIteratorOfMapOfInteger aItMI, aItMI1;
2464 aDT2=2e-7; // the rich criteria
2465 aDScPr=5.e-9; // the creasing criteria
2466 aIC.Bounds(aTC[0], aTC[1], aPC[0], aPC[1]);
2468 aItMI.Initialize(aMV);
2469 for (; aItMI.More(); aItMI.Next()) {
2471 const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&myDS->Shape(nV));
2472 aPV=BRep_Tool::Pnt(aV);
2474 for (m=0; m<2; ++m) {
2477 aD2=aPC[m].SquareDistance(aPV);
2478 if (aD2>aDT2) {// no rich
2482 for (n=0; n<2; ++n) {
2483 Handle(Geom_Surface)& aS=(!n)? aS1 : aS2;
2484 aC2D[n]->D0(aTC[m], aP2D);
2486 BOPTools_AlgoTools3D::GetNormalToSurface(aS, u, v, aDN[n]);
2489 aScPr=aDN[0]*aDN[1];
2499 // The intersection curve aIC is vanishing curve (the crease)
2502 PutPaveOnCurve(nV, aD, aNC, aMI, aMVTol, aDMVLV);
2504 }//for (jVU=1; jVU=aNbVU; ++jVU) {
2508 //=======================================================================
2509 //function : GetStickVertices
2511 //=======================================================================
2512 void BOPAlgo_PaveFiller::GetStickVertices(const Standard_Integer nF1,
2513 const Standard_Integer nF2,
2514 TColStd_MapOfInteger& aMVStick,
2515 TColStd_MapOfInteger& aMVEF,
2516 TColStd_MapOfInteger& aMI)
2518 Standard_Integer nS1, nS2, nVNew, aTypeInt, i;
2520 BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV();
2521 BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
2522 BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
2523 BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
2524 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
2526 Standard_Integer aNbLines[5] = {
2527 aVVs.Length(), aVEs.Length(), aEEs.Length(),
2528 aVFs.Length(), aEFs.Length()
2530 //collect indices of all shapes from nF1 and nF2.
2532 GetFullShapeMap(nF1, aMI);
2533 GetFullShapeMap(nF2, aMI);
2535 //collect VV, VE, EE, VF interferences
2536 for (aTypeInt = 0; aTypeInt < 4; ++aTypeInt) {
2537 for (i = 0; i < aNbLines[aTypeInt]; ++i) {
2538 BOPDS_Interf* aInt = (aTypeInt==0) ? (BOPDS_Interf*)(&aVVs(i)) :
2539 ((aTypeInt==1) ? (BOPDS_Interf*)(&aVEs(i)) :
2540 ((aTypeInt==2) ? (BOPDS_Interf*)(&aEEs(i)) :
2541 (BOPDS_Interf*)(&aVFs(i))));
2542 if (aInt->HasIndexNew()) {
2543 aInt->Indices(nS1, nS2);
2544 if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
2545 nVNew = aInt->IndexNew();
2546 myDS->HasShapeSD (nVNew, nVNew);
2547 aMVStick.Add(nVNew);
2552 //collect EF interferences
2553 for (i = 0; i < aNbLines[4]; ++i) {
2554 const BOPDS_InterfEF& aInt = aEFs(i);
2555 if (aInt.HasIndexNew()) {
2556 aInt.Indices(nS1, nS2);
2557 if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
2558 nVNew = aInt.IndexNew();
2559 myDS->HasShapeSD (nVNew, nVNew);
2560 aMVStick.Add(nVNew);
2567 //=======================================================================
2568 // function: GetFullShapeMap
2570 //=======================================================================
2571 void BOPAlgo_PaveFiller::GetFullShapeMap(const Standard_Integer nF,
2572 TColStd_MapOfInteger& aMI)
2574 TColStd_ListIteratorOfListOfInteger aIt;
2575 Standard_Integer nS;
2577 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF);
2578 const TColStd_ListOfInteger& aLI = aSI.SubShapes();
2581 aIt.Initialize(aLI);
2582 for (; aIt.More(); aIt.Next()) {
2588 //=======================================================================
2589 // function: RemoveUsedVertices
2591 //=======================================================================
2592 void BOPAlgo_PaveFiller::RemoveUsedVertices(const BOPDS_VectorOfCurve& aVC,
2593 TColStd_MapOfInteger& aMV)
2598 for (Standard_Integer i = 0; i < aVC.Length(); ++i)
2600 const BOPDS_Curve& aNC = aVC.Value(i);
2601 const BOPDS_ListOfPaveBlock& aLPBC = aNC.PaveBlocks();
2602 BOPDS_ListIteratorOfListOfPaveBlock itPB(aLPBC);
2603 for (; itPB.More(); itPB.Next())
2605 const Handle(BOPDS_PaveBlock)& aPB = itPB.Value();
2606 const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
2607 BOPDS_ListIteratorOfListOfPave itLP(aLP);
2608 for (; itLP.More(); itLP.Next())
2609 aMV.Remove(itLP.Value().Index());
2611 aMV.Remove(aPB->Pave1().Index());
2612 aMV.Remove(aPB->Pave2().Index());
2617 //=======================================================================
2618 //function : PutPaveOnCurve
2620 //=======================================================================
2621 void BOPAlgo_PaveFiller::PutPaveOnCurve
2622 (const Standard_Integer nV,
2623 const Standard_Real aTolR3D,
2624 const BOPDS_Curve& aNC,
2625 const TColStd_MapOfInteger& aMI,
2626 TColStd_DataMapOfIntegerReal& aMVTol,
2627 TColStd_DataMapOfIntegerListOfInteger& aDMVLV,
2628 const Standard_Integer iCheckExtend)
2630 Standard_Boolean bIsVertexOnLine;
2633 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
2634 const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First();
2635 const IntTools_Curve& aIC = aNC.Curve();
2637 Standard_Real aTolV = (aMVTol.IsBound(nV) ? aMVTol(nV) : BRep_Tool::Tolerance(aV));
2639 bIsVertexOnLine = myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D + myFuzzyValue, aT);
2640 if (!bIsVertexOnLine && iCheckExtend && !myVertsToAvoidExtension.Contains(nV))
2642 Standard_Real anExtraTol = aTolV;
2643 if (ExtendedTolerance(nV, aMI, anExtraTol, iCheckExtend))
2645 bIsVertexOnLine = myContext->IsVertexOnLine(aV, anExtraTol, aIC, aTolR3D + myFuzzyValue, aT);
2646 if (bIsVertexOnLine)
2650 aTolV = aPOnC.Distance(BRep_Tool::Pnt(aV));
2655 if (bIsVertexOnLine) {
2656 // check if aPB contains the parameter aT
2657 Standard_Boolean bExist;
2658 Standard_Integer nVUsed;
2659 Standard_Real aPTol, aDTol;
2661 aDTol = BOPTools_AlgoTools::DTolerance();
2663 GeomAdaptor_Curve aGAC(aIC.Curve());
2664 aPTol = aGAC.Resolution(Max(aTolR3D, aTolV));
2666 bExist = aPB->ContainsParameter(aT, aPTol, nVUsed);
2668 // use existing pave
2669 TColStd_ListOfInteger* pList = aDMVLV.ChangeSeek(nVUsed);
2671 pList = aDMVLV.Bound(nVUsed, TColStd_ListOfInteger());
2672 pList->Append(nVUsed);
2673 if (!aMVTol.IsBound(nVUsed)) {
2674 const TopoDS_Vertex& aVUsed = (*(TopoDS_Vertex *)(&myDS->Shape(nVUsed)));
2675 aTolV = BRep_Tool::Tolerance(aVUsed);
2676 aMVTol.Bind(nVUsed, aTolV);
2679 // avoid repeated elements in the list
2680 TColStd_ListIteratorOfListOfInteger aItLI(*pList);
2681 for (; aItLI.More(); aItLI.Next()) {
2682 if (aItLI.Value() == nV) {
2686 if (!aItLI.More()) {
2689 // save initial tolerance for the vertex
2690 if (!aMVTol.IsBound(nV)) {
2691 aTolV = BRep_Tool::Tolerance(aV);
2692 aMVTol.Bind(nV, aTolV);
2699 aPave.SetParameter(aT);
2700 aPB->AppendExtPave(aPave);
2702 gp_Pnt aP1 = aGAC.Value(aT);
2703 aTolV = BRep_Tool::Tolerance(aV);
2704 gp_Pnt aP2 = BRep_Tool::Pnt(aV);
2705 Standard_Real aDist = aP1.Distance(aP2);
2706 if (aTolV < aDist + aDTol)
2708 BRep_Builder().UpdateVertex(aV, aDist + aDTol);
2710 if (!aMVTol.IsBound(nV)) {
2711 aMVTol.Bind(nV, aTolV);
2714 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV);
2715 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
2716 BRepBndLib::Add(aV, aBoxDS);
2717 aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
2723 //=======================================================================
2724 //function : ProcessExistingPaveBlocks
2726 //=======================================================================
2727 void BOPAlgo_PaveFiller::ProcessExistingPaveBlocks (const Standard_Integer theInt,
2728 const Standard_Integer theCur,
2729 const Standard_Integer nF1,
2730 const Standard_Integer nF2,
2731 const TopoDS_Edge& theES,
2732 const BOPDS_IndexedMapOfPaveBlock& theMPBOnIn,
2733 BOPTools_BoxTree& thePBTree,
2734 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
2735 TopTools_DataMapOfShapeInteger& theMVI,
2736 BOPDS_ListOfPaveBlock& theLPBC,
2737 BOPAlgo_DataMapOfPaveBlockListOfInteger& thePBFacesMap,
2738 BOPDS_MapOfPaveBlock& theMPB)
2741 BRepBndLib::Add (theES, aBoxES, false);
2743 BOPTools_BoxTreeSelector aSelector;
2744 aSelector.SetBox (Bnd_Tools::Bnd2BVH (aBoxES));
2745 aSelector.SetBVHSet (&thePBTree);
2746 if (!aSelector.Select())
2749 const Standard_Real aTolES = BRep_Tool::Tolerance (theES);
2751 const BOPDS_FaceInfo& aFI1 = myDS->FaceInfo (nF1);
2752 const BOPDS_FaceInfo& aFI2 = myDS->FaceInfo (nF2);
2754 for (TColStd_ListOfInteger::Iterator itPB (aSelector.Indices()); itPB.More(); itPB.Next())
2756 const Handle(BOPDS_PaveBlock)& aPBF = theMPBOnIn (itPB.Value());
2757 if (theMPB.Contains (aPBF))
2760 Standard_Boolean bInF1 = (aFI1.PaveBlocksOn().Contains(aPBF) ||
2761 aFI1.PaveBlocksIn().Contains(aPBF));
2762 Standard_Boolean bInF2 = (aFI2.PaveBlocksOn().Contains(aPBF) ||
2763 aFI2.PaveBlocksIn().Contains(aPBF));
2766 // Add all common edges for post treatment
2768 PreparePostTreatFF (theInt, theCur, aPBF, theMSCPB, theMVI, theLPBC);
2772 const Standard_Integer nF = bInF1 ? nF2 : nF1;
2773 const NCollection_List<EdgeRangeDistance>* pList = myDistances.Seek (BOPDS_Pair (aPBF->OriginalEdge(), nF));
2777 Standard_Real aT1, aT2;
2778 aPBF->Range (aT1, aT2);
2780 Standard_Real aDist = RealLast();
2781 for (NCollection_List<EdgeRangeDistance>::Iterator itR (*pList); itR.More(); itR.Next())
2783 const EdgeRangeDistance& aRangeDist = itR.Value();
2784 if ((aT1 <= aRangeDist.First && aRangeDist.First <= aT2) ||
2785 (aT1 <= aRangeDist.Last && aRangeDist.Last <= aT2) ||
2786 (aRangeDist.First <= aT1 && aT1 <= aRangeDist.Last) ||
2787 (aRangeDist.First <= aT2 && aT2 <= aRangeDist.Last))
2789 aDist = aRangeDist.Distance;
2793 if (aDist < RealLast())
2795 const TopoDS_Edge& aEF = TopoDS::Edge (myDS->Shape (aPBF->Edge()));
2796 const Standard_Real aTolSum = aTolES + BRep_Tool::Tolerance (aEF);
2798 if (aDist <= aTolSum)
2801 PreparePostTreatFF (theInt, theCur, aPBF, theMSCPB, theMVI, theLPBC);
2803 TColStd_ListOfInteger* pFaces = thePBFacesMap.ChangeSeek(aPBF);
2805 pFaces = thePBFacesMap.Bound (aPBF, TColStd_ListOfInteger());
2806 if (pFaces->IsEmpty() || !pFaces->Contains (nF))
2807 pFaces->Append (nF);
2813 //=======================================================================
2814 //function : ProcessExistingPaveBlocks
2816 //=======================================================================
2817 void BOPAlgo_PaveFiller::ProcessExistingPaveBlocks
2818 (const Standard_Integer theInt,
2819 const Standard_Integer nF1,
2820 const Standard_Integer nF2,
2821 const BOPDS_IndexedMapOfPaveBlock& aMPBOnIn,
2822 BOPTools_BoxTree& thePBTree,
2823 const TColStd_DataMapOfIntegerListOfInteger& aDMBV,
2824 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
2825 TopTools_DataMapOfShapeInteger& aMVI,
2826 BOPAlgo_DataMapOfPaveBlockListOfInteger& thePBFacesMap,
2827 BOPDS_MapOfPaveBlock& aMPB)
2829 if (aDMBV.IsEmpty()) {
2833 Standard_Real aT, dummy;
2834 Standard_Integer nV, nE, iC, iFlag;
2835 TColStd_ListIteratorOfListOfInteger aItLI;
2836 TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger aItBV;
2838 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2839 BOPDS_InterfFF& aFF = aFFs(theInt);
2840 BOPDS_VectorOfCurve& aVC = aFF.ChangeCurves();
2842 const BOPDS_FaceInfo& aFI1 = myDS->FaceInfo(nF1);
2843 const BOPDS_FaceInfo& aFI2 = myDS->FaceInfo(nF2);
2845 aItBV.Initialize(aDMBV);
2846 for (; aItBV.More(); aItBV.Next()) {
2848 const TColStd_ListOfInteger& aLBV = aItBV.Value();
2850 BOPDS_Curve& aNC = aVC.ChangeValue(iC);
2851 BOPDS_ListOfPaveBlock& aLPBC = aNC.ChangePaveBlocks();
2853 aItLI.Initialize(aLBV);
2854 for (; aItLI.More(); aItLI.Next()) {
2856 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
2857 const Bnd_Box& aBoxV=aSIV.Box();
2858 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aSIV.Shape();
2859 if (!aMVI.IsBound(aV)) {
2863 BOPTools_BoxTreeSelector aSelector;
2864 aSelector.SetBox (Bnd_Tools::Bnd2BVH (aBoxV));
2865 aSelector.SetBVHSet (&thePBTree);
2866 if (!aSelector.Select())
2869 for (TColStd_ListOfInteger::Iterator it (aSelector.Indices()); it.More(); it.Next())
2871 const Handle(BOPDS_PaveBlock)& aPB = aMPBOnIn (it.Value());
2872 if (aPB->Pave1().Index() == nV || aPB->Pave2().Index() == nV) {
2876 if (aMPB.Contains(aPB)) {
2880 const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE);
2881 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aSIE.Shape();
2883 iFlag = myContext->ComputeVE(aV, aE, aT, dummy, myFuzzyValue);
2886 PreparePostTreatFF(theInt, iC, aPB, aMSCPB, aMVI, aLPBC);
2889 Standard_Boolean bInF1 = (aFI1.PaveBlocksOn().Contains(aPB) ||
2890 aFI1.PaveBlocksIn().Contains(aPB));
2891 Standard_Boolean bInF2 = (aFI2.PaveBlocksOn().Contains(aPB) ||
2892 aFI2.PaveBlocksIn().Contains(aPB));
2893 if (!bInF1 || !bInF2)
2895 // Face without pave block
2896 const Standard_Integer nF = bInF1 ? nF2 : nF1;
2897 TColStd_ListOfInteger* pFaces = thePBFacesMap.ChangeSeek(aPB);
2899 pFaces = thePBFacesMap.Bound(aPB, TColStd_ListOfInteger());
2900 // List is expected to be short, so we allow the check here
2901 if (pFaces->IsEmpty() || !pFaces->Contains(nF))
2909 //=======================================================================
2910 //function : UpdateExistingPaveBlocks
2912 //=======================================================================
2913 void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks
2914 (const Handle(BOPDS_PaveBlock)& aPBf,
2915 BOPDS_ListOfPaveBlock& aLPB,
2916 const BOPAlgo_DataMapOfPaveBlockListOfInteger& thePBFacesMap)
2918 if (!aLPB.Extent()) {
2922 Standard_Integer nE;
2923 Standard_Boolean bCB;
2924 Handle(BOPDS_PaveBlock) aPB, aPB1, aPB2, aPB2n;
2925 Handle(BOPDS_CommonBlock) aCB;
2926 BOPDS_ListIteratorOfListOfPaveBlock aIt, aIt1, aIt2;
2928 // 1. Remove old pave blocks
2929 const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPBf);
2930 bCB = !aCB1.IsNull();
2931 BOPDS_ListOfPaveBlock aLPB1;
2934 aLPB1.Assign(aCB1->PaveBlocks());
2938 aIt1.Initialize(aLPB1);
2939 for (; aIt1.More(); aIt1.Next()) {
2940 aPB1 = aIt1.Value();
2941 nE = aPB1->OriginalEdge();
2943 BOPDS_ListOfPaveBlock& aLPB2 = myDS->ChangePaveBlocks(nE);
2944 aIt2.Initialize(aLPB2);
2945 for (; aIt2.More(); aIt2.Next()) {
2946 aPB2 = aIt2.Value();
2954 // 2. Update pave blocks
2956 // Create new common blocks
2957 BOPDS_ListOfPaveBlock aLPBNew;
2958 const TColStd_ListOfInteger& aFaces = aCB1->Faces();
2959 aIt.Initialize(aLPB);
2960 for (; aIt.More(); aIt.Next()) {
2961 const Handle(BOPDS_PaveBlock)& aPBValue = aIt.Value();
2962 BOPDS_Pave aPBValuePaves[2] = {aPBValue->Pave1(), aPBValue->Pave2()};
2964 aCB = new BOPDS_CommonBlock;
2965 aIt1.Initialize(aLPB1);
2966 for (; aIt1.More(); aIt1.Next()) {
2967 aPB2 = aIt1.Value();
2968 nE = aPB2->OriginalEdge();
2970 // Create new pave block
2971 aPB2n = new BOPDS_PaveBlock;
2972 if (aPBValue->OriginalEdge() == nE) {
2973 aPB2n->SetPave1(aPBValuePaves[0]);
2974 aPB2n->SetPave2(aPBValuePaves[1]);
2977 // For the different original edge compute the parameters of paves
2978 BOPDS_Pave aPave[2];
2980 if (aPBValuePaves[0].Index() == aPBValuePaves[1].Index() &&
2981 aPB2->Pave1().Index() == aPB2->Pave2().Index())
2984 aPave[0].SetIndex (aPBValuePaves[0].Index());
2985 aPave[0].SetParameter (aPB2->Pave1().Parameter());
2986 aPave[1].SetIndex (aPBValuePaves[1].Index());
2987 aPave[1].SetParameter (aPB2->Pave2().Parameter());
2991 for (Standard_Integer i = 0; i < 2; ++i) {
2992 Standard_Integer nV = aPBValuePaves[i].Index();
2993 aPave[i].SetIndex(nV);
2994 if (nV == aPB2->Pave1().Index()) {
2995 aPave[i].SetParameter(aPB2->Pave1().Parameter());
2997 else if (nV == aPB2->Pave2().Index()) {
2998 aPave[i].SetParameter(aPB2->Pave2().Parameter());
3001 // Compute the parameter by projecting the point
3002 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
3003 const TopoDS_Edge& aEOr = TopoDS::Edge(myDS->Shape(nE));
3004 Standard_Real aTOut, aDist;
3005 Standard_Integer iErr = myContext->ComputeVE(aV, aEOr, aTOut, aDist, myFuzzyValue);
3007 aPave[i].SetParameter(aTOut);
3010 // Unable to project - set the parameter of the closest boundary
3011 const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(aPB2->Pave1().Index()));
3012 const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(aPB2->Pave2().Index()));
3014 gp_Pnt aP = BRep_Tool::Pnt(aV);
3015 gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
3016 gp_Pnt aP2 = BRep_Tool::Pnt(aV2);
3018 Standard_Real aDist1 = aP.SquareDistance(aP1);
3019 Standard_Real aDist2 = aP.SquareDistance(aP2);
3021 aPave[i].SetParameter(aDist1 < aDist2 ? aPB2->Pave1().Parameter() : aPB2->Pave2().Parameter());
3027 if (aPave[1].Parameter() < aPave[0].Parameter()) {
3028 BOPDS_Pave aPaveTmp = aPave[0];
3029 aPave[0] = aPave[1];
3030 aPave[1] = aPaveTmp;
3033 aPB2n->SetPave1(aPave[0]);
3034 aPB2n->SetPave2(aPave[1]);
3037 aPB2n->SetEdge(aPBValue->Edge());
3038 aPB2n->SetOriginalEdge(nE);
3039 aCB->AddPaveBlock(aPB2n);
3040 myDS->SetCommonBlock(aPB2n, aCB);
3041 myDS->ChangePaveBlocks(nE).Append(aPB2n);
3043 aCB->SetFaces(aFaces);
3045 const Handle(BOPDS_PaveBlock)& aPBNew = aCB->PaveBlocks().First();
3046 aLPBNew.Append(aPBNew);
3052 nE = aPBf->OriginalEdge();
3053 BOPDS_ListOfPaveBlock& aLPBE = myDS->ChangePaveBlocks(nE);
3054 aIt.Initialize(aLPB);
3055 for (; aIt.More(); aIt.Next()) {
3061 // Try to project the edge on the faces
3062 const TColStd_ListOfInteger* pLFaces = thePBFacesMap.Seek(aPBf);
3065 TColStd_ListIteratorOfListOfInteger itLF(*pLFaces);
3066 for (; itLF.More(); itLF.Next())
3068 const Standard_Integer nF = itLF.Value();
3069 BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF);
3070 const TopoDS_Face& aF = TopoDS::Face(myDS->Shape(nF));
3072 aIt.Initialize(aLPB);
3073 for (; aIt.More(); aIt.Next())
3075 aPB = aIt.ChangeValue();
3076 if (aFI.PaveBlocksOn().Contains(aPB) || aFI.PaveBlocksIn().Contains(aPB))
3079 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPB->Edge());
3081 IntTools_EdgeFace anEF;
3084 anEF.SetFuzzyValue(myFuzzyValue);
3085 anEF.SetRange(aPB->Pave1().Parameter(), aPB->Pave2().Parameter());
3086 anEF.SetContext(myContext);
3089 const IntTools_SequenceOfCommonPrts& aCPrts = anEF.CommonParts();
3090 Standard_Boolean bCoincide = (aCPrts.Length() == 1 && aCPrts(1).Type() == TopAbs_EDGE);
3093 aCB = myDS->CommonBlock(aPB);
3096 aCB = new BOPDS_CommonBlock;
3097 aCB->AddPaveBlock(aPB);
3098 myDS->SetCommonBlock(aPB, aCB);
3101 aFI.ChangePaveBlocksIn().Add(aPB);
3107 //=======================================================================
3108 // function: PutClosingPaveOnCurve
3110 //=======================================================================
3111 void BOPAlgo_PaveFiller::PutClosingPaveOnCurve(BOPDS_Curve& aNC)
3113 const IntTools_Curve& aIC = aNC.Curve();
3114 const Handle(Geom_Curve)& aC3D = aIC.Curve();
3120 if (!aIC.HasBounds())
3124 Standard_Real aT[2];
3126 aIC.Bounds(aT[0], aT[1], aP[0], aP[1]);
3128 // Find the pave which has been put at one of the ends
3130 // Index of the vertex put at one of the ends
3131 Standard_Integer nV = -1;
3132 // Keep the opposite parameter
3133 Standard_Real aTOp = 0.;
3134 // Keep the opposite bounding point
3137 Handle(BOPDS_PaveBlock)& aPB = aNC.ChangePaveBlock1();
3138 BOPDS_ListOfPave& aLP = aPB->ChangeExtPaves();
3139 BOPDS_ListIteratorOfListOfPave aItLP(aLP);
3140 for (; aItLP.More() && (nV < 0); aItLP.Next())
3142 aPave = aItLP.Value();
3143 Standard_Real aTC = aPave.Parameter();
3144 for (Standard_Integer j = 0; j < 2; ++j)
3146 if (Abs(aTC - aT[j]) < Precision::PConfusion())
3149 aTOp = (!j) ? aT[1] : aT[0];
3150 aPOp = (!j) ? aP[1] : aP[0];
3157 // No paves on the bounds of the curve
3160 // Check if the curve is closed using the tolerance
3162 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
3163 Standard_Real aTolV = BRep_Tool::Tolerance(aV);
3164 gp_Pnt aPV = BRep_Tool::Pnt(aV);
3165 // Tolerance for the point on the curve
3166 Standard_Real aTolP = Max(aNC.Tolerance(), aNC.TangentialTolerance());
3167 aTolP += Precision::Confusion();
3169 const Standard_Real aDistVP = aPV.Distance(aPOp);
3170 if (aDistVP > aTolV + aTolP)
3172 // Curve is not closed
3176 // Check if there will be valid range on the curve
3177 Standard_Real aFirst, aLast;
3178 Standard_Real aNewTolV = Max(aTolV, aDistVP + BOPTools_AlgoTools::DTolerance());
3179 if (!BRepLib::FindValidRange(GeomAdaptor_Curve(aIC.Curve()), aIC.Tolerance(),
3180 aT[0], aP[0], aNewTolV,
3181 aT[1], aP[1], aNewTolV,
3188 if (aNewTolV > aTolV)
3190 Standard_Integer nVn = UpdateVertex(nV, aNewTolV);
3193 aPave.SetIndex(nVn);
3196 aTolV = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV)));
3199 // Add closing pave to the curve
3200 BOPDS_Pave aNewPave;
3201 aNewPave.SetIndex(nV);
3202 aNewPave.SetParameter(aTOp);
3203 aLP.Append(aNewPave);
3206 //=======================================================================
3207 //function : PreparePostTreatFF
3209 //=======================================================================
3210 void BOPAlgo_PaveFiller::PreparePostTreatFF
3211 (const Standard_Integer aInt,
3212 const Standard_Integer aCur,
3213 const Handle(BOPDS_PaveBlock)& aPB,
3214 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
3215 TopTools_DataMapOfShapeInteger& aMVI,
3216 BOPDS_ListOfPaveBlock& aLPBC)
3218 Standard_Integer nV1, nV2;
3222 aPB->Indices(nV1, nV2);
3223 const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
3224 const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
3225 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPB->Edge());
3226 // Keep info for post treatment
3227 BOPDS_CoupleOfPaveBlocks aCPB;
3228 aCPB.SetIndexInterf(aInt);
3229 aCPB.SetIndex(aCur);
3230 aCPB.SetPaveBlock1(aPB);
3232 aMSCPB.Add(aE, aCPB);
3233 aMVI.Bind(aV1, nV1);
3234 aMVI.Bind(aV2, nV2);
3237 //=======================================================================
3238 //function : CheckPlanes
3240 //=======================================================================
3241 Standard_Boolean BOPAlgo_PaveFiller::CheckPlanes
3242 (const Standard_Integer nF1,
3243 const Standard_Integer nF2)const
3245 Standard_Boolean bToIntersect;
3246 Standard_Integer i, nV2, iCnt;
3247 TColStd_MapIteratorOfMapOfInteger aIt;
3249 bToIntersect=Standard_False;
3251 const BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
3252 const BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
3254 const TColStd_MapOfInteger& aMVIn1=aFI1.VerticesIn();
3255 const TColStd_MapOfInteger& aMVOn1=aFI1.VerticesOn();
3258 for (i=0; (i<2 && !bToIntersect); ++i) {
3259 const TColStd_MapOfInteger& aMV2=(!i) ? aFI2.VerticesIn()
3260 : aFI2.VerticesOn();
3262 aIt.Initialize(aMV2);
3263 for (; aIt.More(); aIt.Next()) {
3265 if (aMVIn1.Contains(nV2) || aMVOn1.Contains(nV2)) {
3268 bToIntersect=!bToIntersect;
3275 return bToIntersect;
3277 //=======================================================================
3278 //function : UpdatePaveBlocks
3280 //=======================================================================
3281 void BOPAlgo_PaveFiller::UpdatePaveBlocks
3282 (const TColStd_DataMapOfIntegerInteger& aDMNewSD)
3284 if (aDMNewSD.IsEmpty()) {
3288 Standard_Integer nSp, aNbPBP, nV[2], i, j;
3289 Standard_Real aT[2];
3290 Standard_Boolean bCB, bRebuild;
3291 BOPDS_ListIteratorOfListOfPaveBlock aItPB;
3292 BOPDS_MapOfPaveBlock aMPB;
3293 TColStd_MapOfInteger aMicroEdges;
3295 BOPDS_ListOfPaveBlock anAllPBs;
3297 // Get pave blocks of section edges
3298 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
3299 Standard_Integer aNbFF = aFFs.Length();
3300 for (i = 0; i < aNbFF; ++i)
3302 const BOPDS_InterfFF& aFF = aFFs(i);
3303 const BOPDS_VectorOfCurve& aVNC = aFF.Curves();
3304 Standard_Integer aNbC = aVNC.Length();
3305 for (j = 0; j < aNbC; ++j)
3307 const BOPDS_Curve& aNC = aVNC(j);
3308 const BOPDS_ListOfPaveBlock& aLPBC = aNC.PaveBlocks();
3309 aItPB.Initialize(aLPBC);
3310 for (; aItPB.More(); aItPB.Next())
3311 anAllPBs.Append(aItPB.Value());
3315 // Get pave blocks from the pool
3316 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
3317 aNbPBP = aPBP.Length();
3318 for (i = 0; i < aNbPBP; ++i) {
3319 BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
3320 aItPB.Initialize(aLPB);
3321 for (; aItPB.More(); aItPB.Next())
3322 anAllPBs.Append(aItPB.Value());
3325 // Process all pave blocks
3326 aItPB.Initialize(anAllPBs);
3327 for (; aItPB.More(); aItPB.Next())
3329 Handle(BOPDS_PaveBlock) aPB = aItPB.Value();
3330 const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
3331 bCB = !aCB.IsNull();
3333 aPB = aCB->PaveBlock1();
3336 if (aMPB.Add(aPB)) {
3337 bRebuild = Standard_False;
3338 aPB->Indices(nV[0], nV[1]);
3339 aPB->Range(aT[0], aT[1]);
3340 // remember the fact if the edge had different vertices before substitution
3341 Standard_Boolean wasRegularEdge = (nV[0] != nV[1]);
3343 for (j = 0; j < 2; ++j) {
3344 if (aDMNewSD.IsBound(nV[j])) {
3347 nV[j] = aDMNewSD.Find(nV[j]);
3348 aPave.SetIndex(nV[j]);
3349 aPave.SetParameter(aT[j]);
3351 bRebuild = Standard_True;
3353 aPB->SetPave1(aPave);
3356 aPB->SetPave2(aPave);
3362 Standard_Integer nE = aPB->Edge();
3363 // Check if the Pave Block has the edge set
3366 nE = aPB->OriginalEdge();
3368 Standard_Boolean isDegEdge = myDS->ShapeInfo(nE).HasFlag();
3369 if (wasRegularEdge && !isDegEdge && nV[0] == nV[1]) {
3370 // now edge has the same vertex on both ends;
3371 // check if it is not a regular closed curve.
3372 FillShrunkData(aPB);
3373 if (!aPB->HasShrunkData())
3375 // micro edge, so mark it for removal
3376 aMicroEdges.Add(nE);
3380 nSp = SplitEdge(nE, nV[0], aT[0], nV[1], aT[1]);
3386 }// if (aMPB.Add(aPB)) {
3387 }// for (; aItPB.More(); aItPB.Next()) {
3390 if (aMicroEdges.Extent())
3391 RemovePaveBlocks(aMicroEdges);
3393 //=======================================================================
3394 //function : RemovePaveBlocks
3396 //=======================================================================
3397 void BOPAlgo_PaveFiller::RemovePaveBlocks(const TColStd_MapOfInteger theEdges)
3399 // Remove all pave blocks referring to input edges:
3401 // 1. from the Pave Blocks Pool
3402 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
3403 Standard_Integer aNbPBP = aPBP.Length(), i;
3404 for (i = 0; i < aNbPBP; ++i) {
3405 BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
3407 BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
3408 while (aItPB.More()) {
3409 const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
3410 if (theEdges.Contains(aPB->Edge()))
3417 // 2. from section curves
3418 TColStd_MapOfInteger aMPassed;
3419 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
3420 Standard_Integer aNbFF = aFFs.Length(), j;
3421 for (i = 0; i < aNbFF; ++i) {
3422 BOPDS_InterfFF& aFF = aFFs(i);
3423 // remove from Section pave blocks
3424 BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
3425 Standard_Integer aNbC = aVNC.Length();
3426 for (j = 0; j < aNbC; ++j) {
3427 BOPDS_Curve& aNC = aVNC(j);
3428 BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
3429 BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
3430 while (aItPB.More()) {
3431 const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
3432 if (theEdges.Contains(aPB->Edge()))
3440 // 3. From Face Info
3441 for (i = 0; i < myDS->NbSourceShapes(); ++i)
3443 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
3444 if (aSI.ShapeType() != TopAbs_FACE)
3446 if (!aSI.HasReference())
3449 BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(i);
3450 BOPDS_IndexedMapOfPaveBlock* aIMPB[] = { &aFI.ChangePaveBlocksIn(),
3451 &aFI.ChangePaveBlocksOn(),
3452 &aFI.ChangePaveBlocksSc() };
3453 for (Standard_Integer k = 0; k < 3; k++)
3455 Standard_Integer aNbPB = aIMPB[k]->Extent(), m;
3456 for (m = 1; m <= aNbPB; ++m)
3458 const Handle(BOPDS_PaveBlock)& aPB = aIMPB[k]->FindKey(m);
3459 if (theEdges.Contains(aPB->Edge()))
3464 BOPDS_IndexedMapOfPaveBlock aMPBCopy = *aIMPB[k];
3466 for (m = 1; m <= aNbPB; ++m)
3468 const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(m);
3469 if (!theEdges.Contains(aPB->Edge()))
3477 //=======================================================================
3478 //function : ToleranceFF
3479 //purpose : Computes the TolFF according to the tolerance value and
3480 // types of the faces.
3481 //=======================================================================
3482 Standard_Real ToleranceFF(const BRepAdaptor_Surface& aBAS1,
3483 const BRepAdaptor_Surface& aBAS2)
3485 Standard_Real aTol1 = aBAS1.Tolerance();
3486 Standard_Real aTol2 = aBAS2.Tolerance();
3487 Standard_Real aTolFF = Max(aTol1, aTol2);
3489 Standard_Boolean isAna1, isAna2;
3490 isAna1 = (aBAS1.GetType() == GeomAbs_Plane ||
3491 aBAS1.GetType() == GeomAbs_Cylinder ||
3492 aBAS1.GetType() == GeomAbs_Cone ||
3493 aBAS1.GetType() == GeomAbs_Sphere ||
3494 aBAS1.GetType() == GeomAbs_Torus);
3496 isAna2 = (aBAS2.GetType() == GeomAbs_Plane ||
3497 aBAS2.GetType() == GeomAbs_Cylinder ||
3498 aBAS2.GetType() == GeomAbs_Cone ||
3499 aBAS2.GetType() == GeomAbs_Sphere ||
3500 aBAS2.GetType() == GeomAbs_Torus);
3502 if (!isAna1 || !isAna2) {
3503 aTolFF = Max(aTolFF, 5.e-6);
3507 //=======================================================================
3508 //function : UpdateBlocksWithSharedVertices
3510 //=======================================================================
3511 void BOPAlgo_PaveFiller::UpdateBlocksWithSharedVertices()
3513 if (!myNonDestructive) {
3517 Standard_Integer aNbFF;
3519 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
3520 aNbFF=aFFs.Length();
3525 Standard_Boolean bOnCurve, bHasShapeSD;
3526 Standard_Integer i, nF1, nF2, aNbC, j, nV, nVSD;
3527 Standard_Real aTolV;
3528 TColStd_MapOfInteger aMF;
3530 for (i=0; i<aNbFF; ++i) {
3531 BOPDS_InterfFF& aFF=aFFs(i);
3533 BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
3539 aFF.Indices(nF1, nF2);
3542 myDS->UpdateFaceInfoOn(nF1);
3545 myDS->UpdateFaceInfoOn(nF2);
3548 // Collect old vertices that are shared for nF1, nF2 ->aMI;
3549 TColStd_MapOfInteger aMI;
3550 TColStd_MapIteratorOfMapOfInteger aItMI;
3552 BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
3553 BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
3555 const TColStd_MapOfInteger& aMVOn1=aFI1.VerticesOn();
3556 const TColStd_MapOfInteger& aMVIn1=aFI1.VerticesIn();
3557 const TColStd_MapOfInteger& aMVOn2=aFI2.VerticesOn();
3558 const TColStd_MapOfInteger& aMVIn2=aFI2.VerticesIn();
3560 for (j=0; j<2; ++j) {
3561 const TColStd_MapOfInteger& aMV1=(!j) ? aMVOn1 : aMVIn1;
3562 aItMI.Initialize(aMV1);
3563 for (; aItMI.More(); aItMI.Next()) {
3565 if (myDS->IsNewShape(nV)) {
3568 if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV)) {
3574 // Try to put vertices aMI on curves
3575 for (j=0; j<aNbC; ++j) {
3576 BOPDS_Curve& aNC=aVC.ChangeValue(j);
3577 Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
3579 aItMI.Initialize(aMI);
3580 for (; aItMI.More(); aItMI.Next()) {
3583 bHasShapeSD=myDS->HasShapeSD(nV, nVSD);
3588 bOnCurve=EstimatePaveOnCurve(nV, aNC, aTolR3D);
3593 const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV));
3594 aTolV=BRep_Tool::Tolerance(aV);
3596 UpdateVertex(nV, aTolV);
3597 myDS->InitPaveBlocksForVertex (nV);
3599 }//for (j=0; j<aNbC; ++j) {
3600 }//for (i=0; i<aNbFF; ++i) {
3602 UpdateCommonBlocksWithSDVertices();
3604 //=======================================================================
3605 //function : EstimatePaveOnCurve
3607 //=======================================================================
3608 Standard_Boolean BOPAlgo_PaveFiller::EstimatePaveOnCurve
3609 (const Standard_Integer nV,
3610 const BOPDS_Curve& aNC,
3611 const Standard_Real aTolR3D)
3613 Standard_Boolean bIsVertexOnLine;
3616 const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV));
3617 const IntTools_Curve& aIC=aNC.Curve();
3619 bIsVertexOnLine=myContext->IsVertexOnLine(aV, aIC, aTolR3D, aT);
3620 return bIsVertexOnLine;
3623 //=======================================================================
3624 //function : CorrectToleranceOfSE
3626 //=======================================================================
3627 void BOPAlgo_PaveFiller::CorrectToleranceOfSE()
3629 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
3630 NCollection_IndexedDataMap<Standard_Integer,BOPDS_ListOfPaveBlock> aMVIPBs;
3631 TColStd_MapOfInteger aMVIToReduce;
3632 // Fence map to avoid repeated checking of the same edge
3633 BOPDS_MapOfPaveBlock aMPB;
3635 // 1. iterate on all sections F-F
3636 Standard_Integer aNb = aFFs.Length(), i;
3637 for (i = 0; i < aNb; ++i) {
3638 BOPDS_InterfFF& aFF = aFFs(i);
3640 BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
3641 Standard_Integer aNbC = aVNC.Length(), k;
3642 for (k = 0; k < aNbC; ++k) {
3643 BOPDS_Curve& aNC = aVNC(k);
3644 BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
3645 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
3646 for (; aItLPB.More(); ) {
3647 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
3648 Standard_Integer nE;
3649 if (!aPB->HasEdge(nE)) {
3650 aLPB.Remove(aItLPB);
3654 if (!aMPB.Add(aPB)) {
3659 Standard_Boolean bIsReduced = Standard_False;
3660 if (aPB->OriginalEdge() < 0) {
3661 // It is possible that due to small angle between faces the
3662 // common zone between faces can be large and the tangential
3663 // tolerance of the curve will be large as well.
3664 // Here we're trying to reduce the tolerance of the section
3665 // edge using the valid tolerance of the edge.
3666 // Note, that if the pave block has created common block with
3667 // other edges its valid tolerance could have been changed to
3668 // cover all edges in common block (see PostTreatFF() method).
3669 Standard_Real aTolC = aNC.Tolerance();
3670 Standard_Real aTolTang = aNC.TangentialTolerance();
3671 if (aTolC < aTolTang) {
3672 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
3673 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
3674 if (aTolC < aTolE) {
3675 // reduce edge tolerance
3676 static_cast<BRep_TEdge*>(aE.TShape().get())->Tolerance(aTolC);
3677 bIsReduced = Standard_True;
3682 // fill in the map vertex index - pave blocks
3683 for (Standard_Integer j=0; j < 2; j++) {
3684 Standard_Integer nV = (j == 0 ? aPB->Pave1().Index() : aPB->Pave2().Index());
3685 myDS->HasShapeSD(nV, nV);
3686 BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV);
3688 pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock()));
3690 pPBList->Append(aPB);
3692 aMVIToReduce.Add(nV);
3700 if (aMVIToReduce.IsEmpty()) {
3704 // 2. try to reduce tolerances of connected vertices
3705 // 2.1 find all other edges containing these connected vertices to avoid
3706 // reducing the tolerance to the value less than the tolerances of edges,
3707 // i.e. minimal tolerance for the vertex is the max tolerance of the
3708 // edges containing this vertex
3709 TColStd_DataMapOfIntegerReal aMVITol;
3710 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
3711 aNb = aPBP.Length();
3712 for (i = 0; i < aNb; ++i) {
3713 const BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
3714 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
3715 for (; aItLPB.More(); aItLPB.Next()) {
3716 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
3717 Standard_Integer nE;
3718 if (!aPB->HasEdge(nE)) {
3721 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
3722 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
3724 Standard_Integer nV[2];
3725 aPB->Indices(nV[0], nV[1]);
3727 for (Standard_Integer j = 0; j < 2; j++) {
3728 if (aMVIToReduce.Contains(nV[j])) {
3729 Standard_Real *aMaxTol = aMVITol.ChangeSeek(nV[j]);
3731 aMVITol.Bind(nV[j], aTolE);
3733 else if (aTolE > *aMaxTol) {
3736 BOPDS_ListOfPaveBlock& aPBList = aMVIPBs.ChangeFromKey(nV[j]);
3737 aPBList.Append(aPB);
3743 // 2.2 reduce tolerances if possible
3744 aNb = aMVIPBs.Extent();
3745 for (i = 1; i <= aNb; ++i) {
3746 Standard_Integer nV = aMVIPBs.FindKey(i);
3747 if (!aMVIToReduce.Contains(nV)) {
3751 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
3752 Standard_Real aTolV = BRep_Tool::Tolerance(aV);
3753 Standard_Real aMaxTol = aMVITol.IsBound(nV) ? aMVITol.Find(nV) : 0.;
3754 // it makes no sense to compute the real tolerance if it is
3755 // impossible to reduce the tolerance at least 0.1% of the current value
3756 if (aTolV - aMaxTol < 0.001 * aTolV) {
3760 // compute the maximal distance from the vertex to the adjacent edges
3761 gp_Pnt aP = BRep_Tool::Pnt(aV);
3763 // Avoid repeated checks
3764 BOPDS_MapOfPaveBlock aMPBFence;
3766 const BOPDS_ListOfPaveBlock& aLPB = aMVIPBs.FindFromIndex(i);
3767 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
3768 for (; aItLPB.More(); aItLPB.Next()) {
3769 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
3770 if (!aMPBFence.Add(aPB)) {
3773 Standard_Integer nE = aPB->Edge();
3774 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
3775 BRepAdaptor_Curve aC(aE);
3776 for (Standard_Integer iPave = 0; iPave < 2; ++iPave) {
3777 const BOPDS_Pave& aPave = !iPave ? aPB->Pave1() : aPB->Pave2();
3778 Standard_Integer nVSD = aPave.Index();
3779 myDS->HasShapeSD(nVSD, nVSD);
3784 gp_Pnt aPonE = aC.Value(aPave.Parameter());
3785 Standard_Real aDist = aP.Distance(aPonE);
3786 aDist += BRep_Tool::Tolerance(aE);
3787 if (aDist > aMaxTol) {
3793 if (aMaxTol < aTolV) {
3794 static_cast<BRep_TVertex*>(aV.TShape().get())->Tolerance(aMaxTol);
3799 //=======================================================================
3800 //function : PutSEInOtherFaces
3802 //=======================================================================
3803 void BOPAlgo_PaveFiller::PutSEInOtherFaces(const Message_ProgressRange& theRange)
3805 // Try to intersect each section edge with the faces
3806 // not participated in its creation
3808 // Get all section edges
3809 BOPDS_IndexedMapOfPaveBlock aMPBScAll;
3811 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
3812 const Standard_Integer aNbFF = aFFs.Length();
3813 Message_ProgressScope aPS(theRange, NULL, 1);
3814 for (Standard_Integer i = 0; i < aNbFF; ++i)
3816 const BOPDS_VectorOfCurve& aVNC = aFFs(i).Curves();
3817 const Standard_Integer aNbC = aVNC.Length();
3818 for (Standard_Integer j = 0; j < aNbC; ++j)
3820 const BOPDS_ListOfPaveBlock& aLPBC = aVNC(j).PaveBlocks();
3821 BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPBC);
3822 for (; aItPB.More(); aItPB.Next())
3823 aMPBScAll.Add(aItPB.Value());
3826 // Perform intersection of collected pave blocks
3827 ForceInterfEF(aMPBScAll, aPS.Next(), Standard_False);
3830 //=======================================================================
3831 //function : RemoveMicroSectionEdges
3833 //=======================================================================
3834 void BOPAlgo_PaveFiller::RemoveMicroSectionEdges
3835 (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
3836 BOPDS_IndexedMapOfPaveBlock& theMicroPB)
3838 if (theMSCPB.IsEmpty())
3842 // Get all F/F interferences
3843 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
3845 // Build the new map of section edges avoiding the micro edges
3846 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aSEPBMap;
3847 // Analyze all section edges
3848 Standard_Integer aNbCPB = theMSCPB.Extent();
3849 for (Standard_Integer i = 1; i <= aNbCPB; ++i)
3851 const TopoDS_Shape& aSI = theMSCPB.FindKey(i);
3852 const BOPDS_CoupleOfPaveBlocks& aCPB = theMSCPB(i);
3854 if (aSI.ShapeType() != TopAbs_EDGE)
3857 aSEPBMap.Add(aSI, aCPB);
3861 // Get pave block for analysis
3862 const Handle(BOPDS_PaveBlock)& aPB = aCPB.PaveBlock1();
3865 // Not a real section edge
3866 aSEPBMap.Add(aSI, aCPB);
3870 if (!BOPTools_AlgoTools::IsMicroEdge(TopoDS::Edge(aSI), myContext, Standard_False))
3873 aSEPBMap.Add(aSI, aCPB);
3877 // Micro edge is found, avoid it in the <theMSCPB> map
3878 // and remove from the F/F Intersection info structure
3880 // Get F/F interference which created this micro edge
3881 BOPDS_InterfFF& aFF = aFFs(aCPB.IndexInterf());
3882 // Get curve from which this edge has been created
3883 BOPDS_Curve& aCurve = aFF.ChangeCurves().ChangeValue(aCPB.Index());
3884 // Get all section pave blocks created from this curve
3885 BOPDS_ListOfPaveBlock& aLPBC = aCurve.ChangePaveBlocks();
3886 // Remove pave block from the list
3887 for (BOPDS_ListIteratorOfListOfPaveBlock it(aLPBC); it.More(); it.Next())
3889 if (it.Value() == aPB)
3896 // Add the pave block of "micro" edge into outgoing map for
3897 // unification of its vertices in the PostTreatFF method
3898 theMicroPB.Add(aPB);
3901 // Overwrite the old map if necessary
3902 if (aSEPBMap.Extent() != theMSCPB.Extent())
3903 theMSCPB = aSEPBMap;
3906 //=======================================================================
3907 //function : RemoveMicroEdges
3909 //=======================================================================
3910 void BOPAlgo_PaveFiller::RemoveMicroEdges()
3913 BOPDS_MapOfPaveBlock aMPBFence;
3914 // Resulting map of micro edges
3915 TColStd_MapOfInteger aMicroEdges;
3916 // Check all pave blocks from the pool to find the micro edges
3917 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
3918 Standard_Integer aNbPBP = aPBP.Length();
3919 for (Standard_Integer i = 0; i < aNbPBP; ++i)
3921 BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
3922 if (aLPB.Extent() < 2)
3926 if (myDS->ShapeInfo(aLPB.First()->OriginalEdge()).HasFlag())
3929 BOPDS_ListOfPaveBlock::Iterator it(aLPB);
3930 for (; it.More(); it.Next())
3932 const Handle(BOPDS_PaveBlock)& aPB = it.Value();
3933 Handle(BOPDS_PaveBlock) aPBR = myDS->RealPaveBlock(aPB);
3935 if (aMPBFence.Add(aPBR))
3937 Standard_Integer nV1, nV2;
3938 aPBR->Indices(nV1, nV2);
3941 // Check if it has the valid range
3942 FillShrunkData(aPBR);
3943 if (!aPBR->HasShrunkData())
3944 aMicroEdges.Add(aPBR->Edge());
3949 RemovePaveBlocks(aMicroEdges);