From cca66b9ec4e494c1d919bff0f71a820d8afab1fa Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:24:48 +0200 Subject: Adding upstream version 1.2.2. Signed-off-by: Daniel Baumann --- src/live_effects/lpe-recursiveskeleton.cpp | 121 +++++++++++++++++++++++++++++ 1 file changed, 121 insertions(+) create mode 100644 src/live_effects/lpe-recursiveskeleton.cpp (limited to 'src/live_effects/lpe-recursiveskeleton.cpp') diff --git a/src/live_effects/lpe-recursiveskeleton.cpp b/src/live_effects/lpe-recursiveskeleton.cpp new file mode 100644 index 0000000..0a67cdb --- /dev/null +++ b/src/live_effects/lpe-recursiveskeleton.cpp @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** + * @file + * Inspired by Hofstadter's 'Goedel Escher Bach', chapter V. + */ +/* Authors: + * Johan Engelen + * + * Copyright (C) 2007-2009 Authors + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "live_effects/lpe-recursiveskeleton.h" + +#include <2geom/bezier-to-sbasis.h> + +// TODO due to internal breakage in glibmm headers, this must be last: +#include + +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(&iterations); + +} + +LPERecursiveSkeleton::~LPERecursiveSkeleton() += default; + + +Geom::Piecewise > +LPERecursiveSkeleton::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) +{ + using namespace Geom; + + Piecewise > output; + double prop_scale = 1.0; + + D2 > patternd2 = make_cuts_independent(pwd2_in); + Piecewise x0 = false /*vertical_pattern.get_value()*/ ? Piecewise(patternd2[1]) : Piecewise(patternd2[0]); + Piecewise y0 = false /*vertical_pattern.get_value()*/ ? Piecewise(patternd2[0]) : Piecewise(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 noffset = 0;//normal_offset; + double toffset = 0;//tang_offset; + if (false /*prop_units.get_value()*/){ + noffset *= pattBndsY->extent(); + toffset *= pattBndsX->extent(); + } + + y0+=noffset; + + output = pwd2_in; + + for (int i = 0; i < iterations; ++i) { + std::vector > > skeleton = split_at_discontinuities(output); + + output.clear(); + for (auto path_i : skeleton){ + Piecewise x = x0; + Piecewise y = y0; + Piecewise > uskeleton = arc_length_parametrization(path_i,2,.1); + uskeleton = remove_short_cuts(uskeleton,.01); + Piecewise > n = rot90(derivative(uskeleton)); + n = force_continuity(remove_short_cuts(n,.1)); + + double scaling = (uskeleton.domain().extent() - toffset)/pattBndsX->extent(); + + // TODO investigate why pattWidth is not being used: + // - Doesn't appear to have been used anywhere in bzr history (Alex V: 2013-03-16) + // 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:fileencoding=utf-8:textwidth=99 : -- cgit v1.2.3