diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2016-03-15 21:57:03 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2016-03-15 21:57:03 +0000 |
| commit | 6bd1c2a30b66e15fe055b22bd47dadb771f7fae2 (patch) | |
| tree | 1b991cc2736f84fb069666802d485bd29cff6394 /src/live_effects | |
| parent | Update to limit options to radius = 0, radious > 0 or both (diff) | |
| parent | fix-bug-1557192. paint-order crash with multiple items (diff) | |
| download | inkscape-6bd1c2a30b66e15fe055b22bd47dadb771f7fae2.tar.gz inkscape-6bd1c2a30b66e15fe055b22bd47dadb771f7fae2.zip | |
Update to trunk
(bzr r13645.1.119)
Diffstat (limited to 'src/live_effects')
40 files changed, 836 insertions, 284 deletions
diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index fe7bf3a97..38d59a43a 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -133,25 +133,24 @@ const Util::EnumData<EffectType> LPETypeData[] = { /* 0.91 */ {POWERSTROKE, N_("Power stroke"), "powerstroke"}, {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, -/* EXPERIMENTAL */ +/* 0.92 */ + {SIMPLIFY, N_("Simplify"), "simplify"}, + {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, + {PERSPECTIVE_ENVELOPE, N_("Perspective/Envelope"), "perspective-envelope"}, + {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet-chamfer"}, + {INTERPOLATE_POINTS, N_("Interpolate points"), "interpolate_points"}, + {TRANSFORM_2PTS, N_("Transform by 2 points"), "transform_2pts"}, {SHOW_HANDLES, N_("Show handles"), "show_handles"}, {ROUGHEN, N_("Roughen"), "roughen"}, {BSPLINE, N_("BSpline"), "bspline"}, {JOIN_TYPE, N_("Join type"), "join_type"}, {TAPER_STROKE, N_("Taper stroke"), "taper_stroke"}, -/* Ponyscape */ +/* Ponyscape -> Inkscape 0.92*/ {ATTACH_PATH, N_("Attach path"), "attach_path"}, {FILL_BETWEEN_STROKES, N_("Fill between strokes"), "fill_between_strokes"}, {FILL_BETWEEN_MANY, N_("Fill between many"), "fill_between_many"}, {ELLIPSE_5PTS, N_("Ellipse by 5 points"), "ellipse_5pts"}, {BOUNDING_BOX, N_("Bounding Box"), "bounding_box"}, -/* 0.91 */ - {SIMPLIFY, N_("Simplify"), "simplify"}, - {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, - {PERSPECTIVE_ENVELOPE, N_("Perspective/Envelope"), "perspective-envelope"}, - {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet-chamfer"}, - {INTERPOLATE_POINTS, N_("Interpolate points"), "interpolate_points"}, - {TRANSFORM_2PTS, N_("Transform by 2 points"), "transform_2pts"}, }; const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); @@ -356,7 +355,8 @@ Effect::createAndApply(EffectType type, SPDocument *doc, SPItem *item) } Effect::Effect(LivePathEffectObject *lpeobject) - : _provides_knotholder_entities(false), + : apply_to_clippath_and_mask(false), + _provides_knotholder_entities(false), oncanvasedit_it(0), is_visible(_("Is visible?"), _("If unchecked, the effect remains applied to the object but is temporarily disabled on canvas"), "is_visible", &wr, this, true), show_orig_path(false), diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index ea57ff243..898e089b7 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -121,6 +121,7 @@ public: inline bool isVisible() const { return is_visible; } void editNextParamOncanvas(SPItem * item, SPDesktop * desktop); + bool apply_to_clippath_and_mask; protected: Effect(LivePathEffectObject *lpeobject); @@ -144,6 +145,7 @@ protected: std::vector<Parameter *> param_vector; bool _provides_knotholder_entities; + int oncanvasedit_it; BoolParam is_visible; diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp index 33171b184..bc112285f 100644 --- a/src/live_effects/lpe-bendpath.cpp +++ b/src/live_effects/lpe-bendpath.cpp @@ -20,7 +20,13 @@ #include <2geom/d2.h> #include <2geom/piecewise.h> +#include "knot-holder-entity.h" +#include "knotholder.h" + +#include <glibmm/i18n.h> + #include <algorithm> + using std::vector; @@ -48,10 +54,21 @@ first) but I think we can first forget about them. namespace Inkscape { namespace LivePathEffect { +Geom::PathVector bp_helper_path; +namespace BeP { +class KnotHolderEntityWidthBendPath : public LPEKnotHolderEntity { + public: + KnotHolderEntityWidthBendPath(LPEBendPath * effect) : LPEKnotHolderEntity(effect) {} + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; + }; +} // BeP + LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) : Effect(lpeobject), bend_path(_("Bend path:"), _("Path along which to bend the original path"), "bendpath", &wr, this, "M0,0 L1,0"), - prop_scale(_("_Width:"), _("Width of the path"), "prop_scale", &wr, this, 1), + original_height(0.0), + prop_scale(_("_Width:"), _("Width of the path"), "prop_scale", &wr, this, 1.0), scale_y_rel(_("W_idth in units of length"), _("Scale the width of the path in units of its length"), "scale_y_rel", &wr, this, false), vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false) { @@ -63,6 +80,8 @@ LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) : prop_scale.param_set_digits(3); prop_scale.param_set_increments(0.01, 0.10); + _provides_knotholder_entities = true; + apply_to_clippath_and_mask = true; concatenate_before_pwd2 = true; } @@ -76,9 +95,7 @@ LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem) { // get the item bounding box original_bbox(lpeitem); - SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); + original_height = boundingbox_Y.max() - boundingbox_Y.min(); } Geom::Piecewise<Geom::D2<Geom::SBasis> > @@ -148,7 +165,75 @@ LPEBendPath::resetDefaults(SPItem const* item) bend_path.set_new_value( path.toPwSb(), true ); } +void +LPEBendPath::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec) +{ + hp_vec.push_back(bp_helper_path); +} + +void +LPEBendPath::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) +{ + KnotHolderEntity *e = new BeP::KnotHolderEntityWidthBendPath(this); + e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE); + knotholder->add(e); +} + +namespace BeP { +void +KnotHolderEntityWidthBendPath::knot_set(Geom::Point const &p, Geom::Point const& /*origin*/, guint state) +{ + LPEBendPath *lpe = dynamic_cast<LPEBendPath *> (_effect); + + Geom::Point const s = snap_knot_position(p, state); + Geom::Path path_in = lpe->bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0)); + Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0)); + Geom::Point B = path_in.pointAt(Geom::PathTime(1, 0.0)); + Geom::Curve const *first_curve = &path_in.curveAt(Geom::PathTime(0, 0.0)); + Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*first_curve); + Geom::Ray ray(ptA, B); + if (cubic) { + ray.setPoints(ptA, (*cubic)[1]); + } + ray.setAngle(ray.angle() + Geom::rad_from_deg(90)); + Geom::Point knot_pos = this->knot->pos * item->i2dt_affine().inverse(); + Geom::Coord nearest_to_ray = ray.nearestTime(knot_pos); + if(nearest_to_ray == 0){ + lpe->prop_scale.param_set_value(-Geom::distance(s , ptA)/(lpe->original_height/2.0)); + } else { + lpe->prop_scale.param_set_value(Geom::distance(s , ptA)/(lpe->original_height/2.0)); + } + + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); +} + +Geom::Point +KnotHolderEntityWidthBendPath::knot_get() const +{ + LPEBendPath *lpe = dynamic_cast<LPEBendPath *> (_effect); + + Geom::Path path_in = lpe->bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0)); + Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0)); + Geom::Point B = path_in.pointAt(Geom::PathTime(1, 0.0)); + Geom::Curve const *first_curve = &path_in.curveAt(Geom::PathTime(0, 0.0)); + Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*first_curve); + Geom::Ray ray(ptA, B); + if (cubic) { + ray.setPoints(ptA,(*cubic)[1]); + } + ray.setAngle(ray.angle() + Geom::rad_from_deg(90)); + Geom::Point result_point = Geom::Point::polar(ray.angle(), (lpe->original_height/2.0) * lpe->prop_scale) + ptA; + + bp_helper_path.clear(); + Geom::Path hp(result_point); + hp.appendNew<Geom::LineSegment>(ptA); + bp_helper_path.push_back(hp); + hp.clear(); + + return result_point; +} +} // namespace BeP } // namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index 0871d532e..eeda86a5e 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -27,6 +27,10 @@ namespace Inkscape { namespace LivePathEffect { +namespace BeP { +class KnotHolderEntityWidthBendPath; +} + //for Bend path on group : we need information concerning the group Bounding box class LPEBendPath : public Effect, GroupBBoxEffect { public: @@ -39,12 +43,19 @@ public: virtual void resetDefaults(SPItem const* item); - PathParam bend_path; + void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec); + + virtual void addKnotHolderEntities(KnotHolder * knotholder, SPDesktop * desktop, SPItem * item); + + PathParam bend_path; + + friend class BeP::KnotHolderEntityWidthBendPath; +protected: + double original_height; + ScalarParam prop_scale; private: - ScalarParam prop_scale; BoolParam scale_y_rel; - BoolParam vertical_pattern; - + BoolParam vertical_pattern; Geom::Piecewise<Geom::D2<Geom::SBasis> > uskeleton; Geom::Piecewise<Geom::D2<Geom::SBasis> > n; diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 08ef7ca1b..1423e670a 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -10,6 +10,8 @@ #include "svg/svg.h" #include "xml/repr.h" #include "preferences.h" +#include "document-undo.h" +#include "verbs.h" // TODO due to internal breakage in glibmm headers, this must be last: #include <glibmm/i18n.h> @@ -18,8 +20,8 @@ namespace LivePathEffect { const double HANDLE_CUBIC_GAP = 0.001; const double NO_POWER = 0.0; -const double DEFAULT_START_POWER = 0.333334; -const double DEFAULT_END_POWER = 0.666667; +const double DEFAULT_START_POWER = 1.0/3.0; +const double DEFAULT_END_POWER = 2.0/3.0; Geom::PathVector hp; void sp_bspline_drawHandle(Geom::Point p, double helper_size); @@ -27,25 +29,27 @@ LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : Effect(lpeobject), steps(_("Steps with CTRL:"), _("Change number of steps with CTRL pressed"), "steps", &wr, this, 2), helper_size(_("Helper size:"), _("Helper size"), "helper_size", &wr, this, 0), - apply_cusp(_("Apply on cusp nodes"), _("Apply on cusp nodes"), "apply_cusp", &wr, this, true), - apply_non_cusp(_("Apply on non cusp nodes"), _("Apply on non cusp nodes"), "apply_non_cusp", &wr, this, true), + apply_no_weight(_("Apply changes if weight = 0%"), _("Apply changes if weight = 0%"), "apply_no_weight", &wr, this, true), + apply_with_weight(_("Apply changes if weight > 0%"), _("Apply changes if weight > 0%"), "apply_with_weight", &wr, this, true), only_selected(_("Change only selected nodes"), _("Change only selected nodes"), "only_selected", &wr, this, false), weight(_("Change weight %:"), _("Change weight percent of the effect"), "weight", &wr, this, DEFAULT_START_POWER * 100) { registerParameter(&weight); registerParameter(&steps); registerParameter(&helper_size); - registerParameter(&apply_cusp); - registerParameter(&apply_non_cusp); + registerParameter(&apply_no_weight); + registerParameter(&apply_with_weight); registerParameter(&only_selected); weight.param_set_range(NO_POWER, 100.0); weight.param_set_increments(0.1, 0.1); weight.param_set_digits(4); + weight.param_overwrite_widget(true); steps.param_set_range(1, 10); steps.param_set_increments(1, 1); steps.param_set_digits(0); + steps.param_overwrite_widget(true); helper_size.param_set_range(0.0, 999.0); helper_size.param_set_increments(1, 1); @@ -116,7 +120,7 @@ Gtk::Widget *LPEBSpline::newWidget() entry_widget->set_width_chars(9); } } - if (param->param_key == "only_selected" || param->param_key == "apply_cusp" || param->param_key == "apply_non_cusp") { + if (param->param_key == "only_selected" || param->param_key == "apply_no_weight" || param->param_key == "apply_with_weight") { Gtk::CheckButton *widg_registered = Gtk::manage(dynamic_cast<Gtk::CheckButton *>(widg)); widg = dynamic_cast<Gtk::Widget *>(widg_registered); @@ -140,17 +144,20 @@ Gtk::Widget *LPEBSpline::newWidget() void LPEBSpline::toDefaultWeight() { - changeWeight(DEFAULT_START_POWER); + changeWeight(DEFAULT_START_POWER * 100); + DocumentUndo::done(getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change to default weight")); } void LPEBSpline::toMakeCusp() { changeWeight(NO_POWER); + DocumentUndo::done(getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change to 0 weight")); } void LPEBSpline::toWeight() { changeWeight(weight); + DocumentUndo::done(getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter")); } void LPEBSpline::changeWeight(double weight_ammount) @@ -199,6 +206,18 @@ void sp_bspline_do_effect(SPCurve *curve, double helper_size) Geom::D2<Geom::SBasis> sbasis_helper; Geom::CubicBezier const *cubic = NULL; curve_n->moveto(curve_it1->initialPoint()); + if (path_it->closed()) { + 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(); + } + } while (curve_it1 != curve_endit) { SPCurve *in = new SPCurve(); in->moveto(curve_it1->initialPoint()); @@ -354,6 +373,18 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) Geom::D2<Geom::SBasis> sbasis_out; Geom::CubicBezier const *cubic = NULL; curve_n->moveto(curve_it1->initialPoint()); + if (path_it->closed()) { + 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(); + } + } while (curve_it1 != curve_endit) { SPCurve *in = new SPCurve(); in->moveto(curve_it1->initialPoint()); @@ -363,9 +394,9 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) point_at3 = in->first_segment()->finalPoint(); sbasis_in = in->first_segment()->toSBasis(); if (cubic) { - if ((apply_cusp && apply_non_cusp) || - (apply_cusp && Geom::are_near((*cubic)[1], point_at0)) || - (apply_non_cusp && !Geom::are_near((*cubic)[1], point_at0))) + if ((apply_no_weight && apply_with_weight) || + (apply_no_weight && Geom::are_near((*cubic)[1], point_at0)) || + (apply_with_weight && !Geom::are_near((*cubic)[1], point_at0))) { if (isNodePointSelected(point_at0) || !only_selected) { point_at1 = sbasis_in.valueAt(weight_ammount); @@ -379,9 +410,9 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) } else { point_at1 = (*cubic)[1]; } - if ((apply_cusp && apply_non_cusp) || - (apply_cusp && Geom::are_near((*cubic)[2], point_at3)) || - (apply_non_cusp && !Geom::are_near((*cubic)[2], point_at3))) + if ((apply_no_weight && apply_with_weight) || + (apply_no_weight && Geom::are_near((*cubic)[2], point_at3)) || + (apply_with_weight && !Geom::are_near((*cubic)[2], point_at3))) { if (isNodePointSelected(point_at3) || !only_selected) { point_at2 = sbasis_in.valueAt(1 - weight_ammount); @@ -396,9 +427,9 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) point_at2 = (*cubic)[2]; } } else { - if ((apply_cusp && apply_non_cusp) || - (apply_cusp && weight_ammount == NO_POWER) || - (apply_non_cusp && weight_ammount != NO_POWER)) + if ((apply_no_weight && apply_with_weight) || + (apply_no_weight && weight_ammount == NO_POWER) || + (apply_with_weight && weight_ammount != NO_POWER)) { if (isNodePointSelected(point_at0) || !only_selected) { point_at1 = sbasis_in.valueAt(weight_ammount); @@ -408,7 +439,7 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) point_at1 = in->first_segment()->initialPoint(); } if (isNodePointSelected(point_at3) || !only_selected) { - point_at2 = sbasis_in.valueAt(weight_ammount); + point_at2 = sbasis_in.valueAt(1 - weight_ammount); point_at2 = Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP); } else { diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index b9cd336a9..7823f00f0 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -38,8 +38,8 @@ public: private: ScalarParam helper_size; - BoolParam apply_cusp; - BoolParam apply_non_cusp; + BoolParam apply_no_weight; + BoolParam apply_with_weight; BoolParam only_selected; ScalarParam weight; diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index fd9b853d5..8dfaf7525 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -17,7 +17,6 @@ #include "live_effects/lpe-copy_rotate.h" #include <2geom/path.h> #include <2geom/transforms.h> -#include <2geom/d2-sbasis.h> #include <2geom/angle.h> #include "knot-holder-entity.h" @@ -62,6 +61,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : { show_orig_path = true; _provides_knotholder_entities = true; + apply_to_clippath_and_mask = true; // register all your parameters here, so Inkscape knows which parameters this effect has: registerParameter(&copiesTo360); @@ -107,15 +107,11 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) dir = unit_vector(B - A); // I first suspected the minus sign to be a bug in 2geom but it is // likely due to SVG's choice of coordinate system orientation (max) - start_pos = origin + dir * Rotate(-deg_to_rad(starting_angle)) * dist_angle_handle; - rot_pos = origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle; + start_pos = origin + dir * Rotate(-rad_from_deg(starting_angle)) * dist_angle_handle; + rot_pos = origin + dir * Rotate(-rad_from_deg(rotation_angle+starting_angle)) * dist_angle_handle; if(copiesTo360 ){ rot_pos = origin; } - SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); - } @@ -129,9 +125,9 @@ LPECopyRotate::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & p } Piecewise<D2<SBasis> > output; - Affine pre = Translate(-origin) * Rotate(-deg_to_rad(starting_angle)); + Affine pre = Translate(-origin) * Rotate(-rad_from_deg(starting_angle)); for (int i = 0; i < num_copies; ++i) { - Rotate rot(-deg_to_rad(rotation_angle * i)); + Rotate rot(-rad_from_deg(rotation_angle * i)); Affine t = pre * rot * Translate(origin); output.concat(pwd2_in * t); } @@ -146,7 +142,7 @@ LPECopyRotate::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geo Geom::Path hp; hp.start(start_pos); hp.appendNew<Geom::LineSegment>((Geom::Point)origin); - hp.appendNew<Geom::LineSegment>(origin + dir * Rotate(-deg_to_rad(rotation_angle+starting_angle)) * dist_angle_handle); + hp.appendNew<Geom::LineSegment>(origin + dir * Rotate(-rad_from_deg(rotation_angle+starting_angle)) * dist_angle_handle); Geom::PathVector pathv; pathv.push_back(hp); hp_vec.push_back(pathv); @@ -188,7 +184,7 @@ KnotHolderEntityStartingAngle::knot_set(Geom::Point const &p, Geom::Point const // I first suspected the minus sign to be a bug in 2geom but it is // likely due to SVG's choice of coordinate system orientation (max) - lpe->starting_angle.param_set_value(rad_to_deg(-angle_between(lpe->dir, s - lpe->origin))); + lpe->starting_angle.param_set_value(deg_from_rad(-angle_between(lpe->dir, s - lpe->origin))); if (state & GDK_SHIFT_MASK) { lpe->dist_angle_handle = L2(lpe->B - lpe->A); } else { @@ -208,7 +204,7 @@ KnotHolderEntityRotationAngle::knot_set(Geom::Point const &p, Geom::Point const // I first suspected the minus sign to be a bug in 2geom but it is // likely due to SVG's choice of coordinate system orientation (max) - lpe->rotation_angle.param_set_value(rad_to_deg(-angle_between(lpe->dir, s - lpe->origin)) - lpe->starting_angle); + lpe->rotation_angle.param_set_value(deg_from_rad(-angle_between(lpe->dir, s - lpe->origin)) - lpe->starting_angle); if (state & GDK_SHIFT_MASK) { lpe->dist_angle_handle = L2(lpe->B - lpe->A); } else { diff --git a/src/live_effects/lpe-dynastroke.cpp b/src/live_effects/lpe-dynastroke.cpp index c60db4fc4..aeecd5d5c 100644 --- a/src/live_effects/lpe-dynastroke.cpp +++ b/src/live_effects/lpe-dynastroke.cpp @@ -20,7 +20,6 @@ #include <2geom/bezier-to-sbasis.h> #include <2geom/sbasis-to-bezier.h> #include <2geom/d2.h> -#include <2geom/d2-sbasis.h> #include <2geom/sbasis-math.h> #include <2geom/piecewise.h> diff --git a/src/live_effects/lpe-envelope.cpp b/src/live_effects/lpe-envelope.cpp index 05a672ae8..e873c0b15 100644 --- a/src/live_effects/lpe-envelope.cpp +++ b/src/live_effects/lpe-envelope.cpp @@ -42,6 +42,7 @@ LPEEnvelope::LPEEnvelope(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast<Parameter *>(&bend_path3) ); registerParameter( dynamic_cast<Parameter *>(&bend_path4) ); concatenate_before_pwd2 = true; + apply_to_clippath_and_mask = true; } LPEEnvelope::~LPEEnvelope() @@ -54,9 +55,6 @@ LPEEnvelope::doBeforeEffect (SPLPEItem const* lpeitem) { // get the item bounding box original_bbox(lpeitem); - SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); } Geom::Piecewise<Geom::D2<Geom::SBasis> > diff --git a/src/live_effects/lpe-fill-between-many.cpp b/src/live_effects/lpe-fill-between-many.cpp index 3e0810cfc..574ec3580 100644 --- a/src/live_effects/lpe-fill-between-many.cpp +++ b/src/live_effects/lpe-fill-between-many.cpp @@ -37,7 +37,7 @@ void LPEFillBetweenMany::doEffect (SPCurve * curve) { Geom::PathVector res_pathv; SPItem * firstObj = NULL; - for (std::vector<PathAndDirection*>::iterator iter = linked_paths._vector.begin(); iter != linked_paths._vector.end(); iter++) { + for (std::vector<PathAndDirection*>::iterator iter = linked_paths._vector.begin(); iter != linked_paths._vector.end(); ++iter) { SPObject *obj; if ((*iter)->ref.isAttached() && (obj = (*iter)->ref.getObject()) && SP_IS_ITEM(obj) && !(*iter)->_pathvector.empty()) { Geom::Path linked_path; diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 8c3b6e2f1..d91225cb7 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -73,12 +73,16 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) radius.param_set_range(0.0, Geom::infinity()); radius.param_set_increments(1, 1); radius.param_set_digits(4); + radius.param_overwrite_widget(true); chamfer_steps.param_set_range(1, 999); chamfer_steps.param_set_increments(1, 1); chamfer_steps.param_set_digits(0); + //chamfer_steps.param_overwrite_widget(true); helper_size.param_set_range(0, 999); helper_size.param_set_increments(5, 5); helper_size.param_set_digits(0); + //helper_size.param_overwrite_widget(true); + } void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) @@ -142,6 +146,14 @@ Gtk::Widget *LPEFilletChamfer::newWidget() vbox->set_border_width(5); vbox->set_homogeneous(false); vbox->set_spacing(2); + Gtk::HBox *advertaising = Gtk::manage(new Gtk::HBox(true, 0)); + Gtk::Button *advert = Gtk::manage(new Gtk::Button(Glib::ustring(_("IMPORTANT! New version soon...")))); + advertaising->pack_start(*advert, true, true, 2); + vbox->pack_start(*advertaising, true, true, 2); + Gtk::HBox *advertaising2 = Gtk::manage(new Gtk::HBox(true, 0)); + Gtk::Button *advert2 = Gtk::manage(new Gtk::Button(Glib::ustring(_("Not compatible. Convert to path after.")))); + advertaising2->pack_start(*advert2, true, true, 2); + vbox->pack_start(*advertaising2, true, true, 2); std::vector<Parameter *>::iterator it = param_vector.begin(); while (it != param_vector.end()) { if ((*it)->widget_is_visible) { diff --git a/src/live_effects/lpe-interpolate.cpp b/src/live_effects/lpe-interpolate.cpp index b1ad07d23..74c7efd90 100644 --- a/src/live_effects/lpe-interpolate.cpp +++ b/src/live_effects/lpe-interpolate.cpp @@ -16,7 +16,6 @@ #include <2geom/path.h> #include <2geom/sbasis-to-bezier.h> -#include <2geom/d2-sbasis.h> #include <2geom/piecewise.h> #include <2geom/sbasis-geometric.h> diff --git a/src/live_effects/lpe-interpolate_points.cpp b/src/live_effects/lpe-interpolate_points.cpp index 4ac139752..cf70832ee 100644 --- a/src/live_effects/lpe-interpolate_points.cpp +++ b/src/live_effects/lpe-interpolate_points.cpp @@ -52,8 +52,11 @@ Geom::PathVector LPEInterpolatePoints::doEffect_path (Geom::PathVector const & path_in) { Geom::PathVector path_out; - +#if __cplusplus <= 199711L std::auto_ptr<Geom::Interpolate::Interpolator> interpolator( Geom::Interpolate::Interpolator::create(static_cast<Geom::Interpolate::InterpolatorType>(interpolator_type.get_value())) ); +#else + std::unique_ptr<Geom::Interpolate::Interpolator> interpolator( Geom::Interpolate::Interpolator::create(static_cast<Geom::Interpolate::InterpolatorType>(interpolator_type.get_value())) ); +#endif for(Geom::PathVector::const_iterator path_it = path_in.begin(); path_it != path_in.end(); ++path_it) { if (path_it->empty()) diff --git a/src/live_effects/lpe-jointype.cpp b/src/live_effects/lpe-jointype.cpp index 28f99eb94..2eef315dd 100644 --- a/src/live_effects/lpe-jointype.cpp +++ b/src/live_effects/lpe-jointype.cpp @@ -33,6 +33,9 @@ static const Util::EnumData<unsigned> JoinTypeData[] = { {JOIN_MITER, N_("Miter"), "miter"}, {JOIN_MITER_CLIP, N_("Miter Clip"), "miter-clip"}, {JOIN_EXTRAPOLATE, N_("Extrapolated arc"), "extrp_arc"}, + {JOIN_EXTRAPOLATE1, N_("Extrapolated arc Alt1"), "extrp_arc1"}, + {JOIN_EXTRAPOLATE2, N_("Extrapolated arc Alt2"), "extrp_arc2"}, + {JOIN_EXTRAPOLATE3, N_("Extrapolated arc Alt3"), "extrp_arc3"}, }; static const Util::EnumData<unsigned> CapTypeData[] = { diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index c3000fe0d..a033a6c4a 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -27,7 +27,6 @@ #include <2geom/sbasis-to-bezier.h> #include <2geom/sbasis.h> #include <2geom/d2.h> -#include <2geom/d2-sbasis.h> #include <2geom/path.h> #include <2geom/bezier-to-sbasis.h> #include <2geom/basic-intersection.h> @@ -507,7 +506,7 @@ static void collectPathsAndWidths (SPLPEItem const *lpeitem, Geom::PathVector &paths, std::vector<double> &stroke_widths){ if (SP_IS_GROUP(lpeitem)) { std::vector<SPItem*> item_list = sp_item_group_item_list(SP_GROUP(lpeitem)); - for ( std::vector<SPItem*>::const_iterator iter = item_list.begin(); iter != item_list.end(); iter++) { + for ( std::vector<SPItem*>::const_iterator iter = item_list.begin(); iter != item_list.end(); ++iter) { SPObject *subitem = *iter; if (SP_IS_LPE_ITEM(subitem)) { collectPathsAndWidths(SP_LPE_ITEM(subitem), paths, stroke_widths); diff --git a/src/live_effects/lpe-lattice.cpp b/src/live_effects/lpe-lattice.cpp index c05bae7e1..3c23e349e 100644 --- a/src/live_effects/lpe-lattice.cpp +++ b/src/live_effects/lpe-lattice.cpp @@ -78,7 +78,7 @@ LPELattice::LPELattice(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast<Parameter *>(&grid_point14) ); registerParameter( dynamic_cast<Parameter *>(&grid_point15) ); - + apply_to_clippath_and_mask = true; } LPELattice::~LPELattice() @@ -176,9 +176,6 @@ void LPELattice::doBeforeEffect (SPLPEItem const* lpeitem) { original_bbox(lpeitem); - SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); } void diff --git a/src/live_effects/lpe-lattice2.cpp b/src/live_effects/lpe-lattice2.cpp index 8c7f46cbd..0c403daec 100644 --- a/src/live_effects/lpe-lattice2.cpp +++ b/src/live_effects/lpe-lattice2.cpp @@ -46,6 +46,7 @@ LPELattice2::LPELattice2(LivePathEffectObject *lpeobject) : Effect(lpeobject), horizontal_mirror(_("Mirror movements in horizontal"), _("Mirror movements in horizontal"), "horizontal_mirror", &wr, this, false), vertical_mirror(_("Mirror movements in vertical"), _("Mirror movements in vertical"), "vertical_mirror", &wr, this, false), + live_update(_("Update while moving knots (maybe slow)"), _("Update while moving knots (maybe slow)"), "live_update", &wr, this, true), grid_point_0(_("Control 0:"), _("Control 0 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint0", &wr, this), grid_point_1(_("Control 1:"), _("Control 1 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint1", &wr, this), grid_point_2(_("Control 2:"), _("Control 2 - <b>Ctrl+Alt+Click</b>: reset, <b>Ctrl</b>: move along axes"), "gridpoint2", &wr, this), @@ -76,6 +77,7 @@ LPELattice2::LPELattice2(LivePathEffectObject *lpeobject) : // register all your parameters here, so Inkscape knows which parameters this effect has: registerParameter(&horizontal_mirror); registerParameter(&vertical_mirror); + registerParameter(&live_update); registerParameter(&grid_point_0); registerParameter(&grid_point_1); registerParameter(&grid_point_2); @@ -101,6 +103,7 @@ LPELattice2::LPELattice2(LivePathEffectObject *lpeobject) : registerParameter(&grid_point_28x30); registerParameter(&grid_point_29x31); registerParameter(&grid_point_32x33x34x35); + apply_to_clippath_and_mask = true; } LPELattice2::~LPELattice2() @@ -248,7 +251,7 @@ LPELattice2::newWidget() } Glib::ustring * tip = param->param_getTooltip(); if (widg) { - if (param->param_key == "horizontal_mirror" || param->param_key == "vertical_mirror") { + if (param->param_key == "horizontal_mirror" || param->param_key == "vertical_mirror" || param->param_key == "live_update") { vbox->pack_start(*widg, true, true, 2); } else { vbox_expander->pack_start(*widg, true, true, 2); @@ -300,8 +303,8 @@ LPELattice2::vertical(PointParam ¶m_one, PointParam ¶m_two, Geom::Line v } A[Geom::X] = nearest[Geom::X] - distance_middle; B[Geom::X] = nearest[Geom::X] + distance_middle; - param_one.param_setValue(A, true); - param_two.param_setValue(B, true); + param_one.param_setValue(A, live_update); + param_two.param_setValue(B, live_update); } void @@ -321,8 +324,8 @@ LPELattice2::horizontal(PointParam ¶m_one, PointParam ¶m_two, Geom::Line } A[Geom::Y] = nearest[Geom::Y] - distance_middle; B[Geom::Y] = nearest[Geom::Y] + distance_middle; - param_one.param_setValue(A, true); - param_two.param_setValue(B, true); + param_one.param_setValue(A, live_update); + param_two.param_setValue(B, live_update); } void @@ -356,9 +359,6 @@ LPELattice2::doBeforeEffect (SPLPEItem const* lpeitem) horizontal(grid_point_17, grid_point_19,horiz); horizontal(grid_point_20x21, grid_point_22x23,horiz); } - SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); } void @@ -464,6 +464,31 @@ LPELattice2::setDefaults() grid_point_28x30.param_update_default(gp28x30); grid_point_29x31.param_update_default(gp29x31); grid_point_32x33x34x35.param_update_default(gp32x33x34x35); + grid_point_0.param_set_liveupdate(live_update); + grid_point_1.param_set_liveupdate(live_update); + grid_point_2.param_set_liveupdate(live_update); + grid_point_3.param_set_liveupdate(live_update); + grid_point_4.param_set_liveupdate(live_update); + grid_point_5.param_set_liveupdate(live_update); + grid_point_6.param_set_liveupdate(live_update); + grid_point_7.param_set_liveupdate(live_update); + grid_point_8x9.param_set_liveupdate(live_update); + grid_point_10x11.param_set_liveupdate(live_update); + grid_point_12.param_set_liveupdate(live_update); + grid_point_13.param_set_liveupdate(live_update); + grid_point_14.param_set_liveupdate(live_update); + grid_point_15.param_set_liveupdate(live_update); + grid_point_16.param_set_liveupdate(live_update); + grid_point_17.param_set_liveupdate(live_update); + grid_point_18.param_set_liveupdate(live_update); + grid_point_19.param_set_liveupdate(live_update); + grid_point_20x21.param_set_liveupdate(live_update); + grid_point_22x23.param_set_liveupdate(live_update); + grid_point_24x26.param_set_liveupdate(live_update); + grid_point_25x27.param_set_liveupdate(live_update); + grid_point_28x30.param_set_liveupdate(live_update); + grid_point_29x31.param_set_liveupdate(live_update); + grid_point_32x33x34x35.param_set_liveupdate(live_update); } void diff --git a/src/live_effects/lpe-lattice2.h b/src/live_effects/lpe-lattice2.h index b32903c9e..8d0c18a3a 100644 --- a/src/live_effects/lpe-lattice2.h +++ b/src/live_effects/lpe-lattice2.h @@ -63,6 +63,7 @@ private: BoolParam horizontal_mirror; BoolParam vertical_mirror; + BoolParam live_update; PointParam grid_point_0; PointParam grid_point_1; PointParam grid_point_2; diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 783053df2..c13cffb6a 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -33,7 +33,7 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : reflection_line(_("Reflection line:"), _("Line which serves as 'mirror' for the reflection"), "reflection_line", &wr, this, "M0,0 L100,100") { show_orig_path = true; - + apply_to_clippath_and_mask = true; registerParameter( dynamic_cast<Parameter *>(&discard_orig_path) ); registerParameter( dynamic_cast<Parameter *>(&reflection_line) ); } @@ -43,14 +43,6 @@ LPEMirrorSymmetry::~LPEMirrorSymmetry() } void -LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) -{ - SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); -} - -void LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) { using namespace Geom; diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 7a484a473..64a72d7b3 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -30,8 +30,6 @@ public: virtual void doOnApply (SPLPEItem const* lpeitem); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); private: diff --git a/src/live_effects/lpe-offset.cpp b/src/live_effects/lpe-offset.cpp index dd7af92a2..d611b88a1 100644 --- a/src/live_effects/lpe-offset.cpp +++ b/src/live_effects/lpe-offset.cpp @@ -31,7 +31,7 @@ LPEOffset::LPEOffset(LivePathEffectObject *lpeobject) : offset_pt(_("Offset"), _("Handle to control the distance of the offset from the curve"), "offset_pt", &wr, this) { show_orig_path = true; - + apply_to_clippath_and_mask = true; registerParameter(dynamic_cast<Parameter *>(&offset_pt)); } @@ -57,14 +57,6 @@ static void append_half_circle(Geom::Piecewise<Geom::D2<Geom::SBasis> > &pwd2, pwd2.continuousConcat(cap_pwd2); } -void -LPEOffset::doBeforeEffect (SPLPEItem const* lpeitem) -{ - SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); -} - Geom::Piecewise<Geom::D2<Geom::SBasis> > LPEOffset::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in) { diff --git a/src/live_effects/lpe-offset.h b/src/live_effects/lpe-offset.h index 997311c7d..9966fd45d 100644 --- a/src/live_effects/lpe-offset.h +++ b/src/live_effects/lpe-offset.h @@ -28,8 +28,6 @@ public: virtual void doOnApply (SPLPEItem const* lpeitem); - virtual void doBeforeEffect (SPLPEItem const* lpeitem); - virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in); private: diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index ed65a0d50..9397d848f 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -18,6 +18,9 @@ #include <2geom/d2.h> #include <2geom/piecewise.h> +#include "knot-holder-entity.h" +#include "knotholder.h" + #include <algorithm> using std::vector; @@ -45,6 +48,16 @@ first) but I think we can first forget about them. namespace Inkscape { namespace LivePathEffect { +Geom::PathVector pap_helper_path; + +namespace WPAP { + class KnotHolderEntityWidthPatternAlongPath : public LPEKnotHolderEntity { + public: + KnotHolderEntityWidthPatternAlongPath(LPEPatternAlongPath * effect) : LPEKnotHolderEntity(effect) {} + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; + }; +} // WPAP static const Util::EnumData<PAPCopyType> PAPCopyTypeData[PAPCT_END] = { {PAPCT_SINGLE, N_("Single"), "single"}, @@ -57,9 +70,10 @@ static const Util::EnumDataConverter<PAPCopyType> PAPCopyTypeConverter(PAPCopyTy LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : Effect(lpeobject), pattern(_("Pattern source:"), _("Path to put along the skeleton path"), "pattern", &wr, this, "M0,0 L1,0"), + original_height(0), + prop_scale(_("_Width:"), _("Width of the pattern"), "prop_scale", &wr, this, 1.0), copytype(_("Pattern copies:"), _("How many pattern copies to place along the skeleton path"), "copytype", PAPCopyTypeConverter, &wr, this, PAPCT_SINGLE_STRETCHED), - prop_scale(_("_Width:"), _("Width of the pattern"), "prop_scale", &wr, this, 1), scale_y_rel(_("Wid_th in units of length"), _("Scale the width of the pattern in units of its length"), "scale_y_rel", &wr, this, false), @@ -87,9 +101,11 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast<Parameter *>(&prop_units) ); registerParameter( dynamic_cast<Parameter *>(&vertical_pattern) ); registerParameter( dynamic_cast<Parameter *>(&fuse_tolerance) ); - prop_scale.param_set_digits(3); prop_scale.param_set_increments(0.01, 0.10); + + _provides_knotholder_entities = true; + } LPEPatternAlongPath::~LPEPatternAlongPath() @@ -97,6 +113,16 @@ LPEPatternAlongPath::~LPEPatternAlongPath() } +void +LPEPatternAlongPath::doBeforeEffect (SPLPEItem const* lpeitem) +{ + // get the pattern bounding box + Geom::OptRect bbox = pattern.get_pathvector().boundsFast(); + if (bbox) { + original_height = (*bbox)[Geom::Y].max() - (*bbox)[Geom::Y].min(); + } +} + Geom::Piecewise<Geom::D2<Geom::SBasis> > LPEPatternAlongPath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in) { @@ -238,6 +264,83 @@ LPEPatternAlongPath::transform_multiply(Geom::Affine const& postmul, bool set) } } +void +LPEPatternAlongPath::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec) +{ + hp_vec.push_back(pap_helper_path); +} + + +void +LPEPatternAlongPath::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) +{ + KnotHolderEntity *e = new WPAP::KnotHolderEntityWidthPatternAlongPath(this); + e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE); + knotholder->add(e); +} + +namespace WPAP { + +void +KnotHolderEntityWidthPatternAlongPath::knot_set(Geom::Point const &p, Geom::Point const& /*origin*/, guint state) +{ + LPEPatternAlongPath *lpe = dynamic_cast<LPEPatternAlongPath *> (_effect); + + Geom::Point const s = snap_knot_position(p, state); + SPShape const *sp_shape = dynamic_cast<SPShape const *>(SP_LPE_ITEM(item)); + if (sp_shape) { + Geom::Path const *path_in = sp_shape->getCurveBeforeLPE()->first_path(); + Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); + Geom::Point B = path_in->pointAt(Geom::PathTime(1, 0.0)); + Geom::Curve const *first_curve = &path_in->curveAt(Geom::PathTime(0, 0.0)); + Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*first_curve); + Geom::Ray ray(ptA, B); + if (cubic) { + ray.setPoints(ptA, (*cubic)[1]); + } + ray.setAngle(ray.angle() + Geom::rad_from_deg(90)); + Geom::Point knot_pos = this->knot->pos * item->i2dt_affine().inverse(); + Geom::Coord nearest_to_ray = ray.nearestTime(knot_pos); + if(nearest_to_ray == 0){ + lpe->prop_scale.param_set_value(-Geom::distance(s , ptA)/(lpe->original_height/2.0)); + } else { + lpe->prop_scale.param_set_value(Geom::distance(s , ptA)/(lpe->original_height/2.0)); + } + + } + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); +} + +Geom::Point +KnotHolderEntityWidthPatternAlongPath::knot_get() const +{ + LPEPatternAlongPath *lpe = dynamic_cast<LPEPatternAlongPath *> (_effect); + + SPShape const *sp_shape = dynamic_cast<SPShape const *>(SP_LPE_ITEM(item)); + if (sp_shape) { + Geom::Path const *path_in = sp_shape->getCurveBeforeLPE()->first_path(); + Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); + Geom::Point B = path_in->pointAt(Geom::PathTime(1, 0.0)); + Geom::Curve const *first_curve = &path_in->curveAt(Geom::PathTime(0, 0.0)); + Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*first_curve); + Geom::Ray ray(ptA, B); + if (cubic) { + ray.setPoints(ptA, (*cubic)[1]); + } + ray.setAngle(ray.angle() + Geom::rad_from_deg(90)); + Geom::Point result_point = Geom::Point::polar(ray.angle(), (lpe->original_height/2.0) * lpe->prop_scale) + ptA; + + pap_helper_path.clear(); + Geom::Path hp(result_point); + hp.appendNew<Geom::LineSegment>(ptA); + pap_helper_path.push_back(hp); + hp.clear(); + + return result_point; + } + return Geom::Point(); +} +} // namespace WPAP } // namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-patternalongpath.h b/src/live_effects/lpe-patternalongpath.h index be2197ddb..3b9a17ab0 100644 --- a/src/live_effects/lpe-patternalongpath.h +++ b/src/live_effects/lpe-patternalongpath.h @@ -13,10 +13,15 @@ #include "live_effects/effect.h" #include "live_effects/parameter/path.h" #include "live_effects/parameter/bool.h" +#include "live_effects/parameter/point.h" namespace Inkscape { namespace LivePathEffect { +namespace WPAP { +class KnotHolderEntityWidthPatternAlongPath; +} + enum PAPCopyType { PAPCT_SINGLE = 0, PAPCT_SINGLE_STRETCHED, @@ -30,14 +35,25 @@ public: LPEPatternAlongPath(LivePathEffectObject *lpeobject); virtual ~LPEPatternAlongPath(); + virtual void doBeforeEffect (SPLPEItem const* lpeitem); + virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in); virtual void transform_multiply(Geom::Affine const& postmul, bool set); + void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec); + + virtual void addKnotHolderEntities(KnotHolder * knotholder, SPDesktop * desktop, SPItem * item); + PathParam pattern; + + friend class WPAP::KnotHolderEntityWidthPatternAlongPath; +protected: + double original_height; + ScalarParam prop_scale; + private: EnumParam<PAPCopyType> copytype; - ScalarParam prop_scale; BoolParam scale_y_rel; ScalarParam spacing; ScalarParam normal_offset; @@ -45,7 +61,6 @@ private: BoolParam prop_units; BoolParam vertical_pattern; ScalarParam fuse_tolerance; - void on_pattern_pasted(); LPEPatternAlongPath(const LPEPatternAlongPath&); diff --git a/src/live_effects/lpe-perspective-envelope.cpp b/src/live_effects/lpe-perspective-envelope.cpp index 72c1b0e99..5b29df4a7 100644 --- a/src/live_effects/lpe-perspective-envelope.cpp +++ b/src/live_effects/lpe-perspective-envelope.cpp @@ -56,6 +56,7 @@ LPEPerspectiveEnvelope::LPEPerspectiveEnvelope(LivePathEffectObject *lpeobject) registerParameter(&up_right_point); registerParameter(&down_left_point); registerParameter(&down_right_point); + apply_to_clippath_and_mask = true; } LPEPerspectiveEnvelope::~LPEPerspectiveEnvelope() @@ -371,9 +372,6 @@ LPEPerspectiveEnvelope::doBeforeEffect (SPLPEItem const* lpeitem) horizontal(up_left_point, down_left_point,horiz); horizontal(up_right_point, down_right_point,horiz); } - SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); setDefaults(); } diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index 901519b4f..c8cdd7912 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -64,6 +64,7 @@ LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) : concatenate_before_pwd2 = true; // don't split the path into its subpaths _provides_knotholder_entities = true; + apply_to_clippath_and_mask = true; } LPEPerspectivePath::~LPEPerspectivePath() @@ -100,8 +101,6 @@ LPEPerspectivePath::doBeforeEffect (SPLPEItem const* lpeitem) Geom::Affine doc2d = Geom::Scale(1, -1) * Geom::Translate(0, item->document->getHeight().value("px")); pmat = pmat * doc2d; pmat.copy_tmat(tmat); - item->apply_to_clippath(item); - item->apply_to_mask(item); } void LPEPerspectivePath::refresh(Gtk::Entry* perspective) { diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 33ffd96d6..105fe2fc4 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -18,7 +18,9 @@ #include "live_effects/lpe-roughen.h" #include "display/curve.h" #include "live_effects/parameter/parameter.h" +#include <boost/functional/hash.hpp> #include "helper/geom.h" +#include "sp-item-group.h" #include <glibmm/i18n.h> #include <cmath> @@ -32,13 +34,22 @@ static const Util::EnumData<DivisionMethod> DivisionMethodData[DM_END] = { static const Util::EnumDataConverter<DivisionMethod> DMConverter(DivisionMethodData, DM_END); +static const Util::EnumData<HandlesMethod> HandlesMethodData[HM_END] = { + { HM_ALONG_NODES, N_("Along nodes"), "along" }, + { HM_RAND, N_("Rand"), "rand" }, + { HM_RETRACT, N_("Retract"), "retract" }, + { HM_SMOOTH, N_("Smooth"), "smooth" } +}; +static const Util::EnumDataConverter<HandlesMethod> +HMConverter(HandlesMethodData, HM_END); + LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) : Effect(lpeobject), // initialise your parameters here: method(_("Method"), _("Division method"), "method", DMConverter, &wr, this, DM_SEGMENTS), max_segment_size(_("Max. segment size"), _("Max. segment size"), - "max_segment_size", &wr, this, 10.), + "max_segment_size", &wr, this, 10), segments(_("Number of segments"), _("Number of segments"), "segments", &wr, this, 2), displace_x(_("Max. displacement in X"), _("Max. displacement in X"), @@ -47,10 +58,14 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) "displace_y", &wr, this, 10.), global_randomize(_("Global randomize"), _("Global randomize"), "global_randomize", &wr, this, 1.), + handles(_("Handles"), _("Handles options"), "handles", HMConverter, &wr, + this, HM_ALONG_NODES), shift_nodes(_("Shift nodes"), _("Shift nodes"), "shift_nodes", &wr, this, true), - shift_node_handles(_("Shift node handles"), _("Shift node handles"), - "shift_node_handles", &wr, this, true) + fixed_displacement(_("Fixed displacement"), _("Fixed displacement, 1/3 of segment length"), + "fixed_displacement", &wr, this, false), + spray_tool_friendly(_("Spray Tool friendly"), _("For use with spray tool in copy mode"), + "spray_tool_friendly", &wr, this, false) { registerParameter(&method); registerParameter(&max_segment_size); @@ -58,8 +73,10 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) registerParameter(&displace_x); registerParameter(&displace_y); registerParameter(&global_randomize); + registerParameter(&handles); registerParameter(&shift_nodes); - registerParameter(&shift_node_handles); + registerParameter(&fixed_displacement); + registerParameter(&spray_tool_friendly); displace_x.param_set_range(0., Geom::infinity()); displace_y.param_set_range(0., Geom::infinity()); global_randomize.param_set_range(0., Geom::infinity()); @@ -69,19 +86,23 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) segments.param_set_range(1, Geom::infinity()); segments.param_set_increments(1, 1); segments.param_set_digits(0); + seed = 0; + apply_to_clippath_and_mask = true; } LPERoughen::~LPERoughen() {} void LPERoughen::doBeforeEffect(SPLPEItem const *lpeitem) { + if(spray_tool_friendly && seed == 0 && SP_OBJECT(lpeitem)->getId()){ + std::string id_item(SP_OBJECT(lpeitem)->getId()); + long seed = static_cast<long>(boost::hash_value(id_item)); + global_randomize.param_set_value(global_randomize.get_value(), seed); + } displace_x.resetRandomizer(); displace_y.resetRandomizer(); global_randomize.resetRandomizer(); srand(1); - SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); } Gtk::Widget *LPERoughen::newWidget() @@ -122,6 +143,15 @@ Gtk::Widget *LPERoughen::newWidget() vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET); } + if (param->param_key == "handles") { + Gtk::Label *options = Gtk::manage(new Gtk::Label( + Glib::ustring(_("<b>Options</b> Modify options to rough")), + Gtk::ALIGN_START)); + options->set_use_markup(true); + vbox->pack_start(*options, false, false, 2); + vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), + Gtk::PACK_EXPAND_WIDGET); + } Glib::ustring *tip = param->param_getTooltip(); if (widg) { vbox->pack_start(*widg, true, true, 2); @@ -133,7 +163,6 @@ Gtk::Widget *LPERoughen::newWidget() } } } - ++it; } return dynamic_cast<Gtk::Widget *>(vbox); @@ -147,19 +176,25 @@ double LPERoughen::sign(double random_number) return random_number; } -Geom::Point LPERoughen::randomize() +Geom::Point LPERoughen::randomize(double max_lenght, bool is_node) { - double displace_x_parsed = displace_x * global_randomize; - double displace_y_parsed = displace_y * global_randomize; - + double factor = 1.0/3.0; + if(is_node){ + factor = 1.0; + } + double displace_x_parsed = displace_x * global_randomize * factor; + double displace_y_parsed = displace_y * global_randomize * factor; Geom::Point output = Geom::Point(sign(displace_x_parsed), sign(displace_y_parsed)); + if( fixed_displacement ){ + Geom::Ray ray(Geom::Point(0,0),output); + output = Geom::Point::polar(ray.angle(), max_lenght); + } return output; } void LPERoughen::doEffect(SPCurve *curve) { - Geom::PathVector const original_pathv = - pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); + Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(curve->get_pathvector()); curve->reset(); for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { @@ -170,41 +205,30 @@ void LPERoughen::doEffect(SPCurve *curve) Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); Geom::Path::const_iterator curve_endit = path_it->end_default(); SPCurve *nCurve = new SPCurve(); + Geom::Point prev(0, 0); + Geom::Point last_move(0, 0); + nCurve->moveto(curve_it1->initialPoint()); if (path_it->closed()) { - const Geom::Curve &closingline = - path_it->back_closed(); - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - curve_endit = path_it->end_open(); - } - } - Geom::Point initialMove(0, 0); - if (shift_nodes) { - initialMove = randomize(); + 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(); + } } - Geom::Point initialPoint = curve_it1->initialPoint() + initialMove; - nCurve->moveto(initialPoint); - Geom::Point point0(0, 0); - Geom::Point point1(0, 0); - Geom::Point point2(0, 0); - Geom::Point point3(0, 0); - bool first = true; while (curve_it1 != curve_endit) { Geom::CubicBezier const *cubic = NULL; - point0 = curve_it1->initialPoint(); - point1 = curve_it1->initialPoint(); - point2 = curve_it1->finalPoint(); - point3 = curve_it1->finalPoint(); cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1); if (cubic) { - point1 = (*cubic)[1]; - if (shift_nodes && first) { - point1 = (*cubic)[1] + initialMove; - } - point2 = (*cubic)[2]; - nCurve->curveto(point1, point2, point3); + nCurve->curveto((*cubic)[1] + last_move, (*cubic)[2], curve_it1->finalPoint()); } else { - nCurve->lineto(point3); + nCurve->lineto(curve_it1->finalPoint()); } + last_move = Geom::Point(0, 0); double length = curve_it1->length(0.001); std::size_t splits = 0; if (method == DM_SEGMENTS) { @@ -212,15 +236,21 @@ void LPERoughen::doEffect(SPCurve *curve) } else { splits = ceil(length / max_segment_size); } - for (unsigned int t = splits; t >= 1; t--) { - if (t == 1 && splits != 1) { + Geom::Curve const * original = nCurve->last_segment()->duplicate() ; + for (unsigned int t = 1; t <= splits; t++) { + if(t == splits && splits != 1){ continue; } - const SPCurve *tmp; + SPCurve const * tmp; if (splits == 1) { - tmp = jitter(nCurve->last_segment()); + tmp = jitter(nCurve->last_segment(), prev, last_move); } else { - tmp = addNodesAndJitter(nCurve->last_segment(), 1. / t); + bool last = false; + if(t == splits-1){ + last = true; + } + double time = Geom::nearest_time(original->pointAt((1. / (double)splits) * t), *nCurve->last_segment()); + tmp = addNodesAndJitter(nCurve->last_segment(), prev, last_move, time, last); } if (nCurve->get_segment_count() > 1) { nCurve->backspace(); @@ -231,12 +261,44 @@ void LPERoughen::doEffect(SPCurve *curve) delete tmp; } ++curve_it1; - if(curve_it2 != curve_endit) { - ++curve_it2; - } - first = false; + ++curve_it2; } if (path_it->closed()) { + if(handles == HM_SMOOTH && curve_it1 == curve_endit){ + SPCurve *out = new SPCurve(); + nCurve = nCurve->create_reverse(); + Geom::CubicBezier const *cubic_start = dynamic_cast<Geom::CubicBezier const *>(nCurve->first_segment()); + Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(nCurve->last_segment()); + Geom::Point oposite = nCurve->first_segment()->pointAt(1.0/3.0); + if(cubic_start){ + Geom::Ray ray((*cubic_start)[1], (*cubic_start)[0]); + double dist = Geom::distance((*cubic_start)[1], (*cubic_start)[0]); + oposite = Geom::Point::polar(ray.angle(),dist) + (*cubic_start)[0]; + } + if(cubic){ + out->moveto((*cubic)[0]); + out->curveto((*cubic)[1], oposite, (*cubic)[3]); + } else { + out->moveto(nCurve->last_segment()->initialPoint()); + out->curveto(nCurve->last_segment()->initialPoint(), oposite, nCurve->last_segment()->finalPoint()); + } + nCurve->backspace(); + nCurve->append_continuous(out, 0.001); + nCurve = nCurve->create_reverse(); + } + if(handles == HM_ALONG_NODES && curve_it1 == curve_endit){ + SPCurve *out = new SPCurve(); + nCurve = nCurve->create_reverse(); + Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(nCurve->last_segment()); + if(cubic){ + out->moveto((*cubic)[0]); + out->curveto((*cubic)[1], (*cubic)[2] - ((*cubic)[3] - nCurve->first_segment()->initialPoint()) , (*cubic)[3]); + nCurve->backspace(); + nCurve->append_continuous(out, 0.001); + } + nCurve = nCurve->create_reverse(); + } + nCurve->move_endpoints(nCurve->last_segment()->finalPoint(), nCurve->last_segment()->finalPoint()); nCurve->closepath_current(); } curve->append(nCurve, false); @@ -245,77 +307,211 @@ void LPERoughen::doEffect(SPCurve *curve) } } -SPCurve *LPERoughen::addNodesAndJitter(const Geom::Curve *A, double t) +SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move, double t, bool last) { SPCurve *out = new SPCurve(); Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*A); - Geom::Point point1(0, 0); - Geom::Point point2(0, 0); - Geom::Point point3(0, 0); + double max_lenght = Geom::distance(A->initialPoint(),A->pointAt(t)) / 3.0; + Geom::Point point_a1(0, 0); + Geom::Point point_a2(0, 0); + Geom::Point point_a3(0, 0); Geom::Point point_b1(0, 0); Geom::Point point_b2(0, 0); Geom::Point point_b3(0, 0); if (shift_nodes) { - point3 = randomize(); - point_b3 = randomize(); + point_a3 = randomize(max_lenght, true); + if(last){ + point_b3 = randomize(max_lenght, true); + } } - if (shift_node_handles) { - point1 = randomize(); - point2 = randomize(); - point_b1 = randomize(); - point_b2 = randomize(); + if (handles == HM_RAND || handles == HM_SMOOTH) { + point_a1 = randomize(max_lenght); + point_a2 = randomize(max_lenght); + point_b1 = randomize(max_lenght); + if(last){ + point_b2 = randomize(max_lenght); + } } else { - point2 = point3; - point_b1 = point3; - point_b2 = point_b3; + point_a2 = point_a3; + point_b1 = point_a3; + if(last){ + point_b2 = point_b3; + } } - if (cubic) { - std::pair<Geom::CubicBezier, Geom::CubicBezier> div = cubic->subdivide(t); - std::vector<Geom::Point> seg1 = div.first.controlPoints(), - seg2 = div.second.controlPoints(); - out->moveto(seg1[0]); - out->curveto(seg1[1] + point1, seg1[2] + point2, seg1[3] + point3); - out->curveto(seg2[1] + point_b1, seg2[2], seg2[3]); - } else if (shift_node_handles) { - out->moveto(A->initialPoint()); - out->curveto(A->pointAt(t / 3) + point1, A->pointAt((t / 3) * 2) + point2, - A->pointAt(t) + point3); - out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t + ((t / 3) * 2)), - A->finalPoint()); - } else { + if(handles == HM_SMOOTH){ + if(cubic) { + std::pair<Geom::CubicBezier, Geom::CubicBezier> div = cubic->subdivide(t); + std::vector<Geom::Point> seg1 = div.first.controlPoints(), + seg2 = div.second.controlPoints(); + Geom::Ray ray(seg1[3] + point_a3, seg2[1] + point_a3); + double lenght = max_lenght; + if(!fixed_displacement ){ + lenght = Geom::distance(seg1[3] + point_a3, seg2[1] + point_a3); + } + point_b1 = seg1[3] + point_a3 + Geom::Point::polar(ray.angle() , lenght); + point_b2 = seg2[2]; + point_b3 = seg2[3] + point_b3; + point_a3 = seg1[3] + point_a3; + ray.setPoints(prev,A->initialPoint()); + point_a1 = A->initialPoint() + Geom::Point::polar(ray.angle(), max_lenght); + if(prev == Geom::Point(0,0)){ + point_a1 = randomize(max_lenght); + } + if(last){ + Geom::Path b2(point_b3); + b2.appendNew<Geom::LineSegment>(point_a3); + lenght = max_lenght; + ray.setPoints(point_b3, point_b2); + if(!fixed_displacement ){ + lenght = Geom::distance(b2.pointAt(1.0/3.0), point_b3); + } + point_b2 = point_b3 + Geom::Point::polar(ray.angle() , lenght); + } + ray.setPoints(point_b1, point_a3); + point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); + if(last){ + prev = point_b2; + } else { + prev = point_a2; + } + out->moveto(seg1[0]); + out->curveto(point_a1,point_a2,point_a3); + out->curveto(point_b1, point_b2, point_b3); + } else { + Geom::Ray ray(A->pointAt(t) + point_a3, A->pointAt(t + (t / 3))); + double lenght = max_lenght; + if(!fixed_displacement ){ + lenght = Geom::distance(A->pointAt(t) + point_a3, A->pointAt(t + (t / 3))); + } + point_b1 = A->pointAt(t) + point_a3 + Geom::Point::polar(ray.angle() , lenght); + point_b2 = A->pointAt(t +((t / 3) * 2)); + point_b3 = A->finalPoint() + point_b3; + point_a3 = A->pointAt(t) + point_a3; + ray.setPoints(prev,A->initialPoint()); + point_a1 = A->initialPoint() + Geom::Point::polar(ray.angle(), max_lenght); + if(prev == Geom::Point(0,0)){ + point_a1 = randomize(max_lenght); + } + if(last){ + Geom::Path b2(point_b3); + b2.appendNew<Geom::LineSegment>(point_a3); + lenght = max_lenght; + ray.setPoints(point_b3, point_b2); + if(!fixed_displacement ){ + lenght = Geom::distance(b2.pointAt(1.0/3.0), point_b3); + } + point_b2 = point_b3 + Geom::Point::polar(ray.angle() , lenght); + } + ray.setPoints(point_b1, point_a3); + point_a2 = point_a3 + Geom::Point::polar(ray.angle(), max_lenght); + if(last){ + prev = point_b2; + } else { + prev = point_a2; + } + out->moveto(A->initialPoint()); + out->curveto(point_a1,point_a2,point_a3); + out->curveto(point_b1, point_b2, point_b3); + } + } else if(handles == HM_RETRACT){ out->moveto(A->initialPoint()); - out->lineto(A->pointAt(t) + point3); - out->lineto(A->finalPoint()); + out->lineto(A->pointAt(t) + point_a3); + if(cubic && !last){ + std::pair<Geom::CubicBezier, Geom::CubicBezier> div = cubic->subdivide(t); + std::vector<Geom::Point> seg2 = div.second.controlPoints(); + out->curveto(seg2[1], seg2[2], seg2[3]); + } else { + out->lineto(A->finalPoint() + point_b3); + } + } else if(handles == HM_ALONG_NODES){ + if (cubic) { + std::pair<Geom::CubicBezier, Geom::CubicBezier> div = cubic->subdivide(t); + std::vector<Geom::Point> seg1 = div.first.controlPoints(), + seg2 = div.second.controlPoints(); + out->moveto(seg1[0]); + out->curveto(seg1[1] + last_move, seg1[2] + point_a3, seg1[3] + point_a3); + last_move = point_a3; + if(last){ + last_move = point_b3; + } + out->curveto(seg2[1] + point_a3, seg2[2] + point_b3, seg2[3] + point_b3); + } else { + out->moveto(A->initialPoint()); + out->lineto(A->pointAt(t) + point_a3); + out->lineto(A->finalPoint() + point_b3); + } + } else if(handles == HM_RAND) { + if (cubic) { + std::pair<Geom::CubicBezier, Geom::CubicBezier> div = cubic->subdivide(t); + std::vector<Geom::Point> seg1 = div.first.controlPoints(), + seg2 = div.second.controlPoints(); + out->moveto(seg1[0]); + out->curveto(seg1[1] + point_a1, seg1[2] + point_a2 + point_a3, seg1[3] + point_a3); + out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3); + } else { + out->moveto(A->initialPoint()); + out->lineto(A->pointAt(t) + point_a3); + out->lineto(A->finalPoint() + point_b3); + } } return out; } -SPCurve *LPERoughen::jitter(const Geom::Curve *A) +SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move) { SPCurve *out = new SPCurve(); Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*A); - Geom::Point point1(0, 0); - Geom::Point point2(0, 0); - Geom::Point point3(0, 0); + double max_lenght = Geom::distance(A->initialPoint(),A->finalPoint()) / 3.0; + Geom::Point point_a1(0, 0); + Geom::Point point_a2(0, 0); + Geom::Point point_a3(0, 0); if (shift_nodes) { - point3 = randomize(); + point_a3 = randomize(max_lenght, true); } - if (shift_node_handles) { - point1 = randomize(); - point2 = randomize(); - } else { - point2 = point3; + if (handles == HM_RAND || handles == HM_SMOOTH) { + point_a1 = randomize(max_lenght); + point_a2 = randomize(max_lenght); } - if (cubic) { - out->moveto((*cubic)[0]); - out->curveto((*cubic)[1] + point1, (*cubic)[2] + point2, (*cubic)[3] + point3); - } else if (shift_node_handles) { + if(handles == HM_SMOOTH) { + if (cubic) { + Geom::Ray ray(prev,A->initialPoint()); + point_a1 = Geom::Point::polar(ray.angle(), max_lenght); + if(prev == Geom::Point(0,0)){ + point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght); + } + ray.setPoints((*cubic)[3] + point_a3, (*cubic)[2] + point_a3); + point_a2 = randomize(max_lenght, ray.angle()); + prev = (*cubic)[2] + point_a2; + out->moveto((*cubic)[0]); + out->curveto((*cubic)[0] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3); + } else { + Geom::Ray ray(prev,A->initialPoint()); + point_a1 = Geom::Point::polar(ray.angle(), max_lenght); + if(prev==Geom::Point(0,0)){ + point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght); + } + ray.setPoints(A->finalPoint() + point_a3, A->pointAt((1.0/3.0) * 2) + point_a3); + point_a2 = randomize(max_lenght, ray.angle()); + prev = A->pointAt((1.0/3.0) * 2) + point_a2 + point_a3; + out->moveto(A->initialPoint()); + out->curveto(A->initialPoint() + point_a1, A->pointAt((1.0/3.0) * 2) + point_a2 + point_a3, A->finalPoint() + point_a3); + } + } else if(handles == HM_RETRACT){ out->moveto(A->initialPoint()); - out->curveto(A->pointAt(0.3333) + point1, A->pointAt(0.6666) + point2, - A->finalPoint() + point3); - } else { + out->lineto(A->finalPoint() + point_a3); + } else if (handles == HM_ALONG_NODES) { + if(cubic){ + out->moveto((*cubic)[0]); + out->curveto((*cubic)[1] + last_move, (*cubic)[2] + point_a3, (*cubic)[3] + point_a3); + last_move = point_a3; + } else { + out->moveto(A->initialPoint()); + out->lineto(A->finalPoint() + point_a3); + } + } else if (handles == HM_RAND) { out->moveto(A->initialPoint()); - out->lineto(A->finalPoint() + point3); + out->curveto(A->pointAt(0.3333) + point_a1, A->pointAt(0.6666) + point_a2 + point_a3, + A->finalPoint() + point_a3); } return out; } diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index 2b285cd40..44a723c89 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -28,6 +28,15 @@ enum DivisionMethod { DM_END }; +enum HandlesMethod { + HM_ALONG_NODES, + HM_RAND, + HM_RETRACT, + HM_SMOOTH, + HM_END +}; + + class LPERoughen : public Effect { public: @@ -36,10 +45,10 @@ public: virtual void doEffect(SPCurve *curve); virtual double sign(double randNumber); - virtual Geom::Point randomize(); + virtual Geom::Point randomize(double max_lenght, bool is_node = false); virtual void doBeforeEffect(SPLPEItem const * lpeitem); - virtual SPCurve *addNodesAndJitter(const Geom::Curve *A, double t); - virtual SPCurve *jitter(const Geom::Curve *A); + virtual SPCurve const * addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move, double t, bool last); + virtual SPCurve *jitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move); virtual Geom::Point tPoint(Geom::Point A, Geom::Point B, double t = 0.5); virtual Gtk::Widget *newWidget(); @@ -50,9 +59,11 @@ private: RandomParam displace_x; RandomParam displace_y; RandomParam global_randomize; + EnumParam<HandlesMethod> handles; BoolParam shift_nodes; - BoolParam shift_node_handles; - + BoolParam fixed_displacement; + BoolParam spray_tool_friendly; + long seed; LPERoughen(const LPERoughen &); LPERoughen &operator=(const LPERoughen &); diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp index f6842a030..f807bdc8d 100644 --- a/src/live_effects/lpe-simplify.cpp +++ b/src/live_effects/lpe-simplify.cpp @@ -28,8 +28,8 @@ namespace LivePathEffect { LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) : Effect(lpeobject), steps(_("Steps:"),_("Change number of simplify steps "), "steps", &wr, this,1), - threshold(_("Roughly threshold:"), _("Roughly threshold:"), "threshold", &wr, this, 0.003), - smooth_angles(_("Smooth angles:"), _("Max degree difference on handles to preform a smooth"), "smooth_angles", &wr, this, 20.), + threshold(_("Roughly threshold:"), _("Roughly threshold:"), "threshold", &wr, this, 0.002), + smooth_angles(_("Smooth angles:"), _("Max degree difference on handles to perform a smooth"), "smooth_angles", &wr, this, 0.), helper_size(_("Helper size:"), _("Helper size"), "helper_size", &wr, this, 5), simplify_individual_paths(_("Paths separately"), _("Simplifying paths (separately)"), "simplify_individual_paths", &wr, this, false, "", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), @@ -51,7 +51,7 @@ LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) steps.param_set_increments(1, 1); steps.param_set_digits(0); - smooth_angles.param_set_range(0.0, 365.0); + smooth_angles.param_set_range(0.0, 360.0); smooth_angles.param_set_increments(10, 10); smooth_angles.param_set_digits(2); @@ -60,6 +60,7 @@ LPESimplify::LPESimplify(LivePathEffectObject *lpeobject) helper_size.param_set_digits(2); radius_helper_nodes = 6.0; + apply_to_clippath_and_mask = true; } LPESimplify::~LPESimplify() {} @@ -71,10 +72,7 @@ LPESimplify::doBeforeEffect (SPLPEItem const* lpeitem) hp.clear(); } bbox = SP_ITEM(lpeitem)->visualBounds(); - SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); radius_helper_nodes = helper_size; - item->apply_to_clippath(item); - item->apply_to_mask(item); } Gtk::Widget * @@ -138,6 +136,7 @@ LPESimplify::doEffect(SPCurve *curve) if(simplify_individual_paths) { size = Geom::L2(Geom::bounds_fast(original_pathv)->dimensions()); } + size /= sp_lpe_item->i2doc_affine().descrim(); for (int unsigned i = 0; i < steps; i++) { if ( simplify_just_coalesce ) { pathliv->Coalesce(threshold * size); @@ -198,13 +197,15 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) Geom::Point point_at2 = curve_it1->finalPoint(); Geom::Point point_at3 = curve_it1->finalPoint(); Geom::Point point_at4 = curve_it1->finalPoint(); + + if(start == Geom::Point(0,0)) { + start = point_at1; + } + if (cubic) { point_at1 = (*cubic)[1]; point_at2 = (*cubic)[2]; } - if(start == Geom::Point(0,0)) { - start = point_at1; - } if(path_it->closed() && curve_it2 == curve_endit) { point_at4 = start; @@ -217,13 +218,13 @@ LPESimplify::generateHelperPathAndSmooth(Geom::PathVector &result) } Geom::Ray ray1(point_at2, point_at3); Geom::Ray ray2(point_at3, point_at4); - double angle1 = Geom::rad_to_deg(ray1.angle()); - double angle2 = Geom::rad_to_deg(ray2.angle()); - if((smooth_angles >= angle2 - angle1) && !are_near(point_at4,point_at3) && !are_near(point_at2,point_at3)) { + double angle1 = Geom::deg_from_rad(ray1.angle()); + double angle2 = Geom::deg_from_rad(ray2.angle()); + if((smooth_angles >= std::abs(angle2 - angle1)) && !are_near(point_at4,point_at3) && !are_near(point_at2,point_at3)) { double dist = Geom::distance(point_at2,point_at3); Geom::Angle angleFixed = ray2.angle(); angleFixed -= Geom::Angle::from_degrees(180.0); - point_at2 = Geom::Point::polar(angleFixed,dist) + point_at3; + point_at2 = Geom::Point::polar(angleFixed, dist) + point_at3; } nCurve->curveto(point_at1, point_at2, curve_it1->finalPoint()); cubic = dynamic_cast<Geom::CubicBezier const *>(nCurve->last_segment()); diff --git a/src/live_effects/lpe-taperstroke.cpp b/src/live_effects/lpe-taperstroke.cpp index ef616f802..f2ddd4929 100644 --- a/src/live_effects/lpe-taperstroke.cpp +++ b/src/live_effects/lpe-taperstroke.cpp @@ -408,9 +408,8 @@ Piecewise<D2<SBasis> > stretch_along(Piecewise<D2<SBasis> > pwd2_in, Geom::Path n = force_continuity(remove_short_cuts(n,.1)); int nbCopies = 0; - double scaling = 1; + double scaling = (uskeleton.domain().extent() - toffset)/pattBndsX->extent(); nbCopies = 1; - scaling = (uskeleton.domain().extent() - toffset)/pattBndsX->extent(); double pattWidth = pattBndsX->extent() * scaling; diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index 79ffd74de..1cd59b7fa 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -19,7 +19,8 @@ #include "sp-path.h" #include "ui/icon-names.h" #include "svg/svg.h" - +#include "verbs.h" +// TODO due to internal breakage in glibmm headers, this must be last: #include <glibmm/i18n.h> namespace Inkscape { @@ -29,10 +30,14 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : Effect(lpeobject), elastic(_("Elastic"), _("Elastic transform mode"), "elastic", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), from_original_width(_("From original width"), _("From original width"), "from_original_width", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), - lock_lenght(_("Lock lenght"), _("Lock lenght to current distance"), "lock_lenght", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), + lock_lenght(_("Lock length"), _("Lock length to current distance"), "lock_lenght", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), lock_angle(_("Lock angle"), _("Lock angle"), "lock_angle", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), + flip_horizontal(_("Flip horizontal"), _("Flip horizontal"), "flip_horizontal", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), + flip_vertical(_("Flip vertical"), _("Flip vertical"), "flip_vertical", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), start(_("Start"), _("Start point"), "start", &wr, this, "Start point"), end(_("End"), _("End point"), "end", &wr, this, "End point"), + strech(_("Stretch"), _("Stretch the result"), "strech", &wr, this, 1), + offset(_("Offset"), _("Offset from knots"), "offset", &wr, this, 0), first_knot(_("First Knot"), _("First Knot"), "first_knot", &wr, this, 1), last_knot(_("Last Knot"), _("Last Knot"), "last_knot", &wr, this, 1), helper_size(_("Helper size:"), _("Rotation helper size"), "helper_size", &wr, this, 3), @@ -41,25 +46,39 @@ LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : point_b(Geom::Point()), pathvector(), append_path(false), - previous_angle(Geom::deg_to_rad(0)), + previous_angle(Geom::rad_from_deg(0)), previous_start(Geom::Point()), previous_lenght(-1) { - registerParameter(&start); - registerParameter(&end); + registerParameter(&first_knot); registerParameter(&last_knot); registerParameter(&helper_size); + registerParameter(&strech); + registerParameter(&offset); + registerParameter(&start); + registerParameter(&end); registerParameter(&elastic); registerParameter(&from_original_width); + registerParameter(&flip_vertical); + registerParameter(&flip_horizontal); registerParameter(&lock_lenght); registerParameter(&lock_angle); first_knot.param_make_integer(true); + first_knot.param_overwrite_widget(true); last_knot.param_make_integer(true); + last_knot.param_overwrite_widget(true); helper_size.param_set_range(0, 999); helper_size.param_set_increments(1, 1); helper_size.param_set_digits(0); + offset.param_set_range(-999999.0, 999999.0); + offset.param_set_increments(1, 1); + offset.param_set_digits(2); + strech.param_set_range(0, 999.0); + strech.param_set_increments(0.01, 0.01); + strech.param_set_digits(4); + apply_to_clippath_and_mask = true; } LPETransform2Pts::~LPETransform2Pts() @@ -133,10 +152,10 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) } if(lock_lenght && !lock_angle && previous_lenght != -1) { Geom::Ray transformed((Geom::Point)start,(Geom::Point)end); - if(previous_start == start || previous_angle == Geom::deg_to_rad(0)) { + if(previous_start == start || previous_angle == Geom::rad_from_deg(0)) { previous_angle = transformed.angle(); } - } else if(lock_angle && !lock_lenght && previous_angle != Geom::deg_to_rad(0)) { + } else if(lock_angle && !lock_lenght && previous_angle != Geom::rad_from_deg(0)) { if(previous_start == start){ previous_lenght = Geom::distance((Geom::Point)start, (Geom::Point)end); } @@ -149,8 +168,6 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) previous_angle = transformed.angle(); previous_lenght = Geom::distance((Geom::Point)start, (Geom::Point)end); previous_start = start; - splpeitem->apply_to_clippath(splpeitem); - splpeitem->apply_to_mask(splpeitem); } void @@ -176,6 +193,7 @@ LPETransform2Pts::updateIndex() start.param_set_default(); end.param_set_default(); } + DocumentUndo::done(getSPDoc(), SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change index of knot")); } //todo migrate to PathVector class? size_t @@ -259,6 +277,7 @@ Gtk::Widget *LPETransform2Pts::newWidget() Gtk::HBox * button1 = Gtk::manage(new Gtk::HBox(true,0)); Gtk::HBox * button2 = Gtk::manage(new Gtk::HBox(true,0)); Gtk::HBox * button3 = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::HBox * button4 = Gtk::manage(new Gtk::HBox(true,0)); while (it != param_vector.end()) { if ((*it)->widget_is_visible) { Parameter *param = *it; @@ -292,7 +311,7 @@ Gtk::Widget *LPETransform2Pts::newWidget() widg->set_has_tooltip(false); } } - } else if (param->param_key == "lock_angle" || param->param_key == "lock_lenght") { + } else if (param->param_key == "flip_horizontal" || param->param_key == "flip_vertical") { Glib::ustring * tip = param->param_getTooltip(); if (widg) { button2->pack_start(*widg, true, true, 2); @@ -303,6 +322,17 @@ Gtk::Widget *LPETransform2Pts::newWidget() widg->set_has_tooltip(false); } } + } else if (param->param_key == "lock_angle" || param->param_key == "lock_lenght") { + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + button3->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } } else if (widg) { vbox->pack_start(*widg, true, true, 2); if (tip) { @@ -318,10 +348,11 @@ Gtk::Widget *LPETransform2Pts::newWidget() } Gtk::Button *reset = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset")))); reset->signal_clicked().connect(sigc::mem_fun(*this, &LPETransform2Pts::reset)); - button3->pack_start(*reset, true, true, 2); + button4->pack_start(*reset, true, true, 2); vbox->pack_start(*button1, true, true, 2); vbox->pack_start(*button2, true, true, 2); vbox->pack_start(*button3, true, true, 2); + vbox->pack_start(*button4, true, true, 2); return dynamic_cast<Gtk::Widget *>(vbox); } @@ -337,8 +368,26 @@ LPETransform2Pts::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const helper.start(point_a); helper.appendNew<Geom::LineSegment>(point_b); Geom::Affine m; + Geom::Angle original_angle = original.angle(); + if(flip_horizontal && flip_vertical){ + m *= Geom::Rotate(-original_angle); + m *= Geom::Scale(-1,-1); + m *= Geom::Rotate(original_angle); + } else if(flip_vertical){ + m *= Geom::Rotate(-original_angle); + m *= Geom::Scale(1,-1); + m *= Geom::Rotate(original_angle); + } else if(flip_horizontal){ + m *= Geom::Rotate(-original_angle); + m *= Geom::Scale(-1,1); + m *= Geom::Rotate(original_angle); + } + if(strech != 1){ + m *= Geom::Rotate(-original_angle); + m *= Geom::Scale(1,strech); + m *= Geom::Rotate(original_angle); + } if(elastic) { - Geom::Angle original_angle = original.angle(); m *= Geom::Rotate(-original_angle); if(sca > 1){ m *= Geom::Scale(sca, 1.0); @@ -346,14 +395,20 @@ LPETransform2Pts::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const m *= Geom::Scale(sca, 1.0-((1.0-sca)/2.0)); } m *= Geom::Rotate(transformed.angle()); - helper *= m; - m *= Geom::Translate((Geom::Point)start - helper.initialPoint()); } else { m *= Geom::Scale(sca); m *= Geom::Rotate(rot); - helper *= m; - m *= Geom::Translate((Geom::Point)start - helper.initialPoint()); } + helper *= m; + Geom::Point trans = (Geom::Point)start - helper.initialPoint(); + if(flip_horizontal){ + trans = (Geom::Point)end - helper.initialPoint(); + } + if(offset != 0){ + trans = Geom::Point::polar(transformed.angle() + Geom::rad_from_deg(-90),offset) + trans; + } + m *= Geom::Translate(trans); + output.concat(pwd2_in * m); return output; diff --git a/src/live_effects/lpe-transform_2pts.h b/src/live_effects/lpe-transform_2pts.h index 947243c82..c20d56206 100644 --- a/src/live_effects/lpe-transform_2pts.h +++ b/src/live_effects/lpe-transform_2pts.h @@ -53,8 +53,12 @@ private: ToggleButtonParam from_original_width; ToggleButtonParam lock_lenght; ToggleButtonParam lock_angle; + ToggleButtonParam flip_horizontal; + ToggleButtonParam flip_vertical; PointParam start; PointParam end; + ScalarParam strech; + ScalarParam offset; ScalarParam first_knot; ScalarParam last_knot; ScalarParam helper_size; diff --git a/src/live_effects/lpe-vonkoch.cpp b/src/live_effects/lpe-vonkoch.cpp index 7b424e019..7eda7446e 100644 --- a/src/live_effects/lpe-vonkoch.cpp +++ b/src/live_effects/lpe-vonkoch.cpp @@ -64,7 +64,7 @@ LPEVonKoch::LPEVonKoch(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast<Parameter *>(&drawall) ); registerParameter( dynamic_cast<Parameter *>(&maxComplexity) ); //registerParameter( dynamic_cast<Parameter *>(&draw_boxes) ); - + apply_to_clippath_and_mask = true; nbgenerations.param_make_integer(); nbgenerations.param_set_range(0, Geom::infinity()); maxComplexity.param_make_integer(); @@ -262,9 +262,6 @@ LPEVonKoch::doBeforeEffect (SPLPEItem const* lpeitem) tmp_pathv.push_back(tmp_path); ref_path.set_new_value(tmp_pathv,true); } - SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); - item->apply_to_clippath(item); - item->apply_to_mask(item); } diff --git a/src/live_effects/parameter/bool.cpp b/src/live_effects/parameter/bool.cpp index c1e8f8a7b..9ecadbdeb 100644 --- a/src/live_effects/parameter/bool.cpp +++ b/src/live_effects/parameter/bool.cpp @@ -21,8 +21,8 @@ namespace LivePathEffect { BoolParam::BoolParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, bool default_value ) - : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value) + Effect* effect, bool default_value , bool no_widget) + : Parameter(label, tip, key, wr, effect), value(default_value), defvalue(default_value), hide_widget(no_widget) { } @@ -53,20 +53,24 @@ BoolParam::param_getSVGValue() const Gtk::Widget * BoolParam::param_newWidget() { - Inkscape::UI::Widget::RegisteredCheckButton * checkwdg = Gtk::manage( - new Inkscape::UI::Widget::RegisteredCheckButton( param_label, - param_tooltip, - param_key, - *param_wr, - false, - param_effect->getRepr(), - param_effect->getSPDoc()) ); + if(!hide_widget){ + Inkscape::UI::Widget::RegisteredCheckButton * checkwdg = Gtk::manage( + new Inkscape::UI::Widget::RegisteredCheckButton( param_label, + param_tooltip, + param_key, + *param_wr, + false, + param_effect->getRepr(), + param_effect->getSPDoc()) ); - checkwdg->setActive(value); - checkwdg->setProgrammatically = false; - checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change bool parameter")); + checkwdg->setActive(value); + checkwdg->setProgrammatically = false; + checkwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change bool parameter")); - return dynamic_cast<Gtk::Widget *> (checkwdg); + return dynamic_cast<Gtk::Widget *> (checkwdg); + } else { + return NULL; + } } void diff --git a/src/live_effects/parameter/bool.h b/src/live_effects/parameter/bool.h index b45eeb0b3..403dd0b87 100644 --- a/src/live_effects/parameter/bool.h +++ b/src/live_effects/parameter/bool.h @@ -25,7 +25,8 @@ public: const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, - bool default_value = false); + bool default_value = false, + bool no_widget = false); virtual ~BoolParam(); virtual Gtk::Widget * param_newWidget(); @@ -46,6 +47,7 @@ private: bool value; bool defvalue; + bool hide_widget; }; diff --git a/src/live_effects/parameter/originalpatharray.cpp b/src/live_effects/parameter/originalpatharray.cpp index 78e061e66..7e3a6f5fe 100644 --- a/src/live_effects/parameter/originalpatharray.cpp +++ b/src/live_effects/parameter/originalpatharray.cpp @@ -215,7 +215,7 @@ void OriginalPathArrayParam::on_up_button_click() int i = -1; std::vector<PathAndDirection*>::iterator piter = _vector.begin(); - for (std::vector<PathAndDirection*>::iterator iter = _vector.begin(); iter != _vector.end(); piter = iter, i++, iter++) { + for (std::vector<PathAndDirection*>::iterator iter = _vector.begin(); iter != _vector.end(); piter = iter, i++, ++iter) { if (*iter == row[_model->_colObject]) { _vector.erase(iter); _vector.insert(piter, row[_model->_colObject]); @@ -241,11 +241,11 @@ void OriginalPathArrayParam::on_down_button_click() Gtk::TreeModel::Row row = *iter; int i = 0; - for (std::vector<PathAndDirection*>::iterator iter = _vector.begin(); iter != _vector.end(); i++, iter++) { + for (std::vector<PathAndDirection*>::iterator iter = _vector.begin(); iter != _vector.end(); i++, ++iter) { if (*iter == row[_model->_colObject]) { std::vector<PathAndDirection*>::iterator niter = _vector.erase(iter); if (niter != _vector.end()) { - niter++; + ++niter; i++; } _vector.insert(niter, row[_model->_colObject]); @@ -295,7 +295,7 @@ OriginalPathArrayParam::on_link_button_click() Inkscape::SVGOStringStream os; bool foundOne = false; - for (std::vector<PathAndDirection*>::const_iterator iter = _vector.begin(); iter != _vector.end(); iter++) { + for (std::vector<PathAndDirection*>::const_iterator iter = _vector.begin(); iter != _vector.end(); ++iter) { if (foundOne) { os << "|"; } else { @@ -330,7 +330,7 @@ void OriginalPathArrayParam::unlink(PathAndDirection* to) void OriginalPathArrayParam::remove_link(PathAndDirection* to) { unlink(to); - for (std::vector<PathAndDirection*>::iterator iter = _vector.begin(); iter != _vector.end(); iter++) { + for (std::vector<PathAndDirection*>::iterator iter = _vector.begin(); iter != _vector.end(); ++iter) { if (*iter == to) { PathAndDirection *w = *iter; _vector.erase(iter); @@ -455,7 +455,7 @@ gchar * OriginalPathArrayParam::param_getSVGValue() const { Inkscape::SVGOStringStream os; bool foundOne = false; - for (std::vector<PathAndDirection*>::const_iterator iter = _vector.begin(); iter != _vector.end(); iter++) { + for (std::vector<PathAndDirection*>::const_iterator iter = _vector.begin(); iter != _vector.end(); ++iter) { if (foundOne) { os << "|"; } else { diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp index 527bc06fe..d4e213948 100644 --- a/src/live_effects/parameter/parameter.cpp +++ b/src/live_effects/parameter/parameter.cpp @@ -54,7 +54,7 @@ void Parameter::write_to_SVG(void) */ ScalarParam::ScalarParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, gdouble default_value) + Effect* effect, gdouble default_value, bool no_widget) : Parameter(label, tip, key, wr, effect), value(default_value), min(-SCALARPARAM_G_MAXDOUBLE), @@ -64,7 +64,9 @@ ScalarParam::ScalarParam( const Glib::ustring& label, const Glib::ustring& tip, digits(2), inc_step(0.1), inc_page(1), - add_slider(false) + add_slider(false), + overwrite_widget(false), + hide_widget(no_widget) { } @@ -143,24 +145,34 @@ ScalarParam::param_make_integer(bool yes) inc_page = 10; } +void +ScalarParam::param_overwrite_widget(bool overwrite_widget) +{ + this->overwrite_widget = overwrite_widget; +} + Gtk::Widget * ScalarParam::param_newWidget() { - Inkscape::UI::Widget::RegisteredScalar *rsu = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar( - param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc() ) ); - - rsu->setValue(value); - rsu->setDigits(digits); - rsu->setIncrements(inc_step, inc_page); - rsu->setRange(min, max); - rsu->setProgrammatically = false; - if (add_slider) { - rsu->addSlider(); + if(!hide_widget){ + Inkscape::UI::Widget::RegisteredScalar *rsu = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar( + param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc() ) ); + + rsu->setValue(value); + rsu->setDigits(digits); + rsu->setIncrements(inc_step, inc_page); + rsu->setRange(min, max); + rsu->setProgrammatically = false; + if (add_slider) { + rsu->addSlider(); + } + if(!overwrite_widget){ + rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter")); + } + return dynamic_cast<Gtk::Widget *> (rsu); + } else { + return NULL; } - - rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter")); - - return dynamic_cast<Gtk::Widget *> (rsu); } void diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h index cc2c4f3d6..0ef28650a 100644 --- a/src/live_effects/parameter/parameter.h +++ b/src/live_effects/parameter/parameter.h @@ -102,7 +102,8 @@ public: const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, - gdouble default_value = 1.0); + gdouble default_value = 1.0, + bool no_widget = false); virtual ~ScalarParam(); virtual bool param_readSVGValue(const gchar * strvalue); @@ -117,6 +118,7 @@ public: void addSlider(bool add_slider_widget) { add_slider = add_slider_widget; }; + void param_overwrite_widget(bool overwrite_widget); virtual Gtk::Widget * param_newWidget(); inline operator gdouble() const { return value; }; @@ -131,6 +133,8 @@ protected: double inc_step; double inc_page; bool add_slider; + bool overwrite_widget; + bool hide_widget; private: ScalarParam(const ScalarParam&); diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp index 4c4d2cd9c..ca3471b29 100644 --- a/src/live_effects/parameter/point.cpp +++ b/src/live_effects/parameter/point.cpp @@ -25,9 +25,11 @@ namespace LivePathEffect { PointParam::PointParam( const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, - Effect* effect, const gchar *htip, Geom::Point default_value) + Effect* effect, const gchar *htip, Geom::Point default_value, + bool live_update ) : Parameter(label, tip, key, wr, effect), defvalue(default_value), + liveupdate(live_update), knoth(NULL) { knot_shape = SP_KNOT_SHAPE_DIAMOND; @@ -48,6 +50,12 @@ PointParam::param_set_default() param_setValue(defvalue,true); } +void +PointParam::param_set_liveupdate( bool live_update) +{ + liveupdate = live_update; +} + Geom::Point PointParam::param_get_default() const{ return defvalue; @@ -70,7 +78,7 @@ PointParam::param_setValue(Geom::Point newpoint, bool write) param_write_to_repr(str); g_free(str); } - if(knoth){ + if(knoth && liveupdate){ knoth->update_knots(); } } @@ -166,9 +174,9 @@ PointParamKnotHolderEntity::knot_set(Geom::Point const &p, Geom::Point const &or s = A; } } - pparam->param_setValue(s, true); + pparam->param_setValue(s, this->pparam->liveupdate); SPLPEItem * splpeitem = dynamic_cast<SPLPEItem *>(item); - if(splpeitem){ + if(splpeitem && this->pparam->liveupdate){ sp_lpe_item_update_patheffect(splpeitem, false, false); } } diff --git a/src/live_effects/parameter/point.h b/src/live_effects/parameter/point.h index 471fbc993..4329e0bcd 100644 --- a/src/live_effects/parameter/point.h +++ b/src/live_effects/parameter/point.h @@ -29,8 +29,9 @@ public: const Glib::ustring& key, Inkscape::UI::Widget::Registry* wr, Effect* effect, - const gchar *handle_tip = NULL, - Geom::Point default_value = Geom::Point(0,0) ); // tip for automatically associated on-canvas handle + const gchar *handle_tip = NULL,// tip for automatically associated on-canvas handle + Geom::Point default_value = Geom::Point(0,0), + bool live_update = true ); virtual ~PointParam(); virtual Gtk::Widget * param_newWidget(); @@ -41,6 +42,7 @@ public: void param_setValue(Geom::Point newpoint, bool write = false); void param_set_default(); Geom::Point param_get_default() const; + void param_set_liveupdate(bool live_update); void param_update_default(Geom::Point newpoint); virtual void param_transform_multiply(Geom::Affine const& /*postmul*/, bool /*set*/); @@ -54,6 +56,7 @@ private: PointParam(const PointParam&); PointParam& operator=(const PointParam&); Geom::Point defvalue; + bool liveupdate; KnotHolder *knoth; SPKnotShapeType knot_shape; SPKnotModeType knot_mode; |
