summaryrefslogtreecommitdiffstats
path: root/src/live_effects
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2009-11-29 19:01:07 +0000
committerTed Gould <ted@gould.cx>2009-11-29 19:01:07 +0000
commit29d3c0b15028e61f176df3a75189bf0959d0d03e (patch)
tree727afe596c693a9bdd098d72618abd9ceb0d1969 /src/live_effects
parentAdd the build dir dbus directory to grab some headerfiles for distcheck. (diff)
parenthopefully fix build on linux (diff)
downloadinkscape-29d3c0b15028e61f176df3a75189bf0959d0d03e.tar.gz
inkscape-29d3c0b15028e61f176df3a75189bf0959d0d03e.zip
Merging in from trunk
(bzr r8254.1.37)
Diffstat (limited to 'src/live_effects')
-rw-r--r--src/live_effects/Makefile_insert2
-rw-r--r--src/live_effects/effect-enum.h1
-rw-r--r--src/live_effects/effect.cpp8
-rw-r--r--src/live_effects/effect.h6
-rw-r--r--src/live_effects/lpe-bendpath.cpp13
-rwxr-xr-xsrc/live_effects/lpe-envelope.cpp9
-rw-r--r--src/live_effects/lpe-extrude.cpp145
-rw-r--r--src/live_effects/lpe-extrude.h52
-rw-r--r--src/live_effects/lpe-interpolate.cpp7
-rw-r--r--src/live_effects/lpe-knot.cpp25
-rw-r--r--src/live_effects/lpe-mirror_symmetry.cpp5
-rw-r--r--src/live_effects/lpe-patternalongpath.cpp7
-rw-r--r--src/live_effects/lpe-perspective_path.cpp1
-rw-r--r--src/live_effects/lpe-rough-hatches.cpp30
-rw-r--r--src/live_effects/lpe-spiro.cpp4
-rw-r--r--src/live_effects/lpe-vonkoch.cpp2
-rw-r--r--src/live_effects/lpeobject.h13
-rw-r--r--src/live_effects/parameter/point.cpp1
-rw-r--r--src/live_effects/spiro.cpp5
19 files changed, 298 insertions, 38 deletions
diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert
index d992dd7bb..1cc2e1b69 100644
--- a/src/live_effects/Makefile_insert
+++ b/src/live_effects/Makefile_insert
@@ -18,6 +18,8 @@ ink_common_sources += \
live_effects/lpe-boolops.h \
live_effects/lpe-dynastroke.cpp \
live_effects/lpe-dynastroke.h \
+ live_effects/lpe-extrude.cpp \
+ live_effects/lpe-extrude.h \
live_effects/lpe-sketch.cpp \
live_effects/lpe-sketch.h \
live_effects/lpe-knot.cpp \
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 de0535448..9232792f6 100644
--- a/src/live_effects/effect.cpp
+++ b/src/live_effects/effect.cpp
@@ -29,6 +29,7 @@
#include "message-stack.h"
#include "desktop.h"
#include "nodepath.h"
+#include "knotholder.h"
#include "live_effects/lpeobject.h"
#include "live_effects/parameter/parameter.h"
@@ -74,6 +75,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 +92,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 +235,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;
@@ -505,7 +511,7 @@ Effect::getHelperPaths(SPLPEItem *lpeitem)
std::vector<Geom::PathVector> hp_vec;
if (!SP_IS_SHAPE(lpeitem)) {
- g_print ("How to handle helperpaths for non-shapes?\n"); // non-shapes are for example SPGroups.
+// g_print ("How to handle helperpaths for non-shapes?\n"); // non-shapes are for example SPGroups.
return hp_vec;
}
diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h
index 6f195b176..5d67ed016 100644
--- a/src/live_effects/effect.h
+++ b/src/live_effects/effect.h
@@ -13,11 +13,10 @@
#include "display/display-forward.h"
#include <map>
#include <glibmm/ustring.h>
-#include <2geom/path.h>
#include <2geom/forward.h>
#include "ui/widget/registry.h"
#include "sp-lpe-item.h"
-#include "knotholder.h"
+//#include "knotholder.h"
#include "parameter/bool.h"
#include "effect-enum.h"
@@ -28,6 +27,9 @@ struct SPDesktop;
struct SPItem;
class SPNodeContext;
struct LivePathEffectObject;
+class SPLPEItem;
+class KnotHolder;
+class KnotHolderEntity;
namespace Gtk {
class Widget;
diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp
index a820fe478..bc8477829 100644
--- a/src/live_effects/lpe-bendpath.cpp
+++ b/src/live_effects/lpe-bendpath.cpp
@@ -35,7 +35,7 @@ B is a map t --> B(t) = ( a(t), b(t) ).
The first step is to re-parametrize B by its arc length: this is the parametrization in which a point p on B is located by its distance s from start. One obtains a new map s --> U(s) = (a'(s),b'(s)), that still describes the same path B, but where the distance along B from start to
U(s) is s itself.
-We also need a unit normal to the path. This can be obtained by computing a unit tangent vector, and rotate it by 90°. Call this normal vector N(s).
+We also need a unit normal to the path. This can be obtained by computing a unit tangent vector, and rotate it by 90�. Call this normal vector N(s).
The basic deformation associated to B is then given by:
@@ -100,11 +100,14 @@ LPEBendPath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd
Piecewise<SBasis> x = vertical_pattern.get_value() ? Piecewise<SBasis>(patternd2[1]) : Piecewise<SBasis>(patternd2[0]);
Piecewise<SBasis> y = vertical_pattern.get_value() ? Piecewise<SBasis>(patternd2[0]) : Piecewise<SBasis>(patternd2[1]);
-//We use the group bounding box size or the path bbox size to translate well x and y
- x-= vertical_pattern.get_value() ? boundingbox_Y.min() : boundingbox_X.min();
- y-= vertical_pattern.get_value() ? boundingbox_X.middle() : boundingbox_Y.middle();
+ Interval bboxHorizontal = vertical_pattern.get_value() ? boundingbox_Y : boundingbox_X;
+ Interval bboxVertical = vertical_pattern.get_value() ? boundingbox_X : boundingbox_Y;
- double scaling = uskeleton.cuts.back()/boundingbox_X.extent();
+ //We use the group bounding box size or the path bbox size to translate well x and y
+ x-= bboxHorizontal.min();
+ y-= bboxVertical.middle();
+
+ double scaling = uskeleton.cuts.back()/bboxHorizontal.extent();
if (scaling != 1.0) {
x*=scaling;
diff --git a/src/live_effects/lpe-envelope.cpp b/src/live_effects/lpe-envelope.cpp
index a730f14ff..abd975b4e 100755
--- a/src/live_effects/lpe-envelope.cpp
+++ b/src/live_effects/lpe-envelope.cpp
@@ -69,6 +69,15 @@ LPEEnvelope::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd
using namespace Geom;
+ // Don't allow empty path parameters:
+ if ( bend_path1.get_pathvector().empty()
+ || bend_path2.get_pathvector().empty()
+ || bend_path3.get_pathvector().empty()
+ || bend_path4.get_pathvector().empty() )
+ {
+ return pwd2_in;
+ }
+
/*
The code below is inspired from the Bend Path code developed by jfb and mgsloan
Please, read it before tring to understand this one
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 :
diff --git a/src/live_effects/lpe-interpolate.cpp b/src/live_effects/lpe-interpolate.cpp
index e19d2e6e7..e77a392e9 100644
--- a/src/live_effects/lpe-interpolate.cpp
+++ b/src/live_effects/lpe-interpolate.cpp
@@ -52,8 +52,13 @@ LPEInterpolate::~LPEInterpolate()
Geom::PathVector
LPEInterpolate::doEffect_path (Geom::PathVector const & path_in)
{
- if ( (path_in.size() < 2) || (number_of_steps < 2))
+ if ( (path_in.size() < 2) || (number_of_steps < 2)) {
return path_in;
+ }
+ // Don't allow empty path parameter:
+ if ( trajectory_path.get_pathvector().empty() ) {
+ return path_in;
+ }
std::vector<Geom::Path> path_out;
diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp
index f6cf5ea78..b3aa2df45 100644
--- a/src/live_effects/lpe-knot.cpp
+++ b/src/live_effects/lpe-knot.cpp
@@ -10,10 +10,12 @@
*/
#include "sp-shape.h"
+#include "sp-path.h"
#include "display/curve.h"
#include "live_effects/lpe-knot.h"
#include "svg/svg.h"
#include "style.h"
+#include "knot-holder-entity.h"
#include <2geom/sbasis-to-bezier.h>
#include <2geom/sbasis.h>
@@ -25,6 +27,10 @@
#include <2geom/basic-intersection.h>
#include <2geom/exception.h>
+// for change crossing undo
+#include "verbs.h"
+#include "document.h"
+
#include <exception>
namespace Inkscape {
@@ -320,10 +326,10 @@ CrossingPoints::inherit_signs(CrossingPoints const &other, int default_value)
LPEKnot::LPEKnot(LivePathEffectObject *lpeobject) :
Effect(lpeobject),
// initialise your parameters here:
- interruption_width(_("Interruption width"), _("Size of hidden region of lower string"), "interruption_width", &wr, this, 3),
- prop_to_stroke_width(_("unit of stroke width"), _("Consider 'Interruption width' as a ratio of stroke width."), "prop_to_stroke_width", &wr, this, true),
- add_stroke_width(_("add stroke width to interruption size"), _("Add the stroke width to the interruption size."), "add_stroke_width", &wr, this, true),
- add_other_stroke_width(_("add other's stroke width to interruption size"), _("Add crossed stroke width to the interruption size."), "add_other_stroke_width", &wr, this, true),
+ interruption_width(_("Fixed width"), _("Size of hidden region of lower string"), "interruption_width", &wr, this, 3),
+ prop_to_stroke_width(_("In units of stroke width"), _("Consider 'Interruption width' as a ratio of stroke width"), "prop_to_stroke_width", &wr, this, true),
+ add_stroke_width(_("Stroke width"), _("Add the stroke width to the interruption size"), "add_stroke_width", &wr, this, true),
+ add_other_stroke_width(_("Crossing path stroke width"), _("Add crossed stroke width to the interruption size"), "add_other_stroke_width", &wr, this, true),
switcher_size(_("Switcher size"), _("Orientation indicator/switcher size"), "switcher_size", &wr, this, 15),
crossing_points_vector(_("Crossing Signs"), _("Crossings signs"), "crossing_points_vector", &wr, this),
gpaths(),gstroke_widths()
@@ -486,7 +492,12 @@ void collectPathsAndWidths (SPLPEItem const *lpeitem, std::vector<Geom::Path> &p
}
}
else if (SP_IS_SHAPE(lpeitem)) {
- SPCurve * c = sp_shape_get_curve(SP_SHAPE(lpeitem));
+ SPCurve * c = NULL;
+ if (SP_IS_PATH(lpeitem)) {
+ c = sp_path_get_curve_for_edit(SP_PATH(lpeitem));
+ } else {
+ c = sp_shape_get_curve(SP_SHAPE(lpeitem));
+ }
if (c) {
Geom::PathVector subpaths = c->get_pathvector();
for (unsigned i=0; i<subpaths.size(); i++){
@@ -623,9 +634,11 @@ KnotHolderEntityCrossingSwitcher::knot_click(guint state)
//std::cout<<"crossing set to"<<lpe->crossing_points[s].sign<<".\n";
}
lpe->crossing_points_vector.param_set_and_write_new_value(lpe->crossing_points.to_vector());
+ sp_document_done(lpe->getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, /// @todo Is this the right verb?
+ _("Change knot crossing"));
// FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating.
- sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true);
+// sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true);
}
}
diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp
index cd724b70e..a3a0faf37 100644
--- a/src/live_effects/lpe-mirror_symmetry.cpp
+++ b/src/live_effects/lpe-mirror_symmetry.cpp
@@ -60,6 +60,11 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem *lpeitem)
std::vector<Geom::Path>
LPEMirrorSymmetry::doEffect_path (std::vector<Geom::Path> const & path_in)
{
+ // Don't allow empty path parameter:
+ if ( reflection_line.get_pathvector().empty() ) {
+ return path_in;
+ }
+
std::vector<Geom::Path> path_out;
if (!discard_orig_path) {
path_out = path_in;
diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp
index 29c5517bf..45b2b67b4 100644
--- a/src/live_effects/lpe-patternalongpath.cpp
+++ b/src/live_effects/lpe-patternalongpath.cpp
@@ -33,7 +33,7 @@ B is a map t --> B(t) = ( a(t), b(t) ).
The first step is to re-parametrize B by its arc length: this is the parametrization in which a point p on B is located by its distance s from start. One obtains a new map s --> U(s) = (a'(s),b'(s)), that still describes the same path B, but where the distance along B from start to
U(s) is s itself.
-We also need a unit normal to the path. This can be obtained by computing a unit tangent vector, and rotate it by 90°. Call this normal vector N(s).
+We also need a unit normal to the path. This can be obtained by computing a unit tangent vector, and rotate it by 90�. Call this normal vector N(s).
The basic deformation associated to B is then given by:
@@ -104,6 +104,11 @@ LPEPatternAlongPath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > con
{
using namespace Geom;
+ // Don't allow empty path parameter:
+ if ( pattern.get_pathvector().empty() ) {
+ return pwd2_in;
+ }
+
/* Much credit should go to jfb and mgsloan of lib2geom development for the code below! */
Piecewise<D2<SBasis> > output;
std::vector<Geom::Piecewise<Geom::D2<Geom::SBasis> > > pre_output;
diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp
index d5262f33c..091a4d9ae 100644
--- a/src/live_effects/lpe-perspective_path.cpp
+++ b/src/live_effects/lpe-perspective_path.cpp
@@ -16,6 +16,7 @@
#include "live_effects/lpe-perspective_path.h"
#include "sp-item-group.h"
+#include "knot-holder-entity.h"
#include "inkscape.h"
diff --git a/src/live_effects/lpe-rough-hatches.cpp b/src/live_effects/lpe-rough-hatches.cpp
index 4df1064ce..bcfd0f373 100644
--- a/src/live_effects/lpe-rough-hatches.cpp
+++ b/src/live_effects/lpe-rough-hatches.cpp
@@ -226,24 +226,24 @@ LPERoughHatches::LPERoughHatches(LivePathEffectObject *lpeobject) :
dist_rdm(_("Frequency randomness"), _("Variation of distance between hatches, in %."), "dist_rdm", &wr, this, 75),
growth(_("Growth"), _("Growth of distance between hatches."), "growth", &wr, this, 0.),
//FIXME: top/bottom names are inverted in the UI/svg and in the code!!
- scale_tf(_("Half turns smoothness: 1st side, in"), _("Set smoothness/sharpness of path when reaching a 'bottom' halfturn. 0=sharp, 1=default"), "scale_bf", &wr, this, 1.),
- scale_tb(_("1st side, out"), _("Set smoothness/sharpness of path when leaving a 'bottom' halfturn. 0=sharp, 1=default"), "scale_bb", &wr, this, 1.),
- scale_bf(_("2nd side, in"), _("Set smoothness/sharpness of path when reaching a 'top' halfturn. 0=sharp, 1=default"), "scale_tf", &wr, this, 1.),
- scale_bb(_("2nd side, out"), _("Set smoothness/sharpness of path when leaving a 'top' halfturn. 0=sharp, 1=default"), "scale_tb", &wr, this, 1.),
- top_edge_variation(_("Magnitude jitter: 1st side"), _("Randomly moves 'bottom' halfsturns to produce magnitude variations."), "bottom_edge_variation", &wr, this, 0),
- bot_edge_variation(_("2nd side"), _("Randomly moves 'top' halfsturns to produce magnitude variations."), "top_edge_variation", &wr, this, 0),
- top_tgt_variation(_("Parallelism jitter: 1st side"), _("Add direction randomness by moving 'bottom' halfsturns tangentially to the boundary."), "bottom_tgt_variation", &wr, this, 0),
- bot_tgt_variation(_("2nd side"), _("Add direction randomness by randomly moving 'top' halfsturns tangentially to the boundary."), "top_tgt_variation", &wr, this, 0),
- top_smth_variation(_("Variance: 1st side"), _("Randomness of 'bottom' halfturns smoothness"), "top_smth_variation", &wr, this, 0),
- bot_smth_variation(_("2nd side"), _("Randomness of 'top' halfturns smoothness"), "bottom_smth_variation", &wr, this, 0),
+ scale_tf(_("Half-turns smoothness: 1st side, in"), _("Set smoothness/sharpness of path when reaching a 'bottom' half-turn. 0=sharp, 1=default"), "scale_bf", &wr, this, 1.),
+ scale_tb(_("1st side, out"), _("Set smoothness/sharpness of path when leaving a 'bottom' half-turn. 0=sharp, 1=default"), "scale_bb", &wr, this, 1.),
+ scale_bf(_("2nd side, in"), _("Set smoothness/sharpness of path when reaching a 'top' half-turn. 0=sharp, 1=default"), "scale_tf", &wr, this, 1.),
+ scale_bb(_("2nd side, out"), _("Set smoothness/sharpness of path when leaving a 'top' half-turn. 0=sharp, 1=default"), "scale_tb", &wr, this, 1.),
+ top_edge_variation(_("Magnitude jitter: 1st side"), _("Randomly moves 'bottom' half-turns to produce magnitude variations."), "bottom_edge_variation", &wr, this, 0),
+ bot_edge_variation(_("2nd side"), _("Randomly moves 'top' half-turns to produce magnitude variations."), "top_edge_variation", &wr, this, 0),
+ top_tgt_variation(_("Parallelism jitter: 1st side"), _("Add direction randomness by moving 'bottom' half-turns tangentially to the boundary."), "bottom_tgt_variation", &wr, this, 0),
+ bot_tgt_variation(_("2nd side"), _("Add direction randomness by randomly moving 'top' half-turns tangentially to the boundary."), "top_tgt_variation", &wr, this, 0),
+ top_smth_variation(_("Variance: 1st side"), _("Randomness of 'bottom' half-turns smoothness"), "top_smth_variation", &wr, this, 0),
+ bot_smth_variation(_("2nd side"), _("Randomness of 'top' half-turns smoothness"), "bottom_smth_variation", &wr, this, 0),
//
- fat_output(_("Generate thick/thin path"), _("Simulate a stroke of varrying width"), "fat_output", &wr, this, true),
+ fat_output(_("Generate thick/thin path"), _("Simulate a stroke of varying width"), "fat_output", &wr, this, true),
do_bend(_("Bend hatches"), _("Add a global bend to the hatches (slower)"), "do_bend", &wr, this, true),
- stroke_width_top(_("Thickness: at 1st side"), _("Width at 'bottom' half turns"), "stroke_width_top", &wr, this, 1.),
- stroke_width_bot(_("at 2nd side"), _("Width at 'top' halfturns"), "stroke_width_bottom", &wr, this, 1.),
+ stroke_width_top(_("Thickness: at 1st side"), _("Width at 'bottom' half-turns"), "stroke_width_top", &wr, this, 1.),
+ stroke_width_bot(_("at 2nd side"), _("Width at 'top' half-turns"), "stroke_width_bottom", &wr, this, 1.),
//
- front_thickness(_("from 2nd to 1st side"), _("Width of paths from 'top' to 'bottom' halfturns"), "front_thickness", &wr, this, 1.),
- back_thickness(_("from 1st to 2nd side"), _("Width of paths from 'top' to 'bottom' halfturns"), "back_thickness", &wr, this, .25),
+ front_thickness(_("from 2nd to 1st side"), _("Width from 'top' to 'bottom'"), "front_thickness", &wr, this, 1.),
+ back_thickness(_("from 1st to 2nd side"), _("Width from 'bottom' to 'top'"), "back_thickness", &wr, this, .25),
direction(_("Hatches width and dir"), _("Defines hatches frequency and direction"), "direction", &wr, this, Geom::Point(50,0)),
//
diff --git a/src/live_effects/lpe-spiro.cpp b/src/live_effects/lpe-spiro.cpp
index 72b77622d..794fd980e 100644
--- a/src/live_effects/lpe-spiro.cpp
+++ b/src/live_effects/lpe-spiro.cpp
@@ -158,7 +158,9 @@ LPESpiro::doEffect(SPCurve * curve)
Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop
if (path_it->closed()) {
// if the path is closed, maybe we have to stop a bit earlier because the closing line segment has zerolength.
- if (path_it->back_closed().isDegenerate()) {
+ const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment.
+ if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
+ // closingline.isDegenerate() did not work, because it only checks for *exact* zero length, which goes wrong for relative coordinates and rounding errors...
// the closing line segment has zero-length. So stop before that one!
curve_endit = path_it->end_open();
}
diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp
index 32fb763d3..7fd0ac0b4 100644
--- a/src/live_effects/lpe-vonkoch.cpp
+++ b/src/live_effects/lpe-vonkoch.cpp
@@ -49,7 +49,7 @@ LPEVonKoch::LPEVonKoch(LivePathEffectObject *lpeobject) :
similar_only(_("Use uniform transforms only"), _("2 consecutive segments are used to reverse/preserve orientation only (otherwise, they define a general transform)."), "similar_only", &wr, this, false),
drawall(_("Draw all generations"), _("If unchecked, draw only the last generation"), "drawall", &wr, this, true),
//,draw_boxes(_("Display boxes"), _("Display boxes instead of paths only"), "draw_boxes", &wr, this, true)
- ref_path(_("Reference segment"), _("The reference segment. Defaults to bbox diameter."), "ref_path", &wr, this, "M0,0 L10,0"),
+ ref_path(_("Reference segment"), _("The reference segment. Defaults to the horizontal midline of the bbox."), "ref_path", &wr, this, "M0,0 L10,0"),
//refA(_("Ref Start"), _("Left side middle of the reference box"), "refA", &wr, this),
//refB(_("Ref End"), _("Right side middle of the reference box"), "refB", &wr, this),
//FIXME: a path is used here instead of 2 points to work around path/point param incompatibility bug.
diff --git a/src/live_effects/lpeobject.h b/src/live_effects/lpeobject.h
index dc631a5c1..9f802643b 100644
--- a/src/live_effects/lpeobject.h
+++ b/src/live_effects/lpeobject.h
@@ -10,13 +10,16 @@
*/
#include "sp-object.h"
-#include "effect.h"
+#include "effect-enum.h"
namespace Inkscape {
-namespace XML {
-class Node;
-class Document;
-}
+ namespace XML {
+ class Node;
+ class Document;
+ }
+ namespace LivePathEffect {
+ class Effect;
+ }
}
#define TYPE_LIVEPATHEFFECT (LivePathEffectObject::livepatheffect_get_type())
diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp
index 057cc424b..e7abb70ea 100644
--- a/src/live_effects/parameter/point.cpp
+++ b/src/live_effects/parameter/point.cpp
@@ -16,6 +16,7 @@
#include "ui/widget/registered-widget.h"
#include "inkscape.h"
#include "verbs.h"
+#include "knotholder.h"
// needed for on-canvas editting:
#include "desktop.h"
diff --git a/src/live_effects/spiro.cpp b/src/live_effects/spiro.cpp
index 612348ab8..abc9c94ca 100644
--- a/src/live_effects/spiro.cpp
+++ b/src/live_effects/spiro.cpp
@@ -731,6 +731,10 @@ spiro_iter(spiro_seg *s, bandmat *m, int *perm, double *v, int n)
add_mat_line(m, v, derivs[1][1], -ends[1][1], 1, j, jk0r, jinc, nmat);
add_mat_line(m, v, derivs[2][1], -ends[1][2], 1, j, jk1r, jinc, nmat);
add_mat_line(m, v, derivs[3][1], -ends[1][3], 1, j, jk2r, jinc, nmat);
+ if (jthl >= 0)
+ v[jthl] = mod_2pi(v[jthl]);
+ if (jthr >= 0)
+ v[jthr] = mod_2pi(v[jthr]);
j += jinc;
}
if (cyclic) {
@@ -771,6 +775,7 @@ spiro_iter(spiro_seg *s, bandmat *m, int *perm, double *v, int n)
s[i].ks[k] += dk;
norm += dk * dk;
}
+ s[i].ks[0] = 2.0*mod_2pi(s[i].ks[0]/2.0);
}
return norm;
}