From: abk Date: Tue, 17 Dec 2013 13:01:51 +0000 (+0400) Subject: 0024474: GCPnts_AbscissaPoint calculates invalid point X-Git-Tag: HYDRO-2014-01-31~39 X-Git-Url: http://git.dev.opencascade.org/gitweb/?p=occt.git;a=commitdiff_plain;h=bb0e6b9bcb1bab442eba9b14112133b9dbf6e880 0024474: GCPnts_AbscissaPoint calculates invalid point DRAW command discrCurve was created to test GCPnts_UniformAbscissa by count of discretization point. Two bugs in GCPnts_AbscissaPoint were fixed. DRAW tests for the bug were created. --- diff --git a/src/GCPnts/GCPnts_AbscissaPoint.gxx b/src/GCPnts/GCPnts_AbscissaPoint.gxx index 0a657c0..01c9aad 100644 --- a/src/GCPnts/GCPnts_AbscissaPoint.gxx +++ b/src/GCPnts/GCPnts_AbscissaPoint.gxx @@ -167,12 +167,6 @@ static void AdvCompute(CPnts_AbscissaPoint& theComputer, Standard_Real& Ui, const Standard_Real EPSILON) { - // test for easy solution - if (Abs(Abscis) <= EPSILON) { - theComputer.SetParameter(U0); - return; - } - Standard_Real Ratio; GCPnts_AbscissaType Type = computeType(C,Ratio); @@ -230,7 +224,7 @@ static void AdvCompute(CPnts_AbscissaPoint& theComputer, while ((Index >= 1) && (Index <= NbIntervals)) { L = CPnts_AbscissaPoint::Length(C, U0, TI(Index+Direction), EPSILON); - if (Abs(L - Abscis) <= /*Precision::Confusion()*/EPSILON) { + if (Abs(L - Abscis) <= Precision::PConfusion()) { theComputer.SetParameter(TI(Index+Direction)); return; } diff --git a/src/GeometryTest/GeometryTest_CurveCommands.cxx b/src/GeometryTest/GeometryTest_CurveCommands.cxx index f12ddb7..2e98440 100644 --- a/src/GeometryTest/GeometryTest_CurveCommands.cxx +++ b/src/GeometryTest/GeometryTest_CurveCommands.cxx @@ -1126,6 +1126,107 @@ static Standard_Integer EllipsUniformAbscissa (Draw_Interpretor& di, Standard_In } //======================================================================= +//function : discrCurve +//purpose : +//======================================================================= +static Standard_Integer discrCurve(Draw_Interpretor& di, Standard_Integer theArgNb, const char** theArgVec) +{ + if (theArgNb < 3) + { + di << "Invalid number of parameters.\n"; + return 1; + } + + Handle(Geom_Curve) aCurve = DrawTrSurf::GetCurve(theArgVec[2]); + if (aCurve.IsNull()) + { + di << "Curve is NULL.\n"; + return 1; + } + + Standard_Integer aSrcNbPnts = 0; + Standard_Boolean isUniform = Standard_False; + for (Standard_Integer anArgIter = 3; anArgIter < theArgNb; ++anArgIter) + { + TCollection_AsciiString anArg (theArgVec[anArgIter]); + TCollection_AsciiString anArgCase (anArg); + anArgCase.LowerCase(); + if (anArgCase == "nbpnts") + { + if (++anArgIter >= theArgNb) + { + di << "Value for argument '" << anArg << "' is absent.\n"; + return 1; + } + + aSrcNbPnts = Draw::Atoi (theArgVec[anArgIter]); + } + else if (anArgCase == "uniform") + { + if (++anArgIter >= theArgNb) + { + di << "Value for argument '" << anArg << "' is absent.\n"; + return 1; + } + + isUniform = (Draw::Atoi (theArgVec[anArgIter]) == 1); + } + else + { + di << "Invalid argument '" << anArg << "'.\n"; + return 1; + } + } + + if (aSrcNbPnts < 2) + { + di << "Invalid count of points.\n"; + return 1; + } + + if (!isUniform) + { + di << "Invalid type of discretization.\n"; + return 1; + } + + GeomAdaptor_Curve aCurveAdaptor(aCurve); + GCPnts_UniformAbscissa aSplitter(aCurveAdaptor, aSrcNbPnts, Precision::Confusion()); + if (!aSplitter.IsDone()) + { + di << "Error: Invalid result.\n"; + return 0; + } + + const Standard_Integer aDstNbPnts = aSplitter.NbPoints(); + + if (aDstNbPnts < 2) + { + di << "Error: Invalid result.\n"; + return 0; + } + + TColgp_Array1OfPnt aPoles(1, aDstNbPnts); + TColStd_Array1OfReal aKnots(1, aDstNbPnts); + TColStd_Array1OfInteger aMultiplicities(1, aDstNbPnts); + + for (Standard_Integer aPntIter = 1; aPntIter <= aDstNbPnts; ++aPntIter) + { + aPoles.ChangeValue(aPntIter) = aCurveAdaptor.Value(aSplitter.Parameter(aPntIter)); + aKnots.ChangeValue(aPntIter) = (aPntIter - 1) / (aDstNbPnts - 1.0); + aMultiplicities.ChangeValue(aPntIter) = 1; + } + aMultiplicities.ChangeValue(1) = 2; + aMultiplicities.ChangeValue(aDstNbPnts) = 2; + + Handle(Geom_BSplineCurve) aPolyline = + new Geom_BSplineCurve(aPoles, aKnots, aMultiplicities, 1); + DrawTrSurf::Set(theArgVec[1], aPolyline); + + return 0; +} + +//======================================================================= //function : mypoints //purpose : //======================================================================= @@ -1622,6 +1723,13 @@ void GeometryTest::CurveCommands(Draw_Interpretor& theCommands) "uniformAbscissaEl maxR minR nbPnt", __FILE__, EllipsUniformAbscissa,g); + theCommands.Add("discrCurve", + "discrCurve polyline curve params\n" + "Approximates a curve by a polyline (first degree B-spline).\n" + "nbPnts number - creates polylines with the number points\n" + "uniform 0 | 1 - creates polyline with equal length segments", + __FILE__, discrCurve, g); + theCommands.Add("mypoints", "mypoints result curv deflection", __FILE__, diff --git a/tests/bugs/moddata_3/bug24474 b/tests/bugs/moddata_3/bug24474 new file mode 100644 index 0000000..1c3e110 --- /dev/null +++ b/tests/bugs/moddata_3/bug24474 @@ -0,0 +1,11 @@ +puts "==================================================" +puts "Check count of segments in approximating polyline." +puts "==================================================" +puts "" + +restore [locate_data_file bug24474.brep] c +discrCurve p c nbPnts 3 uniform 1 +regexp {Poles\, +([0-9]+)} [dump p] full n +if {$n != 3} { + puts "Error: invalid discretization." +} diff --git a/tests/bugs/moddata_3/bug24474_2 b/tests/bugs/moddata_3/bug24474_2 new file mode 100644 index 0000000..662c1f9 --- /dev/null +++ b/tests/bugs/moddata_3/bug24474_2 @@ -0,0 +1,11 @@ +puts "==================================================" +puts "Check count of segments in approximating polyline." +puts "==================================================" +puts "" + +restore [locate_data_file bug24474_2.brep] c +discrCurve p c nbPnts 3 uniform 1 +regexp {Poles\, +([0-9]+)} [dump p] full n +if {$n != 3} { + puts "Error: invalid discretization." +}