Code

add powerstroke initial shot
authorJohan Engelen <goejendaagh@zonnet.nl>
Mon, 26 Jul 2010 22:26:16 +0000 (00:26 +0200)
committerJohan Engelen <goejendaagh@zonnet.nl>
Mon, 26 Jul 2010 22:26:16 +0000 (00:26 +0200)
src/live_effects/CMakeLists.txt
src/live_effects/Makefile_insert
src/live_effects/effect-enum.h
src/live_effects/effect.cpp
src/live_effects/lpe-powerstroke.cpp [new file with mode: 0644]
src/live_effects/lpe-powerstroke.h [new file with mode: 0644]

index adf172247793aa341d55994a58c3f35f3e203d3a..70e8cbaf843ba2060fb79be16e8b32ef18bf7829 100644 (file)
@@ -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
index 1cc2e1b69df334c6c17e095523b309494fc850ab..aacabc2dbc518f2ba59195cb8adbb0e15cbdd057 100644 (file)
@@ -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      \
index 6f1004ae587767a70cf852e6e636c94bb290a14b..535cc25646e28503509e9449b1c77fcaf861cee4 100644 (file)
@@ -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)
 };
 
index 6266fade0297cfe2934de1a0d2df4b8654a6ab18..9dbd27b5041383c10ff45e94ed130433e367f429 100644 (file)
@@ -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<EffectType> 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<EffectType> LPETypeData[] = {
     {ROUGH_HATCHES,         N_("Hatches (rough)"),         "rough_hatches"},
     {SKETCH,                N_("Sketch"),                  "sketch"},
     {RULER,                 N_("Ruler"),                   "ruler"},
+/* 0.49 */
 };
 const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData));
 
@@ -237,6 +240,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj)
         case EXTRUDE:
             neweffect = static_cast<Effect*> ( new LPEExtrude(lpeobj) );
             break;
+        case POWERSTROKE:
+            neweffect = static_cast<Effect*> ( 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 (file)
index 0000000..c3de621
--- /dev/null
@@ -0,0 +1,156 @@
+#define INKSCAPE_LPE_POWERSTROKE_CPP
+/** \file
+ * @brief  PowerStroke LPE implementation. Creates curves with modifiable stroke width.
+ */
+/* Authors:
+ *   Johan Engelen <j.b.c.engelen@utwente.nl>
+ *
+ * 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<Parameter *>(&offset_1) );
+    registerParameter( dynamic_cast<Parameter *>(&offset_2) );
+    registerParameter( dynamic_cast<Parameter *>(&offset_3) );
+//    registerParameter( dynamic_cast<Parameter *>(&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<Geom::D2<Geom::SBasis> > &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<D2<SBasis> > cap_pwd2(cap.toSBasis());
+    pwd2.continuousConcat(cap_pwd2);
+}
+
+Geom::Piecewise<Geom::D2<Geom::SBasis> >
+LPEPowerStroke::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > 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<Geom::LineSegment>( Point(t1, offset1) );
+    strokepath.appendNew<Geom::LineSegment>( Point(t2, offset2) );
+    strokepath.appendNew<Geom::LineSegment>( Point(t3, offset3) );
+    strokepath.appendNew<Geom::LineSegment>( Point(pwd2_in.domain().max(), 0) );
+    strokepath.appendNew<Geom::LineSegment>( Point(t3, -offset3) );
+    strokepath.appendNew<Geom::LineSegment>( Point(t2, -offset2) );
+    strokepath.appendNew<Geom::LineSegment>( Point(t1, -offset1) );
+    strokepath.close();
+    
+    D2<Piecewise<SBasis> > patternd2 = make_cuts_independent(strokepath.toPwSb());
+    Piecewise<SBasis> x = Piecewise<SBasis>(patternd2[0]);
+    Piecewise<SBasis> y = Piecewise<SBasis>(patternd2[1]);
+
+    Piecewise<D2<SBasis> > der = unitVector(derivative(pwd2_in));
+    Piecewise<D2<SBasis> > 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<D2<SBasis> > 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 (file)
index 0000000..9c6e3ef
--- /dev/null
@@ -0,0 +1,67 @@
+/** @file
+ * @brief PowerStroke LPE effect, see lpe-powerstroke.cpp.
+ */
+/* Authors:
+ *   Johan Engelen <j.b.c.engelen@utwente.nl>
+ *
+ * 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<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > 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<Geom::Point> 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 :