Code

New LPE: Perspective paths
authorcilix42 <cilix42@users.sourceforge.net>
Wed, 2 Apr 2008 11:23:50 +0000 (11:23 +0000)
committercilix42 <cilix42@users.sourceforge.net>
Wed, 2 Apr 2008 11:23:50 +0000 (11:23 +0000)
src/live_effects/Makefile_insert
src/live_effects/effect.cpp
src/live_effects/effect.h
src/live_effects/lpe-perspective_path.cpp [new file with mode: 0644]
src/live_effects/lpe-perspective_path.h [new file with mode: 0644]

index 0c6ba4a0099ee48163b186096d1e3992a9bcb604..4edc2c19fc3e5e33dad7818f80c4940cd8cd289c 100644 (file)
@@ -35,5 +35,7 @@ live_effects_liblive_effects_a_SOURCES = \
        live_effects/lpe-slant.cpp      \
        live_effects/lpe-slant.h        \
        live_effects/lpe-circle_with_radius.cpp \
-       live_effects/lpe-circle_with_radius.h
+       live_effects/lpe-circle_with_radius.h   \
+       live_effects/lpe-perspective_path.cpp   \
+       live_effects/lpe-perspective_path.h
 
index 48a3ab9ff02112c5f74c2c92fd49f17d4ce8b1d6..73f6e3dec767c0d10cd5466b4df4699dbed69549 100644 (file)
@@ -43,6 +43,7 @@
 #include "live_effects/lpe-gears.h"
 #include "live_effects/lpe-curvestitch.h"
 #include "live_effects/lpe-circle_with_radius.h"
+#include "live_effects/lpe-perspective_path.h"
 
 #include "nodepath.h"
 
@@ -64,6 +65,7 @@ const Util::EnumData<EffectType> LPETypeData[INVALID_LPE] = {
     {GEARS,                 N_("Gears"),                 "gears"},
     {CURVE_STITCH,          N_("Stitch Sub-Paths"),      "curvestitching"},
     {CIRCLE_WITH_RADIUS,    N_("Circle (center+radius)"), "circle_with_radius"},
+    {PERSPECTIVE_PATH,      N_("Perspective path"),      "perspective_path"},
 };
 const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, INVALID_LPE);
 
@@ -105,6 +107,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj)
         case CIRCLE_WITH_RADIUS:
             neweffect = (Effect*) new LPECircleWithRadius(lpeobj);
             break;
+        case PERSPECTIVE_PATH:
+            neweffect = (Effect*) new LPEPerspectivePath(lpeobj);
+            break;
         default:
             g_warning("LivePathEffect::Effect::New   called with invalid patheffect type (%d)", lpenr);
             neweffect = NULL;
index f3143124b9668b9ce0354d4c97c1c9eb2e33c4d3..4293fd854da81c4a652044acd80482f417deef33 100644 (file)
@@ -63,6 +63,7 @@ enum EffectType {
     GEARS,
     CURVE_STITCH,
     CIRCLE_WITH_RADIUS,
+    PERSPECTIVE_PATH,
     INVALID_LPE // This must be last
 };
 
diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp
new file mode 100644 (file)
index 0000000..923a4ba
--- /dev/null
@@ -0,0 +1,148 @@
+#define INKSCAPE_LPE_PERSPECTIVE_PATH_CPP
+/** \file
+ * LPE <perspective_path> implementation, used as an example for a base starting class
+ * when implementing new LivePathEffects.
+ *
+ * In vi, three global search-and-replaces will let you rename everything
+ * in this and the .h file:
+ *
+ *   :%s/PERSPECTIVE_PATH/YOURNAME/g
+ *   :%s/PerspectivePath/Yourname/g
+ *   :%s/perspective_path/yourname/g
+ */
+/*
+ * Authors:
+ *   Johan Engelen
+ *   Maximilian Albert
+ *
+ * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>
+ * Copyright (C) Maximilian Albert 2008 <maximilian.albert@gmail.com>
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "persp3d.h"
+//#include "transf_mat_3x4.h"
+#include "document.h"
+
+#include "live_effects/lpe-perspective_path.h"
+#include "display/curve.h"
+#include <libnr/n-art-bpath.h>
+
+#include "inkscape.h"
+
+// You might need to include other 2geom files. You can add them here:
+#include <2geom/path.h>
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) :
+    Effect(lpeobject),
+    // initialise your parameters here:
+    scalex(_("Scale x"), _("Scale factor in x direction"), "scalex", &wr, this, 1.0),
+    scaley(_("Scale y"), _("Scale factor in y direction"), "scaley", &wr, this, 1.0),
+    offsetx(_("Offset x"), _("Offset in x direction"), "offsetx", &wr, this, 0.0),
+    offsety(_("Offset y"), _("Offset in y direction"), "offsety", &wr, this, 0.0),
+    uses_plane_xy(_("Uses XY plane?"), _("If true, put the path on the left side of an imaginary box, otherwise on the right side"), "uses_plane_xy", &wr, this, true)
+{
+    // register all your parameters here, so Inkscape knows which parameters this effect has:
+    registerParameter( dynamic_cast<Parameter *>(&scalex) );
+    registerParameter( dynamic_cast<Parameter *>(&scaley) );
+    registerParameter( dynamic_cast<Parameter *>(&offsetx) );
+    registerParameter( dynamic_cast<Parameter *>(&offsety) );
+    registerParameter( dynamic_cast<Parameter *>(&uses_plane_xy) );
+
+    Persp3D *persp = persp3d_document_first_persp(inkscape_active_document());
+
+    Proj::TransfMat3x4 pmat = persp->tmat;
+
+    pmat.copy_tmat(tmat);
+}
+
+LPEPerspectivePath::~LPEPerspectivePath()
+{
+
+}
+
+Geom::Piecewise<Geom::D2<Geom::SBasis> >
+LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in)
+{
+    using namespace Geom;
+
+    Piecewise<D2<SBasis> > path_a_pw = pwd2_in;
+
+    // FIXME: the minus sign is there because the SVG coordinate system goes down;
+    //        remove this once we have unified coordinate systems
+    path_a_pw = path_a_pw + Geom::Point(offsetx, -offsety);
+
+    D2<Piecewise<SBasis> > B = make_cuts_independant(path_a_pw);
+    Piecewise<SBasis> preimage[4];
+
+    Geom::Interval bounds_X = bounds_fast(pwd2_in)[0];
+    Geom::Interval bounds_Y = bounds_fast(pwd2_in)[1];
+
+    Geom::Point orig = Geom::Point(uses_plane_xy ? bounds_X.max() : bounds_X.min(),
+                                   bounds_Y.middle());
+    //Geom::Point orig = Geom::Point(bounds_X.min(), bounds_Y.middle());
+    //orig = Geom::Point(orig[X], sp_document_height(inkscape_active_document()) - orig[Y]);
+
+    double offset = uses_plane_xy ? bounds_X.extent() : 0.0;
+
+    /**
+    g_print ("Orig: (%8.2f, %8.2f)\n", orig[X], orig[Y]);
+
+    g_print ("B[1] - orig[1]: %8.2f\n", (B[1] - orig[1])[0].valueAt(0));
+    g_print ("B[0] - orig[0]: %8.2f\n", (B[0] - orig[0])[0].valueAt(0));
+    **/
+
+    if (uses_plane_xy) {
+        preimage[0] =  (-B[0] + orig[0]) * scalex / 200.0;
+        preimage[1] =  ( B[1] - orig[1]) * scaley / 400.0;
+        preimage[2] =  B[0] - B[0]; // hack!
+    } else {
+        preimage[0] =  B[0] - B[0]; // hack!
+        preimage[1] =  (B[1] - orig[1]) * scaley / 400.0;
+        preimage[2] =  (B[0] - orig[0]) * scalex / 200.0;
+    }
+
+    /* set perspective origin to first point of path */
+    tmat[0][3] = orig[0];
+    tmat[1][3] = orig[1];
+
+    /**
+    g_print ("preimage[1]: %8.2f\n", preimage[1][0].valueAt(0));
+    g_print ("preimage[2]: %8.2f\n", preimage[2][0].valueAt(0));
+    **/
+
+    Piecewise<SBasis> res[3];
+    for (int j = 0; j < 3; ++j) {
+        res[j] =
+              preimage[0] * tmat[j][0]
+            + preimage[1] * tmat[j][1]
+            + preimage[2] * tmat[j][2]
+            +               tmat[j][3];
+    }
+    D2<Piecewise<SBasis> > result(divide(res[0],res[2], 3), 
+                                  divide(res[1],res[2], 3));
+
+    Piecewise<D2<SBasis> > output = sectionize(result);
+
+    return output;
+}
+
+/* ######################## */
+
+} //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-perspective_path.h b/src/live_effects/lpe-perspective_path.h
new file mode 100644 (file)
index 0000000..f02df30
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef INKSCAPE_LPE_PERSPECTIVE_PATH_H
+#define INKSCAPE_LPE_PERSPECTIVE_PATH_H
+
+/** \file
+ * LPE <perspective_path> implementation, see lpe-perspective_path.cpp.
+ */
+
+/*
+ * Authors:
+ *   Johan Engelen
+*
+* Copyright (C) Johan Engelen 2007 <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/bool.h"
+
+#include <vector>
+#include "2geom/point.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+class LPEPerspectivePath : public Effect {
+public:
+    LPEPerspectivePath(LivePathEffectObject *lpeobject);
+    virtual ~LPEPerspectivePath();
+
+    virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > & pwd2_in);
+
+private:
+    // add the parameters for your effect here:
+    ScalarParam scalex;
+    ScalarParam scaley;
+    ScalarParam offsetx;
+    ScalarParam offsety;
+    BoolParam uses_plane_xy;
+    // there are all kinds of parameters. Check the /live_effects/parameter directory which types exist!
+
+    LPEPerspectivePath(const LPEPerspectivePath&);
+    LPEPerspectivePath& operator=(const LPEPerspectivePath&);
+
+    std::vector<Geom::Point> handles;
+    double tmat[3][4];
+};
+
+} //namespace LivePathEffect
+} //namespace Inkscape
+
+#endif