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_CommonBlock.hxx>
24 #include <BOPDS_CoupleOfPaveBlocks.hxx>
25 #include <BOPDS_Curve.hxx>
26 #include <BOPDS_DataMapOfPaveBlockListOfPaveBlock.hxx>
27 #include <BOPDS_DS.hxx>
28 #include <BOPDS_FaceInfo.hxx>
29 #include <BOPDS_Interf.hxx>
30 #include <BOPDS_Iterator.hxx>
31 #include <BOPDS_ListOfPave.hxx>
32 #include <BOPDS_ListOfPaveBlock.hxx>
33 #include <BOPDS_MapOfPaveBlock.hxx>
34 #include <BOPDS_PaveBlock.hxx>
35 #include <BOPDS_Point.hxx>
36 #include <BOPDS_ShapeInfo.hxx>
37 #include <BOPDS_VectorOfCurve.hxx>
38 #include <BOPDS_VectorOfPoint.hxx>
39 #include <BOPTools_AlgoTools.hxx>
40 #include <BOPTools_AlgoTools3D.hxx>
41 #include <BOPTools_Parallel.hxx>
42 #include <BRep_Builder.hxx>
43 #include <BRep_TEdge.hxx>
44 #include <BRep_Tool.hxx>
45 #include <BRepAdaptor_Curve.hxx>
46 #include <BRepAdaptor_Surface.hxx>
47 #include <BRepBndLib.hxx>
48 #include <BRepBuilderAPI_MakeVertex.hxx>
49 #include <BRepLib.hxx>
50 #include <BRepTools.hxx>
51 #include <Geom_Curve.hxx>
52 #include <Geom2d_Curve.hxx>
53 #include <GeomAPI_ProjectPointOnCurve.hxx>
54 #include <GeomAPI_ProjectPointOnSurf.hxx>
56 #include <IntSurf_ListOfPntOn2S.hxx>
57 #include <IntSurf_PntOn2S.hxx>
58 #include <IntTools.hxx>
59 #include <IntTools_Context.hxx>
60 #include <IntTools_Curve.hxx>
61 #include <IntTools_EdgeFace.hxx>
62 #include <IntTools_FaceFace.hxx>
63 #include <IntTools_PntOn2Faces.hxx>
64 #include <IntTools_SequenceOfCurves.hxx>
65 #include <IntTools_SequenceOfPntOn2Faces.hxx>
66 #include <IntTools_ShrunkRange.hxx>
67 #include <IntTools_Tools.hxx>
68 #include <NCollection_Vector.hxx>
69 #include <Precision.hxx>
70 #include <TColStd_ListOfInteger.hxx>
71 #include <TColStd_MapOfInteger.hxx>
73 #include <TopExp_Explorer.hxx>
75 #include <TopoDS_Compound.hxx>
76 #include <TopoDS_Edge.hxx>
77 #include <TopoDS_Face.hxx>
78 #include <TopoDS_Vertex.hxx>
79 #include <TopTools_DataMapOfShapeInteger.hxx>
80 #include <TopTools_ListOfShape.hxx>
83 static Standard_Real ToleranceFF(const BRepAdaptor_Surface& aBAS1,
84 const BRepAdaptor_Surface& aBAS2);
86 /////////////////////////////////////////////////////////////////////////
87 //=======================================================================
88 //class : BOPAlgo_FaceFace
90 //=======================================================================
91 class BOPAlgo_FaceFace :
92 public IntTools_FaceFace,
101 myIF1(-1), myIF2(-1), myTolFF(1.e-7) {
104 virtual ~BOPAlgo_FaceFace() {
107 void SetIndices(const Standard_Integer nF1,
108 const Standard_Integer nF2) {
113 void Indices(Standard_Integer& nF1,
114 Standard_Integer& nF2) const {
119 void SetFaces(const TopoDS_Face& aF1,
120 const TopoDS_Face& aF2) {
125 const TopoDS_Face& Face1()const {
129 const TopoDS_Face& Face2()const {
133 void SetTolFF(const Standard_Real aTolFF) {
137 Standard_Real TolFF() const{
141 void SetFuzzyValue(const Standard_Real theFuzz) {
142 IntTools_FaceFace::SetFuzzyValue(theFuzz);
145 virtual void Perform() {
146 BOPAlgo_Algo::UserBreak();
151 IntTools_FaceFace::Perform(myF1, myF2);
153 catch (Standard_Failure)
155 AddError(new BOPAlgo_AlertIntersectionFailed);
160 Standard_Integer myIF1;
161 Standard_Integer myIF2;
162 Standard_Real myTolFF;
167 //=======================================================================
168 typedef NCollection_Vector
169 <BOPAlgo_FaceFace> BOPAlgo_VectorOfFaceFace;
171 typedef BOPTools_Functor
173 BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceFunctor;
176 <BOPAlgo_FaceFaceFunctor,
177 BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceCnt;
178 /////////////////////////////////////////////////////////////////////////
179 //=======================================================================
180 //function : PerformFF
182 //=======================================================================
183 void BOPAlgo_PaveFiller::PerformFF()
185 myIterator->Initialize(TopAbs_FACE, TopAbs_FACE);
186 Standard_Integer iSize = myIterator->ExpectedLength();
191 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
192 aFFs.SetIncrement(iSize);
194 // Options for the intersection algorithm
195 Standard_Boolean bApprox = mySectionAttribute.Approximation(),
196 bCompC2D1 = mySectionAttribute.PCurveOnS1(),
197 bCompC2D2 = mySectionAttribute.PCurveOnS2();
198 Standard_Real anApproxTol = 1.e-7;
199 // Post-processing options
200 Standard_Boolean bSplitCurve = Standard_False;
202 // Fence map to store faces with updated FaceInfo structure
203 TColStd_MapOfInteger aMIFence;
204 // Prepare the pairs of faces for intersection
205 BOPAlgo_VectorOfFaceFace aVFaceFace;
206 Standard_Integer nF1, nF2;
208 for (; myIterator->More(); myIterator->Next()) {
209 myIterator->Value(nF1, nF2);
211 // Update/Initialize FaceInfo structure for first face
212 if (myDS->HasFaceInfo(nF1))
214 if (aMIFence.Add(nF1))
216 myDS->UpdateFaceInfoOn(nF1);
217 myDS->UpdateFaceInfoIn(nF1);
220 else if (myDS->HasInterfShapeSubShapes(nF2, nF1))
222 myDS->ChangeFaceInfo(nF1);
226 // Update/Initialize FaceInfo structure for second face
227 if (myDS->HasFaceInfo(nF2))
229 if (aMIFence.Add(nF2))
231 myDS->UpdateFaceInfoOn(nF2);
232 myDS->UpdateFaceInfoIn(nF2);
235 else if (myDS->HasInterfShapeSubShapes(nF1, nF2))
237 myDS->ChangeFaceInfo(nF2);
241 if (myGlue == BOPAlgo_GlueOff)
243 const TopoDS_Face& aF1 = (*(TopoDS_Face *)(&myDS->Shape(nF1)));
244 const TopoDS_Face& aF2 = (*(TopoDS_Face *)(&myDS->Shape(nF2)));
246 const BRepAdaptor_Surface& aBAS1 = myContext->SurfaceAdaptor(aF1);
247 const BRepAdaptor_Surface& aBAS2 = myContext->SurfaceAdaptor(aF2);
248 if (aBAS1.GetType() == GeomAbs_Plane &&
249 aBAS2.GetType() == GeomAbs_Plane) {
250 // Check if the planes are really interfering
251 Standard_Boolean bToIntersect = CheckPlanes(nF1, nF2);
253 BOPDS_InterfFF& aFF = aFFs.Appended();
254 aFF.SetIndices(nF1, nF2);
260 BOPAlgo_FaceFace& aFaceFace=aVFaceFace.Appended();
262 aFaceFace.SetIndices(nF1, nF2);
263 aFaceFace.SetFaces(aF1, aF2);
264 // compute minimal tolerance for the curves
265 Standard_Real aTolFF = ToleranceFF(aBAS1, aBAS2);
266 aFaceFace.SetTolFF(aTolFF);
268 IntSurf_ListOfPntOn2S aListOfPnts;
269 GetEFPnts(nF1, nF2, aListOfPnts);
270 Standard_Integer aNbLP = aListOfPnts.Extent();
272 aFaceFace.SetList(aListOfPnts);
275 aFaceFace.SetParameters(bApprox, bCompC2D1, bCompC2D2, anApproxTol);
276 aFaceFace.SetFuzzyValue(myFuzzyValue);
277 aFaceFace.SetProgressIndicator(myProgressIndicator);
280 // for the Glue mode just add all interferences of that type
281 BOPDS_InterfFF& aFF = aFFs.Appended();
282 aFF.SetIndices(nF1, nF2);
283 aFF.SetTangentFaces(Standard_False);
286 }//for (; myIterator->More(); myIterator->Next()) {
288 //======================================================
289 // Perform intersection
290 BOPAlgo_FaceFaceCnt::Perform(myRunParallel, aVFaceFace);
291 //======================================================
292 // Treatment of the results
293 Standard_Integer k, aNbFaceFace = aVFaceFace.Length();
294 for (k = 0; k < aNbFaceFace; ++k) {
295 BOPAlgo_FaceFace& aFaceFace = aVFaceFace(k);
296 aFaceFace.Indices(nF1, nF2);
297 if (!aFaceFace.IsDone() || aFaceFace.HasErrors()) {
298 BOPDS_InterfFF& aFF = aFFs.Appended();
299 aFF.SetIndices(nF1, nF2);
301 // Warn about failed intersection of faces
302 AddIntersectionFailedWarning(aFaceFace.Face1(), aFaceFace.Face2());
306 Standard_Boolean bTangentFaces = aFaceFace.TangentFaces();
307 Standard_Real aTolFF = aFaceFace.TolFF();
309 aFaceFace.PrepareLines3D(bSplitCurve);
311 const IntTools_SequenceOfCurves& aCvsX = aFaceFace.Lines();
312 const IntTools_SequenceOfPntOn2Faces& aPntsX = aFaceFace.Points();
314 Standard_Integer aNbCurves = aCvsX.Length();
315 Standard_Integer aNbPoints = aPntsX.Length();
317 if (aNbCurves || aNbPoints) {
318 myDS->AddInterf(nF1, nF2);
321 BOPDS_InterfFF& aFF = aFFs.Appended();
322 aFF.SetIndices(nF1, nF2);
323 aFF.SetTangentFaces(bTangentFaces);
324 aFF.Init(aNbCurves, aNbPoints);
327 // Fix bounding box expanding coefficient.
328 Standard_Real aBoxExpandValue = aTolFF;
331 // Modify geometric expanding coefficient by topology value,
332 // since this bounding box used in sharing (vertex or edge).
333 Standard_Real aMaxVertexTol = Max(BRep_Tool::MaxTolerance(aFaceFace.Face1(), TopAbs_VERTEX),
334 BRep_Tool::MaxTolerance(aFaceFace.Face2(), TopAbs_VERTEX));
335 aBoxExpandValue += aMaxVertexTol;
338 BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
339 for (Standard_Integer i = 1; i <= aNbCurves; ++i) {
341 const IntTools_Curve& aIC = aCvsX(i);
342 Standard_Boolean bIsValid = IntTools_Tools::CheckCurve(aIC, aBox);
344 BOPDS_Curve& aNC = aVNC.Appended();
346 // make sure that the bounding box has the maximal gap
347 aBox.Enlarge(aBoxExpandValue);
349 aNC.SetTolerance(Max(aIC.Tolerance(), aTolFF));
354 BOPDS_VectorOfPoint& aVNP = aFF.ChangePoints();
355 for (Standard_Integer i = 1; i <= aNbPoints; ++i) {
356 const IntTools_PntOn2Faces& aPi = aPntsX(i);
357 const gp_Pnt& aP = aPi.P1().Pnt();
359 BOPDS_Point& aNP = aVNP.Appended();
364 //=======================================================================
365 //function : MakeBlocks
367 //=======================================================================
368 void BOPAlgo_PaveFiller::MakeBlocks()
370 if (myGlue != BOPAlgo_GlueOff) {
374 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
375 Standard_Integer aNbFF = aFFs.Length();
380 Standard_Boolean bExist, bValid2D;
381 Standard_Integer i, nF1, nF2, aNbC, aNbP, j;
382 Standard_Integer nV1, nV2;
383 Standard_Real aT1, aT2;
384 Handle(NCollection_BaseAllocator) aAllocator;
385 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
387 Handle(BOPDS_PaveBlock) aPBOut;
389 //-----------------------------------------------------scope f
391 NCollection_BaseAllocator::CommonBaseAllocator();
393 TColStd_ListOfInteger aLSE(aAllocator), aLBV(aAllocator);
394 TColStd_MapOfInteger aMVOnIn(100, aAllocator), aMVCommon(100, aAllocator),
395 aMVStick(100,aAllocator), aMVEF(100, aAllocator),
396 aMI(100, aAllocator), aMVBounds(100, aAllocator);
397 BOPDS_IndexedMapOfPaveBlock aMPBOnIn(100, aAllocator);
398 BOPDS_MapOfPaveBlock aMPBAdd(100, aAllocator), aMPBCommon;
399 BOPDS_ListOfPaveBlock aLPB(aAllocator);
400 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMSCPB(100, aAllocator);
401 TopTools_DataMapOfShapeInteger aMVI(100, aAllocator);
402 BOPDS_DataMapOfPaveBlockListOfPaveBlock aDMExEdges(100, aAllocator);
403 TColStd_DataMapOfIntegerReal aMVTol(100, aAllocator);
404 TColStd_DataMapOfIntegerInteger aDMNewSD(100, aAllocator);
405 TColStd_DataMapOfIntegerListOfInteger aDMVLV;
406 TColStd_DataMapOfIntegerListOfInteger aDMBV(100, aAllocator);
407 TColStd_DataMapIteratorOfDataMapOfIntegerReal aItMV;
408 TopTools_IndexedMapOfShape aMicroEdges(100, aAllocator);
409 TopTools_IndexedMapOfShape aVertsOnRejectedPB;
411 for (i=0; i<aNbFF; ++i) {
415 BOPDS_InterfFF& aFF=aFFs(i);
416 aFF.Indices(nF1, nF2);
418 BOPDS_VectorOfPoint& aVP=aFF.ChangePoints();
420 BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
422 if (!aNbP && !aNbC) {
426 const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
427 const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
429 Standard_Real aTolFF = Max(BRep_Tool::Tolerance(aF1), BRep_Tool::Tolerance(aF2));
431 BOPDS_FaceInfo& aFI1 = myDS->ChangeFaceInfo(nF1);
432 BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2);
442 myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMVCommon, aMPBOnIn, aMPBCommon);
443 myDS->SharedEdges(nF1, nF2, aLSE, aAllocator);
445 Standard_Boolean bHasRealSectionEdge = Standard_False;
447 for (j=0; j<aNbP; ++j) {
449 BOPDS_CoupleOfPaveBlocks aCPB;
451 BOPDS_Point& aNP=aVP.ChangeValue(j);
452 const gp_Pnt& aP=aNP.Pnt();
454 bExist=IsExistingVertex(aP, aTolFF, aMVOnIn);
456 BOPTools_AlgoTools::MakeNewVertex(aP, aTolFF, aV);
458 aCPB.SetIndexInterf(i);
460 aMSCPB.Add(aV, aCPB);
467 GetStickVertices(nF1, nF2, aMVStick, aMVEF, aMI);
469 for (j = 0; j < aNbC; ++j) {
470 BOPDS_Curve& aNC = aVC.ChangeValue(j);
472 aNC.InitPaveBlock1();
474 // In order to avoid problems connected with
475 // extending tolerance of vertex while putting
476 // (e.g. see "bugs modalg_6 bug26789_1" test case),
477 // all not-common vertices will be checked by
478 // BndBoxes before putting. For common-vertices,
479 // filtering by BndBoxes is not necessary.
480 PutPavesOnCurve(aMVOnIn, aMVCommon, aNC, aMI, aMVEF, aMVTol, aDMVLV);
483 // if some E-F vertex was put on a curve due to large E-F intersection range,
484 // and it also was put on another curve correctly then remove this vertex from
485 // the first curve. Detect such case if the distance to curve exceeds aTolR3D.
486 FilterPavesOnCurves(aVC);
488 for (j = 0; j<aNbC; ++j) {
489 BOPDS_Curve& aNC=aVC.ChangeValue(j);
490 const IntTools_Curve& aIC=aNC.Curve();
492 PutStickPavesOnCurve(aF1, aF2, aMI, aNC, aMVStick, aMVTol, aDMVLV);
495 PutEFPavesOnCurve(aNC, aMI, aMVEF, aMVTol, aDMVLV);
498 if (aIC.HasBounds()) {
501 PutBoundPaveOnCurve(aF1, aF2, aNC, aLBV);
503 if (!aLBV.IsEmpty()) {
505 TColStd_ListIteratorOfListOfInteger aItI(aLBV);
506 for (; aItI.More(); aItI.Next()) {
507 aMVBounds.Add(aItI.Value());
511 }//for (j=0; j<aNbC; ++j) {
513 // Put closing pave if needed
514 for (j=0; j<aNbC; ++j) {
515 BOPDS_Curve& aNC=aVC.ChangeValue(j);
516 PutClosingPaveOnCurve (aNC);
519 // 3. Make section edges
520 for (j=0; j<aNbC; ++j) {
521 BOPDS_Curve& aNC=aVC.ChangeValue(j);
522 const IntTools_Curve& aIC=aNC.Curve();
523 Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
525 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
526 Handle(BOPDS_PaveBlock)& aPB1=aNC.ChangePaveBlock1();
529 aPB1->Update(aLPB, Standard_False);
531 aItLPB.Initialize(aLPB);
532 for (; aItLPB.More(); aItLPB.Next()) {
533 Handle(BOPDS_PaveBlock)& aPB=aItLPB.ChangeValue();
534 aPB->Indices(nV1, nV2);
535 aPB->Range (aT1, aT2);
537 if (fabs(aT1 - aT2) < Precision::PConfusion()) {
541 bValid2D=myContext->IsValidBlockForFaces(aT1, aT2, aIC,
547 bExist=IsExistingPaveBlock(aPB, aNC, aLSE);
552 const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
553 const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
556 BOPTools_AlgoTools::MakeEdge (aIC, aV1, aT1, aV2, aT2, aTolR3D, aES);
558 // check for micro edge
559 if (BOPTools_AlgoTools::IsMicroEdge(aES, myContext, Standard_False)) {
560 // If the section edge is a micro edge, i.e. the whole edge is
561 // covered by the tolerance spheres of its vertices, it will be
562 // passed into post treatment process to fuse its vertices.
563 // The edge itself will not be kept.
564 if (!aMVBounds.Contains(nV1) && !aMVBounds.Contains(nV2)) {
565 aMicroEdges.Add(aES);
566 // keep vertices for post treatment
573 Standard_Real aTolNew;
574 bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aMPBCommon, aPBOut, aTolNew);
576 if (!aMPBAdd.Contains(aPBOut)) {
577 Standard_Boolean bInBothFaces = Standard_True;
578 if (!myDS->IsCommonBlock(aPBOut)) {
583 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(nE);
584 aTolE = BRep_Tool::Tolerance(aE);
585 if (aTolNew < aNC.Tolerance())
586 aTolNew = aNC.Tolerance(); // use real tolerance of intersection
587 if (aTolNew > aTolE) {
588 UpdateEdgeTolerance(nE, aTolNew);
590 bInBothFaces = Standard_False;
593 bInBothFaces = (aFI1.PaveBlocksOn().Contains(aPBOut) ||
594 aFI1.PaveBlocksIn().Contains(aPBOut))&&
595 (aFI2.PaveBlocksOn().Contains(aPBOut) ||
596 aFI2.PaveBlocksIn().Contains(aPBOut));
600 PreparePostTreatFF(i, j, aPBOut, aMSCPB, aMVI, aLPBC);
601 // Try fusing the vertices of the existing pave block
602 // with the vertices put on the real section curve (except
603 // for technological vertices, which will be removed)
604 Standard_Integer nVOut1, nVOut2;
605 aPBOut->Indices(nVOut1, nVOut2);
606 if (nV1 != nVOut1 && nV1 != nVOut2 && !aMVBounds.Contains(nV1))
608 aVertsOnRejectedPB.Add(aV1);
610 if (nV2 != nVOut1 && nV2 != nVOut2 && !aMVBounds.Contains(nV2))
612 aVertsOnRejectedPB.Add(aV2);
620 BOPTools_AlgoTools::MakePCurve(aES, aF1, aF2, aIC,
621 mySectionAttribute.PCurveOnS1(),
622 mySectionAttribute.PCurveOnS2(),
625 // Append the Pave Block to the Curve j
628 // Keep info for post treatment
629 BOPDS_CoupleOfPaveBlocks aCPB;
630 aCPB.SetIndexInterf(i);
632 aCPB.SetPaveBlock1(aPB);
634 aMSCPB.Add(aES, aCPB);
641 bHasRealSectionEdge = Standard_True;
645 }//for (j=0; j<aNbC; ++j) {
647 //back to previous tolerance values for unused vertices
648 //and forget about SD groups of such vertices
649 aItMV.Initialize(aMVTol);
650 for (; aItMV.More(); aItMV.Next()) {
652 Standard_Real aTol = aItMV.Value();
654 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV1);
655 const Handle(BRep_TVertex)& TV =
656 *((Handle(BRep_TVertex)*)&aV.TShape());
659 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV1);
660 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
662 BRepBndLib::Add(aV, aBoxDS);
663 aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
665 if (aDMVLV.IsBound(nV1))
669 ProcessExistingPaveBlocks(i, aMPBOnIn, aDMBV, aMSCPB, aMVI, aMPBAdd);
671 // If the pair of faces has produced any real section edges
672 // it is necessary to check if these edges do not intersect
673 // any common IN edges of the faces. For that, all such edges
674 // are added for Post Treatment along with sections edges.
675 if (bHasRealSectionEdge) {
676 const BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.PaveBlocksIn();
677 const BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.PaveBlocksIn();
679 // For simplicity add all IN edges into the first set of section curves.
680 // These existing edges will be removed from the set on the post treatment
681 // stage in the UpdateFaceInfo function.
682 BOPDS_ListOfPaveBlock& aLPBC = aVC.ChangeValue(0).ChangePaveBlocks();
684 Standard_Integer aNbIn1 = aMPBIn1.Extent();
685 for (j = 1; j <= aNbIn1; ++j) {
686 const Handle(BOPDS_PaveBlock)& aPB = aMPBIn1(j);
687 if (aMPBIn2.Contains(aPB) && aMPBAdd.Add(aPB)) {
688 PreparePostTreatFF(i, 0, aPB, aMSCPB, aMVI, aLPBC);
692 }//for (i=0; i<aNbFF; ++i) {
694 // Remove "micro" section edges
695 RemoveMicroSectionEdges(aMSCPB, aMicroEdges);
698 MakeSDVerticesFF(aDMVLV, aDMNewSD);
699 PostTreatFF(aMSCPB, aDMExEdges, aDMNewSD, aMicroEdges, aVertsOnRejectedPB, aAllocator);
703 // reduce tolerances of section edges where it is appropriate
704 CorrectToleranceOfSE();
707 UpdateFaceInfo(aDMExEdges, aDMNewSD);
708 //Update all pave blocks
709 UpdatePaveBlocks(aDMNewSD);
711 // Treat possible common zones by trying to put each section edge
712 // into all faces, not participated in creation of that edge, as IN edge
715 //-----------------------------------------------------scope t
725 //=======================================================================
726 //function : MakeSDVerticesFF
728 //=======================================================================
729 void BOPAlgo_PaveFiller::MakeSDVerticesFF
730 (const TColStd_DataMapOfIntegerListOfInteger& theDMVLV,
731 TColStd_DataMapOfIntegerInteger& theDMNewSD)
733 // Create a new SD vertex for each group of coinciding vertices
734 // and put new substitutions to theDMNewSD.
735 TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger aItG(theDMVLV);
736 for (; aItG.More(); aItG.Next()) {
737 const TColStd_ListOfInteger& aList = aItG.Value();
738 // make SD vertices w/o creation of interfs
739 Standard_Integer nSD = MakeSDVertices(aList, Standard_False);
741 TColStd_ListIteratorOfListOfInteger aItL(aList);
742 for (; aItL.More(); aItL.Next()) {
743 Standard_Integer nV = aItL.Value();
744 theDMNewSD.Bind(nV, nSD);
749 //=======================================================================
750 //function : PostTreatFF
752 //=======================================================================
753 void BOPAlgo_PaveFiller::PostTreatFF
754 (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
755 BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges,
756 TColStd_DataMapOfIntegerInteger& aDMNewSD,
757 const TopTools_IndexedMapOfShape& theMicroEdges,
758 const TopTools_IndexedMapOfShape& theVertsOnRejectedPB,
759 const Handle(NCollection_BaseAllocator)& theAllocator)
761 Standard_Integer aNbS = theMSCPB.Extent();
766 Standard_Boolean bHasPaveBlocks, bOld;
767 Standard_Integer nSx, nVSD, iX, iP, iC, j, nV, iV = 0, iE, k;
768 Standard_Integer aNbLPBx;
769 TopAbs_ShapeEnum aType;
771 TopTools_ListIteratorOfListOfShape aItLS;
772 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
774 Handle(BOPDS_PaveBlock) aPB1;
778 TopTools_ListOfShape aLS(theAllocator);
779 BOPAlgo_PaveFiller aPF(theAllocator);
780 aPF.SetIsPrimary(Standard_False);
781 aPF.SetNonDestructive(myNonDestructive);
783 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
785 Standard_Integer aNbME = theMicroEdges.Extent();
786 Standard_Integer aNbVOnRPB = theVertsOnRejectedPB.Extent();
788 if (aNbS==1 && (aNbME == 0) && (aNbVOnRPB == 0)) {
789 const TopoDS_Shape& aS=theMSCPB.FindKey(1);
790 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromIndex(1);
792 aType=aS.ShapeType();
793 if (aType==TopAbs_VERTEX) {
794 aSI.SetShapeType(aType);
796 iV=myDS->Append(aSI);
798 iX=aCPB.IndexInterf();
800 BOPDS_InterfFF& aFF=aFFs(iX);
801 BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
802 BOPDS_Point& aNP=aVNP(iP);
805 else if (aType==TopAbs_EDGE) {
806 aPB1=aCPB.PaveBlock1();
808 if (aPB1->HasEdge()) {
809 BOPDS_ListOfPaveBlock aLPBx;
811 aDMExEdges.Bind(aPB1, aLPBx);
813 aSI.SetShapeType(aType);
815 iE=myDS->Append(aSI);
823 // 1 prepare arguments
824 TopTools_MapOfShape anAddedSD;
825 for (k=1; k<=aNbS; ++k) {
826 const TopoDS_Shape& aS=theMSCPB.FindKey(k);
828 // add vertices-candidates for SD from the map aDMNewSD,
829 // so that they took part in fuse operation.
830 TopoDS_Iterator itV(aS);
831 for (; itV.More(); itV.Next())
833 const TopoDS_Shape& aVer = itV.Value();
834 Standard_Integer iVer = myDS->Index(aVer);
835 const Standard_Integer* pSD = aDMNewSD.Seek(iVer);
838 const TopoDS_Shape& aVSD = myDS->Shape(*pSD);
839 if (anAddedSD.Add(aVSD))
845 // The section edges considered as a micro should be
846 // specially treated - their vertices should be united and
847 // the edge itself should be removed. Thus, we add only
848 // its vertices into operation.
851 for (k = 1; k <= aNbME; ++k) {
852 const TopoDS_Edge& aEM = TopoDS::Edge(theMicroEdges(k));
854 TopoDS_Vertex aVerts[2];
855 TopExp::Vertices(aEM, aVerts[0], aVerts[1]);
856 for (Standard_Integer i = 0; i < 2; ++i) {
857 nV = myDS->Index(aVerts[i]);
858 const Standard_Integer* pSD = aDMNewSD.Seek(nV);
860 aVerts[i] = TopoDS::Vertex(myDS->Shape(*pSD));
863 if (anAddedSD.Add(aVerts[i])) {
864 aLS.Append(aVerts[i]);
868 if (aVerts[0].IsSame(aVerts[1])) {
872 // make sure these vertices will be united
873 const gp_Pnt& aP1 = BRep_Tool::Pnt(aVerts[0]);
874 const gp_Pnt& aP2 = BRep_Tool::Pnt(aVerts[1]);
876 Standard_Real aDist = aP1.Distance(aP2);
877 Standard_Real aTolV1 = BRep_Tool::Tolerance(aVerts[0]);
878 Standard_Real aTolV2 = BRep_Tool::Tolerance(aVerts[1]);
880 aDist -= (aTolV1 + aTolV2);
883 aBB.UpdateVertex(aVerts[0], aTolV1 + aDist);
884 aBB.UpdateVertex(aVerts[1], aTolV2 + aDist);
888 // Add vertices put on the real section curves to unify them with the
889 // vertices of the edges, by which these sections curves have been rejected
890 for (Standard_Integer i = 1; i <= aNbVOnRPB; ++i)
892 TopoDS_Shape aVer = theVertsOnRejectedPB(i);
893 Standard_Integer iVer = myDS->Index(aVer);
894 const Standard_Integer* pSD = aDMNewSD.Seek(iVer);
896 aVer = myDS->Shape(*pSD);
898 if (anAddedSD.Add(aVer))
903 aPF.SetProgressIndicator(myProgressIndicator);
904 aPF.SetRunParallel(myRunParallel);
905 aPF.SetArguments(aLS);
907 if (aPF.HasErrors()) {
908 AddError (new BOPAlgo_AlertPostTreatFF);
913 // Map to store the real tolerance of the common block
914 // and avoid repeated computation of it
915 NCollection_DataMap<Handle(BOPDS_CommonBlock),
917 TColStd_MapTransientHasher> aMCBTol;
918 // Map to avoid creation of different pave blocks for
919 // the same intersection edge
920 NCollection_DataMap<Standard_Integer, Handle(BOPDS_PaveBlock)> aMEPB;
922 aItLS.Initialize(aLS);
923 for (; aItLS.More(); aItLS.Next()) {
924 const TopoDS_Shape& aSx=aItLS.Value();
925 nSx=aPDS->Index(aSx);
926 const BOPDS_ShapeInfo& aSIx=aPDS->ShapeInfo(nSx);
928 aType=aSIx.ShapeType();
930 if (aType==TopAbs_VERTEX) {
931 Standard_Boolean bIntersectionPoint = theMSCPB.Contains(aSx);
933 if (aPDS->HasShapeSD(nSx, nVSD)) {
934 aV=aPDS->Shape(nVSD);
939 // index of new vertex in theDS -> iV
940 iV = myDS->Index(aV);
942 aSI.SetShapeType(aType);
944 iV=myDS->Append(aSI);
947 if (!bIntersectionPoint) {
948 // save SD connection
949 nSx = myDS->Index(aSx);
950 aDMNewSD.Bind(nSx, iV);
951 myDS->AddShapeSD(nSx, iV);
954 // update FF interference
955 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
956 iX=aCPB.IndexInterf();
958 BOPDS_InterfFF& aFF=aFFs(iX);
959 BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
960 BOPDS_Point& aNP=aVNP(iP);
963 }//if (aType==TopAbs_VERTEX) {
965 else if (aType==TopAbs_EDGE) {
966 bHasPaveBlocks=aPDS->HasPaveBlocks(nSx);
967 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
968 iX=aCPB.IndexInterf();
970 aPB1=aCPB.PaveBlock1();
972 bOld = aPB1->HasEdge();
974 BOPDS_ListOfPaveBlock aLPBx;
975 aDMExEdges.Bind(aPB1, aLPBx);
978 if (!bHasPaveBlocks) {
980 aDMExEdges.ChangeFind(aPB1).Append(aPB1);
983 aSI.SetShapeType(aType);
985 iE = myDS->Append(aSI);
991 BOPDS_InterfFF& aFF=aFFs(iX);
992 BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
993 BOPDS_Curve& aNC=aVNC(iC);
994 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
996 // check if edge occured to be micro edge;
997 // note we check not the edge aSx itself, but its image in aPDS
998 const BOPDS_ListOfPaveBlock& aLPBx = aPDS->PaveBlocks(nSx);
999 aNbLPBx = aLPBx.Extent();
1000 if (aPDS->HasPaveBlocks(nSx) &&
1001 (aNbLPBx == 0 || (aNbLPBx == 1 && !aLPBx.First()->HasShrunkData()))) {
1002 BOPDS_ListIteratorOfListOfPaveBlock it(aLPBC);
1003 for (; it.More(); it.Next()) {
1004 if (it.Value() == aPB1) {
1012 if (bOld && !aNbLPBx) {
1013 aDMExEdges.ChangeFind(aPB1).Append(aPB1);
1018 aItLPB.Initialize(aLPBC);
1019 for (; aItLPB.More(); aItLPB.Next()) {
1020 const Handle(BOPDS_PaveBlock)& aPBC=aItLPB.Value();
1022 aLPBC.Remove(aItLPB);
1029 aItLPB.Initialize(aLPBx);
1030 for (; aItLPB.More(); aItLPB.Next()) {
1031 const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
1032 const Handle(BOPDS_PaveBlock) aPBRx=aPDS->RealPaveBlock(aPBx);
1034 // update vertices of paves
1035 aPave[0] = aPBx->Pave1();
1036 aPave[1] = aPBx->Pave2();
1037 for (j=0; j<2; ++j) {
1038 nV = aPave[j].Index();
1039 aV = aPDS->Shape(nV);
1040 // index of new vertex in myDS -> iV
1041 iV = myDS->Index(aV);
1043 aSI.SetShapeType(TopAbs_VERTEX);
1045 iV = myDS->Append(aSI);
1047 const BOPDS_Pave& aP1 = !j ? aPB1->Pave1() : aPB1->Pave2();
1048 if (aP1.Index() != iV) {
1049 if (aP1.Parameter() == aPave[j].Parameter()) {
1050 aDMNewSD.Bind(aP1.Index(), iV);
1051 myDS->AddShapeSD(aP1.Index(), iV);
1054 // check aPDS to have the SD connection between these vertices
1055 const TopoDS_Shape& aVPave = myDS->Shape(aP1.Index());
1056 Standard_Integer nVnewSD, nVnew = aPDS->Index(aVPave);
1057 if (aPDS->HasShapeSD(nVnew, nVnewSD)) {
1058 if (nVnewSD == nV) {
1059 aDMNewSD.Bind(aP1.Index(), iV);
1060 myDS->AddShapeSD(aP1.Index(), iV);
1066 aPave[j].SetIndex(iV);
1070 aE=aPDS->Shape(aPBRx->Edge());
1071 iE = myDS->Index(aE);
1073 aSI.SetShapeType(aType);
1075 iE=myDS->Append(aSI);
1078 // update real edge tolerance according to distances in common block if any
1079 if (aPDS->IsCommonBlock(aPBRx)) {
1080 const Handle(BOPDS_CommonBlock)& aCB = aPDS->CommonBlock(aPBRx);
1081 Standard_Real *pTol = aMCBTol.ChangeSeek(aCB);
1083 Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, aPDS, aPF.Context());
1084 pTol = aMCBTol.Bound(aCB, aTol);
1087 if (aNC.Tolerance() < *pTol) {
1088 aNC.SetTolerance(*pTol);
1091 // append new PaveBlock to aLPBC
1092 Handle(BOPDS_PaveBlock) *pPBC = aMEPB.ChangeSeek(iE);
1094 pPBC = aMEPB.Bound(iE, new BOPDS_PaveBlock());
1095 BOPDS_Pave aPaveR1, aPaveR2;
1096 aPaveR1 = aPBRx->Pave1();
1097 aPaveR2 = aPBRx->Pave2();
1098 aPaveR1.SetIndex(myDS->Index(aPDS->Shape(aPaveR1.Index())));
1099 aPaveR2.SetIndex(myDS->Index(aPDS->Shape(aPaveR2.Index())));
1101 (*pPBC)->SetPave1(aPaveR1);
1102 (*pPBC)->SetPave2(aPaveR2);
1103 (*pPBC)->SetEdge(iE);
1107 (*pPBC)->SetOriginalEdge(aPB1->OriginalEdge());
1108 aDMExEdges.ChangeFind(aPB1).Append(*pPBC);
1111 aLPBC.Append(*pPBC);
1116 }//else if (aType==TopAbs_EDGE)
1117 }//for (; aItLS.More(); aItLS.Next()) {
1119 // Update SD for vertices that did not participate in operation
1120 TColStd_DataMapOfIntegerInteger::Iterator itDM(aDMNewSD);
1121 for (; itDM.More(); itDM.Next())
1123 const Standard_Integer* pSD = aDMNewSD.Seek(itDM.Value());
1126 itDM.ChangeValue() = *pSD;
1127 myDS->AddShapeSD(itDM.Key(), *pSD);
1133 //=======================================================================
1134 //function : UpdateFaceInfo
1136 //=======================================================================
1137 void BOPAlgo_PaveFiller::UpdateFaceInfo
1138 (BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDME,
1139 const TColStd_DataMapOfIntegerInteger& theDMV)
1141 Standard_Integer i, j, nV1, nF1, nF2,
1143 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
1144 TColStd_MapOfInteger aMF;
1146 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
1147 aNbFF=aFFs.Length();
1149 //1. Sections (curves, points);
1150 for (i=0; i<aNbFF; ++i) {
1151 BOPDS_InterfFF& aFF=aFFs(i);
1152 aFF.Indices(nF1, nF2);
1154 BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
1155 BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
1157 // 1.1. Section edges
1158 BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
1160 for (j=0; j<aNbC; ++j) {
1161 BOPDS_Curve& aNC=aVNC(j);
1162 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
1164 // Add section edges to face info
1165 aItLPB.Initialize(aLPBC);
1166 for (; aItLPB.More(); ) {
1167 const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
1169 // Treat existing pave blocks
1170 if (theDME.IsBound(aPB)) {
1171 BOPDS_ListOfPaveBlock& aLPB=theDME.ChangeFind(aPB);
1172 UpdateExistingPaveBlocks(aPB, aLPB, nF1, nF2);
1173 aLPBC.Remove(aItLPB);
1177 aFI1.ChangePaveBlocksSc().Add(aPB);
1178 aFI2.ChangePaveBlocksSc().Add(aPB);
1183 // 1.2. Section vertices
1184 const BOPDS_VectorOfPoint& aVNP=aFF.Points();
1186 for (j=0; j<aNbP; ++j) {
1187 const BOPDS_Point& aNP=aVNP(j);
1192 aFI1.ChangeVerticesSc().Add(nV1);
1193 aFI2.ChangeVerticesSc().Add(nV1);
1200 Standard_Boolean bVerts, bEdges;
1202 bVerts = theDMV.Extent() > 0;
1203 bEdges = theDME.Extent() > 0;
1205 if (!bVerts && !bEdges) {
1209 // 2. Update Face Info information with new vertices and new
1210 // pave blocks created in PostTreatFF from existing ones
1211 Standard_Integer nV2, aNbPB;
1212 TColStd_MapIteratorOfMapOfInteger aItMF;
1213 TColStd_DataMapIteratorOfDataMapOfIntegerInteger aItMV;
1215 aItMF.Initialize(aMF);
1216 for (; aItMF.More(); aItMF.Next()) {
1217 nF1 = aItMF.Value();
1219 BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF1);
1221 // 2.1. Update information about vertices
1223 TColStd_MapOfInteger& aMVOn = aFI.ChangeVerticesOn();
1224 TColStd_MapOfInteger& aMVIn = aFI.ChangeVerticesIn();
1226 aItMV.Initialize(theDMV);
1227 for (; aItMV.More(); aItMV.Next()) {
1229 nV2 = aItMV.Value();
1231 if (aMVOn.Remove(nV1)) {
1235 if (aMVIn.Remove(nV1)) {
1238 } // for (; aItMV.More(); aItMV.Next()) {
1241 // 2.2. Update information about pave blocks
1243 BOPDS_IndexedMapOfPaveBlock& aMPBOn = aFI.ChangePaveBlocksOn();
1244 BOPDS_IndexedMapOfPaveBlock& aMPBIn = aFI.ChangePaveBlocksIn();
1246 BOPDS_IndexedMapOfPaveBlock aMPBCopy;
1247 for (i = 0; i < 2; ++i) {
1248 BOPDS_IndexedMapOfPaveBlock& aMPBOnIn = !i ? aMPBOn : aMPBIn;
1249 aMPBCopy = aMPBOnIn;
1252 aNbPB = aMPBCopy.Extent();
1253 for (j = 1; j <= aNbPB; ++j) {
1254 const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(j);
1255 if (theDME.IsBound(aPB)) {
1256 const BOPDS_ListOfPaveBlock& aLPB = theDME.Find(aPB);
1257 if (aLPB.IsEmpty()) {
1262 aItLPB.Initialize(aLPB);
1263 for (; aItLPB.More(); aItLPB.Next()) {
1264 const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB.Value();
1271 } // for (j = 1; j <= aNbPB; ++j) {
1272 } // for (i = 0; i < 2; ++i) {
1276 //=======================================================================
1277 //function : IsExistingVertex
1279 //=======================================================================
1280 Standard_Boolean BOPAlgo_PaveFiller::IsExistingVertex
1282 const Standard_Real theTolR3D,
1283 const TColStd_MapOfInteger& aMVOnIn)const
1285 Standard_Boolean bRet;
1286 Standard_Integer nV, iFlag;
1287 Standard_Real aTolCheck;
1290 TColStd_MapIteratorOfMapOfInteger aIt;
1292 aTolCheck = theTolR3D + myFuzzyValue;
1296 aBoxP.Enlarge(theTolR3D);
1298 aIt.Initialize(aMVOnIn);
1299 for (; aIt.More(); aIt.Next()) {
1301 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1302 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aSIV.Shape()));
1303 const Bnd_Box& aBoxV=aSIV.Box();
1305 if (!aBoxP.IsOut(aBoxV)) {
1306 iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP, aTolCheck);
1314 //=======================================================================
1315 //function : IsExistingPaveBlock
1317 //=======================================================================
1318 Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
1319 (const Handle(BOPDS_PaveBlock)& thePB,
1320 const BOPDS_Curve& theNC,
1321 const TColStd_ListOfInteger& theLSE)
1323 Standard_Boolean bRet=Standard_True;
1325 if (theLSE.IsEmpty()) {
1329 Standard_Real aT1, aT2, aTm, aTx, aTolE, aTolCheck, aTol, aDist;
1330 Standard_Integer nE, iFlag, nV1, nV2;
1333 TColStd_ListIteratorOfListOfInteger aItLI;
1335 thePB->Range(aT1, aT2);
1336 thePB->Indices(nV1, nV2);
1337 const TopoDS_Vertex &aV1 = TopoDS::Vertex(myDS->Shape(nV1)),
1338 &aV2 = TopoDS::Vertex(myDS->Shape(nV2));
1339 const Standard_Real aTolV1 = BRep_Tool::Tolerance(aV1),
1340 aTolV2 = BRep_Tool::Tolerance(aV2);
1342 aTol = Max(aTolV1, aTolV2);
1344 aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
1345 theNC.Curve().D0(aTm, aPm);
1347 aBoxPm.Enlarge(aTol);
1349 aItLI.Initialize(theLSE);
1350 for (; aItLI.More(); aItLI.Next()) {
1354 const BOPDS_ShapeInfo& aSIE=myDS->ChangeShapeInfo(nE);
1355 const Bnd_Box& aBoxE=aSIE.Box();
1356 if (!aBoxE.IsOut(aBoxPm)) {
1357 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
1358 aTolE = BRep_Tool::Tolerance(aE);
1359 aTolCheck = Max(aTolE, aTol) + myFuzzyValue;
1360 iFlag = myContext->ComputePE(aPm, aTolCheck, aE, aTx, aDist);
1363 // Update tolerance of the edge
1364 UpdateEdgeTolerance(nE, aDist);
1372 //=======================================================================
1373 //function : IsExistingPaveBlock
1375 //=======================================================================
1376 Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
1377 (const Handle(BOPDS_PaveBlock)& thePB,
1378 const BOPDS_Curve& theNC,
1379 const Standard_Real theTolR3D,
1380 const BOPDS_IndexedMapOfPaveBlock& theMPBOnIn,
1381 const BOPDS_MapOfPaveBlock& theMPBCommon,
1382 Handle(BOPDS_PaveBlock)& aPBOut,
1383 Standard_Real& theTolNew)
1385 Standard_Boolean bRet;
1386 Standard_Real aT1, aT2, aTm, aTx, aTolCheck;
1387 Standard_Integer nSp, iFlag1, iFlag2, nV11, nV12, nV21, nV22, i, aNbPB;
1388 gp_Pnt aP1, aPm, aP2;
1389 Bnd_Box aBoxP1, aBoxPm, aBoxP2, aBoxTmp;
1391 bRet=Standard_False;
1392 aTolCheck = theTolR3D + myFuzzyValue;
1393 const IntTools_Curve& aIC=theNC.Curve();
1395 thePB->Range(aT1, aT2);
1396 thePB->Indices(nV11, nV12);
1397 const Standard_Real aTolV11 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV11)));
1398 const Standard_Real aTolV12 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV12)));
1399 const Standard_Real aTolV1 = Max(aTolV11, aTolV12) + myFuzzyValue;
1404 aBoxP1.Enlarge(aTolV11);
1405 //intermediate point
1406 aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
1412 aBoxP2.Enlarge(aTolV12);
1415 aNbPB = theMPBOnIn.Extent();
1416 for (i = 1; i <= aNbPB; ++i) {
1417 const Handle(BOPDS_PaveBlock)& aPB = theMPBOnIn(i);
1418 aPB->Indices(nV21, nV22);
1419 const Standard_Real aTolV21 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV21)));
1420 const Standard_Real aTolV22 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV22)));
1421 const Standard_Real aTolV2 = Max(aTolV21, aTolV22) + myFuzzyValue;
1425 const BOPDS_ShapeInfo& aSISp=myDS->ChangeShapeInfo(nSp);
1426 const TopoDS_Edge& aSp=(*(TopoDS_Edge *)(&aSISp.Shape()));
1427 const Bnd_Box& aBoxSp=aSISp.Box();
1429 iFlag1 = (nV11 == nV21 || nV11 == nV22) ? 2 :
1430 (!aBoxSp.IsOut(aBoxP1) ? 1 : 0);
1431 iFlag2 = (nV12 == nV21 || nV12 == nV22) ? 2 :
1432 (!aBoxSp.IsOut(aBoxP2) ? 1 : 0);
1433 if (iFlag1 && iFlag2) {
1434 Standard_Real aDist = 0.;
1436 Standard_Real aRealTol = aTolCheck;
1437 if (myDS->IsCommonBlock(aPB))
1439 aRealTol = Max(aRealTol, Max(aTolV1, aTolV2));
1440 if (theMPBCommon.Contains(aPB))
1441 // for an edge, which is a common block with a face,
1442 // increase the chance to coincide with section curve
1447 aBoxTmp.Enlarge(aRealTol);
1449 if (aBoxSp.IsOut(aBoxTmp) || myContext->ComputePE(aPm,
1457 iFlag1 = !myContext->ComputePE(aP1, aRealTol, aSp, aTx, aDist);
1458 if (iFlag1 && theTolNew < aDist)
1463 iFlag2 = !myContext->ComputePE(aP2, aRealTol, aSp, aTx, aDist);
1464 if (iFlag2 && theTolNew < aDist)
1468 if (iFlag1 && iFlag2) {
1478 //=======================================================================
1481 //=======================================================================
1482 static void getBoundPaves(const BOPDS_DS* theDS,
1484 Standard_Integer theNV[2])
1486 theNV[0] = theNV[1] = -1;
1488 // get extreme paves
1489 Handle(BOPDS_PaveBlock)& aPB = theNC.ChangePaveBlock1();
1490 const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
1491 Standard_Integer aNbEP = aLP.Extent();
1494 Standard_Real aTmin = RealLast();
1495 Standard_Real aTmax = -aTmin;
1496 for (BOPDS_ListIteratorOfListOfPave aItLP(aLP); aItLP.More(); aItLP.Next())
1498 const BOPDS_Pave& aPv = aItLP.Value();
1499 Standard_Integer nV;
1501 aPv.Contents(nV, aTV);
1503 theNV[0] = aPv.Index();
1507 theNV[1] = aPv.Index();
1512 // compare extreme vertices with ends of the curve
1513 const IntTools_Curve& aIC = theNC.Curve();
1514 Standard_Real aT[2];
1516 aIC.Bounds(aT[0], aT[1], aP[0], aP[1]);
1517 Standard_Real aTol = Max(theNC.Tolerance(), theNC.TangentialTolerance());
1518 aTol += Precision::Confusion();
1519 for (Standard_Integer j = 0; j < 2; ++j)
1521 const BOPDS_ShapeInfo& aSIV = theDS->ShapeInfo(theNV[j]);
1522 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&aSIV.Shape()));
1523 Standard_Integer iFlag = BOPTools_AlgoTools::ComputeVV(aV, aP[j], aTol);
1529 //=======================================================================
1530 //function : PutBoundPaveOnCurve
1532 //=======================================================================
1533 void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1,
1534 const TopoDS_Face& aF2,
1536 TColStd_ListOfInteger& aLVB)
1538 const IntTools_Curve& aIC=aNC.Curve();
1539 Standard_Real aT[2];
1541 aIC.Bounds(aT[0], aT[1], aP[0], aP[1]);
1542 Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
1543 Handle(BOPDS_PaveBlock)& aPB = aNC.ChangePaveBlock1();
1544 // Get numbers of vertices assigned to the ends of the curve
1545 Standard_Integer aBndNV[2];
1546 getBoundPaves(myDS, aNC, aBndNV);
1548 Standard_Real aTolVnew = Precision::Confusion();
1549 for (Standard_Integer j = 0; j<2; ++j)
1553 // no vertex on this end
1554 if (j && aP[1].IsEqual(aP[0], aTolVnew)) {
1555 //if curve is closed, process only one bound
1558 Standard_Boolean bVF = myContext->IsValidPointForFaces(aP[j], aF1, aF2, aTolR3D);
1563 BOPTools_AlgoTools::MakeNewVertex(aP[j], aTolR3D, aVn);
1564 BOPTools_AlgoTools::UpdateVertex(aIC, aT[j], aVn);
1565 aTolVnew = BRep_Tool::Tolerance(aVn);
1567 BOPDS_ShapeInfo aSIVn;
1568 aSIVn.SetShapeType(TopAbs_VERTEX);
1569 aSIVn.SetShape(aVn);
1571 Bnd_Box& aBox = aSIVn.ChangeBox();
1572 BRepBndLib::Add(aVn, aBox);
1573 aBox.SetGap(aBox.GetGap() + Precision::Confusion());
1575 Standard_Integer nVn = myDS->Append(aSIVn);
1579 aPn.SetParameter(aT[j]);
1580 aPB->AppendExtPave(aPn);
1587 //=======================================================================
1588 //function : PutPavesOnCurve
1590 //=======================================================================
1591 void BOPAlgo_PaveFiller::PutPavesOnCurve(const TColStd_MapOfInteger& theMVOnIn,
1592 const TColStd_MapOfInteger& theMVCommon,
1594 const TColStd_MapOfInteger& theMI,
1595 const TColStd_MapOfInteger& theMVEF,
1596 TColStd_DataMapOfIntegerReal& theMVTol,
1597 TColStd_DataMapOfIntegerListOfInteger& theDMVLV)
1599 Standard_Integer nV;
1600 TColStd_MapIteratorOfMapOfInteger aIt;
1602 const Bnd_Box& aBoxC = theNC.Box();
1603 const Standard_Real aTolR3D = Max(theNC.Tolerance(), theNC.TangentialTolerance());
1605 //Put EF vertices first
1606 aIt.Initialize(theMVEF);
1607 for (; aIt.More(); aIt.Next())
1610 PutPaveOnCurve(nV, aTolR3D, theNC, theMI, theMVTol, theDMVLV, 2);
1613 //Put all other vertices
1614 aIt.Initialize(theMVOnIn);
1615 for (; aIt.More(); aIt.Next())
1618 if (theMVEF.Contains(nV))
1623 if (!theMVCommon.Contains(nV))
1625 const BOPDS_ShapeInfo& aSIV = myDS->ShapeInfo(nV);
1626 const Bnd_Box& aBoxV = aSIV.Box();
1628 if (aBoxC.IsOut(aBoxV))
1632 if (!myDS->IsNewShape(nV))
1638 PutPaveOnCurve(nV, aTolR3D, theNC, theMI, theMVTol, theDMVLV, 1);
1642 //=======================================================================
1643 //function : FilterPavesOnCurves
1645 //=======================================================================
1647 struct PaveBlockDist {
1648 Handle(BOPDS_PaveBlock) PB;
1649 Standard_Real Dist; // square distance from vertex to the paveblock
1650 Standard_Real SinAngle; // sinus of angle between projection vector
1651 // and tangent at projection point
1652 Standard_Real Tolerance; // tolerance of the section curve
1655 void BOPAlgo_PaveFiller::FilterPavesOnCurves(const BOPDS_VectorOfCurve& theVNC)
1657 // For each vertex found in ExtPaves of pave blocks of section curves
1658 // collect list of pave blocks with distance to the curve
1659 NCollection_IndexedDataMap<Standard_Integer,NCollection_List<PaveBlockDist> > aIDMVertPBs;
1661 const Standard_Real anEps = gp::Resolution();
1662 for (i = 0; i < theVNC.Length(); ++i)
1664 const BOPDS_Curve& aNC = theVNC(i);
1665 const IntTools_Curve& aIC = aNC.Curve();
1666 const Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
1667 GeomAdaptor_Curve aGAC(aIC.Curve());
1668 const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First();
1669 const BOPDS_ListOfPave& aPaves = aPB->ExtPaves();
1670 BOPDS_ListOfPave::Iterator itPaves(aPaves);
1671 for (; itPaves.More(); itPaves.Next())
1673 const BOPDS_Pave& aPave = itPaves.Value();
1674 Standard_Integer nV = aPave.Index();
1675 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
1676 // compute distance from vertex to the point on curve with vertex parameter
1677 gp_Pnt aPV = BRep_Tool::Pnt(aV);
1678 Standard_Real aPar = aPave.Parameter();
1681 aGAC.D1(aPar, aPonC, aD1);
1682 gp_Vec aProjVec(aPV, aPonC);
1683 Standard_Real aSqDist = aProjVec.SquareMagnitude();
1684 Standard_Real aSqD1Mod = aD1.SquareMagnitude();
1685 Standard_Real aSin = aProjVec.CrossSquareMagnitude(aD1);
1686 if (aSqDist > anEps && aSqD1Mod > anEps)
1687 aSin = sqrt(aSin / aSqDist / aSqD1Mod);
1688 NCollection_List<PaveBlockDist>* pList = aIDMVertPBs.ChangeSeek(nV);
1690 pList = &aIDMVertPBs.ChangeFromIndex(aIDMVertPBs.Add(nV, NCollection_List<PaveBlockDist>()));
1691 PaveBlockDist aPBD = { aPB, aSqDist, aSin, aTolR3D };
1692 pList->Append(aPBD);
1696 // Process each vertex
1697 const Standard_Real aSinAngleMin = 0.5; // angle below which projection is suspicious
1698 for (i = 1; i <= aIDMVertPBs.Extent(); i++)
1700 Standard_Integer nV = aIDMVertPBs.FindKey(i);
1701 const NCollection_List<PaveBlockDist>& aList = aIDMVertPBs(i);
1702 // Find a pave with minimal distance
1703 Standard_Real aMinDist = RealLast();
1704 Handle(BOPDS_PaveBlock) aPBMinDist;
1705 NCollection_List<PaveBlockDist>::Iterator itL(aList);
1706 for (; itL.More(); itL.Next())
1708 const PaveBlockDist& aPBD = itL.Value();
1709 if (aPBD.Dist < aMinDist)
1711 aMinDist = aPBD.Dist;
1712 aPBMinDist = aPBD.PB;
1715 // Remove a vertex from a pave block if the distance is greater than the tolerance
1716 // and there are other pave blocks for which the distance is less than the current.
1717 // Do not remove a vertex if it is projected on the curve with quite large angle
1718 // (see test bugs modalg_6 bug27761).
1719 for (itL.Init(aList); itL.More(); itL.Next())
1721 const PaveBlockDist& aPBD = itL.Value();
1722 Standard_Real aCheckDist = 100. * Max(aPBD.Tolerance*aPBD.Tolerance, aMinDist);
1723 if (aPBD.Dist > aCheckDist && aPBD.SinAngle < aSinAngleMin)
1725 aPBD.PB->RemoveExtPave(nV);
1731 //=======================================================================
1732 //function : ExtendedTolerance
1734 //=======================================================================
1735 Standard_Boolean BOPAlgo_PaveFiller::ExtendedTolerance
1736 (const Standard_Integer nV,
1737 const TColStd_MapOfInteger& aMI,
1738 Standard_Real& aTolVExt,
1739 const Standard_Integer aType)
1741 Standard_Boolean bFound = Standard_False;
1742 if (!(myDS->IsNewShape(nV))) {
1746 Standard_Integer i, k, aNbLines, aNbInt;
1747 Standard_Real aT11, aT12, aD1, aD2, aD;
1749 gp_Pnt aPV, aP11, aP12;
1755 } else if (aType == 2) {
1759 aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1760 aPV=BRep_Tool::Pnt(aV);
1762 BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
1763 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1765 for (; k<aNbInt; ++k) {
1766 aNbLines = !k ? aEEs.Length() : aEFs.Length();
1767 for (i = 0; i < aNbLines; ++i) {
1768 BOPDS_Interf *aInt = !k ? (BOPDS_Interf*) (&aEEs(i)) :
1769 (BOPDS_Interf*) (&aEFs(i));
1770 if (aInt->IndexNew() == nV) {
1771 if (aMI.Contains(aInt->Index1()) &&
1772 aMI.Contains(aInt->Index2())) {
1773 const IntTools_CommonPrt& aComPrt = !k ? aEEs(i).CommonPart() :
1774 aEFs(i).CommonPart();
1776 const TopoDS_Edge& aE1=aComPrt.Edge1();
1777 aComPrt.Range1(aT11, aT12);
1778 BOPTools_AlgoTools::PointOnEdge(aE1, aT11, aP11);
1779 BOPTools_AlgoTools::PointOnEdge(aE1, aT12, aP12);
1780 aD1=aPV.Distance(aP11);
1781 aD2=aPV.Distance(aP12);
1782 aD=(aD1>aD2)? aD1 : aD2;
1787 }//if (aMI.Contains(aEF.Index1()) && aMI.Contains(aEF.Index2())) {
1788 }//if (aInt->IndexNew() == nV) {
1789 }//for (i = 0; i < aNbLines; ++i) {
1790 }//for (k=0; k<2; ++k) {
1794 //=======================================================================
1795 //function : GetEFPnts
1797 //=======================================================================
1798 void BOPAlgo_PaveFiller::GetEFPnts
1799 (const Standard_Integer nF1,
1800 const Standard_Integer nF2,
1801 IntSurf_ListOfPntOn2S& aListOfPnts)
1803 Standard_Integer nE, nF, nFOpposite, aNbEFs, i;
1804 Standard_Real U1, U2, V1, V2, f, l;
1805 TColStd_MapOfInteger aMI;
1807 //collect indexes of all shapes from nF1 and nF2.
1808 GetFullShapeMap(nF1, aMI);
1809 GetFullShapeMap(nF2, aMI);
1811 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1812 aNbEFs = aEFs.Length();
1814 for(i = 0; i < aNbEFs; ++i) {
1815 const BOPDS_InterfEF& aEF = aEFs(i);
1816 if (aEF.HasIndexNew()) {
1817 aEF.Indices(nE, nFOpposite);
1818 if(aMI.Contains(nE) && aMI.Contains(nFOpposite)) {
1819 const IntTools_CommonPrt& aCP = aEF.CommonPart();
1820 Standard_Real aPar = aCP.VertexParameter1();
1821 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&myDS->Shape(nE)));
1822 const TopoDS_Face& aFOpposite =
1823 (*(TopoDS_Face*)(&myDS->Shape(nFOpposite)));
1825 const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(aE, f, l);
1827 nF = (nFOpposite == nF1) ? nF2 : nF1;
1828 const TopoDS_Face& aF = (*(TopoDS_Face*)(&myDS->Shape(nF)));
1829 Handle(Geom2d_Curve) aPCurve =
1830 BRep_Tool::CurveOnSurface(aE, aF, f, l);
1832 GeomAPI_ProjectPointOnSurf& aProj=myContext->ProjPS(aFOpposite);
1835 aCurve->D0(aPar, aPoint);
1836 IntSurf_PntOn2S aPnt;
1837 if(!aPCurve.IsNull()) {
1838 gp_Pnt2d aP2d = aPCurve->Value(aPar);
1839 aProj.Perform(aPoint);
1840 if(aProj.IsDone()) {
1841 aProj.LowerDistanceParameters(U1,V1);
1843 aPnt.SetValue(aP2d.X(),aP2d.Y(),U1,V1);
1845 aPnt.SetValue(U1,V1,aP2d.X(),aP2d.Y());
1847 aListOfPnts.Append(aPnt);
1851 GeomAPI_ProjectPointOnSurf& aProj1 = myContext->ProjPS(aF);
1852 aProj1.Perform(aPoint);
1853 aProj.Perform(aPoint);
1854 if(aProj1.IsDone() && aProj.IsDone()){
1855 aProj1.LowerDistanceParameters(U1,V1);
1856 aProj.LowerDistanceParameters(U2,V2);
1858 aPnt.SetValue(U1,V1,U2,V2);
1860 aPnt.SetValue(U2,V2,U1,V1);
1862 aListOfPnts.Append(aPnt);
1870 //=======================================================================
1871 //function : PutEFPavesOnCurve
1873 //=======================================================================
1874 void BOPAlgo_PaveFiller::PutEFPavesOnCurve
1876 const TColStd_MapOfInteger& aMI,
1877 const TColStd_MapOfInteger& aMVEF,
1878 TColStd_DataMapOfIntegerReal& aMVTol,
1879 TColStd_DataMapOfIntegerListOfInteger& aDMVLV)
1881 if (!aMVEF.Extent()) {
1885 const IntTools_Curve& aIC=aNC.Curve();
1886 GeomAbs_CurveType aTypeC;
1888 if (!(aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve)) {
1892 Standard_Integer nV;
1893 TColStd_MapOfInteger aMV;
1896 RemoveUsedVertices(aNC, aMV);
1897 if (!aMV.Extent()) {
1901 Standard_Real aDist;
1904 const Handle(Geom_Curve)& aC3D=aIC.Curve();
1905 GeomAPI_ProjectPointOnCurve& aProjPT = myContext->ProjPT(aC3D);
1907 TColStd_MapIteratorOfMapOfInteger aItMI;
1908 aItMI.Initialize(aMV);
1909 for (; aItMI.More(); aItMI.Next()) {
1911 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1912 gp_Pnt aPV = BRep_Tool::Pnt(aV);
1913 aProjPT.Perform(aPV);
1914 Standard_Integer aNbPoints = aProjPT.NbPoints();
1916 aDist = aProjPT.LowerDistance();
1917 PutPaveOnCurve(nV, aDist, aNC, aMI, aMVTol, aDMVLV);
1922 //=======================================================================
1923 //function : PutStickPavesOnCurve
1925 //=======================================================================
1926 void BOPAlgo_PaveFiller::PutStickPavesOnCurve
1927 (const TopoDS_Face& aF1,
1928 const TopoDS_Face& aF2,
1929 const TColStd_MapOfInteger& aMI,
1931 const TColStd_MapOfInteger& aMVStick,
1932 TColStd_DataMapOfIntegerReal& aMVTol,
1933 TColStd_DataMapOfIntegerListOfInteger& aDMVLV)
1935 // Get numbers of vertices assigned to the ends of the curve
1936 Standard_Integer aBndNV[2];
1937 getBoundPaves(myDS, aNC, aBndNV);
1938 if (aBndNV[0] >= 0 && aBndNV[1] >= 0)
1940 // both curve ends already have assigned vertices
1943 TColStd_MapOfInteger aMV;
1944 aMV.Assign(aMVStick);
1945 RemoveUsedVertices(aNC, aMV);
1947 if (!aMV.Extent()) {
1951 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
1952 Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2);
1954 const IntTools_Curve& aIC=aNC.Curve();
1955 //if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) {
1956 Handle(Geom2d_Curve) aC2D[2];
1958 aC2D[0]=aIC.FirstCurve2d();
1959 aC2D[1]=aIC.SecondCurve2d();
1960 if (!aC2D[0].IsNull() && !aC2D[1].IsNull()) {
1961 Standard_Integer nV, m, n;
1962 Standard_Real aTC[2], aD, aD2, u, v, aDT2, aScPr, aDScPr;
1966 TColStd_MapIteratorOfMapOfInteger aItMI, aItMI1;
1968 aDT2=2e-7; // the rich criteria
1969 aDScPr=5.e-9; // the creasing criteria
1970 aIC.Bounds(aTC[0], aTC[1], aPC[0], aPC[1]);
1972 aItMI.Initialize(aMV);
1973 for (; aItMI.More(); aItMI.Next()) {
1975 const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&myDS->Shape(nV));
1976 aPV=BRep_Tool::Pnt(aV);
1978 for (m=0; m<2; ++m) {
1981 aD2=aPC[m].SquareDistance(aPV);
1982 if (aD2>aDT2) {// no rich
1986 for (n=0; n<2; ++n) {
1987 Handle(Geom_Surface)& aS=(!n)? aS1 : aS2;
1988 aC2D[n]->D0(aTC[m], aP2D);
1990 BOPTools_AlgoTools3D::GetNormalToSurface(aS, u, v, aDN[n]);
1993 aScPr=aDN[0]*aDN[1];
2003 // The intersection curve aIC is vanishing curve (the crease)
2006 PutPaveOnCurve(nV, aD, aNC, aMI, aMVTol, aDMVLV);
2008 }//for (jVU=1; jVU=aNbVU; ++jVU) {
2012 //=======================================================================
2013 //function : GetStickVertices
2015 //=======================================================================
2016 void BOPAlgo_PaveFiller::GetStickVertices(const Standard_Integer nF1,
2017 const Standard_Integer nF2,
2018 TColStd_MapOfInteger& aMVStick,
2019 TColStd_MapOfInteger& aMVEF,
2020 TColStd_MapOfInteger& aMI)
2022 Standard_Integer nS1, nS2, nVNew, aTypeInt, i;
2024 BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV();
2025 BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
2026 BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
2027 BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
2028 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
2030 Standard_Integer aNbLines[5] = {
2031 aVVs.Length(), aVEs.Length(), aEEs.Length(),
2032 aVFs.Length(), aEFs.Length()
2034 //collect indices of all shapes from nF1 and nF2.
2036 GetFullShapeMap(nF1, aMI);
2037 GetFullShapeMap(nF2, aMI);
2039 //collect VV, VE, EE, VF interferences
2040 for (aTypeInt = 0; aTypeInt < 4; ++aTypeInt) {
2041 for (i = 0; i < aNbLines[aTypeInt]; ++i) {
2042 BOPDS_Interf* aInt = (aTypeInt==0) ? (BOPDS_Interf*)(&aVVs(i)) :
2043 ((aTypeInt==1) ? (BOPDS_Interf*)(&aVEs(i)) :
2044 ((aTypeInt==2) ? (BOPDS_Interf*)(&aEEs(i)) :
2045 (BOPDS_Interf*)(&aVFs(i))));
2046 if (aInt->HasIndexNew()) {
2047 aInt->Indices(nS1, nS2);
2048 if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
2049 nVNew = aInt->IndexNew();
2050 aMVStick.Add(nVNew);
2055 //collect EF interferences
2056 for (i = 0; i < aNbLines[4]; ++i) {
2057 const BOPDS_InterfEF& aInt = aEFs(i);
2058 if (aInt.HasIndexNew()) {
2059 aInt.Indices(nS1, nS2);
2060 if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
2061 nVNew = aInt.IndexNew();
2062 aMVStick.Add(nVNew);
2069 //=======================================================================
2070 // function: GetFullShapeMap
2072 //=======================================================================
2073 void BOPAlgo_PaveFiller::GetFullShapeMap(const Standard_Integer nF,
2074 TColStd_MapOfInteger& aMI)
2076 TColStd_ListIteratorOfListOfInteger aIt;
2077 Standard_Integer nS;
2079 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF);
2080 const TColStd_ListOfInteger& aLI = aSI.SubShapes();
2083 aIt.Initialize(aLI);
2084 for (; aIt.More(); aIt.Next()) {
2090 //=======================================================================
2091 // function: RemoveUsedVertices
2093 //=======================================================================
2094 void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC,
2095 TColStd_MapOfInteger& aMV)
2097 if (!aMV.Extent()) {
2100 Standard_Integer nV;
2102 BOPDS_ListIteratorOfListOfPave aItLP;
2104 Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
2105 const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
2106 aItLP.Initialize(aLP);
2107 for (;aItLP.More();aItLP.Next()) {
2108 aPave = aItLP.Value();
2114 //=======================================================================
2115 //function : PutPaveOnCurve
2117 //=======================================================================
2118 void BOPAlgo_PaveFiller::PutPaveOnCurve
2119 (const Standard_Integer nV,
2120 const Standard_Real aTolR3D,
2121 const BOPDS_Curve& aNC,
2122 const TColStd_MapOfInteger& aMI,
2123 TColStd_DataMapOfIntegerReal& aMVTol,
2124 TColStd_DataMapOfIntegerListOfInteger& aDMVLV,
2125 const Standard_Integer iCheckExtend)
2127 Standard_Boolean bIsVertexOnLine;
2130 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
2131 const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First();
2132 const IntTools_Curve& aIC = aNC.Curve();
2134 Standard_Real aTolV = (aMVTol.IsBound(nV) ? aMVTol(nV) : BRep_Tool::Tolerance(aV));
2136 bIsVertexOnLine = myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D + myFuzzyValue, aT);
2137 if (!bIsVertexOnLine && iCheckExtend) {
2138 ExtendedTolerance(nV, aMI, aTolV, iCheckExtend);
2139 bIsVertexOnLine = myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D + myFuzzyValue, aT);
2142 if (bIsVertexOnLine) {
2143 // check if aPB contains the parameter aT
2144 Standard_Boolean bExist;
2145 Standard_Integer nVUsed;
2146 Standard_Real aPTol, aDTol;
2150 GeomAdaptor_Curve aGAC(aIC.Curve());
2151 aPTol = aGAC.Resolution(Max(aTolR3D, aTolV));
2153 bExist = aPB->ContainsParameter(aT, aPTol, nVUsed);
2155 // use existing pave
2156 TColStd_ListOfInteger* pList = aDMVLV.ChangeSeek(nVUsed);
2158 pList = aDMVLV.Bound(nVUsed, TColStd_ListOfInteger());
2159 pList->Append(nVUsed);
2160 if (!aMVTol.IsBound(nVUsed)) {
2161 const TopoDS_Vertex& aVUsed = (*(TopoDS_Vertex *)(&myDS->Shape(nVUsed)));
2162 aTolV = BRep_Tool::Tolerance(aVUsed);
2163 aMVTol.Bind(nVUsed, aTolV);
2166 // avoid repeated elements in the list
2167 TColStd_ListIteratorOfListOfInteger aItLI(*pList);
2168 for (; aItLI.More(); aItLI.Next()) {
2169 if (aItLI.Value() == nV) {
2173 if (!aItLI.More()) {
2176 // save initial tolerance for the vertex
2177 if (!aMVTol.IsBound(nV)) {
2178 aTolV = BRep_Tool::Tolerance(aV);
2179 aMVTol.Bind(nV, aTolV);
2186 aPave.SetParameter(aT);
2187 aPB->AppendExtPave(aPave);
2189 gp_Pnt aP1 = aGAC.Value(aT);
2190 aTolV = BRep_Tool::Tolerance(aV);
2191 gp_Pnt aP2 = BRep_Tool::Pnt(aV);
2192 Standard_Real aDist = aP1.Distance(aP2);
2193 if (aDist > aTolV) {
2194 BRep_Builder().UpdateVertex(aV, aDist + aDTol);
2196 if (!aMVTol.IsBound(nV)) {
2197 aMVTol.Bind(nV, aTolV);
2200 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV);
2201 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
2202 BRepBndLib::Add(aV, aBoxDS);
2203 aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
2209 //=======================================================================
2210 //function : ProcessExistingPaveBlocks
2212 //=======================================================================
2213 void BOPAlgo_PaveFiller::ProcessExistingPaveBlocks
2214 (const Standard_Integer theInt,
2215 const BOPDS_IndexedMapOfPaveBlock& aMPBOnIn,
2216 const TColStd_DataMapOfIntegerListOfInteger& aDMBV,
2217 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
2218 TopTools_DataMapOfShapeInteger& aMVI,
2219 BOPDS_MapOfPaveBlock& aMPB)
2221 if (aDMBV.IsEmpty()) {
2225 Standard_Real aT, dummy;
2226 Standard_Integer i, nV, nE, iC, aNbPB, iFlag;
2227 TColStd_ListIteratorOfListOfInteger aItLI;
2228 TColStd_DataMapIteratorOfDataMapOfIntegerListOfInteger aItBV;
2230 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2231 BOPDS_InterfFF& aFF = aFFs(theInt);
2232 BOPDS_VectorOfCurve& aVC = aFF.ChangeCurves();
2234 aNbPB = aMPBOnIn.Extent();
2236 aItBV.Initialize(aDMBV);
2237 for (; aItBV.More(); aItBV.Next()) {
2239 const TColStd_ListOfInteger& aLBV = aItBV.Value();
2241 BOPDS_Curve& aNC = aVC.ChangeValue(iC);
2242 BOPDS_ListOfPaveBlock& aLPBC = aNC.ChangePaveBlocks();
2244 aItLI.Initialize(aLBV);
2245 for (; aItLI.More(); aItLI.Next()) {
2247 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
2248 const Bnd_Box& aBoxV=aSIV.Box();
2249 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aSIV.Shape();
2250 if (!aMVI.IsBound(aV)) {
2254 for (i = 1; i <= aNbPB; ++i) {
2255 const Handle(BOPDS_PaveBlock)& aPB = aMPBOnIn(i);
2256 if (aPB->Pave1().Index() == nV || aPB->Pave2().Index() == nV) {
2260 if (aMPB.Contains(aPB)) {
2263 if (myDS->ShapeInfo(aPB->OriginalEdge()).HasFlag()) { // skip degenerated edges
2268 const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE);
2269 const Bnd_Box& aBoxE = aSIE.Box();
2271 if (aBoxV.IsOut(aBoxE)) {
2275 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aSIE.Shape();
2277 iFlag = myContext->ComputeVE(aV, aE, aT, dummy, myFuzzyValue);
2280 PreparePostTreatFF(theInt, iC, aPB, aMSCPB, aMVI, aLPBC);
2286 //=======================================================================
2287 //function : UpdateExistingPaveBlocks
2289 //=======================================================================
2290 void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks
2291 (const Handle(BOPDS_PaveBlock)& aPBf,
2292 BOPDS_ListOfPaveBlock& aLPB,
2293 const Standard_Integer nF1,
2294 const Standard_Integer nF2)
2296 if (!aLPB.Extent()) {
2300 Standard_Integer nE;
2301 Standard_Boolean bCB;
2302 Handle(BOPDS_PaveBlock) aPB, aPB1, aPB2, aPB2n;
2303 Handle(BOPDS_CommonBlock) aCB;
2304 BOPDS_ListIteratorOfListOfPaveBlock aIt, aIt1, aIt2;
2306 BOPDS_FaceInfo& aFI1 = myDS->ChangeFaceInfo(nF1);
2307 BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2);
2309 BOPDS_IndexedMapOfPaveBlock& aMPBOn1 = aFI1.ChangePaveBlocksOn();
2310 BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.ChangePaveBlocksIn();
2311 BOPDS_IndexedMapOfPaveBlock& aMPBOn2 = aFI2.ChangePaveBlocksOn();
2312 BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.ChangePaveBlocksIn();
2314 // 1. Remove old pave blocks
2315 const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPBf);
2316 bCB = !aCB1.IsNull();
2317 BOPDS_ListOfPaveBlock aLPB1;
2320 aLPB1.Assign(aCB1->PaveBlocks());
2324 aIt1.Initialize(aLPB1);
2325 for (; aIt1.More(); aIt1.Next()) {
2326 aPB1 = aIt1.Value();
2327 nE = aPB1->OriginalEdge();
2329 BOPDS_ListOfPaveBlock& aLPB2 = myDS->ChangePaveBlocks(nE);
2330 aIt2.Initialize(aLPB2);
2331 for (; aIt2.More(); aIt2.Next()) {
2332 aPB2 = aIt2.Value();
2340 // 2. Update pave blocks
2342 // Create new common blocks
2343 BOPDS_ListOfPaveBlock aLPBNew;
2344 const TColStd_ListOfInteger& aFaces = aCB1->Faces();
2345 aIt.Initialize(aLPB);
2346 for (; aIt.More(); aIt.Next()) {
2347 const Handle(BOPDS_PaveBlock)& aPBValue = aIt.Value();
2348 BOPDS_Pave aPBValuePaves[2] = {aPBValue->Pave1(), aPBValue->Pave2()};
2350 aCB = new BOPDS_CommonBlock;
2351 aIt1.Initialize(aLPB1);
2352 for (; aIt1.More(); aIt1.Next()) {
2353 aPB2 = aIt1.Value();
2354 nE = aPB2->OriginalEdge();
2356 // Create new pave block
2357 aPB2n = new BOPDS_PaveBlock;
2358 if (aPBValue->OriginalEdge() == nE) {
2359 aPB2n->SetPave1(aPBValuePaves[0]);
2360 aPB2n->SetPave2(aPBValuePaves[1]);
2363 // For the different original edge compute the parameters of paves
2364 BOPDS_Pave aPave[2];
2365 for (Standard_Integer i = 0; i < 2; ++i) {
2366 Standard_Integer nV = aPBValuePaves[i].Index();
2367 aPave[i].SetIndex(nV);
2368 if (nV == aPB2->Pave1().Index()) {
2369 aPave[i].SetParameter(aPB2->Pave1().Parameter());
2371 else if (nV == aPB2->Pave2().Index()) {
2372 aPave[i].SetParameter(aPB2->Pave2().Parameter());
2375 // Compute the parameter by projecting the point
2376 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
2377 const TopoDS_Edge& aEOr = TopoDS::Edge(myDS->Shape(nE));
2378 Standard_Real aTOut, aDist;
2379 Standard_Integer iErr = myContext->ComputeVE(aV, aEOr, aTOut, aDist, myFuzzyValue);
2381 aPave[i].SetParameter(aTOut);
2384 // Unable to project - set the parameter of the closest boundary
2385 const TopoDS_Vertex& aV1 = TopoDS::Vertex(myDS->Shape(aPB2->Pave1().Index()));
2386 const TopoDS_Vertex& aV2 = TopoDS::Vertex(myDS->Shape(aPB2->Pave2().Index()));
2388 gp_Pnt aP = BRep_Tool::Pnt(aV);
2389 gp_Pnt aP1 = BRep_Tool::Pnt(aV1);
2390 gp_Pnt aP2 = BRep_Tool::Pnt(aV2);
2392 Standard_Real aDist1 = aP.SquareDistance(aP1);
2393 Standard_Real aDist2 = aP.SquareDistance(aP2);
2395 aPave[i].SetParameter(aDist1 < aDist2 ? aPB2->Pave1().Parameter() : aPB2->Pave2().Parameter());
2400 if (aPave[1].Parameter() < aPave[0].Parameter()) {
2401 BOPDS_Pave aPaveTmp = aPave[0];
2402 aPave[0] = aPave[1];
2403 aPave[1] = aPaveTmp;
2406 aPB2n->SetPave1(aPave[0]);
2407 aPB2n->SetPave2(aPave[1]);
2410 aPB2n->SetEdge(aPBValue->Edge());
2411 aPB2n->SetOriginalEdge(nE);
2412 aCB->AddPaveBlock(aPB2n);
2413 myDS->SetCommonBlock(aPB2n, aCB);
2414 myDS->ChangePaveBlocks(nE).Append(aPB2n);
2416 aCB->SetFaces(aFaces);
2418 const Handle(BOPDS_PaveBlock)& aPBNew = aCB->PaveBlocks().First();
2419 aLPBNew.Append(aPBNew);
2425 nE = aPBf->OriginalEdge();
2426 BOPDS_ListOfPaveBlock& aLPBE = myDS->ChangePaveBlocks(nE);
2427 aIt.Initialize(aLPB);
2428 for (; aIt.More(); aIt.Next()) {
2434 Standard_Boolean bIn1, bIn2;
2436 bIn1 = aMPBOn1.Contains(aPBf) || aMPBIn1.Contains(aPBf);
2437 bIn2 = aMPBOn2.Contains(aPBf) || aMPBIn2.Contains(aPBf);
2443 // 3. Check new pave blocks for coincidence
2444 // with the opposite face.
2445 // In case of coincidence create common blocks
2446 Standard_Integer nF;
2448 nF = bIn1 ? nF2 : nF1;
2449 const TopoDS_Face& aF = *(TopoDS_Face*)&myDS->Shape(nF);
2450 BOPDS_IndexedMapOfPaveBlock& aMPBIn = bIn1 ? aMPBIn2 : aMPBIn1;
2452 aIt.Initialize(aLPB);
2453 for (; aIt.More(); aIt.Next()) {
2454 Handle(BOPDS_PaveBlock)& aPBChangeValue = aIt.ChangeValue();
2455 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPBChangeValue->Edge());
2457 IntTools_EdgeFace anEF;
2460 anEF.SetFuzzyValue(myFuzzyValue);
2461 anEF.SetRange(aPBChangeValue->Pave1().Parameter(), aPBChangeValue->Pave2().Parameter());
2462 anEF.SetContext(myContext);
2465 const IntTools_SequenceOfCommonPrts& aCPrts=anEF.CommonParts();
2466 if (aCPrts.Length() == 1) {
2467 Standard_Boolean bCoinc = (aCPrts(1).Type() == TopAbs_EDGE);
2470 aCB = myDS->CommonBlock(aPBChangeValue);
2472 aCB = new BOPDS_CommonBlock;
2473 aCB->AddPaveBlock(aPBChangeValue);
2474 myDS->SetCommonBlock(aPBChangeValue, aCB);
2478 aMPBIn.Add(aPBChangeValue);
2483 //=======================================================================
2484 // function: PutClosingPaveOnCurve
2486 //=======================================================================
2487 void BOPAlgo_PaveFiller::PutClosingPaveOnCurve(BOPDS_Curve& aNC)
2489 const IntTools_Curve& aIC = aNC.Curve();
2490 const Handle(Geom_Curve)& aC3D = aIC.Curve();
2496 if (!aIC.HasBounds())
2500 Standard_Real aT[2];
2502 aIC.Bounds(aT[0], aT[1], aP[0], aP[1]);
2504 // Find the pave which has been put at one of the ends
2505 Standard_Integer nV = -1;
2506 // Keep the opposite parameter
2507 Standard_Real aTOp = 0.;
2509 Standard_Boolean bFound = Standard_False;
2511 Handle(BOPDS_PaveBlock)& aPB = aNC.ChangePaveBlock1();
2512 BOPDS_ListOfPave& aLP = aPB->ChangeExtPaves();
2513 BOPDS_ListIteratorOfListOfPave aItLP(aLP);
2514 for (; aItLP.More() && !bFound; aItLP.Next())
2516 const BOPDS_Pave& aPC = aItLP.Value();
2517 Standard_Real aTC = aPC.Parameter();
2518 for (Standard_Integer j = 0; j < 2; ++j)
2520 if (Abs(aTC - aT[j]) < Precision::PConfusion())
2523 aTOp = (!j) ? aT[1] : aT[0];
2524 bFound = Standard_True;
2533 // Check if the curve is closed using the tolerance
2535 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
2536 const Standard_Real aTolV = BRep_Tool::Tolerance(aV);
2538 Standard_Real aDist = aP[0].Distance(aP[1]);
2542 // Check if there will be valid range on the curve
2543 Standard_Real aFirst, aLast;
2544 if (!BRepLib::FindValidRange(GeomAdaptor_Curve(aIC.Curve()), aIC.Tolerance(),
2545 aT[0], aP[0], aTolV,
2546 aT[1], aP[1], aTolV,
2552 // Add closing pave to the curve
2555 aPave.SetParameter(aTOp);
2558 //=======================================================================
2559 //function : PreparePostTreatFF
2561 //=======================================================================
2562 void BOPAlgo_PaveFiller::PreparePostTreatFF
2563 (const Standard_Integer aInt,
2564 const Standard_Integer aCur,
2565 const Handle(BOPDS_PaveBlock)& aPB,
2566 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
2567 TopTools_DataMapOfShapeInteger& aMVI,
2568 BOPDS_ListOfPaveBlock& aLPBC)
2570 Standard_Integer nV1, nV2;
2574 aPB->Indices(nV1, nV2);
2575 const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
2576 const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
2577 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPB->Edge());
2578 // Keep info for post treatment
2579 BOPDS_CoupleOfPaveBlocks aCPB;
2580 aCPB.SetIndexInterf(aInt);
2581 aCPB.SetIndex(aCur);
2582 aCPB.SetPaveBlock1(aPB);
2584 aMSCPB.Add(aE, aCPB);
2585 aMVI.Bind(aV1, nV1);
2586 aMVI.Bind(aV2, nV2);
2589 //=======================================================================
2590 //function : CheckPlanes
2592 //=======================================================================
2593 Standard_Boolean BOPAlgo_PaveFiller::CheckPlanes
2594 (const Standard_Integer nF1,
2595 const Standard_Integer nF2)const
2597 Standard_Boolean bToIntersect;
2598 Standard_Integer i, nV2, iCnt;
2599 TColStd_MapIteratorOfMapOfInteger aIt;
2601 bToIntersect=Standard_False;
2603 const BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
2604 const BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
2606 const TColStd_MapOfInteger& aMVIn1=aFI1.VerticesIn();
2607 const TColStd_MapOfInteger& aMVOn1=aFI1.VerticesOn();
2610 for (i=0; (i<2 && !bToIntersect); ++i) {
2611 const TColStd_MapOfInteger& aMV2=(!i) ? aFI2.VerticesIn()
2612 : aFI2.VerticesOn();
2614 aIt.Initialize(aMV2);
2615 for (; aIt.More(); aIt.Next()) {
2617 if (aMVIn1.Contains(nV2) || aMVOn1.Contains(nV2)) {
2620 bToIntersect=!bToIntersect;
2627 return bToIntersect;
2629 //=======================================================================
2630 //function : UpdatePaveBlocks
2632 //=======================================================================
2633 void BOPAlgo_PaveFiller::UpdatePaveBlocks
2634 (const TColStd_DataMapOfIntegerInteger& aDMNewSD)
2636 if (aDMNewSD.IsEmpty()) {
2640 Standard_Integer nSp, aNbPBP, nV[2], i, j;
2641 Standard_Real aT[2];
2642 Standard_Boolean bCB, bRebuild;
2643 BOPDS_ListIteratorOfListOfPaveBlock aItPB;
2644 BOPDS_MapOfPaveBlock aMPB;
2645 TColStd_MapOfInteger aMicroEdges;
2647 BOPDS_ListOfPaveBlock anAllPBs;
2649 // Get pave blocks of section edges
2650 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2651 Standard_Integer aNbFF = aFFs.Length();
2652 for (i = 0; i < aNbFF; ++i)
2654 const BOPDS_InterfFF& aFF = aFFs(i);
2655 const BOPDS_VectorOfCurve& aVNC = aFF.Curves();
2656 Standard_Integer aNbC = aVNC.Length();
2657 for (j = 0; j < aNbC; ++j)
2659 const BOPDS_Curve& aNC = aVNC(j);
2660 const BOPDS_ListOfPaveBlock& aLPBC = aNC.PaveBlocks();
2661 aItPB.Initialize(aLPBC);
2662 for (; aItPB.More(); aItPB.Next())
2663 anAllPBs.Append(aItPB.Value());
2667 // Get pave blocks from the pool
2668 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
2669 aNbPBP = aPBP.Length();
2670 for (i = 0; i < aNbPBP; ++i) {
2671 BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2672 aItPB.Initialize(aLPB);
2673 for (; aItPB.More(); aItPB.Next())
2674 anAllPBs.Append(aItPB.Value());
2677 // Process all pave blocks
2678 aItPB.Initialize(anAllPBs);
2679 for (; aItPB.More(); aItPB.Next())
2681 Handle(BOPDS_PaveBlock) aPB = aItPB.Value();
2682 const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
2683 bCB = !aCB.IsNull();
2685 aPB = aCB->PaveBlock1();
2688 if (aMPB.Add(aPB)) {
2689 bRebuild = Standard_False;
2690 aPB->Indices(nV[0], nV[1]);
2691 aPB->Range(aT[0], aT[1]);
2692 // remember the fact if the edge had different vertices before substitution
2693 Standard_Boolean wasRegularEdge = (nV[0] != nV[1]);
2695 for (j = 0; j < 2; ++j) {
2696 if (aDMNewSD.IsBound(nV[j])) {
2699 nV[j] = aDMNewSD.Find(nV[j]);
2700 aPave.SetIndex(nV[j]);
2701 aPave.SetParameter(aT[j]);
2703 bRebuild = Standard_True;
2705 aPB->SetPave1(aPave);
2708 aPB->SetPave2(aPave);
2714 Standard_Integer nE = aPB->Edge();
2715 // Check if the Pave Block has the edge set
2718 nE = aPB->OriginalEdge();
2720 Standard_Boolean isDegEdge = myDS->ShapeInfo(nE).HasFlag();
2721 if (wasRegularEdge && !isDegEdge && nV[0] == nV[1]) {
2722 // now edge has the same vertex on both ends;
2723 // check if it is not a regular closed curve.
2724 FillShrunkData(aPB);
2725 if (!aPB->HasShrunkData())
2727 // micro edge, so mark it for removal
2728 aMicroEdges.Add(nE);
2732 nSp = SplitEdge(nE, nV[0], aT[0], nV[1], aT[1]);
2738 }// if (aMPB.Add(aPB)) {
2739 }// for (; aItPB.More(); aItPB.Next()) {
2742 if (aMicroEdges.Extent())
2743 RemovePaveBlocks(aMicroEdges);
2745 //=======================================================================
2746 //function : RemovePaveBlocks
2748 //=======================================================================
2749 void BOPAlgo_PaveFiller::RemovePaveBlocks(const TColStd_MapOfInteger theEdges)
2751 // Remove all pave blocks referring to input edges:
2753 // 1. from the Pave Blocks Pool
2754 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
2755 Standard_Integer aNbPBP = aPBP.Length(), i;
2756 for (i = 0; i < aNbPBP; ++i) {
2757 BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2759 BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
2760 while (aItPB.More()) {
2761 const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
2762 if (theEdges.Contains(aPB->Edge()))
2769 // 2. from Face Info and section curves
2770 TColStd_MapOfInteger aMPassed;
2771 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2772 Standard_Integer aNbFF = aFFs.Length(), j;
2773 for (i = 0; i < aNbFF; ++i) {
2774 BOPDS_InterfFF& aFF = aFFs(i);
2775 Standard_Integer nF1, nF2;
2776 aFF.Indices(nF1, nF2);
2778 // rebuild pave block maps of face info
2779 for (j = 0; j < 2; j++) {
2780 Standard_Integer nF = (j == 0 ? nF1 : nF2);
2781 if (!aMPassed.Add(nF))
2783 BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF);
2784 BOPDS_IndexedMapOfPaveBlock* aIMPB[] = { &aFI.ChangePaveBlocksIn(),
2785 &aFI.ChangePaveBlocksOn(), &aFI.ChangePaveBlocksSc() };
2786 for (Standard_Integer k = 0; k < 3; k++) {
2787 Standard_Integer aNbPB = aIMPB[k]->Extent(), m;
2788 for (m = 1; m <= aNbPB; ++m) {
2789 const Handle(BOPDS_PaveBlock)& aPB = aIMPB[k]->FindKey(m);
2790 if (theEdges.Contains(aPB->Edge()))
2794 BOPDS_IndexedMapOfPaveBlock aMPBCopy = *aIMPB[k];
2796 for (m = 1; m <= aNbPB; ++m) {
2797 const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(m);
2798 if (!theEdges.Contains(aPB->Edge()))
2804 // remove from Section pave blocks
2805 BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
2806 Standard_Integer aNbC = aVNC.Length();
2807 for (j = 0; j < aNbC; ++j) {
2808 BOPDS_Curve& aNC = aVNC(j);
2809 BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
2810 BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
2811 while (aItPB.More()) {
2812 const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
2813 if (theEdges.Contains(aPB->Edge()))
2821 //=======================================================================
2822 //function : ToleranceFF
2823 //purpose : Computes the TolFF according to the tolerance value and
2824 // types of the faces.
2825 //=======================================================================
2826 Standard_Real ToleranceFF(const BRepAdaptor_Surface& aBAS1,
2827 const BRepAdaptor_Surface& aBAS2)
2829 Standard_Real aTol1 = aBAS1.Tolerance();
2830 Standard_Real aTol2 = aBAS2.Tolerance();
2831 Standard_Real aTolFF = Max(aTol1, aTol2);
2833 Standard_Boolean isAna1, isAna2;
2834 isAna1 = (aBAS1.GetType() == GeomAbs_Plane ||
2835 aBAS1.GetType() == GeomAbs_Cylinder ||
2836 aBAS1.GetType() == GeomAbs_Cone ||
2837 aBAS1.GetType() == GeomAbs_Sphere ||
2838 aBAS1.GetType() == GeomAbs_Torus);
2840 isAna2 = (aBAS2.GetType() == GeomAbs_Plane ||
2841 aBAS2.GetType() == GeomAbs_Cylinder ||
2842 aBAS2.GetType() == GeomAbs_Cone ||
2843 aBAS2.GetType() == GeomAbs_Sphere ||
2844 aBAS2.GetType() == GeomAbs_Torus);
2846 if (!isAna1 || !isAna2) {
2847 aTolFF = Max(aTolFF, 5.e-6);
2851 //=======================================================================
2852 //function : UpdateBlocksWithSharedVertices
2854 //=======================================================================
2855 void BOPAlgo_PaveFiller::UpdateBlocksWithSharedVertices()
2857 if (!myNonDestructive) {
2861 Standard_Integer aNbFF;
2863 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
2864 aNbFF=aFFs.Length();
2869 Standard_Boolean bOnCurve, bHasShapeSD;
2870 Standard_Integer i, nF1, nF2, aNbC, j, nV, nVSD;
2871 Standard_Real aTolV;
2872 TColStd_MapOfInteger aMF;
2874 for (i=0; i<aNbFF; ++i) {
2875 BOPDS_InterfFF& aFF=aFFs(i);
2877 BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
2883 aFF.Indices(nF1, nF2);
2886 myDS->UpdateFaceInfoOn(nF1);
2889 myDS->UpdateFaceInfoOn(nF2);
2892 // Collect old vertices that are shared for nF1, nF2 ->aMI;
2893 TColStd_MapOfInteger aMI;
2894 TColStd_MapIteratorOfMapOfInteger aItMI;
2896 BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
2897 BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
2899 const TColStd_MapOfInteger& aMVOn1=aFI1.VerticesOn();
2900 const TColStd_MapOfInteger& aMVIn1=aFI1.VerticesIn();
2901 const TColStd_MapOfInteger& aMVOn2=aFI2.VerticesOn();
2902 const TColStd_MapOfInteger& aMVIn2=aFI2.VerticesIn();
2904 for (j=0; j<2; ++j) {
2905 const TColStd_MapOfInteger& aMV1=(!j) ? aMVOn1 : aMVIn1;
2906 aItMI.Initialize(aMV1);
2907 for (; aItMI.More(); aItMI.Next()) {
2909 if (myDS->IsNewShape(nV)) {
2912 if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV)) {
2918 // Try to put vertices aMI on curves
2919 for (j=0; j<aNbC; ++j) {
2920 BOPDS_Curve& aNC=aVC.ChangeValue(j);
2921 Standard_Real aTolR3D = Max(aNC.Tolerance(), aNC.TangentialTolerance());
2923 aItMI.Initialize(aMI);
2924 for (; aItMI.More(); aItMI.Next()) {
2927 bHasShapeSD=myDS->HasShapeSD(nV, nVSD);
2932 bOnCurve=EstimatePaveOnCurve(nV, aNC, aTolR3D);
2937 const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV));
2938 aTolV=BRep_Tool::Tolerance(aV);
2940 UpdateVertex(nV, aTolV);
2942 }//for (j=0; j<aNbC; ++j) {
2943 }//for (i=0; i<aNbFF; ++i) {
2945 UpdateCommonBlocksWithSDVertices();
2947 //=======================================================================
2948 //function : EstimatePaveOnCurve
2950 //=======================================================================
2951 Standard_Boolean BOPAlgo_PaveFiller::EstimatePaveOnCurve
2952 (const Standard_Integer nV,
2953 const BOPDS_Curve& aNC,
2954 const Standard_Real aTolR3D)
2956 Standard_Boolean bIsVertexOnLine;
2959 const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV));
2960 const IntTools_Curve& aIC=aNC.Curve();
2962 bIsVertexOnLine=myContext->IsVertexOnLine(aV, aIC, aTolR3D, aT);
2963 return bIsVertexOnLine;
2966 //=======================================================================
2967 //function : CorrectToleranceOfSE
2969 //=======================================================================
2970 void BOPAlgo_PaveFiller::CorrectToleranceOfSE()
2972 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2973 NCollection_IndexedDataMap<Standard_Integer,BOPDS_ListOfPaveBlock> aMVIPBs;
2974 TColStd_MapOfInteger aMVIToReduce;
2975 // Fence map to avoid repeated checking of the same edge
2976 BOPDS_MapOfPaveBlock aMPB;
2978 // 1. iterate on all sections F-F
2979 Standard_Integer aNb = aFFs.Length(), i;
2980 for (i = 0; i < aNb; ++i) {
2981 BOPDS_InterfFF& aFF = aFFs(i);
2983 BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
2984 Standard_Integer aNbC = aVNC.Length(), k;
2985 for (k = 0; k < aNbC; ++k) {
2986 BOPDS_Curve& aNC = aVNC(k);
2987 BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
2988 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
2989 for (; aItLPB.More(); ) {
2990 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
2991 Standard_Integer nE;
2992 if (!aPB->HasEdge(nE)) {
2993 aLPB.Remove(aItLPB);
2997 if (!aMPB.Add(aPB)) {
3002 Standard_Boolean bIsReduced = Standard_False;
3003 if (aPB->OriginalEdge() < 0) {
3004 // It is possible that due to small angle between faces the
3005 // common zone between faces can be large and the tangential
3006 // tolerance of the curve will be large as well.
3007 // Here we're trying to reduce the tolerance of the section
3008 // edge using the valid tolerance of the edge.
3009 // Note, that if the pave block has created common block with
3010 // other edges its valid tolerance could have been changed to
3011 // cover all edges in common block (see PostTreatFF() method).
3012 Standard_Real aTolC = aNC.Tolerance();
3013 Standard_Real aTolTang = aNC.TangentialTolerance();
3014 if (aTolC < aTolTang) {
3015 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
3016 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
3017 if (aTolC < aTolE) {
3018 // reduce edge tolerance
3019 reinterpret_cast<BRep_TEdge*>(aE.TShape().operator->())->Tolerance(aTolC);
3020 bIsReduced = Standard_True;
3025 // fill in the map vertex index - pave blocks
3026 for (Standard_Integer j=0; j < 2; j++) {
3027 Standard_Integer nV = (j == 0 ? aPB->Pave1().Index() : aPB->Pave2().Index());
3028 myDS->HasShapeSD(nV, nV);
3029 BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV);
3031 pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock()));
3033 pPBList->Append(aPB);
3035 aMVIToReduce.Add(nV);
3043 if (aMVIToReduce.IsEmpty()) {
3047 // 2. try to reduce tolerances of connected vertices
3048 // 2.1 find all other edges containing these connected vertices to avoid
3049 // reducing the tolerance to the value less than the tolerances of edges,
3050 // i.e. minimal tolerance for the vertex is the max tolerance of the
3051 // edges containing this vertex
3052 TColStd_DataMapOfIntegerReal aMVITol;
3053 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
3054 aNb = aPBP.Length();
3055 for (i = 0; i < aNb; ++i) {
3056 const BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
3057 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
3058 for (; aItLPB.More(); aItLPB.Next()) {
3059 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
3060 Standard_Integer nE;
3061 if (!aPB->HasEdge(nE)) {
3064 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
3065 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
3067 Standard_Integer nV[2];
3068 aPB->Indices(nV[0], nV[1]);
3070 for (Standard_Integer j = 0; j < 2; j++) {
3071 if (aMVIToReduce.Contains(nV[j])) {
3072 Standard_Real *aMaxTol = aMVITol.ChangeSeek(nV[j]);
3074 aMVITol.Bind(nV[j], aTolE);
3076 else if (aTolE > *aMaxTol) {
3084 // 2.2 reduce tolerances if possible
3085 aNb = aMVIPBs.Extent();
3086 for (i = 1; i <= aNb; ++i) {
3087 Standard_Integer nV = aMVIPBs.FindKey(i);
3088 if (!aMVIToReduce.Contains(nV)) {
3092 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
3093 Standard_Real aTolV = BRep_Tool::Tolerance(aV);
3094 Standard_Real aMaxTol = aMVITol.IsBound(nV) ? aMVITol.Find(nV) : 0.;
3095 // it makes no sense to compute the real tolerance if it is
3096 // impossible to reduce the tolerance at least 0.1% of the current value
3097 if (aTolV - aMaxTol < 0.001 * aTolV) {
3101 // compute the maximal distance from the vertex to the adjacent edges
3102 gp_Pnt aP = BRep_Tool::Pnt(aV);
3104 // Avoid repeated checks
3105 BOPDS_MapOfPaveBlock aMPBFence;
3107 const BOPDS_ListOfPaveBlock& aLPB = aMVIPBs.FindFromIndex(i);
3108 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
3109 for (; aItLPB.More(); aItLPB.Next()) {
3110 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
3111 if (!aMPBFence.Add(aPB)) {
3114 Standard_Integer nE = aPB->Edge();
3115 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
3116 BRepAdaptor_Curve aC(aE);
3117 for (Standard_Integer iPave = 0; iPave < 2; ++iPave) {
3118 const BOPDS_Pave& aPave = !iPave ? aPB->Pave1() : aPB->Pave2();
3119 Standard_Integer nVSD = aPave.Index();
3120 myDS->HasShapeSD(nVSD, nVSD);
3125 gp_Pnt aPonE = aC.Value(aPave.Parameter());
3126 Standard_Real aDist = aP.Distance(aPonE);
3127 aDist += BRep_Tool::Tolerance(aE);
3128 if (aDist > aMaxTol) {
3134 if (aMaxTol < aTolV) {
3135 reinterpret_cast<BRep_TVertex*>(aV.TShape().operator->())->Tolerance(aMaxTol);
3140 //=======================================================================
3141 //function : PutSEInOtherFaces
3143 //=======================================================================
3144 void BOPAlgo_PaveFiller::PutSEInOtherFaces()
3146 // Try to intersect each section edge with the faces
3147 // not participated in its creation
3149 // 1. Get all section edges
3150 BOPDS_IndexedMapOfPaveBlock aMPBScAll;
3152 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
3153 Standard_Integer i, j, aNbFF = aFFs.Length();
3155 for (i = 0; i < aNbFF; ++i) {
3156 const BOPDS_VectorOfCurve& aVNC = aFFs(i).Curves();
3157 Standard_Integer aNbC = aVNC.Length();
3158 for (j = 0; j < aNbC; ++j) {
3159 const BOPDS_ListOfPaveBlock& aLPBC = aVNC(j).PaveBlocks();
3160 BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPBC);
3161 for (; aItPB.More(); aItPB.Next()) {
3162 aMPBScAll.Add(aItPB.Value());
3167 Standard_Integer aNbPBSc = aMPBScAll.Extent();
3169 // 2. Loop for all faces and check each section curve
3170 Standard_Integer aNbS = myDS->NbSourceShapes();
3171 for (i = 0; i < aNbS; ++i) {
3172 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(i);
3173 if (aSI.ShapeType() != TopAbs_FACE) {
3177 const TopoDS_Face& aF = (*(TopoDS_Face*)(&aSI.Shape()));
3178 BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(i);
3180 // IN edges to add new ones
3181 BOPDS_IndexedMapOfPaveBlock& aMFPBIn = aFI.ChangePaveBlocksIn();
3182 // Section edges to check the participation of the face
3183 const BOPDS_IndexedMapOfPaveBlock& aMFPBSc = aFI.PaveBlocksSc();
3185 // Get vertices of the face to check that vertices of the
3186 // processed section edge belong to the face
3187 TColStd_MapOfInteger aMFVerts;
3188 // Get vertices from ON, IN and Sc pave blocks of the face
3189 for (j = 0; j < 3; ++j) {
3190 const BOPDS_IndexedMapOfPaveBlock& aMPB =
3191 !j ? aFI.PaveBlocksOn() : (j == 1 ? aMFPBIn : aMFPBSc);
3192 Standard_Integer aNbPB = aMPB.Extent();
3193 for (Standard_Integer k = 1; k <= aNbPB; ++k) {
3194 const Handle(BOPDS_PaveBlock)& aPB = aMPB(k);
3195 aMFVerts.Add(aPB->Pave1().Index());
3196 aMFVerts.Add(aPB->Pave2().Index());
3199 // Add ON, IN and Sc vertices of the face
3200 for (j = 0; j < 3; ++j) {
3201 const TColStd_MapOfInteger& aMFV = !j ? aFI.VerticesOn() :
3202 (j == 1 ? aFI.VerticesIn() : aFI.VerticesSc());
3203 TColStd_MapIteratorOfMapOfInteger aItMI(aMFV);
3204 for (; aItMI.More(); aItMI.Next()) {
3205 aMFVerts.Add(aItMI.Value());
3209 // Check each section edge for possible belonging to the face
3210 for (j = 1; j <= aNbPBSc; ++j) {
3211 const Handle(BOPDS_PaveBlock)& aPB = aMPBScAll(j);
3212 if (aMFPBSc.Contains(aPB)) {
3216 // Both vertices of the section edge should belong to the face
3217 if (!aMFVerts.Contains(aPB->Pave1().Index()) ||
3218 !aMFVerts.Contains(aPB->Pave2().Index())) {
3222 // Perform intersection
3223 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(aPB->Edge()));
3225 IntTools_EdgeFace anEFInt;
3226 anEFInt.SetEdge(aE);
3227 anEFInt.SetFace(aF);
3228 anEFInt.SetFuzzyValue(myFuzzyValue);
3229 anEFInt.SetRange(aPB->Pave1().Parameter(), aPB->Pave2().Parameter());
3230 anEFInt.SetContext(myContext);
3231 anEFInt.UseQuickCoincidenceCheck(Standard_True);
3234 const IntTools_SequenceOfCommonPrts& aCPrts = anEFInt.CommonParts();
3235 if ((aCPrts.Length() == 1) && (aCPrts(1).Type() == TopAbs_EDGE)) {
3236 Handle(BOPDS_CommonBlock) aCB;
3237 if (myDS->IsCommonBlock(aPB)) {
3238 aCB = myDS->CommonBlock(aPB);
3241 aCB = new BOPDS_CommonBlock;
3242 aCB->AddPaveBlock(aPB);
3253 //=======================================================================
3254 //function : RemoveMicroSectionEdges
3256 //=======================================================================
3257 void BOPAlgo_PaveFiller::RemoveMicroSectionEdges
3258 (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
3259 TopTools_IndexedMapOfShape& theMicroEdges)
3261 if (theMSCPB.IsEmpty())
3265 // Get all F/F interferences
3266 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
3268 // Build the new map of section edges avoiding the micro edges
3269 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aSEPBMap;
3270 // Analyze all section edges
3271 Standard_Integer aNbCPB = theMSCPB.Extent();
3272 for (Standard_Integer i = 1; i <= aNbCPB; ++i)
3274 const TopoDS_Shape& aSI = theMSCPB.FindKey(i);
3275 const BOPDS_CoupleOfPaveBlocks& aCPB = theMSCPB(i);
3277 if (aSI.ShapeType() != TopAbs_EDGE)
3280 aSEPBMap.Add(aSI, aCPB);
3284 // Get pave block for analysis
3285 const Handle(BOPDS_PaveBlock)& aPB = aCPB.PaveBlock1();
3288 // Not a real section edge
3289 aSEPBMap.Add(aSI, aCPB);
3293 if (!BOPTools_AlgoTools::IsMicroEdge(TopoDS::Edge(aSI), myContext, Standard_False))
3296 aSEPBMap.Add(aSI, aCPB);
3300 // Micro edge is found, avoid it in the <theMSCPB> map
3301 // and remove from the F/F Intersection info structure
3303 // Get F/F interference which created this micro edge
3304 BOPDS_InterfFF& aFF = aFFs(aCPB.IndexInterf());
3305 // Get curve from which this edge has been created
3306 BOPDS_Curve& aCurve = aFF.ChangeCurves().ChangeValue(aCPB.Index());
3307 // Get all section pave blocks created from this curve
3308 BOPDS_ListOfPaveBlock& aLPBC = aCurve.ChangePaveBlocks();
3309 // Remove pave block from the list
3310 for (BOPDS_ListIteratorOfListOfPaveBlock it(aLPBC); it.More(); it.Next())
3312 if (it.Value() == aPB)
3319 // Add the "micro" edge to the map of "micro" edges for
3320 // unification of its vertices in the PostTreatFF method
3321 theMicroEdges.Add(aSI);
3324 // Overwrite the old map if necessary
3325 if (aSEPBMap.Extent() != theMSCPB.Extent())
3326 theMSCPB = aSEPBMap;