From 0a75b58e47d3de42550c4f7960e253ea3befc09a Mon Sep 17 00:00:00 2001 From: johanengelen Date: Sun, 27 Jul 2008 18:58:20 +0000 Subject: [PATCH] add LPE Interpolate --- src/live_effects/CMakeLists.txt | 1 + src/live_effects/Makefile_insert | 2 + src/live_effects/effect.cpp | 5 ++ src/live_effects/effect.h | 1 + src/live_effects/lpe-interpolate.cpp | 119 +++++++++++++++++++++++++++ src/live_effects/lpe-interpolate.h | 55 +++++++++++++ 6 files changed, 183 insertions(+) create mode 100644 src/live_effects/lpe-interpolate.cpp create mode 100644 src/live_effects/lpe-interpolate.h diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index 79d403601..98875a5a2 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -9,6 +9,7 @@ lpe-curvestitch.cpp lpe-envelope.cpp lpe-gears.cpp lpegroupbbox.cpp +lpe-interpolate.cpp lpe-knot.cpp lpe-lattice.cpp lpe-mirror_symmetry.cpp diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index e651418d3..b67e44051 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -32,6 +32,8 @@ live_effects_liblive_effects_a_SOURCES = \ live_effects/lpe-constructgrid.h \ live_effects/lpe-gears.cpp \ live_effects/lpe-gears.h \ + live_effects/lpe-interpolate.cpp \ + live_effects/lpe-interpolate.h \ live_effects/lpe-test-doEffect-stack.cpp \ live_effects/lpe-test-doEffect-stack.h \ live_effects/lpe-lattice.cpp \ diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 85f392321..8715927e1 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -63,6 +63,7 @@ #include "live_effects/lpe-offset.h" #include "live_effects/lpe-ruler.h" #include "live_effects/lpe-boolops.h" +#include "live_effects/lpe-interpolate.h" // end of includes namespace Inkscape { @@ -98,6 +99,7 @@ const Util::EnumData LPETypeData[INVALID_LPE] = { {OFFSET, N_("Offset"), "offset"}, {RULER, N_("Ruler"), "ruler"}, {BOOLOPS, N_("Boolops"), "boolops"}, + {INTERPOLATE, N_("Interpolate"), "interpolate"}, }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, INVALID_LPE); @@ -183,6 +185,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case BOOLOPS: neweffect = static_cast ( new LPEBoolops(lpeobj) ); break; + case INTERPOLATE: + neweffect = static_cast ( new LPEInterpolate(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index c72f659f7..4b6099656 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -78,6 +78,7 @@ enum EffectType { OFFSET, RULER, BOOLOPS, + INTERPOLATE, INVALID_LPE // This must be last }; diff --git a/src/live_effects/lpe-interpolate.cpp b/src/live_effects/lpe-interpolate.cpp new file mode 100644 index 000000000..f2ac17ef8 --- /dev/null +++ b/src/live_effects/lpe-interpolate.cpp @@ -0,0 +1,119 @@ +#define INKSCAPE_LPE_INTERPOLATE_CPP +/** \file + * LPE boolops implementation + */ +/* + * Authors: + * Johan Engelen + * + * Copyright (C) Johan Engelen 2007-2008 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-interpolate.h" + +#include <2geom/path.h> +#include <2geom/sbasis-to-bezier.h> +#include <2geom/d2-sbasis.h> +#include <2geom/piecewise.h> + +#include "sp-path.h" +#include "display/curve.h" + +namespace Inkscape { +namespace LivePathEffect { + +LPEInterpolate::LPEInterpolate(LivePathEffectObject *lpeobject) : + Effect(lpeobject), + interpolate_path(_("Interpolate trajectory"), _("Path along which intermediate steps are created."), "trajectory", &wr, this, "M0,0 L0,0"), + number_of_steps(_("Steps"), _("Determines the number of steps from start to end path."), "steps", &wr, this, 5), + spacing(_("Spacing"), _("Determines the spacing between intermediate steps."), "spacing", &wr, this, 1) +{ + show_orig_path = true; + + registerParameter( dynamic_cast(&interpolate_path) ); + registerParameter( dynamic_cast(&number_of_steps) ); + + number_of_steps.param_make_integer(); + number_of_steps.param_set_range(2, NR_HUGE); +} + +LPEInterpolate::~LPEInterpolate() +{ + +} + +/* + * interpolate path_in[0] to path_in[1] + */ +Geom::PathVector +LPEInterpolate::doEffect_path (Geom::PathVector const & path_in) +{ + if ( (path_in.size() < 2) || (number_of_steps < 2)) + return path_in; + + std::vector path_out; + + Geom::Piecewise > pwd2_A = path_in[0].toPwSb(); + Geom::Piecewise > pwd2_B = path_in[1].toPwSb(); + + // Transform both paths to (0,0) midpoint, so they can easily be positioned along interpolate_path + pwd2_A -= Geom::bounds_exact(pwd2_A).midpoint(); + pwd2_B -= Geom::bounds_exact(pwd2_B).midpoint(); + + // Make sure both paths have the same number of segments and cuts at the same locations + pwd2_B.setDomain(pwd2_A.domain()); + Geom::Piecewise > pA = Geom::partition(pwd2_A, pwd2_B.cuts); + Geom::Piecewise > pB = Geom::partition(pwd2_B, pwd2_A.cuts); + + Geom::Path const &trajectory = interpolate_path.get_pathvector()[0]; + double trajectory_length = trajectory.size(); + + for (int i = 0; i < number_of_steps; ++i) { + double fraction = i / (number_of_steps-1); + + Geom::Piecewise > pResult = pA*fraction + pB*(1-fraction); + pResult += trajectory.pointAt((1.-fraction)*trajectory_length); + + Geom::PathVector pathv = Geom::path_from_piecewise(pResult, LPE_CONVERSION_TOLERANCE); + path_out.push_back( pathv[0] ); + } + + return path_out; +} + +void +LPEInterpolate::resetDefaults(SPItem * item) +{ + if (!SP_IS_PATH(item)) + return; + + SPCurve const *crv = sp_path_get_curve_reference(SP_PATH(item)); + Geom::PathVector const &pathv = crv->get_pathvector(); + if ( (pathv.size() < 2) ) + return; + + Geom::Rect bounds_A = pathv[0].boundsExact(); + Geom::Rect bounds_B = pathv[1].boundsExact(); + + Geom::PathVector traj_pathv; + traj_pathv.push_back( Geom::Path() ); + traj_pathv[0].start( bounds_A.midpoint() ); + traj_pathv[0].appendNew( bounds_B.midpoint() ); + interpolate_path.set_new_value( traj_pathv, true ); +} + +} //namespace LivePathEffect +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-interpolate.h b/src/live_effects/lpe-interpolate.h new file mode 100644 index 000000000..10d21e309 --- /dev/null +++ b/src/live_effects/lpe-interpolate.h @@ -0,0 +1,55 @@ +#ifndef INKSCAPE_LPE_INTERPOLATE_H +#define INKSCAPE_LPE_INTERPOLATE_H + +/** \file + * LPE interpolate implementation, see lpe-interpolate.cpp. + */ + +/* + * Authors: + * Johan Engelen + * + * Copyright (C) Johan Engelen 2007-2008 + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/effect.h" +#include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/path.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEInterpolate : public Effect { +public: + LPEInterpolate(LivePathEffectObject *lpeobject); + virtual ~LPEInterpolate(); + + virtual std::vector doEffect_path (std::vector const & path_in); + + virtual void resetDefaults(SPItem * item); +private: + PathParam interpolate_path; + ScalarParam number_of_steps; + ScalarParam spacing; + + LPEInterpolate(const LPEInterpolate&); + LPEInterpolate& operator=(const LPEInterpolate&); +}; + +} //namespace LivePathEffect +} //namespace Inkscape + +#endif // INKSCAPE_LPE_INTERPOLATE_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : -- 2.30.2