Code

add LPE recursive skeleton (experimental)
authorjohanengelen <johanengelen@users.sourceforge.net>
Sun, 12 Apr 2009 16:27:25 +0000 (16:27 +0000)
committerjohanengelen <johanengelen@users.sourceforge.net>
Sun, 12 Apr 2009 16:27:25 +0000 (16:27 +0000)
src/live_effects/Makefile_insert
src/live_effects/effect-enum.h
src/live_effects/effect.cpp
src/live_effects/lpe-recursiveskeleton.cpp [new file with mode: 0644]
src/live_effects/lpe-recursiveskeleton.h [new file with mode: 0644]

index 8831bb135a85c0119ecb15bea688c5b27a333fe8..d992dd7bb30990140206b7e56f318e26767dfec8 100644 (file)
@@ -69,6 +69,8 @@ ink_common_sources += \
        live_effects/lpe-offset.h       \
        live_effects/lpe-ruler.cpp      \
        live_effects/lpe-ruler.h        \
+       live_effects/lpe-recursiveskeleton.cpp  \
+       live_effects/lpe-recursiveskeleton.h    \
        live_effects/lpe-text_label.cpp \
        live_effects/lpe-text_label.h   \
        live_effects/lpe-path_length.cpp        \
index 50001c841133f7afa6d5766f5aac98626cafdd40..1911c6e20c034423062bdfe897a40a11425a084e 100644 (file)
@@ -46,6 +46,7 @@ enum EffectType {
     LINE_SEGMENT,
     DOEFFECTSTACK_TEST,
     DYNASTROKE,
+    RECURSIVE_SKELETON,
     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 0af6cce7253a99db68efcdfcb0fbc37ff1991704..d8fe6bfcfbe6ae475ca5699d6a0c373a88fd59fb 100644 (file)
@@ -73,6 +73,7 @@
 #include "live_effects/lpe-text_label.h"
 #include "live_effects/lpe-path_length.h"
 #include "live_effects/lpe-line_segment.h"
+#include "live_effects/lpe-recursiveskeleton.h"
 
 
 namespace Inkscape {
@@ -98,6 +99,7 @@ const Util::EnumData<EffectType> LPETypeData[] = {
     {PERP_BISECTOR,         N_("Perpendicular bisector"),  "perp_bisector"},
     {PERSPECTIVE_PATH,      N_("Perspective path"),        "perspective_path"},
     {COPY_ROTATE,           N_("Rotate copies"),           "copy_rotate"},
+    {RECURSIVE_SKELETON,    N_("Recursive skeleton"),      "recursive_skeleton"},
     {RULER,                 N_("Ruler"),                   "ruler"},
     {SKETCH,                N_("Sketch"),                  "sketch"},
     {TANGENT_TO_CURVE,      N_("Tangent to curve"),        "tangent_to_curve"},
@@ -226,6 +228,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj)
         case DYNASTROKE:
             neweffect = static_cast<Effect*> ( new LPEDynastroke(lpeobj) );
             break;
+        case RECURSIVE_SKELETON:
+            neweffect = static_cast<Effect*> ( new LPERecursiveSkeleton(lpeobj) );
+            break;
         default:
             g_warning("LivePathEffect::Effect::New   called with invalid patheffect type (%d)", lpenr);
             neweffect = NULL;
diff --git a/src/live_effects/lpe-recursiveskeleton.cpp b/src/live_effects/lpe-recursiveskeleton.cpp
new file mode 100644 (file)
index 0000000..3cbac58
--- /dev/null
@@ -0,0 +1,132 @@
+#define INKSCAPE_LPE_RECURSIVESKELETON_CPP
+/** \file
+ * @brief 
+ *
+ * Inspired by Hofstadter's 'Goedel Escher Bach', chapter V.
+ */
+/* Authors:
+ *   Johan Engelen <j.b.c.engelen@utwente.nl>
+ *
+ * Copyright (C) 2007-2009 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/lpe-recursiveskeleton.h"
+
+#include <2geom/path.h>
+#include <2geom/sbasis.h>
+#include <2geom/sbasis-geometric.h>
+#include <2geom/bezier-to-sbasis.h>
+#include <2geom/sbasis-to-bezier.h>
+#include <2geom/d2.h>
+#include <2geom/piecewise.h>
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+LPERecursiveSkeleton::LPERecursiveSkeleton(LivePathEffectObject *lpeobject) :
+    Effect(lpeobject),
+    iterations(_("Iterations"), _("recursivity"), "iterations", &wr, this, 2)
+{
+    show_orig_path = true;
+    concatenate_before_pwd2 = true;
+    iterations.param_make_integer(true);
+    iterations.param_set_range(1, 15);
+    registerParameter( dynamic_cast<Parameter *>(&iterations) );
+
+}
+
+LPERecursiveSkeleton::~LPERecursiveSkeleton()
+{
+
+}
+
+
+Geom::Piecewise<Geom::D2<Geom::SBasis> >
+LPERecursiveSkeleton::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in)
+{
+    using namespace Geom;
+
+    Piecewise<D2<SBasis> > output;
+    std::vector<Piecewise<D2<SBasis> > > pre_output;
+
+    double prop_scale = 1.0;
+    double fuse_tolerance = 0;
+
+    D2<Piecewise<SBasis> > patternd2 = make_cuts_independent(pwd2_in);
+    Piecewise<SBasis> x0 = false /*vertical_pattern.get_value()*/ ? Piecewise<SBasis>(patternd2[1]) : Piecewise<SBasis>(patternd2[0]);
+    Piecewise<SBasis> y0 = false /*vertical_pattern.get_value()*/ ? Piecewise<SBasis>(patternd2[0]) : Piecewise<SBasis>(patternd2[1]);
+    OptInterval pattBndsX = bounds_exact(x0);
+    OptInterval pattBndsY = bounds_exact(y0);
+
+    if ( !pattBndsX || !pattBndsY) {
+        return pwd2_in;
+    }
+
+    x0 -= pattBndsX->min();
+    y0 -= pattBndsY->middle();
+
+    double xspace  = 0;//spacing;
+    double noffset = 0;//normal_offset;
+    double toffset = 0;//tang_offset;
+    if (false /*prop_units.get_value()*/){
+        xspace  *= pattBndsX->extent();
+        noffset *= pattBndsY->extent();
+        toffset *= pattBndsX->extent();
+    }
+
+    y0+=noffset;
+
+    output = pwd2_in;
+
+    for (int i = 0; i < iterations; ++i) {
+        std::vector<Piecewise<D2<SBasis> > > skeleton = split_at_discontinuities(output);
+
+        output.clear();
+        for (unsigned idx = 0; idx < skeleton.size(); idx++){
+            Piecewise<D2<SBasis> > path_i = skeleton[idx];
+            Piecewise<SBasis> x = x0;
+            Piecewise<SBasis> y = y0;
+            Piecewise<D2<SBasis> > uskeleton = arc_length_parametrization(path_i,2,.1);
+            uskeleton = remove_short_cuts(uskeleton,.01);
+            Piecewise<D2<SBasis> > n = rot90(derivative(uskeleton));
+            n = force_continuity(remove_short_cuts(n,.1));
+
+            double scaling = 1;
+            scaling = (uskeleton.domain().extent() - toffset)/pattBndsX->extent();
+            
+            double pattWidth = pattBndsX->extent() * scaling;
+            
+            if (scaling != 1.0) {
+                x*=scaling;
+            }
+
+            if ( true /*scale_y_rel.get_value()*/ ) {
+                y*=(scaling*prop_scale);
+            } else {
+                if (prop_scale != 1.0) y *= prop_scale;
+            }
+            x += toffset;
+
+            output.concat(compose(uskeleton,x)+y*compose(n,x));
+        }
+    }
+
+    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:encoding=utf-8:textwidth=99 :
diff --git a/src/live_effects/lpe-recursiveskeleton.h b/src/live_effects/lpe-recursiveskeleton.h
new file mode 100644 (file)
index 0000000..2fc9f8b
--- /dev/null
@@ -0,0 +1,50 @@
+/** @file
+ * @brief see lpe-recursiveskeleton.cpp.
+ */
+/* Authors:
+ *   Johan Engelen <j.b.c.engelen@utwente.nl>
+ *
+ * Copyright (C) 2007-2009 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifndef INKSCAPE_LPE_RECURSIVESKELETON_H
+#define INKSCAPE_LPE_RECURSIVESKELETON_H
+
+#include "live_effects/effect.h"
+#include "live_effects/parameter/parameter.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+
+class LPERecursiveSkeleton : public Effect {
+public:
+    LPERecursiveSkeleton(LivePathEffectObject *lpeobject);
+    virtual ~LPERecursiveSkeleton();
+
+    virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in);
+
+private:
+    ScalarParam iterations;
+
+    LPERecursiveSkeleton(const LPERecursiveSkeleton&);
+    LPERecursiveSkeleton& operator=(const LPERecursiveSkeleton&);
+};
+
+} //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 :