diff options
| author | Johan B. C. Engelen <jbc.engelen@swissonline.ch> | 2011-03-18 23:34:21 +0000 |
|---|---|---|
| committer | Johan Engelen <goejendaagh@zonnet.nl> | 2011-03-18 23:34:21 +0000 |
| commit | 4d22a9f26c863dcb99bf1a6f72c3b4a2d33eeb64 (patch) | |
| tree | d765712050e3a22a92d7235fd205c55b7ec04919 /src | |
| parent | D-Bus. Merging branch lp:~joakim-verona/inkscape/dbus-fixes (Bug #666986, Bug... (diff) | |
| download | inkscape-4d22a9f26c863dcb99bf1a6f72c3b4a2d33eeb64.tar.gz inkscape-4d22a9f26c863dcb99bf1a6f72c3b4a2d33eeb64.zip | |
add spiro interpolator to powerstroke
(bzr r10115)
Diffstat (limited to 'src')
| -rw-r--r-- | src/live_effects/lpe-powerstroke.cpp | 165 | ||||
| -rw-r--r-- | src/live_effects/lpe-powerstroke.h | 2 |
2 files changed, 161 insertions, 6 deletions
diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 5dc170e84..3556be61f 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -21,18 +21,31 @@ #include <2geom/transforms.h> #include <2geom/bezier-utils.h> +#include "live_effects/bezctx.h" +#include "live_effects/bezctx_intf.h" +#include "live_effects/spiro.h" + /// @TODO Move this to 2geom namespace Geom { namespace Interpolate { +enum InterpolatorType { + INTERP_LINEAR, + INTERP_CUBICBEZIER, + INTERP_CUBICBEZIER_JOHAN, + INTERP_SPIRO +}; + class Interpolator { public: Interpolator() {}; virtual ~Interpolator() {}; + static Interpolator* create(InterpolatorType type); + // virtual Piecewise<D2<SBasis> > interpolateToPwD2Sb(std::vector<Point> points) = 0; - virtual Path interpolateToPath(std::vector<Point> points) = 0; + virtual Geom::Path interpolateToPath(std::vector<Point> points) = 0; private: Interpolator(const Interpolator&); @@ -120,16 +133,153 @@ private: CubicBezierJohan& operator=(const CubicBezierJohan&); }; + +#define SPIRO_SHOW_INFINITE_COORDINATE_CALLS +class SpiroInterpolator : public Interpolator { +public: + SpiroInterpolator() {}; + virtual ~SpiroInterpolator() {}; + + virtual Path interpolateToPath(std::vector<Point> points) { + Path fit; + + Coord scale_y = 100.; + + guint len = points.size(); + bezctx *bc = new_bezctx_ink(&fit); + spiro_cp *controlpoints = g_new (spiro_cp, len); + for (unsigned int i = 0; i < len; ++i) { + controlpoints[i].x = points[i][X]; + controlpoints[i].y = points[i][Y] / scale_y; + controlpoints[i].ty = 'c'; + } + controlpoints[0].ty = '{'; + controlpoints[1].ty = 'v'; + controlpoints[len-2].ty = 'v'; + controlpoints[len-1].ty = '}'; + + spiro_seg *s = run_spiro(controlpoints, len); + spiro_to_bpath(s, len, bc); + free(s); + free(bc); + + fit *= Scale(1,scale_y); + return fit; + }; + +private: + typedef struct { + bezctx base; + Path *path; + int is_open; + } bezctx_ink; + + static void bezctx_ink_moveto(bezctx *bc, double x, double y, int /*is_open*/) + { + bezctx_ink *bi = (bezctx_ink *) bc; + if ( IS_FINITE(x) && IS_FINITE(y) ) { + bi->path->start(Point(x, y)); + } + #ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS + else { + g_message("spiro moveto not finite"); + } + #endif + } + + static void bezctx_ink_lineto(bezctx *bc, double x, double y) + { + bezctx_ink *bi = (bezctx_ink *) bc; + if ( IS_FINITE(x) && IS_FINITE(y) ) { + bi->path->appendNew<LineSegment>( Point(x, y) ); + } + #ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS + else { + g_message("spiro lineto not finite"); + } + #endif + } + + static void bezctx_ink_quadto(bezctx *bc, double xm, double ym, double x3, double y3) + { + bezctx_ink *bi = (bezctx_ink *) bc; + + if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) { + bi->path->appendNew<QuadraticBezier>(Point(xm, ym), Point(x3, y3)); + } + #ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS + else { + g_message("spiro quadto not finite"); + } + #endif + } + + static void bezctx_ink_curveto(bezctx *bc, double x1, double y1, double x2, double y2, + double x3, double y3) + { + bezctx_ink *bi = (bezctx_ink *) bc; + if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) { + bi->path->appendNew<CubicBezier>(Point(x1, y1), Point(x2, y2), Point(x3, y3)); + } + #ifdef SPIRO_SHOW_INFINITE_COORDINATE_CALLS + else { + g_message("spiro curveto not finite"); + } + #endif + } + + bezctx * + new_bezctx_ink(Geom::Path *path) { + bezctx_ink *result = g_new(bezctx_ink, 1); + result->base.moveto = bezctx_ink_moveto; + result->base.lineto = bezctx_ink_lineto; + result->base.quadto = bezctx_ink_quadto; + result->base.curveto = bezctx_ink_curveto; + result->base.mark_knot = NULL; + result->path = path; + return &result->base; + } + + SpiroInterpolator(const SpiroInterpolator&); + SpiroInterpolator& operator=(const SpiroInterpolator&); +}; + + +Interpolator* +Interpolator::create(InterpolatorType type) { + switch (type) { + case INTERP_LINEAR: + return new Geom::Interpolate::Linear(); + case INTERP_CUBICBEZIER: + return new Geom::Interpolate::CubicBezierFit(); + case INTERP_CUBICBEZIER_JOHAN: + return new Geom::Interpolate::CubicBezierJohan(); + case INTERP_SPIRO: + return new Geom::Interpolate::SpiroInterpolator(); + default: + return new Geom::Interpolate::Linear(); + } +} + } //namespace Interpolate } //namespace Geom namespace Inkscape { namespace LivePathEffect { +static const Util::EnumData<unsigned> 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"} +}; +static const Util::EnumDataConverter<unsigned> InterpolatorTypeConverter(InterpolatorTypeData, sizeof(InterpolatorTypeData)/sizeof(*InterpolatorTypeData)); + LPEPowerStroke::LPEPowerStroke(LivePathEffectObject *lpeobject) : Effect(lpeobject), offset_points(_("Offset points"), _("Offset points"), "offset_points", &wr, this), - sort_points(_("Sort points"), _("Sort offset points according to their time value along the curve."), "sort_points", &wr, this, true) + sort_points(_("Sort points"), _("Sort offset points according to their time value along the curve."), "sort_points", &wr, this, true), + interpolator_type(_("Interpolator type"), _("Determines which kind of interpolator will be used to interpolate between stroke width along the path."), "interpolator_type", InterpolatorTypeConverter, &wr, this, Geom::Interpolate::INTERP_CUBICBEZIER_JOHAN) { show_orig_path = true; @@ -137,6 +287,7 @@ LPEPowerStroke::LPEPowerStroke(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast<Parameter *>(&offset_points) ); registerParameter( dynamic_cast<Parameter *>(&sort_points) ); + registerParameter( dynamic_cast<Parameter *>(&interpolator_type) ); } LPEPowerStroke::~LPEPowerStroke() @@ -195,9 +346,11 @@ LPEPowerStroke::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & } // create stroke path where points (x,y) := (t, offset) - Geom::Interpolate::CubicBezierJohan interpolator; - Path strokepath = interpolator.interpolateToPath(ts); - Path mirroredpath = strokepath.reverse() * Geom::Scale(1,-1); + //Geom::Interpolate::CubicBezierJohan interpolator; + Geom::Interpolate::Interpolator *interpolator = Geom::Interpolate::Interpolator::create(static_cast<Geom::Interpolate::InterpolatorType>(interpolator_type.get_value())); + Geom::Path strokepath = interpolator->interpolateToPath(ts); + Geom::Path mirroredpath = strokepath.reverse() * Geom::Scale(1,-1); + delete interpolator; strokepath.append(mirroredpath, Geom::Path::STITCH_DISCONTINUOUS); strokepath.close(); @@ -222,7 +375,7 @@ LPEPowerStroke::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & ts.push_back( first_point + Point(pwd2_in.domain().extent() ,0) ); // create stroke path where points (x,y) := (t, offset) Geom::Interpolate::CubicBezierJohan interpolator; - Path strokepath = interpolator.interpolateToPath(ts); + Geom::Path strokepath = interpolator.interpolateToPath(ts); // output 2 separate paths D2<Piecewise<SBasis> > patternd2 = make_cuts_independent(strokepath.toPwSb()); diff --git a/src/live_effects/lpe-powerstroke.h b/src/live_effects/lpe-powerstroke.h index 667c94f53..7a1f3829a 100644 --- a/src/live_effects/lpe-powerstroke.h +++ b/src/live_effects/lpe-powerstroke.h @@ -15,6 +15,7 @@ #include "live_effects/effect.h" #include "live_effects/parameter/bool.h" #include "live_effects/parameter/powerstrokepointarray.h" +#include "live_effects/parameter/enum.h" namespace Inkscape { namespace LivePathEffect { @@ -31,6 +32,7 @@ public: private: PowerStrokePointArrayParam offset_points; BoolParam sort_points; + EnumParam<unsigned> interpolator_type; LPEPowerStroke(const LPEPowerStroke&); LPEPowerStroke& operator=(const LPEPowerStroke&); |
