From 3960a8256e0858c8916b23aa34da82899e6cf27e Mon Sep 17 00:00:00 2001 From: aml Date: Thu, 18 Jun 2015 13:39:46 +0300 Subject: [PATCH] 0025981: Wrong result obtained by projection algorithm. Adjust periodic added. processing of V parameter periodicity added. Test case for issue CR25981 --- src/ProjLib/ProjLib_ProjectedCurve.cxx | 188 ++++++++++--------------- tests/bugs/moddata_3/bug25981 | 27 ++++ tests/draft/angle/G8 | 10 +- tests/draft/angle/K7 | 1 + 4 files changed, 111 insertions(+), 115 deletions(-) create mode 100755 tests/bugs/moddata_3/bug25981 diff --git a/src/ProjLib/ProjLib_ProjectedCurve.cxx b/src/ProjLib/ProjLib_ProjectedCurve.cxx index a446bad345..dd42945242 100644 --- a/src/ProjLib/ProjLib_ProjectedCurve.cxx +++ b/src/ProjLib/ProjLib_ProjectedCurve.cxx @@ -54,6 +54,7 @@ #include #include #include +#include //======================================================================= //function : IsoIsDeg @@ -613,129 +614,96 @@ void ProjLib_ProjectedCurve::Load(const Handle(Adaptor3d_HCurve)& C) } myTolerance = Comp.Tolerance(); } - else if (myResult.IsDone()) + + Standard_Boolean isPeriodic[] = {mySurface->IsUPeriodic(), + mySurface->IsVPeriodic()}; + if (myResult.IsDone() && + (isPeriodic[0] || isPeriodic[1])) { - // On remet arbitrairement la tol atteinte a une valeur - // petite en attendant mieux. dub lbo 11/03/97 - myTolerance = Min(myTolerance,Precision::Confusion()); - - // Translate the projected curve to keep the first point - // In the canonical boundaries of periodic surfaces. - if (mySurface->IsUPeriodic()) + // Check result curve to be in params space. + + // U and V parameters space correspondingly. + const Standard_Real aSurfFirstPar[2] = {mySurface->FirstUParameter(), + mySurface->FirstVParameter()}; + Standard_Real aSurfPeriod[2] = {0.0, 0.0}; + if (isPeriodic[0]) + aSurfPeriod[0] = mySurface->UPeriod(); + if (isPeriodic[1]) + aSurfPeriod[1] = mySurface->VPeriod(); + + for(Standard_Integer anIdx = 1; anIdx <= 2; anIdx++) { - // xf - Standard_Real aT1, aT2, aU1, aU2, aUPeriod, aUr, aUm, aUmid, dUm, dUr; - GeomAbs_CurveType aTypeR; - ProjLib_Projector aResult; - // - aT1 = myCurve->FirstParameter(); - aT2 = myCurve->LastParameter(); - aU1 = mySurface->FirstUParameter(); - aU2 = mySurface->LastUParameter(); - aUPeriod = mySurface->UPeriod(); - // - aTypeR = myResult.GetType(); - if ((aU2 - aU1) < (aUPeriod - myTolerance) && aTypeR == GeomAbs_Line) + if (!isPeriodic[anIdx - 1]) + continue; + + if (myResult.GetType() == GeomAbs_BSplineCurve) { - aResult = myResult; - aResult.UFrame(aT1, aT2, aU1, aUPeriod); - // - gp_Lin2d &aLr = (gp_Lin2d &) aResult.Line(); - aUr=aLr.Location().X(); - gp_Lin2d &aLm = (gp_Lin2d &) myResult.Line(); - aUm=aLm.Location().X(); - // - aUmid = 0.5 * (aU2 + aU1); - dUm = fabs(aUm - aUmid); - dUr = fabs(aUr - aUmid); - if (dUr < dUm) + NCollection_DataMap aMap; + Handle(Geom2d_BSplineCurve) aRes = myResult.BSpline(); + const Standard_Integer aDeg = aRes->Degree(); + + for(Standard_Integer aKnotIdx = aRes->FirstUKnotIndex(); + aKnotIdx < aRes->LastUKnotIndex(); + aKnotIdx++) { - myResult = aResult; + const Standard_Real aFirstParam = aRes->Knot(aKnotIdx); + const Standard_Real aLastParam = aRes->Knot(aKnotIdx + 1); + + for(Standard_Integer anIntIdx = 0; anIntIdx <= aDeg; anIntIdx++) + { + const Standard_Real aCurrParam = aFirstParam + (aLastParam - aFirstParam) * anIntIdx / (aDeg + 1.0); + gp_Pnt2d aPnt2d; + aRes->D0(aCurrParam, aPnt2d); + + Standard_Integer aMapKey = Standard_Integer ((aPnt2d.Coord(anIdx) - aSurfFirstPar[anIdx - 1]) / aSurfPeriod[anIdx - 1]); + + if (aPnt2d.Coord(anIdx) - aSurfFirstPar[anIdx - 1] < 0.0) + aMapKey--; + + if (aMap.IsBound(aMapKey)) + aMap.ChangeFind(aMapKey)++; + else + aMap.Bind(aMapKey, 1); + } + } + + Standard_Integer aMaxPoints = 0, aMaxIdx = 0; + NCollection_DataMap::Iterator aMapIter(aMap); + for( ; aMapIter.More(); aMapIter.Next()) + { + if (aMapIter.Value() > aMaxPoints) + { + aMaxPoints = aMapIter.Value(); + aMaxIdx = aMapIter.Key(); + } + } + if (aMaxIdx != 0) + { + gp_Pnt2d aFirstPnt = aRes->Value(aRes->FirstParameter()); + gp_Pnt2d aSecondPnt = aFirstPnt; + aSecondPnt.SetCoord(anIdx, aFirstPnt.Coord(anIdx) - aSurfPeriod[anIdx - 1] * aMaxIdx); + aRes->Translate(gp_Vec2d(aFirstPnt, aSecondPnt)); } } - else - { - myResult.UFrame(aT1, aT2, aU1, aUPeriod); - } - // - /* - myResult.UFrame(myCurve->FirstParameter(), - myCurve->LastParameter(), - mySurface->FirstUParameter(), - mySurface->UPeriod()); - */ - //xt - // Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 Begin - // Correct the U isoline in periodical surface - // to be inside restriction boundaries. + if (myResult.GetType() == GeomAbs_Line) { - gp_Lin2d &aLine = (gp_Lin2d &) myResult.Line(); + Standard_Real aT1 = myCurve->FirstParameter(); + Standard_Real aT2 = myCurve->LastParameter(); - Standard_Real aPeriod = mySurface->UPeriod(); - Standard_Real aFUPar = mySurface->FirstUParameter(); - Standard_Real aLUPar = mySurface->LastUParameter(); - - // Check if the parametric range is lower then the period. - if (aLUPar - aFUPar < aPeriod - myTolerance) + if (anIdx == 1) { - Standard_Real aU = aLine.Location().X(); - - if (Abs(aU + aPeriod - aFUPar) < myTolerance || - Abs(aU - aPeriod - aFUPar) < myTolerance) - { - gp_Pnt2d aNewLoc(aFUPar, aLine.Location().Y()); - - aLine.SetLocation(aNewLoc); - } - else if (Abs(aU + aPeriod - aLUPar) < myTolerance || - Abs(aU - aPeriod - aLUPar) < myTolerance) - { - gp_Pnt2d aNewLoc(aLUPar, aLine.Location().Y()); - aLine.SetLocation(aNewLoc); - } + // U param space. + myResult.UFrame(aT1, aT2, aSurfFirstPar[anIdx - 1], aSurfPeriod[anIdx - 1]); + } + else + { + // V param space. + myResult.VFrame(aT1, aT2, aSurfFirstPar[anIdx - 1], aSurfPeriod[anIdx - 1]); } } } - // Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 End - - if (mySurface->IsVPeriodic()) - { - myResult.VFrame(myCurve->FirstParameter(), myCurve->LastParameter(), - mySurface->FirstVParameter(), mySurface->VPeriod()); - // Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 Begin - // Correct the V isoline in a periodical surface - // to be inside restriction boundaries. - if (myResult.GetType() == GeomAbs_Line) - { - gp_Lin2d &aLine = (gp_Lin2d &) myResult.Line(); - - Standard_Real aPeriod = mySurface->VPeriod(); - Standard_Real aFVPar = mySurface->FirstVParameter(); - Standard_Real aLVPar = mySurface->LastVParameter(); - - // Check if the parametric range is lower then the period. - if (aLVPar - aFVPar < aPeriod - myTolerance) - { - Standard_Real aV = aLine.Location().Y(); - - if (Abs(aV + aPeriod - aFVPar) < myTolerance || - Abs(aV - aPeriod - aFVPar) < myTolerance) - { - gp_Pnt2d aNewLoc(aLine.Location().X(), aFVPar); - aLine.SetLocation(aNewLoc); - } - else if (Abs(aV + aPeriod - aLVPar) < myTolerance || - Abs(aV - aPeriod - aLVPar) < myTolerance) - { - gp_Pnt2d aNewLoc(aLine.Location().X(), aLVPar); - aLine.SetLocation(aNewLoc); - } - } - } - } - // Modified by skv - Wed Aug 11 15:45:58 2004 OCC6272 End - } + } } diff --git a/tests/bugs/moddata_3/bug25981 b/tests/bugs/moddata_3/bug25981 new file mode 100755 index 0000000000..822f9a0c01 --- /dev/null +++ b/tests/bugs/moddata_3/bug25981 @@ -0,0 +1,27 @@ +puts "========" +puts "OCC25981" +puts "========" +puts "" +################################################# +# Wrong result obtained by projection algorithm. +################################################# + +restore [locate_data_file bug25981_cb1_4.draw] c +restore [locate_data_file bug25981_b2f.brep] f +mksurface s f +project x c s + +2dcvalue x 0 firstX firstY +set log [dump firstX] +regexp {([-0-9.+eE]+)} ${log} x1 + +set tol_abs 1.e-7 +if {abs($x1) > $tol_abs} { + puts "Error: Bad start position of projected curve" +} + +view 1 -2D- 465 20 400 400 +2dfit +pcurve f + +xwd ${imagedir}/${casename}.png diff --git a/tests/draft/angle/G8 b/tests/draft/angle/G8 index 8f059eb110..86c36c44de 100644 --- a/tests/draft/angle/G8 +++ b/tests/draft/angle/G8 @@ -1,8 +1,8 @@ #F6---------------------------------------------- -puts "TODO OCC22803 Linux: Error in depouille" -puts "TODO OCC22803 Linux: Error : The skin cannot be built." -puts "TODO OCC22803 Windows: Faulty shapes in variables faulty_1 to faulty_" -puts "TODO OCC22803 Windows: Error : The area of the resulting shape is" +#puts "TODO OCC22803 Linux: Error in depouille" +#puts "TODO OCC22803 Linux: Error : The skin cannot be built." +puts "TODO OCC22803 Linux Windows: Faulty shapes in variables faulty_1 to faulty_" +puts "TODO OCC22803 Linux Windows: Error : The area of the resulting shape is" polyline p 0 0 3 0 0 0 10 0 0 10 0 3 beziercurve bc 4 10 0 3 7 0 2 3 0 3 0 0 3 mkedge bc bc @@ -18,4 +18,4 @@ if { [catch { depouille result f 0 0 1 f_4 3 0 0 10 0 0 1 } ] != 0 } { puts "Error in depouille" } -set square 492.768 \ No newline at end of file +set square 492.768 diff --git a/tests/draft/angle/K7 b/tests/draft/angle/K7 index 9f0420c715..7d5a335493 100644 --- a/tests/draft/angle/K7 +++ b/tests/draft/angle/K7 @@ -1,5 +1,6 @@ #D3--------------------------------------------- puts "TODO OCC22803 All:Faulty shapes in variables faulty_1 to faulty_6" +puts "TODO OCC22803 Linux Windows: Error : The area of the resulting shape is" plane pt 0 0 0 1 0 0 ptorus pt pt 9 7