From 70eb1fc448cb08acf3468f80fa2296c03b32afd2 Mon Sep 17 00:00:00 2001 From: cilix42 Date: Wed, 2 Apr 2008 11:23:50 +0000 Subject: [PATCH] New LPE: Perspective paths --- src/live_effects/Makefile_insert | 4 +- src/live_effects/effect.cpp | 5 + src/live_effects/effect.h | 1 + src/live_effects/lpe-perspective_path.cpp | 148 ++++++++++++++++++++++ src/live_effects/lpe-perspective_path.h | 53 ++++++++ 5 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 src/live_effects/lpe-perspective_path.cpp create mode 100644 src/live_effects/lpe-perspective_path.h diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index 0c6ba4a00..4edc2c19f 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -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 diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 48a3ab9ff..73f6e3dec 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -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 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 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; diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index f3143124b..4293fd854 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -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 index 000000000..923a4baa4 --- /dev/null +++ b/src/live_effects/lpe-perspective_path.cpp @@ -0,0 +1,148 @@ +#define INKSCAPE_LPE_PERSPECTIVE_PATH_CPP +/** \file + * LPE 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 + * Copyright (C) Maximilian Albert 2008 + * + * 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 + +#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(&scalex) ); + registerParameter( dynamic_cast(&scaley) ); + registerParameter( dynamic_cast(&offsetx) ); + registerParameter( dynamic_cast(&offsety) ); + registerParameter( dynamic_cast(&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 > +LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise > & pwd2_in) +{ + using namespace Geom; + + Piecewise > 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 > B = make_cuts_independant(path_a_pw); + Piecewise 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 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 > result(divide(res[0],res[2], 3), + divide(res[1],res[2], 3)); + + Piecewise > 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 index 000000000..f02df30f0 --- /dev/null +++ b/src/live_effects/lpe-perspective_path.h @@ -0,0 +1,53 @@ +#ifndef INKSCAPE_LPE_PERSPECTIVE_PATH_H +#define INKSCAPE_LPE_PERSPECTIVE_PATH_H + +/** \file + * LPE implementation, see lpe-perspective_path.cpp. + */ + +/* + * Authors: + * Johan Engelen +* +* Copyright (C) Johan Engelen 2007 + * + * 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 +#include "2geom/point.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEPerspectivePath : public Effect { +public: + LPEPerspectivePath(LivePathEffectObject *lpeobject); + virtual ~LPEPerspectivePath(); + + virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > & 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 handles; + double tmat[3][4]; +}; + +} //namespace LivePathEffect +} //namespace Inkscape + +#endif -- 2.30.2