diff --git a/src/LocOpe/LocOpe_WiresOnShape.cxx b/src/LocOpe/LocOpe_WiresOnShape.cxx index 84f322259d..be1bfd2d56 100644 --- a/src/LocOpe/LocOpe_WiresOnShape.cxx +++ b/src/LocOpe/LocOpe_WiresOnShape.cxx @@ -71,6 +71,7 @@ #include #include +#include IMPLEMENT_STANDARD_RTTIEXT(LocOpe_WiresOnShape,MMgt_TShared) @@ -613,19 +614,77 @@ Standard_Boolean Project(const TopoDS_Vertex& V, //distance in 2D space recomputed in the 3D space in order to tolerance of vertex //cover gap in 2D space. For consistency with check of the validity in the BRepCheck_Wire - Standard_Real aDist3d = p2d.Distance(aPBound2d) / Min(anUResolution, aVResolution); + Standard_Real dumax = 0.01 * (adSurf.LastUParameter() - adSurf.FirstUParameter()); + Standard_Real dvmax = 0.01 * (adSurf.LastVParameter() - adSurf.FirstVParameter()); + + gp_Pnt2d aPcur = p2d; + Standard_Real dumin = Abs(aPcur.X() - aPBound2d.X()); + Standard_Real dvmin = Abs(aPcur.Y() - aPBound2d.Y()); + if (dumin > dumax && adSurf.IsUPeriodic()) + { + Standard_Real aX1 = aPBound2d.X(); + Standard_Real aShift = ShapeAnalysis::AdjustToPeriod(aX1, adSurf.FirstUParameter(), adSurf.LastUParameter()); + aX1 += aShift; + aPBound2d.SetX(aX1); + Standard_Real aX2 = p2d.X(); + aShift = ShapeAnalysis::AdjustToPeriod(aX2, adSurf.FirstUParameter(), adSurf.LastUParameter()); + aX2 += aShift; + dumin = Abs(aX2 - aX1); + if (dumin > dumax && (Abs(dumin - adSurf.UPeriod()) < Precision::PConfusion()) ) + { + aX2 = aX1; + dumin = 0.; + } + aPcur.SetX(aX2); + } + + if (dvmin > dvmax && adSurf.IsVPeriodic()) + { + Standard_Real aY1 = aPBound2d.Y(); + Standard_Real aShift = ShapeAnalysis::AdjustToPeriod(aY1, adSurf.FirstVParameter(), adSurf.LastVParameter()); + aY1 += aShift; + aPBound2d.SetY(aY1); + Standard_Real aY2 = p2d.Y(); + aShift = ShapeAnalysis::AdjustToPeriod(aY2, adSurf.FirstVParameter(), adSurf.LastVParameter()); + aY2 += aShift; + dvmin = Abs(aY1 - aY2); + if (dvmin > dvmax && ( Abs(dvmin - adSurf.VPeriod()) < Precision::Confusion()) ) + { + aY2 = aY1; + dvmin = 0.; + } + aPcur.SetY(aY2); + } + Standard_Real aDist3d = aTolV; + if ((dumin > dumax) || (dvmin > dvmax)) + { + + dumax = adSurf.UResolution(aTolV); + dvmax = adSurf.VResolution(aTolV); + Standard_Real aTol2d = 2. * Max(dumax, dvmax); + Standard_Real aDist2d = Max(dumin, dvmin); + + if (aDist2d > aTol2d) + { + Standard_Real aDist3d1 = aDist2d / Max(anUResolution, aVResolution); + if( aDist3d1 > aDist3d) + aDist3d = aDist3d1; + } + } + + //added check by 3D the same as in the BRepCheck_Wire::SelfIntersect gp_Pnt aPBound; aSurf->D0(aPBound2d.X(), aPBound2d.Y(), aPBound); gp_Pnt aPV2d; aSurf->D0(p2d.X(), p2d.Y(), aPV2d); Standard_Real aDistPoints_3D = aPV2d.SquareDistance(aPBound); - Standard_Real aDist2d = Max(aDistPoints_3D, aDist3d * aDist3d); - + Standard_Real aMaxDist = Max(aDistPoints_3D, aDist3d * aDist3d); + BRep_Builder B; - if (aTolV * aTolV < aDist2d) + if (aTolV * aTolV < aMaxDist) { - Standard_Real aNewTol = sqrt(aDist2d) + Precision::Confusion(); + Standard_Real aNewTol = sqrt(aMaxDist); B.UpdateVertex(V, aNewTol); } } diff --git a/tests/bugs/modalg_6/bug28094 b/tests/bugs/modalg_6/bug28094 new file mode 100644 index 0000000000..ff5396817e --- /dev/null +++ b/tests/bugs/modalg_6/bug28094 @@ -0,0 +1,30 @@ +puts "============" +puts "OCC28094" +puts "============" +puts "" +###################################################### +# Shape obtained after DRAW command "splitshape" has unnecessary high tolerance. +###################################################### + +smallview + +set expected_MaxTolerance 2.e-07 +set tol_abs_MaxTolerance 1.e-06 +set tol_rel_MaxTolerance 1.e-06 + +psphere a 10 +plane p2 2 0 0 1 0 0 +mkface f2 p2 -100 100 -100 100 +bsection s2 a f2 +explode a f +explode s2 e +splitshape res a_1 a_1 s2_1 a_1 s2_2 + +regexp {Tolerance +MAX=([-0-9.+eE]+)} [tolerance res] full MaxTolerance +checkreal "MaxTolerance" ${MaxTolerance} ${expected_MaxTolerance} ${tol_abs_MaxTolerance} ${tol_rel_MaxTolerance} + +clear +donly res +fit + +xwd ${imagedir}/${test_image}.png