From 4fe8248cd521387d0829c423bf4492e2cbdfd7cd Mon Sep 17 00:00:00 2001 From: Johan Engelen Date: Tue, 27 Jul 2010 00:26:16 +0200 Subject: [PATCH] add powerstroke initial shot --- src/live_effects/CMakeLists.txt | 1 + src/live_effects/Makefile_insert | 2 + src/live_effects/effect-enum.h | 1 + src/live_effects/effect.cpp | 6 ++ src/live_effects/lpe-powerstroke.cpp | 156 +++++++++++++++++++++++++++ src/live_effects/lpe-powerstroke.h | 67 ++++++++++++ 6 files changed, 233 insertions(+) create mode 100644 src/live_effects/lpe-powerstroke.cpp create mode 100644 src/live_effects/lpe-powerstroke.h diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt index adf172247..70e8cbaf8 100644 --- a/src/live_effects/CMakeLists.txt +++ b/src/live_effects/CMakeLists.txt @@ -21,6 +21,7 @@ lpeobject-reference.cpp lpe-patternalongpath.cpp lpe-perp_bisector.cpp lpe-perspective_path.cpp +lpe-powerstroke.cpp lpe-skeleton.cpp lpe-sketch.cpp lpe-spiro.cpp diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index 1cc2e1b69..aacabc2db 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -67,6 +67,8 @@ ink_common_sources += \ live_effects/lpe-parallel.h \ live_effects/lpe-copy_rotate.cpp \ live_effects/lpe-copy_rotate.h \ + live_effects/lpe-powerstroke.cpp \ + live_effects/lpe-powerstroke.h \ live_effects/lpe-offset.cpp \ live_effects/lpe-offset.h \ live_effects/lpe-ruler.cpp \ diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 6f1004ae5..535cc2564 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -48,6 +48,7 @@ enum EffectType { DYNASTROKE, RECURSIVE_SKELETON, EXTRUDE, + POWERSTROKE, 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 6266fade0..9dbd27b50 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -75,6 +75,7 @@ #include "live_effects/lpe-line_segment.h" #include "live_effects/lpe-recursiveskeleton.h" #include "live_effects/lpe-extrude.h" +#include "live_effects/lpe-powerstroke.h" namespace Inkscape { @@ -100,6 +101,7 @@ const Util::EnumData LPETypeData[] = { {PATH_LENGTH, N_("Path length"), "path_length"}, {PERP_BISECTOR, N_("Perpendicular bisector"), "perp_bisector"}, {PERSPECTIVE_PATH, N_("Perspective path"), "perspective_path"}, + {POWERSTROKE, N_("Power stroke"), "powerstroke"}, {COPY_ROTATE, N_("Rotate copies"), "copy_rotate"}, {RECURSIVE_SKELETON, N_("Recursive skeleton"), "recursive_skeleton"}, {TANGENT_TO_CURVE, N_("Tangent to curve"), "tangent_to_curve"}, @@ -120,6 +122,7 @@ const Util::EnumData LPETypeData[] = { {ROUGH_HATCHES, N_("Hatches (rough)"), "rough_hatches"}, {SKETCH, N_("Sketch"), "sketch"}, {RULER, N_("Ruler"), "ruler"}, +/* 0.49 */ }; const Util::EnumDataConverter LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); @@ -237,6 +240,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case EXTRUDE: neweffect = static_cast ( new LPEExtrude(lpeobj) ); break; + case POWERSTROKE: + neweffect = static_cast ( new LPEPowerStroke(lpeobj) ); + break; default: g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr); neweffect = NULL; diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp new file mode 100644 index 000000000..c3de621ee --- /dev/null +++ b/src/live_effects/lpe-powerstroke.cpp @@ -0,0 +1,156 @@ +#define INKSCAPE_LPE_POWERSTROKE_CPP +/** \file + * @brief PowerStroke LPE implementation. Creates curves with modifiable stroke width. + */ +/* Authors: + * Johan Engelen + * + * Copyright (C) 2010 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-powerstroke.h" + +#include "sp-shape.h" +#include "display/curve.h" + +#include <2geom/path.h> +#include <2geom/piecewise.h> +#include <2geom/sbasis-geometric.h> +#include <2geom/svg-elliptical-arc.h> +#include <2geom/transforms.h> + +namespace Inkscape { +namespace LivePathEffect { + +LPEPowerStroke::LPEPowerStroke(LivePathEffectObject *lpeobject) : + Effect(lpeobject), + offset_1(_("Start Offset"), _("Handle to control the distance of the offset from the curve"), "offset_1", &wr, this), + offset_2(_("End Offset"), _("Handle to control the distance of the offset from the curve"), "offset_2", &wr, this), + offset_3(_("End Offset"), _("Handle to control the distance of the offset from the curve"), "offset_3", &wr, this) +// offset_points(_("Offset points"), _("Offset points"), "offset_points", &wr, this) +{ + show_orig_path = true; + + registerParameter( dynamic_cast(&offset_1) ); + registerParameter( dynamic_cast(&offset_2) ); + registerParameter( dynamic_cast(&offset_3) ); +// registerParameter( dynamic_cast(&offset_points) ); + + /* register all your knotholder handles here: */ + //registerKnotHolderHandle(new PowerStroke::KnotHolderEntityAttachMyHandle(), _("help message")); +} + +LPEPowerStroke::~LPEPowerStroke() +{ + +} + + +void +LPEPowerStroke::doOnApply(SPLPEItem *lpeitem) +{ + offset_1.param_set_and_write_new_value(*(SP_SHAPE(lpeitem)->curve->first_point())); + offset_2.param_set_and_write_new_value(*(SP_SHAPE(lpeitem)->curve->last_point())); + offset_3.param_set_and_write_new_value(*(SP_SHAPE(lpeitem)->curve->last_point())); +} + +static void append_half_circle(Geom::Piecewise > &pwd2, + Geom::Point const center, Geom::Point const &dir) { + using namespace Geom; + + double r = L2(dir); + SVGEllipticalArc cap(center + dir, r, r, angle_between(Point(1,0), dir), false, false, center - dir); + Piecewise > cap_pwd2(cap.toSBasis()); + pwd2.continuousConcat(cap_pwd2); +} + +Geom::Piecewise > +LPEPowerStroke::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) +{ + using namespace Geom; + + double t1 = nearest_point(offset_1, pwd2_in); + double offset1 = L2(pwd2_in.valueAt(t1) - offset_1); + + double t2 = nearest_point(offset_2, pwd2_in); + double offset2 = L2(pwd2_in.valueAt(t2) - offset_2); + + double t3 = nearest_point(offset_3, pwd2_in); + double offset3 = L2(pwd2_in.valueAt(t3) - offset_3); + + /* + unsigned number_of_points = offset_points.data.size(); + double* t = new double[number_of_points]; + Point* offset = new double[number_of_points]; + for (unsigned i = 0; i < number_of_points; ++i) { + t[i] = nearest_point(offset_points.data[i], pwd2_in); + Point A = pwd2_in.valueAt(t[i]); + offset[i] = L2(A - offset_points.data[i]); + } + */ + + // create stroke path where points (x,y) = (t, offset) + Path strokepath; + strokepath.start( Point(pwd2_in.domain().min(),0) ); + strokepath.appendNew( Point(t1, offset1) ); + strokepath.appendNew( Point(t2, offset2) ); + strokepath.appendNew( Point(t3, offset3) ); + strokepath.appendNew( Point(pwd2_in.domain().max(), 0) ); + strokepath.appendNew( Point(t3, -offset3) ); + strokepath.appendNew( Point(t2, -offset2) ); + strokepath.appendNew( Point(t1, -offset1) ); + strokepath.close(); + + D2 > patternd2 = make_cuts_independent(strokepath.toPwSb()); + Piecewise x = Piecewise(patternd2[0]); + Piecewise y = Piecewise(patternd2[1]); + + Piecewise > der = unitVector(derivative(pwd2_in)); + Piecewise > n = rot90(der); + +// output = pwd2_in + n * offset; +// append_half_circle(output, pwd2_in.lastValue(), n.lastValue() * offset); +// output.continuousConcat(reverse(pwd2_in - n * offset)); +// append_half_circle(output, pwd2_in.firstValue(), -n.firstValue() * offset); + + Piecewise > output = compose(pwd2_in,x) + y*compose(n,x); + return output; +} + + +/* ######################## + * Define the classes for your knotholder handles here + */ + +/* +namespace PowerStroke { + +class KnotHolderEntityMyHandle : public LPEKnotHolderEntity +{ +public: + // the set() and get() methods must be implemented, click() is optional + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get(); + //virtual void knot_click(guint state); +}; + +} // namespace PowerStroke +*/ + +/* ######################## */ + +} //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-powerstroke.h b/src/live_effects/lpe-powerstroke.h new file mode 100644 index 000000000..9c6e3effe --- /dev/null +++ b/src/live_effects/lpe-powerstroke.h @@ -0,0 +1,67 @@ +/** @file + * @brief PowerStroke LPE effect, see lpe-powerstroke.cpp. + */ +/* Authors: + * Johan Engelen + * + * Copyright (C) 2010 Authors + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#ifndef INKSCAPE_LPE_POWERSTROKE_H +#define INKSCAPE_LPE_POWERSTROKE_H + +#include "live_effects/effect.h" +#include "live_effects/parameter/point.h" +#include "live_effects/parameter/array.h" + +namespace Inkscape { +namespace LivePathEffect { + +// each knotholder handle for your LPE requires a separate class derived from KnotHolderEntity; +// define it in lpe-powerstroke.cpp and register it in the effect's constructor +/** +namespace PowerStroke { + // we need a separate namespace to avoid clashes with other LPEs + class KnotHolderEntityMyHandle; +} +**/ + +class LPEPowerStroke : public Effect { +public: + LPEPowerStroke(LivePathEffectObject *lpeobject); + virtual ~LPEPowerStroke(); + + virtual Geom::Piecewise > doEffect_pwd2 (Geom::Piecewise > const & pwd2_in); + + virtual void doOnApply(SPLPEItem *lpeitem); + + /* the knotholder entity classes (if any) must be declared friends */ + //friend class PowerStroke::KnotHolderEntityMyHandle; + +private: + PointParam offset_1; + PointParam offset_2; + PointParam offset_3; +// ArrayParam offset_points; + + LPEPowerStroke(const LPEPowerStroke&); + LPEPowerStroke& operator=(const LPEPowerStroke&); +}; + +} //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