Code

add LPE Interpolate
authorjohanengelen <johanengelen@users.sourceforge.net>
Sun, 27 Jul 2008 18:58:20 +0000 (18:58 +0000)
committerjohanengelen <johanengelen@users.sourceforge.net>
Sun, 27 Jul 2008 18:58:20 +0000 (18:58 +0000)
src/live_effects/CMakeLists.txt
src/live_effects/Makefile_insert
src/live_effects/effect.cpp
src/live_effects/effect.h
src/live_effects/lpe-interpolate.cpp [new file with mode: 0644]
src/live_effects/lpe-interpolate.h [new file with mode: 0644]

index 79d403601e73bf289c3f9dc23a6bbc718bcc7577..98875a5a21ba4bb1b0422536462fd9e46add9482 100644 (file)
@@ -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
index e651418d38aec39f3169146dd4ea594ac48998a4..b67e44051b47bfa8ce0ce3b2b8e48e46e4fabbbe 100644 (file)
@@ -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    \
index 85f392321559418b2663c5edfe9d6b181a692a03..8715927e1f764a660a0af0d6fe4b0aaf27ef743d 100644 (file)
@@ -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<EffectType> LPETypeData[INVALID_LPE] = {
     {OFFSET, N_("Offset"), "offset"},
     {RULER, N_("Ruler"), "ruler"},
     {BOOLOPS, N_("Boolops"), "boolops"},
+    {INTERPOLATE, N_("Interpolate"), "interpolate"},
 };
 const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, INVALID_LPE);
 
@@ -183,6 +185,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj)
         case BOOLOPS:
             neweffect = static_cast<Effect*> ( new LPEBoolops(lpeobj) );
             break;
+        case INTERPOLATE:
+            neweffect = static_cast<Effect*> ( new LPEInterpolate(lpeobj) );
+            break;
         default:
             g_warning("LivePathEffect::Effect::New   called with invalid patheffect type (%d)", lpenr);
             neweffect = NULL;
index c72f659f7c95193e7a85e455805b2745cb674b19..4b609965696db533f5f2ec9d9bab7d0ee430f885 100644 (file)
@@ -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 (file)
index 0000000..f2ac17e
--- /dev/null
@@ -0,0 +1,119 @@
+#define INKSCAPE_LPE_INTERPOLATE_CPP
+/** \file
+ * LPE boolops implementation
+ */
+/*
+ * Authors:
+ *   Johan Engelen
+ *
+ * Copyright (C) Johan Engelen 2007-2008 <j.b.c.engelen@utwente.nl>
+ *
+ * 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<Parameter *>(&interpolate_path) );
+    registerParameter( dynamic_cast<Parameter *>(&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<Geom::Path> path_out;
+
+    Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_A = path_in[0].toPwSb();
+    Geom::Piecewise<Geom::D2<Geom::SBasis> > 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<Geom::D2<Geom::SBasis> > pA = Geom::partition(pwd2_A, pwd2_B.cuts);
+    Geom::Piecewise<Geom::D2<Geom::SBasis> > 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<Geom::D2<Geom::SBasis> > 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<Geom::LineSegment>( 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 (file)
index 0000000..10d21e3
--- /dev/null
@@ -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 <j.b.c.engelen@utwente.nl>
+ *
+ * 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<Geom::Path> doEffect_path (std::vector<Geom::Path> 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 :