From b23778eebc405977fc79e8ccf2b309afb7f66433 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sun, 15 May 2016 16:07:23 +0200 Subject: [PATCH] Speedup for flatcurves and NURBS curves getval() functions --- rtengine/curves.cc | 12 ++++++++++++ rtengine/curves.h | 4 +++- rtengine/diagonalcurves.cc | 18 +++++++++--------- rtengine/flatcurves.cc | 31 ++++++------------------------- 4 files changed, 30 insertions(+), 35 deletions(-) diff --git a/rtengine/curves.cc b/rtengine/curves.cc index 568f1e8ea..a5214e451 100644 --- a/rtengine/curves.cc +++ b/rtengine/curves.cc @@ -70,6 +70,18 @@ void Curve::AddPolygons () poly_y.push_back(y3); } +void Curve::fillDyByDx () +{ + dyByDx.resize(poly_x.size() - 1); + + for(unsigned int i = 0; i < poly_x.size() - 1; i++) { + double dx = poly_x[i + 1] - poly_x[i]; + double dy = poly_y[i + 1] - poly_y[i]; + dyByDx[i] = dy / dx; + + } +} + void Curve::fillHash() { hash.resize(hashSize + 2); diff --git a/rtengine/curves.h b/rtengine/curves.h index d841b2eb1..d5e1412eb 100644 --- a/rtengine/curves.h +++ b/rtengine/curves.h @@ -336,6 +336,7 @@ protected: // end of variables used in Parametric curves only std::vector poly_x; // X points of the faceted curve std::vector poly_y; // Y points of the faceted curve + std::vector dyByDx; std::vector hash; unsigned short hashSize; // hash table's size, between [10, 100, 1000] @@ -369,6 +370,7 @@ protected: } void fillHash(); + void fillDyByDx(); public: Curve (); @@ -406,7 +408,7 @@ public: class FlatCurve : public Curve { -protected: +private: FlatCurveType kind; double* leftTangent; double* rightTangent; diff --git a/rtengine/diagonalcurves.cc b/rtengine/diagonalcurves.cc index 4b41c2c29..19c662c0b 100644 --- a/rtengine/diagonalcurves.cc +++ b/rtengine/diagonalcurves.cc @@ -72,11 +72,15 @@ DiagonalCurve::DiagonalCurve (const std::vector& p, int poly_pn) if(x[0] == 0.f && x[1] == 0.f) // Avoid crash when first two points are at x = 0 (git Issue 2888) + { x[1] = 0.01f; + } if(x[0] == 1.f && x[1] == 1.f) // Avoid crash when first two points are at x = 1 (100 in gui) (git Issue 2923) + { x[0] = 0.99f; + } if (!identity) { if (kind == DCT_Spline && N > 2) { @@ -260,6 +264,8 @@ void DiagonalCurve::NURBS_set () // adding the final horizontal segment, always (see under) poly_x.push_back(3.0); // 3.0 is a hack for optimization purpose of the getVal method (the last value has to be beyond the normal range) poly_y.push_back(y[N - 1]); + + fillDyByDx(); } double DiagonalCurve::getVal (double t) const @@ -303,7 +309,7 @@ double DiagonalCurve::getVal (double t) const // do a binary search for the right interval: unsigned int k_lo = 0, k_hi = N - 1; - while (k_hi - k_lo > 1) { + while (k_hi > 1 + k_lo) { unsigned int k = (k_hi + k_lo) / 2; if (x[k] > t) { @@ -347,7 +353,7 @@ double DiagonalCurve::getVal (double t) const k_hi = hash.at(i).higherValue; // do a binary search for the right interval : - while (k_hi - k_lo > 1) { + while (k_hi > 1 + k_lo) { unsigned int k = (k_hi + k_lo) / 2; if (poly_x[k] > t) { @@ -357,13 +363,7 @@ double DiagonalCurve::getVal (double t) const } } - if (k_lo == k_hi) { - k_hi = k_lo + 1; - } - - double dx = poly_x[k_hi] - poly_x[k_lo]; - double dy = poly_y[k_hi] - poly_y[k_lo]; - return poly_y[k_lo] + (t - poly_x[k_lo]) * ( dy ) / dx; + return poly_y[k_lo] + (t - poly_x[k_lo]) * dyByDx[k_lo]; break; } diff --git a/rtengine/flatcurves.cc b/rtengine/flatcurves.cc index ee4d6d29c..5a4dfeacf 100644 --- a/rtengine/flatcurves.cc +++ b/rtengine/flatcurves.cc @@ -16,21 +16,14 @@ * You should have received a copy of the GNU General Public License * along with RawTherapee. If not, see . */ -#include -#include #include "curves.h" #include #include -#include "mytime.h" -#include - -#include -#include namespace rtengine { -FlatCurve::FlatCurve (const std::vector& p, bool isPeriodic, int poly_pn) : kind(FCT_Empty), leftTangent(NULL), rightTangent(NULL), identityValue(0.5), periodic(isPeriodic) +FlatCurve::FlatCurve (const std::vector& p, bool isPeriodic, int poly_pn) : kind(FCT_Empty), leftTangent(nullptr), rightTangent(nullptr), identityValue(0.5), periodic(isPeriodic) { ppn = poly_pn > 65500 ? 65500 : poly_pn; @@ -341,17 +334,7 @@ void FlatCurve::CtrlPoints_set () poly_x.push_back(3.0); // 3.0 is a hack for optimization purpose of the getVal method (the last value has to be beyond the normal range) poly_y.push_back(sc_y[j - 1]); - /* - // Checking the values - Glib::ustring fname = "Curve.xyz"; // TopSolid'Design "plot" file format - std::ofstream f (fname.c_str()); - f << "$" << std::endl;; - for (unsigned int iter = 0; iter < poly_x.size(); iter++) { - f << poly_x[iter] << ", " << poly_y[iter] << ", 0." << std::endl;; - } - f << "$" << std::endl;; - f.close (); - */ + fillDyByDx(); } double FlatCurve::getVal (double t) const @@ -367,10 +350,10 @@ double FlatCurve::getVal (double t) const } // do a binary search for the right interval: - int k_lo = 0, k_hi = poly_x.size() - 1; + unsigned int k_lo = 0, k_hi = poly_x.size() - 1; - while (k_hi - k_lo > 1) { - int k = (k_hi + k_lo) / 2; + while (k_hi > 1 + k_lo) { + unsigned int k = (k_hi + k_lo) / 2; if (poly_x[k] > t) { k_hi = k; @@ -379,9 +362,7 @@ double FlatCurve::getVal (double t) const } } - double dx = poly_x[k_hi] - poly_x[k_lo]; - double dy = poly_y[k_hi] - poly_y[k_lo]; - return poly_y[k_lo] + (t - poly_x[k_lo]) * dy / dx; + return poly_y[k_lo] + (t - poly_x[k_lo]) * dyByDx[k_lo]; break; }