summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJohan B. C. Engelen <jbc.engelen@swissonline.ch>2009-11-23 20:36:50 +0000
committerjohanengelen <johanengelen@users.sourceforge.net>2009-11-23 20:36:50 +0000
commit8c1bebebcb819658b21ee33419361f991ad08da2 (patch)
treeb57770e672ab57d6a40777f7ba2e8881c694a771 /src
parentfix bug 379378 (diff)
downloadinkscape-8c1bebebcb819658b21ee33419361f991ad08da2.tar.gz
inkscape-8c1bebebcb819658b21ee33419361f991ad08da2.zip
add LPE extrude. it's not finished yet!
(bzr r8838)
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/effect-enum.h1
-rw-r--r--src/live_effects/effect.cpp5
-rw-r--r--src/live_effects/lpe-extrude.cpp145
-rw-r--r--src/live_effects/lpe-extrude.h52
4 files changed, 203 insertions, 0 deletions
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<EffectType> 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<Effect*> ( new LPERecursiveSkeleton(lpeobj) );
break;
+ case EXTRUDE:
+ neweffect = static_cast<Effect*> ( 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 <j.b.c.engelen@utwente.nl>
+ *
+ * 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<Parameter *>(&extrude_vector) );
+}
+
+LPEExtrude::~LPEExtrude()
+{
+
+}
+
+
+Geom::Piecewise<Geom::D2<Geom::SBasis> >
+LPEExtrude::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in)
+{
+ using namespace Geom;
+
+ // generate connecting lines (the 'sides' of the extrusion)
+ Path path(Point(0.,0.));
+ path.appendNew<Geom::LineSegment>( extrude_vector.getVector() );
+ Piecewise<D2<SBasis> > connector = path.toPwSb();
+
+ switch( 1 ) {
+ case 0: {
+ Piecewise<D2<SBasis> > 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<T> 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<D2<SBasis> > deriv = derivative(pwd2_in);
+ std::vector<double> 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<double> 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<D2<SBasis> > pwd2_out;
+ bool closed_path = are_near(pwd2_in.firstValue(), pwd2_in.lastValue());
+ // split input path in pieces between points where deriv == vector
+ Piecewise<D2<SBasis> > deriv = derivative(pwd2_in);
+ std::vector<double> rts = roots(dot(deriv, rot90(extrude_vector.getVector())));
+ double portion_t = 0.;
+ for (unsigned i = 0; i < rts.size() ; ++i) {
+ Piecewise<D2<SBasis> > 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<D2<SBasis> > 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<D2<SBasis> > cut = portion(pwd2_in, portion_t, pwd2_in.domain().max() );
+ cut.continuousConcat(portion(pwd2_in, pwd2_in.domain().min(), rts[0] ));
+ Piecewise<D2<SBasis> > 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<D2<SBasis> > cut = portion(pwd2_in, portion_t, pwd2_in.domain().max() );
+ Piecewise<D2<SBasis> > 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 <j.b.c.engelen@utwente.nl>
+ *
+ * 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<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > 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 :