From d685d3f417cbecaf96e2acb55918283f36f21cd3 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 5 Sep 2014 00:02:09 +0200 Subject: LPE Powerstroke: add Centripetal Catmull-Rom interpolator (bzr r13545) --- src/live_effects/lpe-powerstroke-interpolators.h | 90 +++++++++++++++++++++++- src/live_effects/lpe-powerstroke.cpp | 3 +- 2 files changed, 91 insertions(+), 2 deletions(-) (limited to 'src/live_effects') diff --git a/src/live_effects/lpe-powerstroke-interpolators.h b/src/live_effects/lpe-powerstroke-interpolators.h index 6f5b75af8..ee4951882 100644 --- a/src/live_effects/lpe-powerstroke-interpolators.h +++ b/src/live_effects/lpe-powerstroke-interpolators.h @@ -27,7 +27,8 @@ enum InterpolatorType { INTERP_LINEAR, INTERP_CUBICBEZIER, INTERP_CUBICBEZIER_JOHAN, - INTERP_SPIRO + INTERP_SPIRO, + INTERP_CENTRIPETAL_CATMULLROM }; class Interpolator { @@ -167,6 +168,91 @@ private: SpiroInterpolator& operator=(const SpiroInterpolator&); }; +class CentripetalCatmullRomInterpolator : public Interpolator { +// the code in this class can certainly be optimized and made more terse, feel free +public: + CentripetalCatmullRomInterpolator() {}; + virtual ~CentripetalCatmullRomInterpolator() {}; + + virtual Path interpolateToPath(std::vector const &points) const { + unsigned int n_points = points.size(); + + Geom::Path fit(points.front()); + + if (n_points < 2) return fit; + if (n_points < 3) { + // if only 2 points, return linear segment + fit.appendNew(points[1]); + return fit; + } + + // return n_points-1 cubic segments + + // duplicate first point + fit.append(calc_bezier(points[0],points[0],points[1],points[2])); + + for (std::size_t i = 0; i < n_points-2; ++i) { + Point p0 = points[i]; + Point p1 = points[i+1]; + Point p2 = points[i+2]; + Point p3 = (i < n_points-3) ? points[i+3] : points[i+2]; + + fit.append(calc_bezier(p0, p1, p2, p3)); + // this is quite wasteful: the distances between the same points are repeatedly calculated by calc_bezier + } + + return fit; + }; + +private: + CubicBezier calc_bezier(Point p0, Point p1, Point p2, Point p3) const { + // create interpolating bezier between p1 and p2 + + // Part of the code comes from StackOverflow user eriatarka84 + // http://stackoverflow.com/a/23980479/2929337 + + // calculate time coords (deltas) of points + // the factor 0.25 can be generalized for other Catmull-Rom interpolation types + // see alpha in Yuksel et al. "On the Parameterization of Catmull-Rom Curves", + // --> http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf + double dt0 = powf(distanceSq(p0, p1), 0.25); + double dt1 = powf(distanceSq(p1, p2), 0.25); + double dt2 = powf(distanceSq(p2, p3), 0.25); + + + // safety check for repeated points + double eps = Geom::EPSILON; + if (dt1 < eps) + dt1 = 1.0; + if (dt0 < eps) + dt0 = dt1; + if (dt2 < eps) + dt2 = dt1; + + // compute tangents when parameterized in [t1,t2] + Point tan1 = (p1 - p0) / dt0 - (p2 - p0) / (dt0 + dt1) + (p2 - p1) / dt1; + Point tan2 = (p2 - p1) / dt1 - (p3 - p1) / (dt1 + dt2) + (p3 - p2) / dt2; + // rescale tangents for parametrization in [0,1] + tan1 *= dt1; + tan2 *= dt1; + + // create bezier from tangents (this is already in 2geom somewhere, or should be moved to it) + // the tangent of a bezier curve is: B'(t) = 3(1-t)^2 (b1 - b0) + 6(1-t)t(b2-b1) + 3t^2(b3-b2) + // So we have to make sure that B'(0) = tan1 and B'(1) = tan2, and we already know that b0=p1 and b3=p2 + // tan1 = B'(0) = 3 (b1 - p1) --> p1 + (tan1)/3 = b1 + // tan2 = B'(1) = 3 (p2 - b2) --> p2 - (tan2)/3 = b2 + + Point b0 = p1; + Point b1 = p1 + tan1 / 3; + Point b2 = p2 - tan2 / 3; + Point b3 = p2; + + return CubicBezier(b0, b1, b2, b3); + } + + CentripetalCatmullRomInterpolator(const CentripetalCatmullRomInterpolator&); + CentripetalCatmullRomInterpolator& operator=(const CentripetalCatmullRomInterpolator&); +}; Interpolator* Interpolator::create(InterpolatorType type) { @@ -179,6 +265,8 @@ Interpolator::create(InterpolatorType type) { return new Geom::Interpolate::CubicBezierJohan(); case INTERP_SPIRO: return new Geom::Interpolate::SpiroInterpolator(); + case INTERP_CENTRIPETAL_CATMULLROM: + return new Geom::Interpolate::CentripetalCatmullRomInterpolator(); default: return new Geom::Interpolate::Linear(); } diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 90b01aaa4..eed564b20 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -188,7 +188,8 @@ static const Util::EnumData InterpolatorTypeData[] = { {Geom::Interpolate::INTERP_LINEAR , N_("Linear"), "Linear"}, {Geom::Interpolate::INTERP_CUBICBEZIER , N_("CubicBezierFit"), "CubicBezierFit"}, {Geom::Interpolate::INTERP_CUBICBEZIER_JOHAN , N_("CubicBezierJohan"), "CubicBezierJohan"}, - {Geom::Interpolate::INTERP_SPIRO , N_("SpiroInterpolator"), "SpiroInterpolator"} + {Geom::Interpolate::INTERP_SPIRO , N_("SpiroInterpolator"), "SpiroInterpolator"}, + {Geom::Interpolate::INTERP_CENTRIPETAL_CATMULLROM , N_("Centripetal Catmull-Rom"), "CentripetalCatmullRom"} }; static const Util::EnumDataConverter InterpolatorTypeConverter(InterpolatorTypeData, sizeof(InterpolatorTypeData)/sizeof(*InterpolatorTypeData)); -- cgit v1.2.3 From e043dcd131751f2a0d29068f178fc008dc8c73d7 Mon Sep 17 00:00:00 2001 From: "Johan B. C. Engelen" Date: Fri, 5 Sep 2014 20:30:18 +0200 Subject: LPE Powerstroke: enable Extrapolated arc, remove Extrapolated (mirroring) The code to deal with Extrapolated mirroring is still working (if someone has an old file with that type of extrapolation), but perhaps that should also be removed. (bzr r13546) --- src/live_effects/lpe-powerstroke.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'src/live_effects') diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index eed564b20..b8657e165 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -220,12 +220,10 @@ enum LineJoinType { static const Util::EnumData LineJoinTypeData[] = { {LINEJOIN_BEVEL, N_("Beveled"), "bevel"}, {LINEJOIN_ROUND, N_("Rounded"), "round"}, - {LINEJOIN_EXTRP_MITER, N_("Extrapolated"), "extrapolated"}, +// {LINEJOIN_EXTRP_MITER, N_("Extrapolated"), "extrapolated"}, // disabled because doesn't work well + {LINEJOIN_EXTRP_MITER_ARC, N_("Extrapolated arc"), "extrp_arc"}, {LINEJOIN_MITER, N_("Miter"), "miter"}, {LINEJOIN_SPIRO, N_("Spiro"), "spiro"}, -#ifdef LPE_ENABLE_TEST_EFFECTS - {LINEJOIN_EXTRP_MITER_ARC, N_("Extrapolated arc"), "extrp_arc"}, -#endif }; static const Util::EnumDataConverter LineJoinTypeConverter(LineJoinTypeData, sizeof(LineJoinTypeData)/sizeof(*LineJoinTypeData)); @@ -407,8 +405,9 @@ static Geom::Path path_from_piecewise_fix_cusps( Geom::Piecewise Date: Wed, 10 Sep 2014 15:12:07 -0400 Subject: Fix bug #1367520 (crash regression) Fixed bugs: - https://launchpad.net/bugs/1367520 (bzr r13551) --- src/live_effects/parameter/path.cpp | 2 +- src/live_effects/parameter/text.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/live_effects') diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index 8095056b7..89947034d 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -143,7 +143,7 @@ gchar * PathParam::param_getSVGValue() const { if (href) { - return href; + return g_strdup(href); } else { gchar * svgd = sp_svg_write_path( _pathvector ); return svgd; diff --git a/src/live_effects/parameter/text.cpp b/src/live_effects/parameter/text.cpp index fcb2fc9fc..956a001ad 100644 --- a/src/live_effects/parameter/text.cpp +++ b/src/live_effects/parameter/text.cpp @@ -85,7 +85,7 @@ TextParam::param_readSVGValue(const gchar * strvalue) gchar * TextParam::param_getSVGValue() const { - return (gchar *) value.c_str(); + return g_strdup(value.c_str()); } Gtk::Widget * -- cgit v1.2.3 From 50a19700fb02a712803aa3623f0920d562116534 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Thu, 2 Oct 2014 10:32:46 +0200 Subject: i18n. Fix for Bug #380522 (strings that need to be fixed for translation). Translations. Inkscape.pot and French translation update. Fixed bugs: - https://launchpad.net/bugs/380522 (bzr r13576) --- src/live_effects/lpe-ruler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/live_effects') diff --git a/src/live_effects/lpe-ruler.cpp b/src/live_effects/lpe-ruler.cpp index 788ab593a..fd611c78d 100644 --- a/src/live_effects/lpe-ruler.cpp +++ b/src/live_effects/lpe-ruler.cpp @@ -29,7 +29,7 @@ static const Util::EnumData MarkDirData[] = { static const Util::EnumDataConverter MarkDirTypeConverter(MarkDirData, sizeof(MarkDirData)/sizeof(*MarkDirData)); static const Util::EnumData BorderMarkData[] = { - {BORDERMARK_NONE , N_("None"), "none"}, + {BORDERMARK_NONE , NC_("Border mark", "None"), "none"}, {BORDERMARK_START , N_("Start"), "start"}, {BORDERMARK_END , N_("End"), "end"}, {BORDERMARK_BOTH , N_("Both"), "both"}, -- cgit v1.2.3