1 // Created by: Peter KURNEV
2 // Copyright (c) 2010-2014 OPEN CASCADE SAS
3 // Copyright (c) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
4 // Copyright (c) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, CEDRAT,
5 // EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
7 // This file is part of Open CASCADE Technology software library.
9 // This library is free software; you can redistribute it and/or modify it under
10 // the terms of the GNU Lesser General Public License version 2.1 as published
11 // by the Free Software Foundation, with special exception defined in the file
12 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
13 // distribution for complete text of the license and disclaimer of any warranty.
15 // Alternatively, this file may be used under the terms of Open CASCADE
16 // commercial license or contractual agreement.
18 #include <Bnd_Box.hxx>
19 #include <BOPAlgo_PaveFiller.hxx>
20 #include <BOPAlgo_SectionAttribute.hxx>
21 #include <BOPAlgo_Tools.hxx>
22 #include <BOPCol_DataMapOfShapeInteger.hxx>
23 #include <BOPCol_ListOfInteger.hxx>
24 #include <BOPCol_ListOfShape.hxx>
25 #include <BOPCol_MapOfInteger.hxx>
26 #include <BOPCol_NCVector.hxx>
27 #include <BOPCol_Parallel.hxx>
28 #include <BOPDS_CommonBlock.hxx>
29 #include <BOPDS_CoupleOfPaveBlocks.hxx>
30 #include <BOPDS_Curve.hxx>
31 #include <BOPDS_DataMapOfPaveBlockListOfPaveBlock.hxx>
32 #include <BOPDS_DS.hxx>
33 #include <BOPDS_FaceInfo.hxx>
34 #include <BOPDS_Interf.hxx>
35 #include <BOPDS_Iterator.hxx>
36 #include <BOPDS_ListOfPave.hxx>
37 #include <BOPDS_ListOfPaveBlock.hxx>
38 #include <BOPDS_MapOfPaveBlock.hxx>
39 #include <BOPDS_PaveBlock.hxx>
40 #include <BOPDS_Point.hxx>
41 #include <BOPDS_ShapeInfo.hxx>
42 #include <BOPDS_VectorOfCurve.hxx>
43 #include <BOPDS_VectorOfPoint.hxx>
44 #include <BOPTools.hxx>
45 #include <BOPTools_AlgoTools.hxx>
46 #include <BOPTools_AlgoTools3D.hxx>
47 #include <BRep_Builder.hxx>
48 #include <BRep_Tool.hxx>
49 #include <BRep_TEdge.hxx>
50 #include <BRepAdaptor_Curve.hxx>
51 #include <BRepAdaptor_Surface.hxx>
52 #include <BRepBndLib.hxx>
53 #include <BRepBuilderAPI_MakeVertex.hxx>
54 #include <BRepTools.hxx>
55 #include <Geom2d_Curve.hxx>
56 #include <Geom_Curve.hxx>
57 #include <GeomAPI_ProjectPointOnCurve.hxx>
58 #include <GeomAPI_ProjectPointOnSurf.hxx>
60 #include <IntSurf_ListOfPntOn2S.hxx>
61 #include <IntSurf_PntOn2S.hxx>
62 #include <IntTools.hxx>
63 #include <IntTools_Context.hxx>
64 #include <IntTools_Curve.hxx>
65 #include <IntTools_EdgeFace.hxx>
66 #include <IntTools_FaceFace.hxx>
67 #include <IntTools_PntOn2Faces.hxx>
68 #include <IntTools_SequenceOfCurves.hxx>
69 #include <IntTools_SequenceOfPntOn2Faces.hxx>
70 #include <IntTools_ShrunkRange.hxx>
71 #include <IntTools_Tools.hxx>
72 #include <Precision.hxx>
74 #include <TopExp_Explorer.hxx>
76 #include <TopoDS_Compound.hxx>
77 #include <TopoDS_Edge.hxx>
78 #include <TopoDS_Face.hxx>
79 #include <TopoDS_Vertex.hxx>
82 static void ToleranceFF(const BRepAdaptor_Surface& aBAS1,
83 const BRepAdaptor_Surface& aBAS2,
84 Standard_Real& aTolFF);
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();
147 IntTools_FaceFace::Perform(myF1, myF2);
151 Standard_Integer myIF1;
152 Standard_Integer myIF2;
153 Standard_Real myTolFF;
158 //=======================================================================
159 typedef BOPCol_NCVector
160 <BOPAlgo_FaceFace> BOPAlgo_VectorOfFaceFace;
162 typedef BOPCol_Functor
164 BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceFunctor;
167 <BOPAlgo_FaceFaceFunctor,
168 BOPAlgo_VectorOfFaceFace> BOPAlgo_FaceFaceCnt;
169 /////////////////////////////////////////////////////////////////////////
170 //=======================================================================
171 //function : PerformFF
173 //=======================================================================
174 void BOPAlgo_PaveFiller::PerformFF()
176 Standard_Integer iSize;
177 Standard_Boolean bValid;
181 myIterator->Initialize(TopAbs_FACE, TopAbs_FACE);
182 iSize=myIterator->ExpectedLength();
187 Standard_Boolean bJustAdd, bApp, bCompC2D1, bCompC2D2, bIsDone;
188 Standard_Boolean bToSplit, bTangentFaces;
189 Standard_Integer nF1, nF2, aNbCurves, aNbPoints, i, aNbLP;
190 Standard_Integer aNbFaceFace, k;
191 Standard_Real aApproxTol, aTolR3D, aTolR2D, aTolFF, aTolReal;
192 BOPCol_MapOfInteger aMI;
193 BOPAlgo_VectorOfFaceFace aVFaceFace;
195 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
196 aFFs.SetIncrement(iSize);
198 bApp=mySectionAttribute.Approximation();
199 bCompC2D1=mySectionAttribute.PCurveOnS1();
200 bCompC2D2=mySectionAttribute.PCurveOnS2();
202 bToSplit = Standard_False;
204 for (; myIterator->More(); myIterator->Next()) {
205 myIterator->Value(nF1, nF2, bJustAdd);
210 const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
211 const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
214 myDS->UpdateFaceInfoOn(nF1);
215 myDS->UpdateFaceInfoIn(nF1);
218 myDS->UpdateFaceInfoOn(nF2);
219 myDS->UpdateFaceInfoIn(nF2);
222 const BRepAdaptor_Surface& aBAS1 = myContext->SurfaceAdaptor(aF1);
223 const BRepAdaptor_Surface& aBAS2 = myContext->SurfaceAdaptor(aF2);
224 if (aBAS1.GetType() == GeomAbs_Plane &&
225 aBAS2.GetType() == GeomAbs_Plane) {
226 Standard_Boolean bToIntersect;
228 bToIntersect = CheckPlanes(nF1, nF2);
230 BOPDS_InterfFF& aFF=aFFs.Append1();
231 aFF.SetIndices(nF1, nF2);
237 ToleranceFF(aBAS1, aBAS2, aTolFF);
239 if (myGlue == BOPAlgo_GlueOff) {
240 BOPAlgo_FaceFace& aFaceFace=aVFaceFace.Append1();
242 aFaceFace.SetIndices(nF1, nF2);
243 aFaceFace.SetFaces(aF1, aF2);
244 aFaceFace.SetTolFF(aTolFF);
246 IntSurf_ListOfPntOn2S aListOfPnts;
247 GetEFPnts(nF1, nF2, aListOfPnts);
248 aNbLP = aListOfPnts.Extent();
250 aFaceFace.SetList(aListOfPnts);
253 aFaceFace.SetParameters(bApp, bCompC2D1, bCompC2D2, aApproxTol);
254 aFaceFace.SetFuzzyValue(myFuzzyValue);
255 aFaceFace.SetProgressIndicator(myProgressIndicator);
258 // for the Glue mode just add all interferences of that type
259 BOPDS_InterfFF& aFF = aFFs.Append1();
260 aFF.SetIndices(nF1, nF2);
261 aFF.SetTolR3D(Precision::Confusion());
262 aFF.SetTolR2D(Precision::PConfusion());
263 aFF.SetTolReal(Precision::Confusion());
264 aFF.SetTangentFaces(Standard_False);
267 }//for (; myIterator->More(); myIterator->Next()) {
269 aNbFaceFace=aVFaceFace.Extent();
270 //======================================================
271 BOPAlgo_FaceFaceCnt::Perform(myRunParallel, aVFaceFace);
272 //======================================================
274 for (k=0; k < aNbFaceFace; ++k) {
275 BOPAlgo_FaceFace& aFaceFace=aVFaceFace(k);
277 aFaceFace.Indices(nF1, nF2);
278 aTolFF=aFaceFace.TolFF();
280 bIsDone=aFaceFace.IsDone();
282 aTolR3D=aFaceFace.TolReached3d();
283 aTolR2D=aFaceFace.TolReached2d();
284 aTolReal = aFaceFace.TolReal();
285 bTangentFaces=aFaceFace.TangentFaces();
287 if (aTolR3D < aTolFF){
290 if (aTolReal < aTolFF) {
293 if (aTolR2D < 1.e-7){
297 aFaceFace.PrepareLines3D(bToSplit);
299 const IntTools_SequenceOfCurves& aCvsX=aFaceFace.Lines();
300 const IntTools_SequenceOfPntOn2Faces& aPntsX=aFaceFace.Points();
302 aNbCurves=aCvsX.Length();
303 aNbPoints=aPntsX.Length();
305 if (aNbCurves || aNbPoints) {
306 myDS->AddInterf(nF1, nF2);
309 BOPDS_InterfFF& aFF=aFFs.Append1();
310 aFF.SetIndices(nF1, nF2);
312 aFF.SetTolR3D(aTolR3D);
313 aFF.SetTolR2D(aTolR2D);
314 aFF.SetTolReal(aTolReal);
315 aFF.SetTangentFaces(bTangentFaces);
318 aFF.Init(aNbCurves, aNbPoints);
322 // Fix bounding box expanding coefficient.
323 Standard_Real aBoxExpandValue = aTolR3D;
326 // Modify geometric expanding coefficient by topology value,
327 // since this bounging box used in sharing (vertex or edge).
328 Standard_Real aMaxVertexTol = Max (BRep_Tool::MaxTolerance(aFaceFace.Face1(), TopAbs_VERTEX),
329 BRep_Tool::MaxTolerance(aFaceFace.Face2(), TopAbs_VERTEX));
330 aBoxExpandValue += aMaxVertexTol;
333 BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
334 for (i=1; i<=aNbCurves; ++i) {
337 const IntTools_Curve& aIC=aCvsX(i);
338 const Handle(Geom_Curve)& aC3D= aIC.Curve();
339 bValid=IntTools_Tools::CheckCurve(aC3D, aBoxExpandValue, aBox);
341 BOPDS_Curve& aNC=aVNC.Append1();
348 BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
349 for (i=1; i<=aNbPoints; ++i) {
350 const IntTools_PntOn2Faces& aPi=aPntsX(i);
351 const gp_Pnt& aP=aPi.P1().Pnt();
353 BOPDS_Point& aNP=aVNP.Append1();
356 //}// if (aNbCs || aNbPs)
359 BOPDS_InterfFF& aFF=aFFs.Append1();
360 aFF.SetIndices(nF1, nF2);
363 aFF.Init(aNbCurves, aNbPoints);
365 }// for (k=0; k < aNbFaceFace; ++k) {
367 //=======================================================================
368 //function : MakeBlocks
370 //=======================================================================
371 void BOPAlgo_PaveFiller::MakeBlocks()
373 if (myGlue != BOPAlgo_GlueOff) {
377 Standard_Integer aNbFF;
381 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
387 Standard_Boolean bExist, bValid2D;
388 Standard_Integer i, nF1, nF2, aNbC, aNbP, j;
389 Standard_Integer nV1, nV2;
390 Standard_Real aTolR3D, aT1, aT2;
391 Handle(NCollection_BaseAllocator) aAllocator;
392 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
394 Handle(BOPDS_PaveBlock) aPBOut;
396 //-----------------------------------------------------scope f
398 NCollection_BaseAllocator::CommonBaseAllocator();
400 BOPCol_ListOfInteger aLSE(aAllocator), aLBV(aAllocator);
401 BOPCol_MapOfInteger aMVOnIn(100, aAllocator), aMF(100, aAllocator),
402 aMVStick(100,aAllocator), aMVEF(100, aAllocator),
403 aMI(100, aAllocator), aMVBounds(100, aAllocator);
404 BOPDS_IndexedMapOfPaveBlock aMPBOnIn(100, aAllocator);
405 BOPDS_MapOfPaveBlock aMPBAdd(100, aAllocator), aMPBCommon;
406 BOPDS_ListOfPaveBlock aLPB(aAllocator);
407 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks aMSCPB(100, aAllocator);
408 BOPCol_DataMapOfShapeInteger aMVI(100, aAllocator);
409 BOPDS_DataMapOfPaveBlockListOfPaveBlock aDMExEdges(100, aAllocator);
410 BOPCol_DataMapOfIntegerReal aMVTol(100, aAllocator);
411 BOPCol_DataMapOfIntegerInteger aDMNewSD(100, aAllocator);
412 BOPCol_DataMapOfIntegerListOfInteger aDMVLV;
413 BOPCol_DataMapOfIntegerListOfInteger aDMBV(100, aAllocator);
414 BOPCol_DataMapIteratorOfDataMapOfIntegerReal aItMV;
415 BOPCol_IndexedMapOfShape aMicroEdges(100, aAllocator);
417 for (i=0; i<aNbFF; ++i) {
421 BOPDS_InterfFF& aFF=aFFs(i);
422 aFF.Indices(nF1, nF2);
424 BOPDS_VectorOfPoint& aVP=aFF.ChangePoints();
426 BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
428 if (!aNbP && !aNbC) {
432 const TopoDS_Face& aF1=(*(TopoDS_Face *)(&myDS->Shape(nF1)));
433 const TopoDS_Face& aF2=(*(TopoDS_Face *)(&myDS->Shape(nF2)));
435 aTolR3D=aFF.TolR3D();
439 myDS->UpdateFaceInfoOn(nF1);
440 myDS->UpdateFaceInfoIn(nF1);
443 myDS->UpdateFaceInfoOn(nF2);
444 myDS->UpdateFaceInfoIn(nF2);
447 BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
448 BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
457 myDS->SubShapesOnIn(nF1, nF2, aMVOnIn, aMPBOnIn, aMPBCommon);
458 myDS->SharedEdges(nF1, nF2, aLSE, aAllocator);
461 for (j=0; j<aNbP; ++j) {
463 BOPDS_CoupleOfPaveBlocks aCPB;
465 BOPDS_Point& aNP=aVP.ChangeValue(j);
466 const gp_Pnt& aP=aNP.Pnt();
468 bExist=IsExistingVertex(aP, aTolR3D, aMVOnIn);
470 BOPTools_AlgoTools::MakeNewVertex(aP, aTolR3D, aV);
472 aCPB.SetIndexInterf(i);
474 aMSCPB.Add(aV, aCPB);
481 GetStickVertices(nF1, nF2, aMVStick, aMVEF, aMI);
483 for (j = 0; j < aNbC; ++j) {
484 BOPDS_Curve& aNC = aVC.ChangeValue(j);
486 aNC.InitPaveBlock1();
488 PutPavesOnCurve(aMVOnIn, aTolR3D, aNC, nF1, nF2, aMI, aMVEF, aMVTol, aDMVLV);
491 // if some E-F vertex was put on a curve due to large E-F intersection range,
492 // and it also was put on another curve correctly then remove this vertex from
493 // the first curve. Detect such case if the distance to curve exceeds aTolR3D.
494 FilterPavesOnCurves(aVC, aTolR3D);
496 for (j = 0; j<aNbC; ++j) {
497 BOPDS_Curve& aNC=aVC.ChangeValue(j);
498 const IntTools_Curve& aIC=aNC.Curve();
500 PutStickPavesOnCurve(aF1, aF2, aMI, aNC, aMVStick, aMVTol, aDMVLV);
503 PutEFPavesOnCurve(aNC, aMI, aMVEF, aMVTol, aDMVLV);
506 if (aIC.HasBounds()) {
509 PutBoundPaveOnCurve(aF1, aF2, aTolR3D, aNC, aLBV);
511 if (!aLBV.IsEmpty()) {
513 BOPCol_ListIteratorOfListOfInteger aItI(aLBV);
514 for (; aItI.More(); aItI.Next()) {
515 aMVBounds.Add(aItI.Value());
519 }//for (j=0; j<aNbC; ++j) {
521 // Put closing pave if needed
522 for (j=0; j<aNbC; ++j) {
523 BOPDS_Curve& aNC=aVC.ChangeValue(j);
524 PutClosingPaveOnCurve (aNC);
527 // 3. Make section edges
528 for (j=0; j<aNbC; ++j) {
529 BOPDS_Curve& aNC=aVC.ChangeValue(j);
530 const IntTools_Curve& aIC=aNC.Curve();
532 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
533 Handle(BOPDS_PaveBlock)& aPB1=aNC.ChangePaveBlock1();
536 aPB1->Update(aLPB, Standard_False);
538 aItLPB.Initialize(aLPB);
539 for (; aItLPB.More(); aItLPB.Next()) {
540 Handle(BOPDS_PaveBlock)& aPB=aItLPB.ChangeValue();
541 aPB->Indices(nV1, nV2);
542 aPB->Range (aT1, aT2);
544 if (fabs(aT1 - aT2) < Precision::PConfusion()) {
548 bValid2D=myContext->IsValidBlockForFaces(aT1, aT2, aIC,
554 bExist=IsExistingPaveBlock(aPB, aNC, aLSE);
559 const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
560 const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
563 BOPTools_AlgoTools::MakeEdge (aIC, aV1, aT1, aV2, aT2, aTolR3D, aES);
565 // check for micro edge
566 if (BOPTools_AlgoTools::IsMicroEdge(aES, myContext, Standard_False)) {
567 // If the section edge is a micro edge, i.e. the whole edge is
568 // covered by the tolerance spheres of its vertices, it will be
569 // passed into post treatment process to fuse its vertices.
570 // The edge itself will not be kept.
571 if (!aMVBounds.Contains(nV1) && !aMVBounds.Contains(nV2)) {
572 aMicroEdges.Add(aES);
573 // keep vertices for post treatment
580 Standard_Real aTolNew;
581 bExist=IsExistingPaveBlock(aPB, aNC, aTolR3D, aMPBOnIn, aMPBCommon, aPBOut, aTolNew);
583 if (aMPBAdd.Add(aPBOut)) {
584 Standard_Boolean bInBothFaces = Standard_True;
585 if (!myDS->IsCommonBlock(aPBOut)) {
590 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(nE);
591 aTolE = BRep_Tool::Tolerance(aE);
592 if (aTolNew < aFF.TolReal())
593 aTolNew = aFF.TolReal(); // use real tolerance of intersection
594 if (aTolNew > aTolE) {
595 UpdateEdgeTolerance(nE, aTolNew);
597 bInBothFaces = Standard_False;
600 bInBothFaces = (aFI1.PaveBlocksOn().Contains(aPBOut) ||
601 aFI1.PaveBlocksIn().Contains(aPBOut))&&
602 (aFI2.PaveBlocksOn().Contains(aPBOut) ||
603 aFI2.PaveBlocksIn().Contains(aPBOut));
606 PreparePostTreatFF(i, j, aPBOut, aMSCPB, aMVI, aLPBC);
613 BOPTools_AlgoTools::MakePCurve(aES, aF1, aF2, aIC,
614 mySectionAttribute.PCurveOnS1(),
615 mySectionAttribute.PCurveOnS2(),
618 // Append the Pave Block to the Curve j
621 // Keep info for post treatment
622 BOPDS_CoupleOfPaveBlocks aCPB;
623 aCPB.SetIndexInterf(i);
625 aCPB.SetPaveBlock1(aPB);
627 aMSCPB.Add(aES, aCPB);
636 }//for (j=0; j<aNbC; ++j) {
638 //back to previous tolerance values for unused vertices
639 //and forget about SD groups of such vertices
640 aItMV.Initialize(aMVTol);
641 for (; aItMV.More(); aItMV.Next()) {
643 Standard_Real aTol = aItMV.Value();
645 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&myDS->Shape(nV1);
646 const Handle(BRep_TVertex)& TV =
647 *((Handle(BRep_TVertex)*)&aV.TShape());
650 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV1);
651 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
653 BRepBndLib::Add(aV, aBoxDS);
654 aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
656 if (aDMVLV.IsBound(nV1))
660 ProcessExistingPaveBlocks(i, aMPBOnIn, aDMBV, aMSCPB, aMVI, aMPBAdd);
661 }//for (i=0; i<aNbFF; ++i) {
664 MakeSDVerticesFF(aDMVLV, aDMNewSD);
665 myErrorStatus=PostTreatFF(aMSCPB, aMVI, aDMExEdges, aDMNewSD, aMicroEdges, aAllocator);
669 // reduce tolerances of section edges where it is appropriate
670 CorrectToleranceOfSE();
673 UpdateFaceInfo(aDMExEdges, aDMNewSD);
674 //Update all pave blocks
675 UpdatePaveBlocks(aDMNewSD);
676 //-----------------------------------------------------scope t
686 //=======================================================================
687 //function : MakeSDVerticesFF
689 //=======================================================================
690 void BOPAlgo_PaveFiller::MakeSDVerticesFF
691 (const BOPCol_DataMapOfIntegerListOfInteger& theDMVLV,
692 BOPCol_DataMapOfIntegerInteger& theDMNewSD)
694 // Create a new SD vertex for each group of coinciding vertices
695 // and put new substitutions to theDMNewSD.
696 BOPCol_DataMapIteratorOfDataMapOfIntegerListOfInteger aItG(theDMVLV);
697 for (; aItG.More(); aItG.Next()) {
698 const BOPCol_ListOfInteger& aList = aItG.Value();
699 // make SD vertices w/o creation of interfs
700 Standard_Integer nSD = MakeSDVertices(aList, Standard_False);
702 BOPCol_ListIteratorOfListOfInteger aItL(aList);
703 for (; aItL.More(); aItL.Next()) {
704 Standard_Integer nV = aItL.Value();
705 theDMNewSD.Bind(nV, nSD);
710 //=======================================================================
711 //function : PostTreatFF
713 //=======================================================================
714 Standard_Integer BOPAlgo_PaveFiller::PostTreatFF
715 (BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& theMSCPB,
716 BOPCol_DataMapOfShapeInteger& aMVI,
717 BOPDS_DataMapOfPaveBlockListOfPaveBlock& aDMExEdges,
718 BOPCol_DataMapOfIntegerInteger& aDMNewSD,
719 const BOPCol_IndexedMapOfShape& theMicroEdges,
720 const Handle(NCollection_BaseAllocator)& theAllocator)
722 Standard_Integer iRet, aNbS;
725 aNbS=theMSCPB.Extent();
730 Standard_Boolean bHasPaveBlocks, bOld;
731 Standard_Integer iErr, nSx, nVSD, iX, iP, iC, j, nV, iV = 0, iE, k;
732 Standard_Integer aNbLPBx;
733 TopAbs_ShapeEnum aType;
735 BOPCol_ListIteratorOfListOfShape aItLS;
736 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
738 Handle(BOPDS_PaveBlock) aPB1;
742 BOPCol_ListOfShape aLS(theAllocator);
743 BOPAlgo_PaveFiller aPF(theAllocator);
744 aPF.SetIsPrimary(Standard_False);
745 aPF.SetNonDestructive(myNonDestructive);
747 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
749 Standard_Integer aNbME = theMicroEdges.Extent();
751 if (aNbS==1 && (aNbME == 0)) {
752 const TopoDS_Shape& aS=theMSCPB.FindKey(1);
753 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromIndex(1);
755 aType=aS.ShapeType();
756 if (aType==TopAbs_VERTEX) {
757 aSI.SetShapeType(aType);
759 iV=myDS->Append(aSI);
761 iX=aCPB.IndexInterf();
763 BOPDS_InterfFF& aFF=aFFs(iX);
764 BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
765 BOPDS_Point& aNP=aVNP(iP);
768 else if (aType==TopAbs_EDGE) {
769 aPB1=aCPB.PaveBlock1();
771 if (aPB1->HasEdge()) {
772 BOPDS_ListOfPaveBlock aLPBx;
774 aDMExEdges.Bind(aPB1, aLPBx);
776 aSI.SetShapeType(aType);
778 iE=myDS->Append(aSI);
786 // 1 prepare arguments
787 for (k=1; k<=aNbS; ++k) {
788 const TopoDS_Shape& aS=theMSCPB.FindKey(k);
792 // The section edges considered as a micro should be
793 // specially treated - their vertices should be united and
794 // the edge itself should be removed. Thus, we add only
795 // its vertices into operation.
798 for (k = 1; k <= aNbME; ++k) {
799 const TopoDS_Edge& aEM = TopoDS::Edge(theMicroEdges(k));
801 TopoDS_Vertex aV1, aV2;
802 TopExp::Vertices(aEM, aV1, aV2);
807 // make sure these vertices will be united
808 const gp_Pnt& aP1 = BRep_Tool::Pnt(aV1);
809 const gp_Pnt& aP2 = BRep_Tool::Pnt(aV2);
811 Standard_Real aDist = aP1.Distance(aP2);
812 Standard_Real aTolV1 = BRep_Tool::Tolerance(aV1);
813 Standard_Real aTolV2 = BRep_Tool::Tolerance(aV2);
815 aDist -= (aTolV1 + aTolV2);
818 aBB.UpdateVertex(aV1, aTolV1 + aDist);
819 aBB.UpdateVertex(aV2, aTolV2 + aDist);
824 aPF.SetProgressIndicator(myProgressIndicator);
825 aPF.SetRunParallel(myRunParallel);
826 aPF.SetArguments(aLS);
828 iErr=aPF.ErrorStatus();
834 aItLS.Initialize(aLS);
835 for (; aItLS.More(); aItLS.Next()) {
836 const TopoDS_Shape& aSx=aItLS.Value();
837 nSx=aPDS->Index(aSx);
838 const BOPDS_ShapeInfo& aSIx=aPDS->ShapeInfo(nSx);
840 aType=aSIx.ShapeType();
842 if (aType==TopAbs_VERTEX) {
843 Standard_Boolean bIntersectionPoint = theMSCPB.Contains(aSx);
845 if (aPDS->HasShapeSD(nSx, nVSD)) {
846 aV=aPDS->Shape(nVSD);
851 // index of new vertex in theDS -> iV
852 if (!aMVI.IsBound(aV)) {
853 aSI.SetShapeType(aType);
855 iV=myDS->Append(aSI);
863 if (!bIntersectionPoint) {
864 // save SD connection
865 nSx = aMVI.Find(aSx);
866 aDMNewSD.Bind(nSx, iV);
867 myDS->AddShapeSD(nSx, iV);
870 // update FF interference
871 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
872 iX=aCPB.IndexInterf();
874 BOPDS_InterfFF& aFF=aFFs(iX);
875 BOPDS_VectorOfPoint& aVNP=aFF.ChangePoints();
876 BOPDS_Point& aNP=aVNP(iP);
879 }//if (aType==TopAbs_VERTEX) {
881 else if (aType==TopAbs_EDGE) {
882 bHasPaveBlocks=aPDS->HasPaveBlocks(nSx);
883 const BOPDS_CoupleOfPaveBlocks &aCPB=theMSCPB.FindFromKey(aSx);
884 iX=aCPB.IndexInterf();
886 aPB1=aCPB.PaveBlock1();
888 bOld = aPB1->HasEdge();
890 BOPDS_ListOfPaveBlock aLPBx;
891 aDMExEdges.Bind(aPB1, aLPBx);
894 if (!bHasPaveBlocks) {
896 aDMExEdges.ChangeFind(aPB1).Append(aPB1);
899 aSI.SetShapeType(aType);
901 iE = myDS->Append(aSI);
907 BOPDS_InterfFF& aFF=aFFs(iX);
908 BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
909 BOPDS_Curve& aNC=aVNC(iC);
910 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
912 // check if edge occured to be micro edge;
913 // note we check not the edge aSx itself, but its image in aPDS
914 const BOPDS_ListOfPaveBlock& aLPBx = aPDS->PaveBlocks(nSx);
915 aNbLPBx = aLPBx.Extent();
916 if (aPDS->HasPaveBlocks(nSx) &&
917 (aNbLPBx == 0 || (aNbLPBx == 1 && !aLPBx.First()->HasShrunkData()))) {
918 BOPDS_ListIteratorOfListOfPaveBlock it(aLPBC);
919 for (; it.More(); it.Next()) {
920 if (it.Value() == aPB1) {
928 if (bOld && !aNbLPBx) {
929 aDMExEdges.ChangeFind(aPB1).Append(aPB1);
934 aItLPB.Initialize(aLPBC);
935 for (; aItLPB.More(); aItLPB.Next()) {
936 const Handle(BOPDS_PaveBlock)& aPBC=aItLPB.Value();
938 aLPBC.Remove(aItLPB);
947 if (!aMVI.IsBound(aE)) {
948 aSI.SetShapeType(aType);
950 iE=myDS->Append(aSI);
956 // append new PaveBlock to aLPBC
962 aItLPB.Initialize(aLPBx);
963 for (; aItLPB.More(); aItLPB.Next()) {
964 const Handle(BOPDS_PaveBlock)& aPBx=aItLPB.Value();
965 const Handle(BOPDS_PaveBlock) aPBRx=aPDS->RealPaveBlock(aPBx);
967 // update vertices of paves
968 aPave[0]=aPBx->Pave1();
969 aPave[1]=aPBx->Pave2();
970 for (j=0; j<2; ++j) {
971 nV = aPave[j].Index();
972 aV = aPDS->Shape(nV);
974 if (!aMVI.IsBound(aV)) {
975 // index of new vertex in theDS -> iV
976 aSI.SetShapeType(TopAbs_VERTEX);
978 iV = myDS->Append(aSI);
984 const BOPDS_Pave& aP1 = !j ? aPB1->Pave1() : aPB1->Pave2();
985 if (aP1.Parameter() == aPave[j].Parameter() &&
987 aDMNewSD.Bind(aP1.Index(), iV);
988 myDS->AddShapeSD(aP1.Index(), iV);
991 aPave[j].SetIndex(iV);
995 aE=aPDS->Shape(aPBRx->Edge());
997 if (!aMVI.IsBound(aE)) {
998 aSI.SetShapeType(aType);
1000 iE=myDS->Append(aSI);
1002 // update real edge tolerance according to distances in common block if any
1003 if (aPDS->IsCommonBlock(aPBx)) {
1004 const Handle(BOPDS_CommonBlock)& aCB = aPDS->CommonBlock(aPBx);
1005 Standard_Real aTol = BOPAlgo_Tools::ComputeToleranceOfCB(aCB, aPDS, aPF.Context());
1006 if (aFF.TolReal() < aTol) {
1007 aFF.SetTolReal(aTol);
1014 // append new PaveBlock to aLPBC
1015 Handle(BOPDS_PaveBlock) aPBC=new BOPDS_PaveBlock();
1017 aPBC->SetPave1(aPave[0]);
1018 aPBC->SetPave2(aPave[1]);
1021 aPBC->SetOriginalEdge(aPB1->OriginalEdge());
1022 aDMExEdges.ChangeFind(aPB1).Append(aPBC);
1030 }//else if (aType==TopAbs_EDGE)
1031 }//for (; aItLS.More(); aItLS.Next()) {
1035 //=======================================================================
1036 //function : UpdateFaceInfo
1038 //=======================================================================
1039 void BOPAlgo_PaveFiller::UpdateFaceInfo
1040 (BOPDS_DataMapOfPaveBlockListOfPaveBlock& theDME,
1041 const BOPCol_DataMapOfIntegerInteger& theDMV)
1043 Standard_Integer i, j, nV1, nF1, nF2,
1045 BOPDS_ListIteratorOfListOfPaveBlock aItLPB;
1046 BOPCol_MapOfInteger aMF;
1048 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
1049 aNbFF=aFFs.Extent();
1051 //1. Sections (curves, points);
1052 for (i=0; i<aNbFF; ++i) {
1053 BOPDS_InterfFF& aFF=aFFs(i);
1054 aFF.Indices(nF1, nF2);
1056 BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
1057 BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
1059 // 1.1. Section edges
1060 BOPDS_VectorOfCurve& aVNC=aFF.ChangeCurves();
1062 for (j=0; j<aNbC; ++j) {
1063 BOPDS_Curve& aNC=aVNC(j);
1064 BOPDS_ListOfPaveBlock& aLPBC=aNC.ChangePaveBlocks();
1066 // Add section edges to face info
1067 aItLPB.Initialize(aLPBC);
1068 for (; aItLPB.More(); ) {
1069 const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value();
1071 // Treat existing pave blocks
1072 if (theDME.IsBound(aPB)) {
1073 BOPDS_ListOfPaveBlock& aLPB=theDME.ChangeFind(aPB);
1074 UpdateExistingPaveBlocks(aPB, aLPB, nF1, nF2);
1075 aLPBC.Remove(aItLPB);
1079 aFI1.ChangePaveBlocksSc().Add(aPB);
1080 aFI2.ChangePaveBlocksSc().Add(aPB);
1085 // 1.2. Section vertices
1086 const BOPDS_VectorOfPoint& aVNP=aFF.Points();
1088 for (j=0; j<aNbP; ++j) {
1089 const BOPDS_Point& aNP=aVNP(j);
1094 aFI1.ChangeVerticesSc().Add(nV1);
1095 aFI2.ChangeVerticesSc().Add(nV1);
1102 Standard_Boolean bVerts, bEdges;
1104 bVerts = theDMV.Extent() > 0;
1105 bEdges = theDME.Extent() > 0;
1107 if (!bVerts && !bEdges) {
1111 // 2. Update Face Info information with new vertices and new
1112 // pave blocks created in PostTreatFF from existing ones
1113 Standard_Integer nV2, aNbPB;
1114 BOPCol_MapIteratorOfMapOfInteger aItMF;
1115 BOPCol_DataMapIteratorOfDataMapOfIntegerInteger aItMV;
1117 aItMF.Initialize(aMF);
1118 for (; aItMF.More(); aItMF.Next()) {
1119 nF1 = aItMF.Value();
1121 BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF1);
1123 // 2.1. Update information about vertices
1125 BOPCol_MapOfInteger& aMVOn = aFI.ChangeVerticesOn();
1126 BOPCol_MapOfInteger& aMVIn = aFI.ChangeVerticesIn();
1128 aItMV.Initialize(theDMV);
1129 for (; aItMV.More(); aItMV.Next()) {
1131 nV2 = aItMV.Value();
1133 if (aMVOn.Remove(nV1)) {
1137 if (aMVIn.Remove(nV1)) {
1140 } // for (; aItMV.More(); aItMV.Next()) {
1143 // 2.2. Update information about pave blocks
1145 BOPDS_IndexedMapOfPaveBlock& aMPBOn = aFI.ChangePaveBlocksOn();
1146 BOPDS_IndexedMapOfPaveBlock& aMPBIn = aFI.ChangePaveBlocksIn();
1148 BOPDS_IndexedMapOfPaveBlock aMPBCopy;
1149 for (i = 0; i < 2; ++i) {
1150 BOPDS_IndexedMapOfPaveBlock& aMPBOnIn = !i ? aMPBOn : aMPBIn;
1151 aMPBCopy = aMPBOnIn;
1154 aNbPB = aMPBCopy.Extent();
1155 for (j = 1; j <= aNbPB; ++j) {
1156 const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(j);
1157 if (theDME.IsBound(aPB)) {
1158 const BOPDS_ListOfPaveBlock& aLPB = theDME.Find(aPB);
1159 if (aLPB.IsEmpty()) {
1164 aItLPB.Initialize(aLPB);
1165 for (; aItLPB.More(); aItLPB.Next()) {
1166 const Handle(BOPDS_PaveBlock)& aPB1 = aItLPB.Value();
1173 } // for (j = 1; j <= aNbPB; ++j) {
1174 } // for (i = 0; i < 2; ++i) {
1178 //=======================================================================
1179 //function : IsExistingVertex
1181 //=======================================================================
1182 Standard_Boolean BOPAlgo_PaveFiller::IsExistingVertex
1184 const Standard_Real theTolR3D,
1185 const BOPCol_MapOfInteger& aMVOnIn)const
1187 Standard_Boolean bRet;
1188 Standard_Integer nV, iFlag;
1189 Standard_Real aTolCheck;
1192 BOPCol_MapIteratorOfMapOfInteger aIt;
1194 aTolCheck = theTolR3D + myFuzzyValue;
1198 aBoxP.Enlarge(theTolR3D);
1200 aIt.Initialize(aMVOnIn);
1201 for (; aIt.More(); aIt.Next()) {
1203 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1204 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aSIV.Shape()));
1205 const Bnd_Box& aBoxV=aSIV.Box();
1207 if (!aBoxP.IsOut(aBoxV)) {
1208 iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP, aTolCheck);
1216 //=======================================================================
1217 //function : IsExistingPaveBlock
1219 //=======================================================================
1220 Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
1221 (const Handle(BOPDS_PaveBlock)& thePB,
1222 const BOPDS_Curve& theNC,
1223 const BOPCol_ListOfInteger& theLSE)
1225 Standard_Boolean bRet=Standard_True;
1227 if (theLSE.IsEmpty()) {
1231 Standard_Real aT1, aT2, aTm, aTx, aTolE, aTolCheck, aTol, aDist;
1232 Standard_Integer nE, iFlag, nV1, nV2;
1235 BOPCol_ListIteratorOfListOfInteger aItLI;
1237 thePB->Range(aT1, aT2);
1238 thePB->Indices(nV1, nV2);
1239 const TopoDS_Vertex &aV1 = TopoDS::Vertex(myDS->Shape(nV1)),
1240 &aV2 = TopoDS::Vertex(myDS->Shape(nV2));
1241 const Standard_Real aTolV1 = BRep_Tool::Tolerance(aV1),
1242 aTolV2 = BRep_Tool::Tolerance(aV2);
1244 aTol = Max(aTolV1, aTolV2);
1246 aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
1247 theNC.Curve().D0(aTm, aPm);
1249 aBoxPm.Enlarge(aTol);
1251 aItLI.Initialize(theLSE);
1252 for (; aItLI.More(); aItLI.Next()) {
1256 const BOPDS_ShapeInfo& aSIE=myDS->ChangeShapeInfo(nE);
1257 const Bnd_Box& aBoxE=aSIE.Box();
1258 if (!aBoxE.IsOut(aBoxPm)) {
1259 const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&aSIE.Shape()));
1260 aTolE = BRep_Tool::Tolerance(aE);
1261 aTolCheck = Max(aTolE, aTol) + myFuzzyValue;
1262 iFlag = myContext->ComputePE(aPm, aTolCheck, aE, aTx, aDist);
1271 //=======================================================================
1272 //function : IsExistingPaveBlock
1274 //=======================================================================
1275 Standard_Boolean BOPAlgo_PaveFiller::IsExistingPaveBlock
1276 (const Handle(BOPDS_PaveBlock)& thePB,
1277 const BOPDS_Curve& theNC,
1278 const Standard_Real theTolR3D,
1279 const BOPDS_IndexedMapOfPaveBlock& theMPBOnIn,
1280 const BOPDS_MapOfPaveBlock& theMPBCommon,
1281 Handle(BOPDS_PaveBlock)& aPBOut,
1282 Standard_Real& theTolNew)
1284 Standard_Boolean bRet;
1285 Standard_Real aT1, aT2, aTm, aTx, aTolCheck;
1286 Standard_Integer nSp, iFlag1, iFlag2, nV11, nV12, nV21, nV22, i, aNbPB;
1287 gp_Pnt aP1, aPm, aP2;
1288 Bnd_Box aBoxP1, aBoxPm, aBoxP2, aBoxTmp;
1290 bRet=Standard_False;
1291 aTolCheck = theTolR3D + myFuzzyValue;
1292 const IntTools_Curve& aIC=theNC.Curve();
1294 thePB->Range(aT1, aT2);
1295 thePB->Indices(nV11, nV12);
1296 const Standard_Real aTolV11 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV11)));
1297 const Standard_Real aTolV12 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV12)));
1298 const Standard_Real aTolV1 = Max(aTolV11, aTolV12) + myFuzzyValue;
1303 aBoxP1.Enlarge(aTolV11);
1304 //intermediate point
1305 aTm=IntTools_Tools::IntermediatePoint (aT1, aT2);
1311 aBoxP2.Enlarge(aTolV12);
1314 aNbPB = theMPBOnIn.Extent();
1315 for (i = 1; i <= aNbPB; ++i) {
1316 const Handle(BOPDS_PaveBlock)& aPB = theMPBOnIn(i);
1317 aPB->Indices(nV21, nV22);
1318 const Standard_Real aTolV21 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV21)));
1319 const Standard_Real aTolV22 = BRep_Tool::Tolerance(TopoDS::Vertex(myDS->Shape(nV22)));
1320 const Standard_Real aTolV2 = Max(aTolV21, aTolV22) + myFuzzyValue;
1324 const BOPDS_ShapeInfo& aSISp=myDS->ChangeShapeInfo(nSp);
1325 const TopoDS_Edge& aSp=(*(TopoDS_Edge *)(&aSISp.Shape()));
1326 const Bnd_Box& aBoxSp=aSISp.Box();
1328 iFlag1 = (nV11 == nV21 || nV11 == nV22) ? 2 :
1329 (!aBoxSp.IsOut(aBoxP1) ? 1 : 0);
1330 iFlag2 = (nV12 == nV21 || nV12 == nV22) ? 2 :
1331 (!aBoxSp.IsOut(aBoxP2) ? 1 : 0);
1332 if (iFlag1 && iFlag2) {
1333 Standard_Real aDist = 0.;
1335 Standard_Real aRealTol = aTolCheck;
1336 if (myDS->IsCommonBlock(aPB))
1338 aRealTol = Max(aRealTol, Max(aTolV1, aTolV2));
1339 if (theMPBCommon.Contains(aPB))
1340 // for an edge, which is a common block with a face,
1341 // increase the chance to coincide with section curve
1346 aBoxTmp.Enlarge(aRealTol);
1348 if (aBoxSp.IsOut(aBoxTmp) || myContext->ComputePE(aPm,
1356 iFlag1 = !myContext->ComputePE(aP1, aRealTol, aSp, aTx, aDist);
1357 if (iFlag1 && theTolNew < aDist)
1362 iFlag2 = !myContext->ComputePE(aP2, aRealTol, aSp, aTx, aDist);
1363 if (iFlag2 && theTolNew < aDist)
1367 if (iFlag1 && iFlag2) {
1376 //=======================================================================
1377 //function : PutBoundPaveOnCurve
1379 //=======================================================================
1380 void BOPAlgo_PaveFiller::PutBoundPaveOnCurve(const TopoDS_Face& aF1,
1381 const TopoDS_Face& aF2,
1382 const Standard_Real aTolR3D,
1384 BOPCol_ListOfInteger& aLVB)
1386 Standard_Boolean bVF;
1387 Standard_Integer nV, iFlag, nVn, j, aNbEP;
1388 Standard_Real aT[2], aTmin, aTmax, aTV, aTol, aTolVnew;
1391 BOPDS_ListIteratorOfListOfPave aItLP;
1392 BOPDS_Pave aPn, aPMM[2];
1394 aTolVnew = Precision::Confusion();
1396 const IntTools_Curve& aIC=aNC.Curve();
1397 aIC.Bounds(aT[0], aT[1], aP[0], aP[1]);
1399 Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
1400 const BOPDS_ListOfPave& aLP=aPB->ExtPaves();
1407 aItLP.Initialize(aLP);
1408 for (; aItLP.More(); aItLP.Next()) {
1409 const BOPDS_Pave& aPv=aItLP.Value();
1410 aPv.Contents(nV, aTV);
1422 for (j=0; j<2; ++j) {
1423 //if curve is closed, process only one bound
1424 if (j && aP[1].IsEqual(aP[0], aTolVnew)) {
1434 aTol = aTolR3D+Precision::Confusion();
1435 aBoxP.Enlarge(aTol);
1436 const BOPDS_Pave& aPV=aPMM[j];
1438 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1439 const TopoDS_Vertex& aV=(*(TopoDS_Vertex *)(&aSIV.Shape()));
1440 const Bnd_Box& aBoxV=aSIV.Box();
1441 if (!aBoxP.IsOut(aBoxV)){
1442 iFlag=BOPTools_AlgoTools::ComputeVV(aV, aP[j], aTol);
1447 bVF=myContext->IsValidPointForFaces (aP[j], aF1, aF2, aTolR3D);
1452 BOPDS_ShapeInfo aSIVn;
1454 BOPTools_AlgoTools::MakeNewVertex(aP[j], aTolR3D, aVn);
1455 aSIVn.SetShapeType(TopAbs_VERTEX);
1456 aSIVn.SetShape(aVn);
1458 nVn=myDS->Append(aSIVn);
1461 aPn.SetParameter(aT[j]);
1462 aPB->AppendExtPave(aPn);
1464 aVn=(*(TopoDS_Vertex *)(&myDS->Shape(nVn)));
1465 BOPTools_AlgoTools::UpdateVertex (aIC, aT[j], aVn);
1467 aTolVnew = BRep_Tool::Tolerance(aVn);
1469 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nVn);
1470 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
1471 BRepBndLib::Add(aVn, aBoxDS);
1472 aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
1479 //=======================================================================
1480 //function : PutPavesOnCurve
1482 //=======================================================================
1483 void BOPAlgo_PaveFiller::PutPavesOnCurve
1484 (const BOPCol_MapOfInteger& aMVOnIn,
1485 const Standard_Real aTolR3D,
1487 const Standard_Integer nF1,
1488 const Standard_Integer nF2,
1489 const BOPCol_MapOfInteger& aMI,
1490 const BOPCol_MapOfInteger& aMVEF,
1491 BOPCol_DataMapOfIntegerReal& aMVTol,
1492 BOPCol_DataMapOfIntegerListOfInteger& aDMVLV)
1494 Standard_Boolean bInBothFaces;
1495 Standard_Integer nV;
1496 BOPCol_MapIteratorOfMapOfInteger aIt;
1498 const Bnd_Box& aBoxC=aNC.Box();
1500 //Put EF vertices first
1501 aIt.Initialize(aMVEF);
1502 for (; aIt.More(); aIt.Next()) {
1504 PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 2);
1506 //Put all other vertices
1507 aIt.Initialize(aMVOnIn);
1508 for (; aIt.More(); aIt.Next()) {
1510 if (aMVEF.Contains(nV)) {
1514 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
1515 const Bnd_Box& aBoxV=aSIV.Box();
1517 if (aBoxC.IsOut(aBoxV)){
1520 if (!myDS->IsNewShape(nV)) {
1521 const BOPDS_FaceInfo& aFI1 = myDS->FaceInfo(nF1);
1522 const BOPDS_FaceInfo& aFI2 = myDS->FaceInfo(nF2);
1524 bInBothFaces = (aFI1.VerticesOn().Contains(nV) ||
1525 aFI1.VerticesIn().Contains(nV))&&
1526 (aFI2.VerticesOn().Contains(nV) ||
1527 aFI2.VerticesIn().Contains(nV));
1528 if (!bInBothFaces) {
1533 PutPaveOnCurve(nV, aTolR3D, aNC, aMI, aMVTol, aDMVLV, 1);
1537 //=======================================================================
1538 //function : FilterPavesOnCurves
1540 //=======================================================================
1542 struct PaveBlockDist {
1543 Handle(BOPDS_PaveBlock) PB;
1544 Standard_Real Dist; // square distance from vertex to the paveblock
1545 Standard_Real SinAngle; // sinus of angle between projection vector
1546 // and tangent at projection point
1549 void BOPAlgo_PaveFiller::FilterPavesOnCurves(const BOPDS_VectorOfCurve& theVNC,
1550 const Standard_Real theTolR3D)
1552 Standard_Real aSqTol = theTolR3D * theTolR3D;
1554 // For each vertex found in ExtPaves of pave blocks of section curves
1555 // collect list of pave blocks with distance to the curve
1556 NCollection_IndexedDataMap<Standard_Integer,NCollection_List<PaveBlockDist> > aIDMVertPBs;
1558 const Standard_Real anEps = gp::Resolution();
1559 for (i = 0; i < theVNC.Extent(); ++i)
1561 const BOPDS_Curve& aNC = theVNC(i);
1562 const IntTools_Curve& aIC = aNC.Curve();
1563 GeomAdaptor_Curve aGAC(aIC.Curve());
1564 const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First();
1565 const BOPDS_ListOfPave& aPaves = aPB->ExtPaves();
1566 BOPDS_ListOfPave::Iterator itPaves(aPaves);
1567 for (; itPaves.More(); itPaves.Next())
1569 const BOPDS_Pave& aPave = itPaves.Value();
1570 Standard_Integer nV = aPave.Index();
1571 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
1572 // compute distance from vertex to the point on curve with vertex parameter
1573 gp_Pnt aPV = BRep_Tool::Pnt(aV);
1574 Standard_Real aPar = aPave.Parameter();
1577 aGAC.D1(aPar, aPonC, aD1);
1578 gp_Vec aProjVec(aPV, aPonC);
1579 Standard_Real aSqDist = aProjVec.SquareMagnitude();
1580 Standard_Real aSqD1Mod = aD1.SquareMagnitude();
1581 Standard_Real aSin = aProjVec.CrossSquareMagnitude(aD1);
1582 if (aSqDist > anEps && aSqD1Mod > anEps)
1583 aSin = sqrt(aSin / aSqDist / aSqD1Mod);
1584 NCollection_List<PaveBlockDist>* pList = aIDMVertPBs.ChangeSeek(nV);
1586 pList = &aIDMVertPBs.ChangeFromIndex(aIDMVertPBs.Add(nV, NCollection_List<PaveBlockDist>()));
1587 PaveBlockDist aPBD = { aPB, aSqDist, aSin };
1588 pList->Append(aPBD);
1592 // Process each vertex
1593 const Standard_Real aSinAngleMin = 0.5; // angle below which projection is suspicious
1594 for (i = 1; i <= aIDMVertPBs.Extent(); i++)
1596 Standard_Integer nV = aIDMVertPBs.FindKey(i);
1597 const NCollection_List<PaveBlockDist>& aList = aIDMVertPBs(i);
1598 // Find a pave with minimal distance
1599 Standard_Real aMinDist = RealLast();
1600 Handle(BOPDS_PaveBlock) aPBMinDist;
1601 NCollection_List<PaveBlockDist>::Iterator itL(aList);
1602 for (; itL.More(); itL.Next())
1604 const PaveBlockDist& aPBD = itL.Value();
1605 if (aPBD.Dist < aMinDist)
1607 aMinDist = aPBD.Dist;
1608 aPBMinDist = aPBD.PB;
1611 // Remove a vertex from a pave block if the distance is greater than the tolerance
1612 // and there are other pave blocks for which the distance is less than the current.
1613 // Do not remove a vertex if it is projected on the curve with quite large angle
1614 // (see test bugs modalg_6 bug27761).
1615 Standard_Real aCheckDist = 100. * Max(aSqTol, aMinDist);
1616 for (itL.Init(aList); itL.More(); itL.Next())
1618 const PaveBlockDist& aPBD = itL.Value();
1619 if (aPBD.Dist > aCheckDist && aPBD.SinAngle < aSinAngleMin)
1621 aPBD.PB->RemoveExtPave(nV);
1627 //=======================================================================
1628 //function : ExtendedTolerance
1630 //=======================================================================
1631 Standard_Boolean BOPAlgo_PaveFiller::ExtendedTolerance
1632 (const Standard_Integer nV,
1633 const BOPCol_MapOfInteger& aMI,
1634 Standard_Real& aTolVExt,
1635 const Standard_Integer aType)
1637 Standard_Boolean bFound = Standard_False;
1638 if (!(myDS->IsNewShape(nV))) {
1642 Standard_Integer i, k, aNbLines, aNbInt;
1643 Standard_Real aT11, aT12, aD1, aD2, aD;
1645 gp_Pnt aPV, aP11, aP12;
1651 } else if (aType == 2) {
1655 aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1656 aPV=BRep_Tool::Pnt(aV);
1658 BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
1659 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1661 for (; k<aNbInt; ++k) {
1662 aNbLines = !k ? aEEs.Extent() : aEFs.Extent();
1663 for (i = 0; i < aNbLines; ++i) {
1664 BOPDS_Interf *aInt = !k ? (BOPDS_Interf*) (&aEEs(i)) :
1665 (BOPDS_Interf*) (&aEFs(i));
1666 if (aInt->IndexNew() == nV) {
1667 if (aMI.Contains(aInt->Index1()) &&
1668 aMI.Contains(aInt->Index2())) {
1669 const IntTools_CommonPrt& aComPrt = !k ? aEEs(i).CommonPart() :
1670 aEFs(i).CommonPart();
1672 const TopoDS_Edge& aE1=aComPrt.Edge1();
1673 aComPrt.Range1(aT11, aT12);
1674 BOPTools_AlgoTools::PointOnEdge(aE1, aT11, aP11);
1675 BOPTools_AlgoTools::PointOnEdge(aE1, aT12, aP12);
1676 aD1=aPV.Distance(aP11);
1677 aD2=aPV.Distance(aP12);
1678 aD=(aD1>aD2)? aD1 : aD2;
1683 }//if (aMI.Contains(aEF.Index1()) && aMI.Contains(aEF.Index2())) {
1684 }//if (aInt->IndexNew() == nV) {
1685 }//for (i = 0; i < aNbLines; ++i) {
1686 }//for (k=0; k<2; ++k) {
1690 //=======================================================================
1691 //function : GetEFPnts
1693 //=======================================================================
1694 void BOPAlgo_PaveFiller::GetEFPnts
1695 (const Standard_Integer nF1,
1696 const Standard_Integer nF2,
1697 IntSurf_ListOfPntOn2S& aListOfPnts)
1699 Standard_Integer nE, nF, nFOpposite, aNbEFs, i;
1700 Standard_Real U1, U2, V1, V2, f, l;
1701 BOPCol_MapOfInteger aMI;
1703 //collect indexes of all shapes from nF1 and nF2.
1704 GetFullShapeMap(nF1, aMI);
1705 GetFullShapeMap(nF2, aMI);
1707 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1708 aNbEFs = aEFs.Extent();
1710 for(i = 0; i < aNbEFs; ++i) {
1711 const BOPDS_InterfEF& aEF = aEFs(i);
1712 if (aEF.HasIndexNew()) {
1713 aEF.Indices(nE, nFOpposite);
1714 if(aMI.Contains(nE) && aMI.Contains(nFOpposite)) {
1715 const IntTools_CommonPrt& aCP = aEF.CommonPart();
1716 Standard_Real aPar = aCP.VertexParameter1();
1717 const TopoDS_Edge& aE = (*(TopoDS_Edge*)(&myDS->Shape(nE)));
1718 const TopoDS_Face& aFOpposite =
1719 (*(TopoDS_Face*)(&myDS->Shape(nFOpposite)));
1721 const Handle(Geom_Curve)& aCurve = BRep_Tool::Curve(aE, f, l);
1723 nF = (nFOpposite == nF1) ? nF2 : nF1;
1724 const TopoDS_Face& aF = (*(TopoDS_Face*)(&myDS->Shape(nF)));
1725 Handle(Geom2d_Curve) aPCurve =
1726 BRep_Tool::CurveOnSurface(aE, aF, f, l);
1728 GeomAPI_ProjectPointOnSurf& aProj=myContext->ProjPS(aFOpposite);
1731 aCurve->D0(aPar, aPoint);
1732 IntSurf_PntOn2S aPnt;
1733 if(!aPCurve.IsNull()) {
1734 gp_Pnt2d aP2d = aPCurve->Value(aPar);
1735 aProj.Perform(aPoint);
1736 if(aProj.IsDone()) {
1737 aProj.LowerDistanceParameters(U1,V1);
1739 aPnt.SetValue(aP2d.X(),aP2d.Y(),U1,V1);
1741 aPnt.SetValue(U1,V1,aP2d.X(),aP2d.Y());
1743 aListOfPnts.Append(aPnt);
1747 GeomAPI_ProjectPointOnSurf& aProj1 = myContext->ProjPS(aF);
1748 aProj1.Perform(aPoint);
1749 aProj.Perform(aPoint);
1750 if(aProj1.IsDone() && aProj.IsDone()){
1751 aProj1.LowerDistanceParameters(U1,V1);
1752 aProj.LowerDistanceParameters(U2,V2);
1754 aPnt.SetValue(U1,V1,U2,V2);
1756 aPnt.SetValue(U2,V2,U1,V1);
1758 aListOfPnts.Append(aPnt);
1766 //=======================================================================
1767 //function : PutEFPavesOnCurve
1769 //=======================================================================
1770 void BOPAlgo_PaveFiller::PutEFPavesOnCurve
1772 const BOPCol_MapOfInteger& aMI,
1773 const BOPCol_MapOfInteger& aMVEF,
1774 BOPCol_DataMapOfIntegerReal& aMVTol,
1775 BOPCol_DataMapOfIntegerListOfInteger& aDMVLV)
1777 if (!aMVEF.Extent()) {
1781 const IntTools_Curve& aIC=aNC.Curve();
1782 GeomAbs_CurveType aTypeC;
1784 if (!(aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve)) {
1788 Standard_Integer nV;
1789 BOPCol_MapOfInteger aMV;
1792 RemoveUsedVertices(aNC, aMV);
1793 if (!aMV.Extent()) {
1797 Standard_Real aDist;
1800 const Handle(Geom_Curve)& aC3D=aIC.Curve();
1801 GeomAPI_ProjectPointOnCurve& aProjPT = myContext->ProjPT(aC3D);
1803 BOPCol_MapIteratorOfMapOfInteger aItMI;
1804 aItMI.Initialize(aMV);
1805 for (; aItMI.More(); aItMI.Next()) {
1807 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
1808 gp_Pnt aPV = BRep_Tool::Pnt(aV);
1809 aProjPT.Perform(aPV);
1810 Standard_Integer aNbPoints = aProjPT.NbPoints();
1812 aDist = aProjPT.LowerDistance();
1813 PutPaveOnCurve(nV, aDist, aNC, aMI, aMVTol, aDMVLV);
1818 //=======================================================================
1819 //function : ProcessUnUsedVertices
1821 //=======================================================================
1822 void BOPAlgo_PaveFiller::PutStickPavesOnCurve
1823 (const TopoDS_Face& aF1,
1824 const TopoDS_Face& aF2,
1825 const BOPCol_MapOfInteger& aMI,
1827 const BOPCol_MapOfInteger& aMVStick,
1828 BOPCol_DataMapOfIntegerReal& aMVTol,
1829 BOPCol_DataMapOfIntegerListOfInteger& aDMVLV)
1831 BOPCol_MapOfInteger aMV;
1832 aMV.Assign(aMVStick);
1833 RemoveUsedVertices(aNC, aMV);
1835 if (!aMV.Extent()) {
1839 Handle(Geom_Surface) aS1=BRep_Tool::Surface(aF1);
1840 Handle(Geom_Surface) aS2=BRep_Tool::Surface(aF2);
1842 const IntTools_Curve& aIC=aNC.Curve();
1843 //if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) {
1844 Handle(Geom2d_Curve) aC2D[2];
1846 aC2D[0]=aIC.FirstCurve2d();
1847 aC2D[1]=aIC.SecondCurve2d();
1848 if (!aC2D[0].IsNull() && !aC2D[1].IsNull()) {
1849 Standard_Integer nV, m, n;
1850 Standard_Real aTC[2], aD, aD2, u, v, aDT2, aScPr, aDScPr;
1854 BOPCol_MapIteratorOfMapOfInteger aItMI, aItMI1;
1856 aDT2=2e-7; // the rich criteria
1857 aDScPr=5.e-9; // the creasing criteria
1858 aIC.Bounds(aTC[0], aTC[1], aPC[0], aPC[1]);
1860 aItMI.Initialize(aMV);
1861 for (; aItMI.More(); aItMI.Next()) {
1863 const TopoDS_Vertex& aV=*((TopoDS_Vertex*)&myDS->Shape(nV));
1864 aPV=BRep_Tool::Pnt(aV);
1866 for (m=0; m<2; ++m) {
1867 aD2=aPC[m].SquareDistance(aPV);
1868 if (aD2>aDT2) {// no rich
1872 for (n=0; n<2; ++n) {
1873 Handle(Geom_Surface)& aS=(!n)? aS1 : aS2;
1874 aC2D[n]->D0(aTC[m], aP2D);
1876 BOPTools_AlgoTools3D::GetNormalToSurface(aS, u, v, aDN[n]);
1879 aScPr=aDN[0]*aDN[1];
1889 // The intersection curve aIC is vanishing curve (the crease)
1892 PutPaveOnCurve(nV, aD, aNC, aMI, aMVTol, aDMVLV);
1894 }//for (jVU=1; jVU=aNbVU; ++jVU) {
1896 //}//if (aTypeC==GeomAbs_BezierCurve || aTypeC==GeomAbs_BSplineCurve) {
1897 //}//if(aType1==GeomAbs_Torus || aType2==GeomAbs_Torus) {
1900 //=======================================================================
1901 //function : GetStickVertices
1903 //=======================================================================
1904 void BOPAlgo_PaveFiller::GetStickVertices(const Standard_Integer nF1,
1905 const Standard_Integer nF2,
1906 BOPCol_MapOfInteger& aMVStick,
1907 BOPCol_MapOfInteger& aMVEF,
1908 BOPCol_MapOfInteger& aMI)
1910 Standard_Integer nS1, nS2, nVNew, aTypeInt, i;
1912 BOPDS_VectorOfInterfVV& aVVs=myDS->InterfVV();
1913 BOPDS_VectorOfInterfVE& aVEs=myDS->InterfVE();
1914 BOPDS_VectorOfInterfEE& aEEs=myDS->InterfEE();
1915 BOPDS_VectorOfInterfVF& aVFs=myDS->InterfVF();
1916 BOPDS_VectorOfInterfEF& aEFs=myDS->InterfEF();
1918 Standard_Integer aNbLines[5] = {
1919 aVVs.Extent(), aVEs.Extent(), aEEs.Extent(),
1920 aVFs.Extent(), aEFs.Extent()
1922 //collect indices of all shapes from nF1 and nF2.
1924 GetFullShapeMap(nF1, aMI);
1925 GetFullShapeMap(nF2, aMI);
1927 //collect VV, VE, EE, VF interferences
1928 for (aTypeInt = 0; aTypeInt < 4; ++aTypeInt) {
1929 for (i = 0; i < aNbLines[aTypeInt]; ++i) {
1930 BOPDS_Interf* aInt = (aTypeInt==0) ? (BOPDS_Interf*)(&aVVs(i)) :
1931 ((aTypeInt==1) ? (BOPDS_Interf*)(&aVEs(i)) :
1932 ((aTypeInt==2) ? (BOPDS_Interf*)(&aEEs(i)) :
1933 (BOPDS_Interf*)(&aVFs(i))));
1934 if (aInt->HasIndexNew()) {
1935 aInt->Indices(nS1, nS2);
1936 if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
1937 nVNew = aInt->IndexNew();
1938 aMVStick.Add(nVNew);
1943 //collect EF interferences
1944 for (i = 0; i < aNbLines[4]; ++i) {
1945 const BOPDS_InterfEF& aInt = aEFs(i);
1946 if (aInt.HasIndexNew()) {
1947 aInt.Indices(nS1, nS2);
1948 if(aMI.Contains(nS1) && aMI.Contains(nS2)) {
1949 nVNew = aInt.IndexNew();
1950 aMVStick.Add(nVNew);
1957 //=======================================================================
1958 // function: GetFullShapeMap
1960 //=======================================================================
1961 void BOPAlgo_PaveFiller::GetFullShapeMap(const Standard_Integer nF,
1962 BOPCol_MapOfInteger& aMI)
1964 BOPCol_ListIteratorOfListOfInteger aIt;
1965 Standard_Integer nS;
1967 const BOPDS_ShapeInfo& aSI = myDS->ShapeInfo(nF);
1968 const BOPCol_ListOfInteger& aLI = aSI.SubShapes();
1971 aIt.Initialize(aLI);
1972 for (; aIt.More(); aIt.Next()) {
1978 //=======================================================================
1979 // function: RemoveUsedVertices
1981 //=======================================================================
1982 void BOPAlgo_PaveFiller::RemoveUsedVertices(BOPDS_Curve& aNC,
1983 BOPCol_MapOfInteger& aMV)
1985 if (!aMV.Extent()) {
1988 Standard_Integer nV;
1990 BOPDS_ListIteratorOfListOfPave aItLP;
1992 Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
1993 const BOPDS_ListOfPave& aLP = aPB->ExtPaves();
1994 aItLP.Initialize(aLP);
1995 for (;aItLP.More();aItLP.Next()) {
1996 aPave = aItLP.Value();
2002 //=======================================================================
2003 //function : PutPaveOnCurve
2005 //=======================================================================
2006 void BOPAlgo_PaveFiller::PutPaveOnCurve
2007 (const Standard_Integer nV,
2008 const Standard_Real aTolR3D,
2009 const BOPDS_Curve& aNC,
2010 const BOPCol_MapOfInteger& aMI,
2011 BOPCol_DataMapOfIntegerReal& aMVTol,
2012 BOPCol_DataMapOfIntegerListOfInteger& aDMVLV,
2013 const Standard_Integer iCheckExtend)
2015 Standard_Boolean bIsVertexOnLine;
2018 const TopoDS_Vertex& aV = (*(TopoDS_Vertex *)(&myDS->Shape(nV)));
2019 const Handle(BOPDS_PaveBlock)& aPB = aNC.PaveBlocks().First();
2020 const IntTools_Curve& aIC = aNC.Curve();
2022 Standard_Real aTolV = (aMVTol.IsBound(nV) ? aMVTol(nV) : BRep_Tool::Tolerance(aV));
2024 bIsVertexOnLine = myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D + myFuzzyValue, aT);
2025 if (!bIsVertexOnLine && iCheckExtend) {
2026 ExtendedTolerance(nV, aMI, aTolV, iCheckExtend);
2027 bIsVertexOnLine = myContext->IsVertexOnLine(aV, aTolV, aIC, aTolR3D + myFuzzyValue, aT);
2030 if (bIsVertexOnLine) {
2031 // check if aPB contains the parameter aT
2032 Standard_Boolean bExist;
2033 Standard_Integer nVUsed;
2034 Standard_Real aPTol, aDTol;
2038 GeomAdaptor_Curve aGAC(aIC.Curve());
2039 aPTol = aGAC.Resolution(aTolR3D);
2041 bExist = aPB->ContainsParameter(aT, aPTol, nVUsed);
2043 // use existing pave
2044 BOPCol_ListOfInteger* pList = aDMVLV.ChangeSeek(nVUsed);
2046 pList = aDMVLV.Bound(nVUsed, BOPCol_ListOfInteger());
2047 pList->Append(nVUsed);
2048 if (!aMVTol.IsBound(nVUsed)) {
2049 const TopoDS_Vertex& aVUsed = (*(TopoDS_Vertex *)(&myDS->Shape(nVUsed)));
2050 aTolV = BRep_Tool::Tolerance(aVUsed);
2051 aMVTol.Bind(nVUsed, aTolV);
2055 if (!aMVTol.IsBound(nV)) {
2056 aTolV = BRep_Tool::Tolerance(aV);
2057 aMVTol.Bind(nV, aTolV);
2064 aPave.SetParameter(aT);
2065 aPB->AppendExtPave(aPave);
2067 gp_Pnt aP1 = aGAC.Value(aT);
2068 aTolV = BRep_Tool::Tolerance(aV);
2069 gp_Pnt aP2 = BRep_Tool::Pnt(aV);
2070 Standard_Real aDist = aP1.Distance(aP2);
2071 if (aDist > aTolV) {
2072 BRep_Builder().UpdateVertex(aV, aDist + aDTol);
2074 if (!aMVTol.IsBound(nV)) {
2075 aMVTol.Bind(nV, aTolV);
2078 BOPDS_ShapeInfo& aSIDS=myDS->ChangeShapeInfo(nV);
2079 Bnd_Box& aBoxDS=aSIDS.ChangeBox();
2080 BRepBndLib::Add(aV, aBoxDS);
2081 aBoxDS.SetGap(aBoxDS.GetGap() + Precision::Confusion());
2087 //=======================================================================
2088 //function : ProcessExistingPaveBlocks
2090 //=======================================================================
2091 void BOPAlgo_PaveFiller::ProcessExistingPaveBlocks
2092 (const Standard_Integer theInt,
2093 const BOPDS_IndexedMapOfPaveBlock& aMPBOnIn,
2094 const BOPCol_DataMapOfIntegerListOfInteger& aDMBV,
2095 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
2096 BOPCol_DataMapOfShapeInteger& aMVI,
2097 BOPDS_MapOfPaveBlock& aMPB)
2099 if (aDMBV.IsEmpty()) {
2103 Standard_Real aT, dummy;
2104 Standard_Integer i, nV, nE, iC, aNbPB, iFlag;
2105 BOPCol_ListIteratorOfListOfInteger aItLI;
2106 BOPCol_DataMapIteratorOfDataMapOfIntegerListOfInteger aItBV;
2108 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2109 BOPDS_InterfFF& aFF = aFFs(theInt);
2110 BOPDS_VectorOfCurve& aVC = aFF.ChangeCurves();
2112 aNbPB = aMPBOnIn.Extent();
2114 aItBV.Initialize(aDMBV);
2115 for (; aItBV.More(); aItBV.Next()) {
2117 const BOPCol_ListOfInteger& aLBV = aItBV.Value();
2119 BOPDS_Curve& aNC = aVC.ChangeValue(iC);
2120 BOPDS_ListOfPaveBlock& aLPBC = aNC.ChangePaveBlocks();
2122 aItLI.Initialize(aLBV);
2123 for (; aItLI.More(); aItLI.Next()) {
2125 const BOPDS_ShapeInfo& aSIV=myDS->ShapeInfo(nV);
2126 const Bnd_Box& aBoxV=aSIV.Box();
2127 const TopoDS_Vertex& aV = *(TopoDS_Vertex*)&aSIV.Shape();
2128 if (!aMVI.IsBound(aV)) {
2132 for (i = 1; i <= aNbPB; ++i) {
2133 const Handle(BOPDS_PaveBlock)& aPB = aMPBOnIn(i);
2134 if (aPB->Pave1().Index() == nV || aPB->Pave2().Index() == nV) {
2138 if (aMPB.Contains(aPB)) {
2141 if (myDS->ShapeInfo(aPB->OriginalEdge()).HasFlag()) { // skip degenerated edges
2146 const BOPDS_ShapeInfo& aSIE = myDS->ShapeInfo(nE);
2147 const Bnd_Box& aBoxE = aSIE.Box();
2149 if (aBoxV.IsOut(aBoxE)) {
2153 const TopoDS_Edge& aE = *(TopoDS_Edge*)&aSIE.Shape();
2155 iFlag = myContext->ComputeVE(aV, aE, aT, dummy, myFuzzyValue);
2158 PreparePostTreatFF(theInt, iC, aPB, aMSCPB, aMVI, aLPBC);
2164 //=======================================================================
2165 //function : UpdateExistingPaveBlocks
2167 //=======================================================================
2168 void BOPAlgo_PaveFiller::UpdateExistingPaveBlocks
2169 (const Handle(BOPDS_PaveBlock)& aPBf,
2170 BOPDS_ListOfPaveBlock& aLPB,
2171 const Standard_Integer nF1,
2172 const Standard_Integer nF2)
2174 if (!aLPB.Extent()) {
2178 Standard_Integer nE;
2179 Standard_Boolean bCB;
2180 Handle(BOPDS_PaveBlock) aPB, aPB1, aPB2, aPB2n;
2181 Handle(BOPDS_CommonBlock) aCB;
2182 BOPDS_ListIteratorOfListOfPaveBlock aIt, aIt1, aIt2;
2184 BOPDS_FaceInfo& aFI1 = myDS->ChangeFaceInfo(nF1);
2185 BOPDS_FaceInfo& aFI2 = myDS->ChangeFaceInfo(nF2);
2187 BOPDS_IndexedMapOfPaveBlock& aMPBOn1 = aFI1.ChangePaveBlocksOn();
2188 BOPDS_IndexedMapOfPaveBlock& aMPBIn1 = aFI1.ChangePaveBlocksIn();
2189 BOPDS_IndexedMapOfPaveBlock& aMPBOn2 = aFI2.ChangePaveBlocksOn();
2190 BOPDS_IndexedMapOfPaveBlock& aMPBIn2 = aFI2.ChangePaveBlocksIn();
2192 // 1. Remove old pave blocks
2193 const Handle(BOPDS_CommonBlock)& aCB1 = myDS->CommonBlock(aPBf);
2194 bCB = !aCB1.IsNull();
2195 BOPDS_ListOfPaveBlock aLPB1;
2198 aLPB1.Assign(aCB1->PaveBlocks());
2202 aIt1.Initialize(aLPB1);
2203 for (; aIt1.More(); aIt1.Next()) {
2204 aPB1 = aIt1.Value();
2205 nE = aPB1->OriginalEdge();
2207 BOPDS_ListOfPaveBlock& aLPB2 = myDS->ChangePaveBlocks(nE);
2208 aIt2.Initialize(aLPB2);
2209 for (; aIt2.More(); aIt2.Next()) {
2210 aPB2 = aIt2.Value();
2218 // 2. Update pave blocks
2220 //create new common blocks
2221 BOPDS_ListOfPaveBlock aLPBNew;
2222 const BOPCol_ListOfInteger& aFaces = aCB1->Faces();
2223 aIt.Initialize(aLPB);
2224 for (; aIt.More(); aIt.Next()) {
2225 const Handle(BOPDS_PaveBlock)& aPBValue = aIt.Value();
2227 aCB = new BOPDS_CommonBlock;
2228 aIt1.Initialize(aLPB1);
2229 for (; aIt1.More(); aIt1.Next()) {
2230 aPB2 = aIt1.Value();
2231 nE = aPB2->OriginalEdge();
2233 aPB2n = new BOPDS_PaveBlock;
2234 aPB2n->SetPave1(aPBValue->Pave1());
2235 aPB2n->SetPave2(aPBValue->Pave2());
2236 aPB2n->SetEdge(aPBValue->Edge());
2237 aPB2n->SetOriginalEdge(nE);
2238 aCB->AddPaveBlock(aPB2n);
2239 myDS->SetCommonBlock(aPB2n, aCB);
2240 myDS->ChangePaveBlocks(nE).Append(aPB2n);
2242 aCB->SetFaces(aFaces);
2243 myDS->SortPaveBlocks(aCB);
2245 const Handle(BOPDS_PaveBlock)& aPBNew = aCB->PaveBlocks().First();
2246 aLPBNew.Append(aPBNew);
2252 nE = aPBf->OriginalEdge();
2253 BOPDS_ListOfPaveBlock& aLPBE = myDS->ChangePaveBlocks(nE);
2254 aIt.Initialize(aLPB);
2255 for (; aIt.More(); aIt.Next()) {
2261 Standard_Boolean bIn1, bIn2;
2263 bIn1 = aMPBOn1.Contains(aPBf) || aMPBIn1.Contains(aPBf);
2264 bIn2 = aMPBOn2.Contains(aPBf) || aMPBIn2.Contains(aPBf);
2270 // 3. Check new pave blocks for coincidence
2271 // with the opposite face.
2272 // In case of coincidence create common blocks
2273 Standard_Integer nF;
2275 nF = bIn1 ? nF2 : nF1;
2276 const TopoDS_Face& aF = *(TopoDS_Face*)&myDS->Shape(nF);
2277 BOPDS_IndexedMapOfPaveBlock& aMPBIn = bIn1 ? aMPBIn2 : aMPBIn1;
2279 aIt.Initialize(aLPB);
2280 for (; aIt.More(); aIt.Next()) {
2281 Handle(BOPDS_PaveBlock)& aPBChangeValue = aIt.ChangeValue();
2282 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPBChangeValue->Edge());
2284 IntTools_EdgeFace anEF;
2287 anEF.SetFuzzyValue(myFuzzyValue);
2288 anEF.SetRange(aPBChangeValue->Pave1().Parameter(), aPBChangeValue->Pave2().Parameter());
2289 anEF.SetContext(myContext);
2292 const IntTools_SequenceOfCommonPrts& aCPrts=anEF.CommonParts();
2293 if (aCPrts.Length() == 1) {
2294 Standard_Boolean bCoinc = (aCPrts(1).Type() == TopAbs_EDGE);
2297 aCB = myDS->CommonBlock(aPBChangeValue);
2299 aCB = new BOPDS_CommonBlock;
2300 aCB->AddPaveBlock(aPBChangeValue);
2301 myDS->SetCommonBlock(aPBChangeValue, aCB);
2305 aMPBIn.Add(aPBChangeValue);
2310 //=======================================================================
2311 // function: PutClosingPaveOnCurve
2313 //=======================================================================
2314 void BOPAlgo_PaveFiller::PutClosingPaveOnCurve(BOPDS_Curve& aNC)
2316 Standard_Boolean bIsClosed, bHasBounds, bAdded;
2317 Standard_Integer nVC, j;
2318 Standard_Real aT[2], aTC, dT, aTx;
2321 BOPDS_ListIteratorOfListOfPave aItLP;
2323 const IntTools_Curve& aIC=aNC.Curve();
2324 const Handle(Geom_Curve)& aC3D=aIC.Curve();
2329 bIsClosed=IntTools_Tools::IsClosed(aC3D);
2334 bHasBounds=aIC.HasBounds ();
2339 bAdded=Standard_False;
2340 dT=Precision::PConfusion();
2341 aIC.Bounds (aT[0], aT[1], aP[0], aP[1]);
2343 Handle(BOPDS_PaveBlock)& aPB=aNC.ChangePaveBlock1();
2344 BOPDS_ListOfPave& aLP=aPB->ChangeExtPaves();
2346 aItLP.Initialize(aLP);
2347 for (; aItLP.More() && !bAdded; aItLP.Next()) {
2348 const BOPDS_Pave& aPC=aItLP.Value();
2350 aTC=aPC.Parameter();
2352 for (j=0; j<2; ++j) {
2353 if (fabs(aTC-aT[j]) < dT) {
2354 aTx=(!j) ? aT[1] : aT[0];
2356 aPVx.SetParameter(aTx);
2359 bAdded=Standard_True;
2365 //=======================================================================
2366 //function : PreparePostTreatFF
2368 //=======================================================================
2369 void BOPAlgo_PaveFiller::PreparePostTreatFF
2370 (const Standard_Integer aInt,
2371 const Standard_Integer aCur,
2372 const Handle(BOPDS_PaveBlock)& aPB,
2373 BOPDS_IndexedDataMapOfShapeCoupleOfPaveBlocks& aMSCPB,
2374 BOPCol_DataMapOfShapeInteger& aMVI,
2375 BOPDS_ListOfPaveBlock& aLPBC)
2377 Standard_Integer nV1, nV2;
2381 aPB->Indices(nV1, nV2);
2382 const TopoDS_Vertex& aV1=(*(TopoDS_Vertex *)(&myDS->Shape(nV1)));
2383 const TopoDS_Vertex& aV2=(*(TopoDS_Vertex *)(&myDS->Shape(nV2)));
2384 const TopoDS_Edge& aE = *(TopoDS_Edge*)&myDS->Shape(aPB->Edge());
2385 // Keep info for post treatment
2386 BOPDS_CoupleOfPaveBlocks aCPB;
2387 aCPB.SetIndexInterf(aInt);
2388 aCPB.SetIndex(aCur);
2389 aCPB.SetPaveBlock1(aPB);
2391 aMSCPB.Add(aE, aCPB);
2392 aMVI.Bind(aV1, nV1);
2393 aMVI.Bind(aV2, nV2);
2396 //=======================================================================
2397 //function : CheckPlanes
2399 //=======================================================================
2400 Standard_Boolean BOPAlgo_PaveFiller::CheckPlanes
2401 (const Standard_Integer nF1,
2402 const Standard_Integer nF2)const
2404 Standard_Boolean bToIntersect;
2405 Standard_Integer i, nV2, iCnt;
2406 BOPCol_MapIteratorOfMapOfInteger aIt;
2408 bToIntersect=Standard_False;
2410 const BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
2411 const BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
2413 const BOPCol_MapOfInteger& aMVIn1=aFI1.VerticesIn();
2414 const BOPCol_MapOfInteger& aMVOn1=aFI1.VerticesOn();
2417 for (i=0; (i<2 && !bToIntersect); ++i) {
2418 const BOPCol_MapOfInteger& aMV2=(!i) ? aFI2.VerticesIn()
2419 : aFI2.VerticesOn();
2421 aIt.Initialize(aMV2);
2422 for (; aIt.More(); aIt.Next()) {
2424 if (aMVIn1.Contains(nV2) || aMVOn1.Contains(nV2)) {
2427 bToIntersect=!bToIntersect;
2434 return bToIntersect;
2436 //=======================================================================
2437 //function : UpdatePaveBlocks
2439 //=======================================================================
2440 void BOPAlgo_PaveFiller::UpdatePaveBlocks
2441 (const BOPCol_DataMapOfIntegerInteger& aDMNewSD)
2443 if (aDMNewSD.IsEmpty()) {
2447 Standard_Integer nSp, aNbPBP, nV[2], i, j;
2448 Standard_Real aT[2];
2449 Standard_Boolean bCB, bRebuild;
2450 BOPDS_ListIteratorOfListOfPaveBlock aItPB;
2451 BOPDS_MapOfPaveBlock aMPB;
2452 BOPCol_MapOfInteger aMicroEdges;
2454 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
2455 aNbPBP = aPBP.Extent();
2456 for (i = 0; i < aNbPBP; ++i) {
2457 BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2459 aItPB.Initialize(aLPB);
2460 for (; aItPB.More(); aItPB.Next()) {
2461 Handle(BOPDS_PaveBlock) aPB = aItPB.Value();
2462 const Handle(BOPDS_CommonBlock)& aCB = myDS->CommonBlock(aPB);
2463 bCB = !aCB.IsNull();
2465 aPB = aCB->PaveBlock1();
2468 if (aMPB.Add(aPB)) {
2469 bRebuild = Standard_False;
2470 aPB->Indices(nV[0], nV[1]);
2471 aPB->Range(aT[0], aT[1]);
2472 // remember the fact if the edge had different vertices before substitution
2473 Standard_Boolean wasRegularEdge = (nV[0] != nV[1]);
2475 for (j = 0; j < 2; ++j) {
2476 if (aDMNewSD.IsBound(nV[j])) {
2479 nV[j] = aDMNewSD.Find(nV[j]);
2480 aPave.SetIndex(nV[j]);
2481 aPave.SetParameter(aT[j]);
2483 bRebuild = Standard_True;
2485 aPB->SetPave1(aPave);
2488 aPB->SetPave2(aPave);
2494 Standard_Boolean isDegEdge = myDS->ShapeInfo(aPB->Edge()).HasFlag();
2495 if (wasRegularEdge && !isDegEdge && nV[0] == nV[1]) {
2496 // now edge has the same vertex on both ends;
2497 // check if it is not a regular closed curve.
2498 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(aPB->Edge()));
2499 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV[0]));
2500 Standard_Real aLength = IntTools::Length(aE);
2501 Standard_Real aTolV = BRep_Tool::Tolerance(aV);
2502 if (aLength <= aTolV * 2.) {
2503 // micro edge, so mark it for removal
2504 aMicroEdges.Add(aPB->Edge());
2508 nSp = SplitEdge(aPB->OriginalEdge(), nV[0], aT[0], nV[1], aT[1]);
2516 }// if (aMPB.Add(aPB)) {
2517 }// for (; aItPB.More(); aItPB.Next()) {
2518 }// for (i=0; i<aNbPBP; ++i) {
2521 if (aMicroEdges.Extent())
2522 RemovePaveBlocks(aMicroEdges);
2524 //=======================================================================
2525 //function : RemovePaveBlocks
2527 //=======================================================================
2528 void BOPAlgo_PaveFiller::RemovePaveBlocks(const BOPCol_MapOfInteger theEdges)
2530 // Remove all pave blocks referring to input edges:
2532 // 1. from the Pave Blocks Pool
2533 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
2534 Standard_Integer aNbPBP = aPBP.Extent(), i;
2535 for (i = 0; i < aNbPBP; ++i) {
2536 BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2538 BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
2539 while (aItPB.More()) {
2540 const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
2541 if (theEdges.Contains(aPB->Edge()))
2548 // 2. from Face Info and section curves
2549 BOPCol_MapOfInteger aMPassed;
2550 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2551 Standard_Integer aNbFF = aFFs.Extent(), j;
2552 for (i = 0; i < aNbFF; ++i) {
2553 BOPDS_InterfFF& aFF = aFFs(i);
2554 Standard_Integer nF1, nF2;
2555 aFF.Indices(nF1, nF2);
2557 // rebuild pave block maps of face info
2558 for (j = 0; j < 2; j++) {
2559 Standard_Integer nF = (j == 0 ? nF1 : nF2);
2560 if (!aMPassed.Add(nF))
2562 BOPDS_FaceInfo& aFI = myDS->ChangeFaceInfo(nF);
2563 BOPDS_IndexedMapOfPaveBlock* aIMPB[] = { &aFI.ChangePaveBlocksIn(),
2564 &aFI.ChangePaveBlocksOn(), &aFI.ChangePaveBlocksSc() };
2565 for (Standard_Integer k = 0; k < 3; k++) {
2566 Standard_Integer aNbPB = aIMPB[k]->Extent(), m;
2567 for (m = 1; m <= aNbPB; ++m) {
2568 const Handle(BOPDS_PaveBlock)& aPB = aIMPB[k]->FindKey(m);
2569 if (theEdges.Contains(aPB->Edge()))
2573 BOPDS_IndexedMapOfPaveBlock aMPBCopy = *aIMPB[k];
2575 for (m = 1; m <= aNbPB; ++m) {
2576 const Handle(BOPDS_PaveBlock)& aPB = aMPBCopy(m);
2577 if (!theEdges.Contains(aPB->Edge()))
2583 // remove from Section pave blocks
2584 BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
2585 Standard_Integer aNbC = aVNC.Extent();
2586 for (j = 0; j < aNbC; ++j) {
2587 BOPDS_Curve& aNC = aVNC(j);
2588 BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
2589 BOPDS_ListIteratorOfListOfPaveBlock aItPB(aLPB);
2590 while (aItPB.More()) {
2591 const Handle(BOPDS_PaveBlock)& aPB = aItPB.Value();
2592 if (theEdges.Contains(aPB->Edge()))
2601 //=======================================================================
2602 //function : ToleranceFF
2603 //purpose : Computes the TolFF according to the tolerance value and
2604 // types of the faces.
2605 //=======================================================================
2606 void ToleranceFF(const BRepAdaptor_Surface& aBAS1,
2607 const BRepAdaptor_Surface& aBAS2,
2608 Standard_Real& aTolFF)
2610 Standard_Real aTol1, aTol2;
2611 Standard_Boolean isAna1, isAna2;
2613 aTol1 = aBAS1.Tolerance();
2614 aTol2 = aBAS2.Tolerance();
2615 aTolFF = Max(aTol1, aTol2);
2617 isAna1 = (aBAS1.GetType() == GeomAbs_Plane ||
2618 aBAS1.GetType() == GeomAbs_Cylinder ||
2619 aBAS1.GetType() == GeomAbs_Cone ||
2620 aBAS1.GetType() == GeomAbs_Sphere ||
2621 aBAS1.GetType() == GeomAbs_Torus);
2623 isAna2 = (aBAS2.GetType() == GeomAbs_Plane ||
2624 aBAS2.GetType() == GeomAbs_Cylinder ||
2625 aBAS2.GetType() == GeomAbs_Cone ||
2626 aBAS2.GetType() == GeomAbs_Sphere ||
2627 aBAS2.GetType() == GeomAbs_Torus);
2629 if (!isAna1 || !isAna2) {
2630 aTolFF = Max(aTolFF, 5.e-6);
2633 //=======================================================================
2634 //function : UpdateBlocksWithSharedVertices
2636 //=======================================================================
2637 void BOPAlgo_PaveFiller::UpdateBlocksWithSharedVertices()
2639 if (!myNonDestructive) {
2645 Standard_Integer aNbFF;
2647 BOPDS_VectorOfInterfFF& aFFs=myDS->InterfFF();
2648 aNbFF=aFFs.Extent();
2653 Standard_Boolean bOnCurve, bHasShapeSD;
2654 Standard_Integer i, nF1, nF2, aNbC, j, nV, nVSD;
2655 Standard_Real aTolR3D, aTolV;
2656 BOPCol_MapOfInteger aMF;
2658 for (i=0; i<aNbFF; ++i) {
2659 BOPDS_InterfFF& aFF=aFFs(i);
2661 BOPDS_VectorOfCurve& aVC=aFF.ChangeCurves();
2667 aFF.Indices(nF1, nF2);
2668 aTolR3D=aFF.TolR3D();
2671 myDS->UpdateFaceInfoOn(nF1);
2674 myDS->UpdateFaceInfoOn(nF2);
2677 // Collect old vertices that are shared for nF1, nF2 ->aMI;
2678 BOPCol_MapOfInteger aMI;
2679 BOPCol_MapIteratorOfMapOfInteger aItMI;
2681 BOPDS_FaceInfo& aFI1=myDS->ChangeFaceInfo(nF1);
2682 BOPDS_FaceInfo& aFI2=myDS->ChangeFaceInfo(nF2);
2684 const BOPCol_MapOfInteger& aMVOn1=aFI1.VerticesOn();
2685 const BOPCol_MapOfInteger& aMVIn1=aFI1.VerticesIn();
2686 const BOPCol_MapOfInteger& aMVOn2=aFI2.VerticesOn();
2687 const BOPCol_MapOfInteger& aMVIn2=aFI2.VerticesIn();
2689 for (j=0; j<2; ++j) {
2690 const BOPCol_MapOfInteger& aMV1=(!j) ? aMVOn1 : aMVIn1;
2691 aItMI.Initialize(aMV1);
2692 for (; aItMI.More(); aItMI.Next()) {
2694 if (myDS->IsNewShape(nV)) {
2697 if (aMVOn2.Contains(nV) || aMVIn2.Contains(nV)) {
2703 // Try to put vertices aMI on curves
2704 for (j=0; j<aNbC; ++j) {
2705 BOPDS_Curve& aNC=aVC.ChangeValue(j);
2706 //const IntTools_Curve& aIC=aNC.Curve();
2708 aItMI.Initialize(aMI);
2709 for (; aItMI.More(); aItMI.Next()) {
2712 bHasShapeSD=myDS->HasShapeSD(nV, nVSD);
2717 bOnCurve=EstimatePaveOnCurve(nV, aNC, aTolR3D);
2722 const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV));
2723 aTolV=BRep_Tool::Tolerance(aV);
2725 UpdateVertex(nV, aTolV);
2727 }//for (j=0; j<aNbC; ++j) {
2728 }//for (i=0; i<aNbFF; ++i) {
2730 UpdateCommonBlocksWithSDVertices();
2732 //=======================================================================
2733 //function : EstimatePaveOnCurve
2735 //=======================================================================
2736 Standard_Boolean BOPAlgo_PaveFiller::EstimatePaveOnCurve
2737 (const Standard_Integer nV,
2738 const BOPDS_Curve& aNC,
2739 const Standard_Real aTolR3D)
2741 Standard_Boolean bIsVertexOnLine;
2744 const TopoDS_Vertex& aV=*((TopoDS_Vertex *)&myDS->Shape(nV));
2745 const IntTools_Curve& aIC=aNC.Curve();
2747 bIsVertexOnLine=myContext->IsVertexOnLine(aV, aIC, aTolR3D, aT);
2748 return bIsVertexOnLine;
2751 //=======================================================================
2752 //function : CorrectToleranceOfSE
2754 //=======================================================================
2755 void BOPAlgo_PaveFiller::CorrectToleranceOfSE()
2757 BOPDS_VectorOfInterfFF& aFFs = myDS->InterfFF();
2758 NCollection_IndexedDataMap<Standard_Integer,BOPDS_ListOfPaveBlock> aMVIPBs;
2759 BOPCol_MapOfInteger aMVIToReduce;
2761 // 1. iterate on all sections F-F
2762 Standard_Integer aNb = aFFs.Extent(), i;
2763 for (i = 0; i < aNb; ++i) {
2764 BOPDS_InterfFF& aFF = aFFs(i);
2765 Standard_Real aTolR3D = aFF.TolR3D();
2766 Standard_Real aTolReal = aFF.TolReal();
2767 Standard_Boolean bToReduce = aTolReal < aTolR3D;
2768 // tolerance of intersection has been increased, so process this intersection
2769 BOPDS_VectorOfCurve& aVNC = aFF.ChangeCurves();
2770 Standard_Integer aNbC = aVNC.Extent(), k;
2771 for (k = 0; k < aNbC; ++k) {
2772 BOPDS_Curve& aNC = aVNC(k);
2773 BOPDS_ListOfPaveBlock& aLPB = aNC.ChangePaveBlocks();
2774 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
2775 for (; aItLPB.More(); ) {
2776 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
2777 Standard_Integer nE;
2778 if (!aPB->HasEdge(nE)) {
2779 aLPB.Remove(aItLPB);
2783 Standard_Boolean bIsReduced = Standard_False;
2784 if (bToReduce && (aPB->OriginalEdge() < 0)) {
2785 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
2786 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
2787 if (aTolReal < aTolE) {
2788 // reduce edge tolerance
2789 reinterpret_cast<BRep_TEdge*>(aE.TShape().operator->())->Tolerance(aTolReal);
2790 bIsReduced = Standard_True;
2794 // fill in the map vertex index - pave blocks
2795 for (Standard_Integer j=0; j < 2; j++) {
2796 Standard_Integer nV = (j == 0 ? aPB->Pave1().Index() : aPB->Pave2().Index());
2797 BOPDS_ListOfPaveBlock *pPBList = aMVIPBs.ChangeSeek(nV);
2799 pPBList = &aMVIPBs.ChangeFromIndex(aMVIPBs.Add(nV, BOPDS_ListOfPaveBlock()));
2801 pPBList->Append(aPB);
2803 aMVIToReduce.Add(nV);
2811 if (aMVIToReduce.IsEmpty()) {
2815 // 2. try to reduce tolerances of connected vertices
2816 // 2.1 find all other edges containing these connected vertices to avoid
2817 // reducing the tolerance to the value less than the tolerances of edges,
2818 // i.e. minimal tolerance for the vertex is the max tolerance of the
2819 // edges containing this vertex
2820 BOPCol_DataMapOfIntegerReal aMVITol;
2821 BOPDS_VectorOfListOfPaveBlock& aPBP = myDS->ChangePaveBlocksPool();
2822 aNb = aPBP.Extent();
2823 for (i = 0; i < aNb; ++i) {
2824 const BOPDS_ListOfPaveBlock& aLPB = aPBP(i);
2825 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
2826 for (; aItLPB.More(); aItLPB.Next()) {
2827 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
2828 Standard_Integer nE;
2829 if (!aPB->HasEdge(nE)) {
2832 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
2833 Standard_Real aTolE = BRep_Tool::Tolerance(aE);
2835 Standard_Integer nV[2];
2836 aPB->Indices(nV[0], nV[1]);
2838 for (Standard_Integer j = 0; j < 2; j++) {
2839 if (aMVIToReduce.Contains(nV[j])) {
2840 Standard_Real *aMaxTol = aMVITol.ChangeSeek(nV[j]);
2842 aMVITol.Bind(nV[j], aTolE);
2844 else if (aTolE > *aMaxTol) {
2852 // 2.2 reduce tolerances if possible
2853 aNb = aMVIPBs.Extent();
2854 for (i = 1; i <= aNb; ++i) {
2855 Standard_Integer nV = aMVIPBs.FindKey(i);
2856 if (!aMVIToReduce.Contains(nV)) {
2860 const TopoDS_Vertex& aV = TopoDS::Vertex(myDS->Shape(nV));
2861 Standard_Real aTolV = BRep_Tool::Tolerance(aV);
2862 Standard_Real aMaxTol = aMVITol.IsBound(nV) ? aMVITol.Find(nV) : 0.;
2863 // it makes no sense to compute the real tolerance if it is
2864 // impossible to reduce the tolerance at least 0.1% of the current value
2865 if (aTolV - aMaxTol < 0.001 * aTolV) {
2869 // compute the maximal distance from the vertex to the adjacent edges
2870 gp_Pnt aP = BRep_Tool::Pnt(aV);
2872 const BOPDS_ListOfPaveBlock& aLPB = aMVIPBs.FindFromIndex(i);
2873 BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPB);
2874 for (; aItLPB.More(); aItLPB.Next()) {
2875 const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value();
2876 Standard_Integer nE = aPB->Edge();
2877 const TopoDS_Edge& aE = TopoDS::Edge(myDS->Shape(nE));
2878 const BOPDS_Pave& aPave = (aPB->Pave1().Index() == nV ? aPB->Pave1() : aPB->Pave2());
2879 BRepAdaptor_Curve aC(aE);
2880 gp_Pnt aPonE = aC.Value(aPave.Parameter());
2881 Standard_Real aDist = aP.Distance(aPonE);
2882 aDist += BRep_Tool::Tolerance(aE);
2883 if (aDist > aMaxTol) {
2888 if (aMaxTol < aTolV) {
2889 reinterpret_cast<BRep_TVertex*>(aV.TShape().operator->())->Tolerance(aMaxTol);