From f80842e34cea947c485e82457826e07f48ab9844 Mon Sep 17 00:00:00 2001 From: emv Date: Wed, 15 Mar 2017 09:15:46 +0300 Subject: [PATCH] 0028556: Invalid result of Fuse operation in the test case bugs moddata_2 bug469 1. Using appropriate intersection tolerance for splitting the degenerated edges in Boolean operations (void BOPAlgo_PaveFiller::FillPaves()). 2. Avoid creation of the wires consisting of degenerated edges only (BOPAlgo_WireSplitter). 3. Test case bugs/moddata_2/bug469 has been corrected to obtain valid result of operation. TODO statements have been removed from the case. --- src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx | 128 ++++++++++++------------- src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx | 15 ++- tests/bugs/moddata_2/bug469 | 17 +++- 3 files changed, 84 insertions(+), 76 deletions(-) diff --git a/src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx b/src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx index 308ceeb2e2..eee930c83b 100644 --- a/src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx +++ b/src/BOPAlgo/BOPAlgo_PaveFiller_8.cxx @@ -231,7 +231,11 @@ void BOPAlgo_PaveFiller::ProcessDE() //======================================================================= //function : FillPaves -//purpose : +//purpose : Find all pave blocks passing through the vertex and +// intersecting the 2D curve of the degenerated edge +// somewhere in the middle. Save intersection points into +// Extra paves of the pave block of degenerated edge for future +// splitting. //======================================================================= void BOPAlgo_PaveFiller::FillPaves(const Standard_Integer nVD, const Standard_Integer nED, @@ -239,102 +243,90 @@ void BOPAlgo_PaveFiller::ProcessDE() const BOPDS_ListOfPaveBlock& aLPBOut, const Handle(BOPDS_PaveBlock)& aPBD) { - Standard_Boolean bXDir, bIsDone; - Standard_Integer nE, aNbPoints, j, anInd; - Standard_Real aTD1, aTD2, aT1, aT2, aTolInter, aX, aDT; - Standard_Real aTolCmp; - gp_Pnt2d aP2d1, aP2d2, aP2D; - gp_Lin2d aLDE; - Handle(Geom2d_Line) aCLDE; - Handle(Geom2d_Curve) aC2DDE1, aC2D; - Handle(Geom2d_TrimmedCurve)aC2DDE; - BOPDS_ListIteratorOfListOfPaveBlock aItLPB; + // Prepare pave to put to pave block as an Extra pave BOPDS_Pave aPave; - // - aDT=Precision::PConfusion(); - // aPave.SetIndex(nVD); // - const TopoDS_Edge& aDE=(*(TopoDS_Edge *)(&myDS->Shape(nED))); - const TopoDS_Face& aDF=(*(TopoDS_Face *)(&myDS->Shape(nFD))); - //aC2DDE - aC2DDE1=BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2); - aC2DDE=new Geom2d_TrimmedCurve(aC2DDE1, aTD1, aTD2); - //aCLDE - Handle(Geom2d_TrimmedCurve) aCLDET1=Handle(Geom2d_TrimmedCurve)::DownCast(aC2DDE1); - if (aCLDET1.IsNull()) { - aCLDE=Handle(Geom2d_Line)::DownCast(aC2DDE1); - } - else { - Handle(Geom2d_Curve) aBasisCurve=aCLDET1->BasisCurve(); - aCLDE=Handle(Geom2d_Line)::DownCast(aBasisCurve); - } + const TopoDS_Vertex& aDV = (*(TopoDS_Vertex *)(&myDS->Shape(nVD))); + const TopoDS_Edge& aDE = (*(TopoDS_Edge *)(&myDS->Shape(nED))); + const TopoDS_Face& aDF = (*(TopoDS_Face *)(&myDS->Shape(nFD))); // - // Choose direction for degenerated edge - aC2DDE->D0(aTD1, aP2d1); - aC2DDE->D0(aTD2, aP2d2); + Standard_Real aTolV = BRep_Tool::Tolerance(aDV); + const BRepAdaptor_Surface& aBAS = myContext->SurfaceAdaptor(aDF); // - bXDir=Standard_False; - if (fabs(aP2d1.Y()-aP2d2.Y()) < aDT){ - bXDir=!bXDir; - } + // 2D intersection tolerance should be computed as a resolution + // from the tolerance of vertex to resolve the touching cases + Standard_Real aTolInt = Precision::PConfusion(); + // UResolution from the tolerance of the vertex + Standard_Real aURes = aBAS.UResolution(aTolV); + // VResolution from the tolerance of the vertex + Standard_Real aVRes = aBAS.VResolution(aTolV); // - aItLPB.Initialize(aLPBOut); + aTolInt = Max(aTolInt, Max(aURes, aVRes)); + // + // Parametric tolerance to compare intersection point with boundaries + // should be computed as a resolution from the tolerance of vertex + // in the direction of the 2D curve of degenerated edge + Standard_Real aTolCmp = Precision::PConfusion(); + // Get 2D curve + Standard_Real aTD1, aTD2; + Handle(Geom2d_Curve) aC2DDE = BRep_Tool::CurveOnSurface(aDE, aDF, aTD1, aTD2); + // Get direction of the curve + Standard_Boolean bUDir = Abs(aC2DDE->Value(aTD1).Y() - aC2DDE->Value(aTD2).Y()) < Precision::PConfusion(); + // + aTolCmp = Max(aTolCmp, (bUDir ? aURes : aVRes)); + // + // Prepare adaptor for the degenerated edge for intersection + Geom2dAdaptor_Curve aGAC1; + aGAC1.Load(aC2DDE, aTD1, aTD2); + // + BOPDS_ListIteratorOfListOfPaveBlock aItLPB(aLPBOut); for (; aItLPB.More(); aItLPB.Next()) { - const Handle(BOPDS_PaveBlock)& aPB=aItLPB.Value(); - nE=aPB->Edge(); + const Handle(BOPDS_PaveBlock)& aPB = aItLPB.Value(); + Standard_Integer nE = aPB->Edge(); if (nE < 0) { continue; } - const TopoDS_Edge& aE=(*(TopoDS_Edge *)(&myDS->Shape(nE))); - aC2D=BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2); + const TopoDS_Edge& aE = (*(TopoDS_Edge *)(&myDS->Shape(nE))); + Standard_Real aT1, aT2; + Handle(Geom2d_Curve) aC2D = BRep_Tool::CurveOnSurface(aE, aDF, aT1, aT2); if (aC2D.IsNull()) { continue; } // - // Intersection - Geom2dAdaptor_Curve aGAC1, aGAC2; - aGAC1.Load(aC2DDE, aTD1, aTD2); + // Prepare adaptor for the passing edge for intersection + Geom2dAdaptor_Curve aGAC2; // - Handle(Geom2d_Line) aL2D= Handle(Geom2d_Line)::DownCast(aC2D); + Handle(Geom2d_Line) aL2D = Handle(Geom2d_Line)::DownCast(aC2D); if (!aL2D.IsNull()) { aGAC2.Load(aC2D); } else { aGAC2.Load(aC2D, aT1, aT2); } - // - aTolInter=0.001; - aTolCmp=1.414213562*aTolInter+aDT; - Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInter, aTolInter); - bIsDone=aGInter.IsDone(); - if(!bIsDone) { + // Intersection + Geom2dInt_GInter aGInter(aGAC1, aGAC2, aTolInt, aTolInt); + if (!aGInter.IsDone()) { continue; } // - aNbPoints=aGInter.NbPoints(); - if (!aNbPoints){ - continue; - } - // - for (j=1; j<=aNbPoints; ++j) { - aP2D=aGInter.Point(j).Value(); - aX=aGInter.Point(j).ParamOnFirst(); - // - if (fabs (aX-aTD1) < aTolCmp || fabs (aX-aTD2) < aTolCmp) { - continue; - } - if (aX < aTD1 || aX > aTD2) { - continue; - } - // - if (aPBD->ContainsParameter(aX, aDT, anInd)) { + // Analyze intersection points + Standard_Integer i, aNbPoints = aGInter.NbPoints(); + for (i = 1; i <= aNbPoints; ++i) { + Standard_Real aX = aGInter.Point(i).ParamOnFirst(); + if (aX - aTD1 < aTolCmp || aTD2 - aX < aTolCmp) { continue; } + // + Standard_Integer anInd; + if (aPBD->ContainsParameter(aX, aTolCmp, anInd)) { + continue; + } + // aPave.SetParameter(aX); aPBD->AppendExtPave1(aPave); } - }//for (; aItLPB.More(); aItLPB.Next()) { + } } //======================================================================= // function: MakeSplitEdge1 diff --git a/src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx b/src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx index e1b1bdf133..8ce06916a4 100644 --- a/src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx +++ b/src/BOPAlgo/BOPAlgo_WireSplitter_1.cxx @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -412,15 +413,23 @@ void Path (const GeomAdaptor_Surface& aGAS, bIsClosed = aVertMap.Find(aVb); { BOPCol_ListOfShape aBuf; + Standard_Boolean bHasEdge = Standard_False; // aNb = aLS.Length(); for (i = aNb; i>0; --i) { const TopoDS_Shape& aVPrev=aVertVa(i); const gp_Pnt2d& aPaPrev=aCoordVa(i); - const TopoDS_Shape& aEPrev=aLS(i); - + const TopoDS_Edge& aEPrev = TopoDS::Edge(aLS(i)); + // aBuf.Append(aEPrev); - + if (!bHasEdge) { + bHasEdge = !BRep_Tool::Degenerated(aEPrev); + // do not create wire from degenerated edges only + if (!bHasEdge) { + continue; + } + } + // anIsSameV = aVPrev.IsSame(aVb); anIsSameV2d = anIsSameV; if (anIsSameV) { diff --git a/tests/bugs/moddata_2/bug469 b/tests/bugs/moddata_2/bug469 index f4bc4ba1ca..bd61c13ca3 100755 --- a/tests/bugs/moddata_2/bug469 +++ b/tests/bugs/moddata_2/bug469 @@ -1,8 +1,3 @@ -puts "TODO OCC28556 ALL: Faulty shapes in variables" -puts "TODO OCC28556 ALL: The area of result shape is" -puts "TODO OCC28556 ALL: The volume of result shape is" -puts "TODO OCC28556 ALL: Error : is WRONG because number of" - puts "========================" puts " OCC469 " puts "========================" @@ -12,10 +7,22 @@ puts "" ###################################################### restore [locate_data_file OCC469.brep] a +# remove small edges from the shape +fixsmalledges a a 0.002 + +# explode to get two arguemnts explode a +# use fuzzy value to treat misalignment of the arguments +bfuzzyvalue 0.002 + +# perform Boolean operation bfuse result a_1 a_2 +# restoring fuzzy value to zero +bfuzzyvalue 0.0 + +# check the obtained result checkshape result checkprops result -s 30523.3 -v 22730.1 checknbshapes result -shell 1 -solid 1