diff options
| -rw-r--r-- | src/CurveEditor.H | 4 | ||||
| -rw-r--r-- | src/CurveEditor.cxx | 40 | ||||
| -rw-r--r-- | src/flcurve.cxx | 36 |
3 files changed, 65 insertions, 15 deletions
diff --git a/src/CurveEditor.H b/src/CurveEditor.H index 333bd45..c7f4691 100644 --- a/src/CurveEditor.H +++ b/src/CurveEditor.H @@ -22,7 +22,9 @@ class CurveEditor : public Fl_Widget { public: CurveEditor(int _x, int _y, int _w, int _h); - void set(int i, double _x, double _y); + void add_point(double _x, double _y); + void init(); + void set_point(int i, double _x, double _y); void draw(); int handle(int e); }; diff --git a/src/CurveEditor.cxx b/src/CurveEditor.cxx index 8ff8671..cfa6592 100644 --- a/src/CurveEditor.cxx +++ b/src/CurveEditor.cxx @@ -18,19 +18,12 @@ CurveEditor::CurveEditor(int my_x, int my_y, int my_w, int my_h) : marked_point = -1; - n = 5; - X = (double*) calloc(n, sizeof(double)); - Y = (double*) calloc(n, sizeof(double)); - - - for (int i = 0; i < n; i++) { - X[i] = (double) i / (n - 1); - Y[i] = (double) i / (n - 1); - } + n = 0; + X = NULL; + Y = NULL; acc = gsl_interp_accel_alloc (); - spline = gsl_spline_alloc (gsl_interp_cspline, n); - gsl_spline_init (spline, X, Y, n); + spline = NULL; } void @@ -83,7 +76,7 @@ CurveEditor::handle(int event) { return 1; break; case FL_DRAG: - set(marked_point, (double) mark_x / w(), 1.0 - (double) mark_y / h()); + set_point(marked_point, (double) mark_x / w(), 1.0 - (double) mark_y / h()); return 1; break; @@ -102,7 +95,28 @@ CurveEditor::handle(int event) { } void -CurveEditor::set(int i, double _x, double _y) { +CurveEditor::add_point(double _x, double _y) { + if ((_x < 0.0 || _x > 1.0 || _y < 0.0 || _y > 1.0) || + n > 0 && _x <= X[n]) { + return; + } + n++; + X = (double*) realloc(X, n * sizeof(double)); + Y = (double*) realloc(Y, n * sizeof(double)); + + X[n - 1] = _x; + Y[n - 1] = _y; +} + +void +CurveEditor::init() { + if (spline) gsl_spline_free(spline); + spline = gsl_spline_alloc (gsl_interp_cspline, n); + gsl_spline_init (spline, X, Y, n); +} + +void +CurveEditor::set_point(int i, double _x, double _y) { if (i >= n || (_x < 0.0 || _x > 1.0 || _y < 0.0 || _y > 1.0) || (i < n - 1 && _x >= X[i + 1]) || diff --git a/src/flcurve.cxx b/src/flcurve.cxx index 2769a51..ca0d901 100644 --- a/src/flcurve.cxx +++ b/src/flcurve.cxx @@ -17,6 +17,9 @@ #include "CurveEditor.H" +static void +parse_curve(CurveEditor *ce, const char *ctrl_points); + void usage() { fprintf(stderr, @@ -27,13 +30,17 @@ usage() { int main(int argc, char **argv) { int c, n, i, err; + char *curve = NULL; - while ((c = getopt(argc, argv, "?hs:g:d:f:i:")) != EOF) { + while ((c = getopt(argc, argv, "?hs:g:d:f:i:C:")) != EOF) { switch (c) { case '?': case 'h': usage(); exit(0); + case 'C': + curve = optarg; + break; default: i = optind - 1; n = Fl::arg(argc, argv, i); @@ -51,7 +58,34 @@ main(int argc, char **argv) { window.end(); window.resizable(ce); + if (curve) { + parse_curve(&ce, curve); + } + window.show(1, argv); return Fl::run(); } + +static void +parse_curve(CurveEditor *ce, const char *ctrl_points) { + char *pstr, *buf = strdup(ctrl_points); + int i, n = 0; + double X, Y; + gsl_interp_accel *acc; + gsl_spline *spline; + + while (pstr = strsep(&buf, ";")) { + if (sscanf(pstr, "%lf,%lf", &X, &Y) != 2 || + X < 0.0 || X > 1.0 || Y < 0.0 || Y > 1.0) { + fprintf(stderr, "Could not parse control point %s.\n", pstr); + continue; + } + + ce->add_point(X, Y); + } + + free(buf); + + ce->init(); +} |
