From b62895f15526ccefdf1e274c49c02aa043895ee9 Mon Sep 17 00:00:00 2001 From: johanengelen Date: Mon, 23 Nov 2009 20:36:50 +0000 Subject: [PATCH] add LPE extrude. it's not finished yet! --- src/live_effects/effect-enum.h | 1 + src/live_effects/effect.cpp | 5 ++ src/live_effects/lpe-extrude.cpp | 145 +++++++++++++++++++++++++++++++ src/live_effects/lpe-extrude.h | 52 +++++++++++ 4 files changed, 203 insertions(+) create mode 100644 src/live_effects/lpe-extrude.cpp create mode 100644 src/live_effects/lpe-extrude.h diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 1911c6e20..6f1004ae5 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -47,6 +47,7 @@ enum EffectType { DOEFFECTSTACK_TEST, DYNASTROKE, RECURSIVE_SKELETON, + EXTRUDE, INVALID_LPE // This must be last (I made it such that it is not needed anymore I think..., Don't trust on it being last. - johan) }; diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 1d001b31a..04549622e 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -74,6 +74,7 @@ #include "live_effects/lpe-path_length.h" #include "live_effects/lpe-line_segment.h" #include "live_effects/lpe-recursiveskeleton.h" +#include "live_effects/lpe-extrude.h" namespace Inkscape { @@ -90,6 +91,7 @@ const Util::EnumData LPETypeData[] = { {CIRCLE_WITH_RADIUS, N_("Circle (by center and radius)"), "circle_with_radius"}, {CIRCLE_3PTS, N_("Circle by 3 points"), "circle_3pts"}, {DYNASTROKE, N_("Dynamic stroke"), "dynastroke"}, + {EXTRUDE, N_("Extrude"), "extrude"}, {LATTICE, N_("Lattice Deformation"), "lattice"}, {LINE_SEGMENT, N_("Line Segment"), "line_segment"}, {MIRROR_SYMMETRY, N_("Mirror symmetry"), "mirror_symmetry"}, @@ -232,6 +234,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case RECURSIVE_SKELETON: neweffect = static_cast ( new LPERecursiveSkeleton(lpeobj) ); break; + case EXTRUDE: + neweffect = static_cast ( new LPEExtrude(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; diff --git a/src/live_effects/lpe-extrude.cpp b/src/live_effects/lpe-extrude.cpp new file mode 100644 index 000000000..93ab60fc5 --- /dev/null +++ b/src/live_effects/lpe-extrude.cpp @@ -0,0 +1,145 @@ +#define INKSCAPE_LPE_EXTRUDE_CPP +/** \file + * @brief LPE effect for extruding paths (making them "3D"). + * + */ +/* Authors: + * Johan Engelen + * + * Copyright (C) 2009 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-extrude.h" + +#include <2geom/path.h> +#include <2geom/piecewise.h> +#include <2geom/transforms.h> + +namespace Inkscape { +namespace LivePathEffect { + +LPEExtrude::LPEExtrude(LivePathEffectObject *lpeobject) : + Effect(lpeobject), + extrude_vector(_("Direction"), _("Defines the direction and magnitude of the extrusion"), "extrude_vector", &wr, this, Geom::Point(-10,10)) +{ + show_orig_path = true; + concatenate_before_pwd2 = false; + + registerParameter( dynamic_cast(&extrude_vector) ); +} + +LPEExtrude::~LPEExtrude() +{ + +} + + +Geom::Piecewise > +LPEExtrude::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) +{ + using namespace Geom; + + // generate connecting lines (the 'sides' of the extrusion) + Path path(Point(0.,0.)); + path.appendNew( extrude_vector.getVector() ); + Piecewise > connector = path.toPwSb(); + + switch( 1 ) { + case 0: { + Piecewise > pwd2_out = pwd2_in; + // generate extrusion bottom: (just a copy of original path, displaced a bit) + pwd2_out.concat( pwd2_in + extrude_vector.getVector() ); + + // connecting lines should be put at start and end of path if it is not closed + // it is not possible to check whether a piecewise path is closed, + // so we check whether start and end are close + if ( ! are_near(pwd2_in.firstValue(), pwd2_in.lastValue()) ) { + pwd2_out.concat( connector + pwd2_in.firstValue() ); + pwd2_out.concat( connector + pwd2_in.lastValue() ); + } + // connecting lines should be put at cusps + Piecewise > deriv = derivative(pwd2_in); + std::vector cusps; // = roots(deriv); + for (unsigned i = 0; i < cusps.size() ; ++i) { + pwd2_out.concat( connector + pwd2_in.valueAt(cusps[i]) ); + } + // connecting lines should be put where the tangent of the path equals the extrude_vector in direction + std::vector rts = roots(dot(deriv, rot90(extrude_vector.getVector()))); + for (unsigned i = 0; i < rts.size() ; ++i) { + pwd2_out.concat( connector + pwd2_in.valueAt(rts[i]) ); + } + return pwd2_out; + } + + case 1: { + Piecewise > pwd2_out; + bool closed_path = are_near(pwd2_in.firstValue(), pwd2_in.lastValue()); + // split input path in pieces between points where deriv == vector + Piecewise > deriv = derivative(pwd2_in); + std::vector rts = roots(dot(deriv, rot90(extrude_vector.getVector()))); + double portion_t = 0.; + for (unsigned i = 0; i < rts.size() ; ++i) { + Piecewise > cut = portion(pwd2_in, portion_t, rts[i] ); + portion_t = rts[i]; + if (closed_path && i == 0) { + // if the path is closed, skip the first cut and add it to the last cut later + continue; + } + Piecewise > part = cut; + part.continuousConcat(connector + cut.lastValue()); + part.continuousConcat(reverse(cut) + extrude_vector.getVector()); + part.continuousConcat(reverse(connector) + cut.firstValue()); + pwd2_out.concat( part ); + } + if (closed_path) { + Piecewise > cut = portion(pwd2_in, portion_t, pwd2_in.domain().max() ); + cut.continuousConcat(portion(pwd2_in, pwd2_in.domain().min(), rts[0] )); + Piecewise > part = cut; + part.continuousConcat(connector + cut.lastValue()); + part.continuousConcat(reverse(cut) + extrude_vector.getVector()); + part.continuousConcat(reverse(connector) + cut.firstValue()); + pwd2_out.concat( part ); + } else if (!are_near(portion_t, pwd2_in.domain().max())) { + Piecewise > cut = portion(pwd2_in, portion_t, pwd2_in.domain().max() ); + Piecewise > part = cut; + part.continuousConcat(connector + cut.lastValue()); + part.continuousConcat(reverse(cut) + extrude_vector.getVector()); + part.continuousConcat(reverse(connector) + cut.firstValue()); + pwd2_out.concat( part ); + } + return pwd2_out; + } + } +} + +void +LPEExtrude::resetDefaults(SPItem * item) +{ + Effect::resetDefaults(item); + + using namespace Geom; + + Geom::OptRect bbox = item->getBounds(Geom::identity(), SPItem::GEOMETRIC_BBOX); + if (bbox) { + Interval boundingbox_X = (*bbox)[Geom::X]; + Interval boundingbox_Y = (*bbox)[Geom::Y]; + extrude_vector.set_and_write_new_values( Geom::Point(boundingbox_X.middle(), boundingbox_Y.middle()), + (boundingbox_X.extent() + boundingbox_Y.extent())*Geom::Point(-0.05,0.2) ); + } +} + +} //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:encoding=utf-8:textwidth=99 : diff --git a/src/live_effects/lpe-extrude.h b/src/live_effects/lpe-extrude.h new file mode 100644 index 000000000..b704aa856 --- /dev/null +++ b/src/live_effects/lpe-extrude.h @@ -0,0 +1,52 @@ +/** @file + * @brief LPE effect for extruding paths (making them "3D"). + */ +/* Authors: + * Johan Engelen + * + * Copyright (C) 2009 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_LPE_EXTRUDE_H +#define INKSCAPE_LPE_EXTRUDE_H + +#include "live_effects/effect.h" +#include "live_effects/parameter/parameter.h" +#include "live_effects/parameter/vector.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEExtrude : public Effect { +public: + LPEExtrude(LivePathEffectObject *lpeobject); + virtual ~LPEExtrude(); + + virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); + + virtual void resetDefaults(SPItem * item); + +private: + VectorParam extrude_vector; + + LPEExtrude(const LPEExtrude&); + LPEExtrude& operator=(const LPEExtrude&); +}; + +} //namespace LivePathEffect +} //namespace Inkscape + +#endif + +/* + 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:encoding=utf-8:textwidth=99 : -- 2.30.2