From ea883fa7a8b207aea8a86fb41084da03ee2ef827 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Wed, 5 Aug 2015 21:25:52 +0200 Subject: Fix some transform problems in Bend path. Also refactor a bit the file to simplify it (bzr r14276) --- src/live_effects/lpe-bendpath.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src/live_effects') diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h index 16b8c6137..0871d532e 100644 --- a/src/live_effects/lpe-bendpath.h +++ b/src/live_effects/lpe-bendpath.h @@ -39,9 +39,8 @@ public: virtual void resetDefaults(SPItem const* item); - -private: PathParam bend_path; +private: ScalarParam prop_scale; BoolParam scale_y_rel; BoolParam vertical_pattern; -- cgit v1.2.3 From 98e57f9888244c7bb7c1e528f4d9d0feca935d19 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 6 Aug 2015 23:42:52 +0200 Subject: Refactor BSPline and Spiro to remove duplicated functions (bzr r14280) --- src/live_effects/lpe-bspline.cpp | 239 ++++++++++++++++++--------------------- src/live_effects/lpe-bspline.h | 13 +-- src/live_effects/lpe-spiro.cpp | 16 +-- src/live_effects/lpe-spiro.h | 2 + 4 files changed, 120 insertions(+), 150 deletions(-) (limited to 'src/live_effects') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 6575700c7..d2da33aa9 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -20,6 +20,8 @@ const double HANDLE_CUBIC_GAP = 0.01; const double NO_POWER = 0.0; const double DEFAULT_START_POWER = 0.3334; const double DEFAULT_END_POWER = 0.6667; +Geom::PathVector hp; +void sp_bspline_drawHandle(Geom::Point p, double helper_size); LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : Effect(lpeobject), @@ -67,15 +69,115 @@ void LPEBSpline::doOnApply(SPLPEItem const* lpeitem) } } +void +LPEBSpline::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) +{ + hp_vec.push_back(hp); +} + +Gtk::Widget *LPEBSpline::newWidget() +{ + // use manage here, because after deletion of Effect object, others might + // still be pointing to this widget. + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); + + vbox->set_border_width(5); + std::vector::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter *param = *it; + Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); + if (param->param_key == "weight") { + Gtk::HBox * buttons = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::Button *default_weight = + Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight")))); + default_weight->signal_clicked() + .connect(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight)); + buttons->pack_start(*default_weight, true, true, 2); + Gtk::Button *make_cusp = + Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp")))); + make_cusp->signal_clicked() + .connect(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp)); + buttons->pack_start(*make_cusp, true, true, 2); + vbox->pack_start(*buttons, true, true, 2); + } + if (param->param_key == "weight" || param->param_key == "steps") { + Inkscape::UI::Widget::Scalar *widg_registered = + Gtk::manage(dynamic_cast(widg)); + widg_registered->signal_value_changed() + .connect(sigc::mem_fun(*this, &LPEBSpline::toWeight)); + widg = dynamic_cast(widg_registered); + if (widg) { + Gtk::HBox * hbox_weight_steps = dynamic_cast(widg); + std::vector< Gtk::Widget* > childList = hbox_weight_steps->get_children(); + Gtk::Entry* entry_widget = dynamic_cast(childList[1]); + entry_widget->set_width_chars(6); + } + } + if (param->param_key == "only_selected") { + Gtk::CheckButton *widg_registered = + Gtk::manage(dynamic_cast(widg)); + widg = dynamic_cast(widg_registered); + } + if (param->param_key == "ignore_cusp") { + Gtk::CheckButton *widg_registered = + Gtk::manage(dynamic_cast(widg)); + widg = dynamic_cast(widg_registered); + } + Glib::ustring *tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + + ++it; + } + return dynamic_cast(vbox); +} + +void LPEBSpline::toDefaultWeight() +{ + changeWeight(DEFAULT_START_POWER); +} + +void LPEBSpline::toMakeCusp() +{ + changeWeight(NO_POWER); +} + +void LPEBSpline::toWeight() +{ + changeWeight(weight); +} + +void LPEBSpline::changeWeight(double weight_ammount) +{ + SPPath *path = dynamic_cast(sp_lpe_item); + if(path) { + SPCurve *curve = path->get_curve_for_edit(); + doBSplineFromWidget(curve, weight_ammount); + gchar *str = sp_svg_write_path(curve->get_pathvector()); + path->getRepr()->setAttribute("inkscape:original-d", str); + } +} + void LPEBSpline::doEffect(SPCurve *curve) { + sp_bspline_do_effect(curve, helper_size); +} +void sp_bspline_do_effect(SPCurve *curve, double helper_size) +{ if (curve->get_segment_count() < 1) { return; } - // Make copy of old path as it is changed during processing Geom::PathVector const original_pathv = curve->get_pathvector(); - curve->reset(); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); @@ -99,20 +201,6 @@ void LPEBSpline::doEffect(SPCurve *curve) Geom::D2 sbasis_out; Geom::D2 sbasis_helper; Geom::CubicBezier const *cubic = NULL; - if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the - // closing line segment has zerolength. - 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(); - } - } curve_n->moveto(curve_it1->initialPoint()); while (curve_it1 != curve_endit) { SPCurve *in = new SPCurve(); @@ -209,12 +297,11 @@ void LPEBSpline::doEffect(SPCurve *curve) curve_n->curveto(point_at1, point_at2, node); } if(!are_near(node,curve_it1->finalPoint()) && helper_size > 0.0) { - drawHandle(node, helper_size); + sp_bspline_drawHandle(node, helper_size); } ++curve_it1; ++curve_it2; } - //y cerramos la curva if (path_it->closed()) { curve_n->closepath_current(); } @@ -228,8 +315,8 @@ void LPEBSpline::doEffect(SPCurve *curve) } } -void -LPEBSpline::drawHandle(Geom::Point p, double helper_size) + +void sp_bspline_drawHandle(Geom::Point p, double helper_size) { char const * svgd = "M 1,0.5 A 0.5,0.5 0 0 1 0.5,1 0.5,0.5 0 0 1 0,0.5 0.5,0.5 0 0 1 0.5,0 0.5,0.5 0 0 1 1,0.5 Z"; Geom::PathVector pathv = sp_svg_read_pathv(svgd); @@ -240,104 +327,6 @@ LPEBSpline::drawHandle(Geom::Point p, double helper_size) hp.push_back(pathv[0]); } -void -LPEBSpline::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec) -{ - hp_vec.push_back(hp); -} - -Gtk::Widget *LPEBSpline::newWidget() -{ - // use manage here, because after deletion of Effect object, others might - // still be pointing to this widget. - Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); - - vbox->set_border_width(5); - std::vector::iterator it = param_vector.begin(); - while (it != param_vector.end()) { - if ((*it)->widget_is_visible) { - Parameter *param = *it; - Gtk::Widget *widg = dynamic_cast(param->param_newWidget()); - if (param->param_key == "weight") { - Gtk::HBox * buttons = Gtk::manage(new Gtk::HBox(true,0)); - Gtk::Button *default_weight = - Gtk::manage(new Gtk::Button(Glib::ustring(_("Default weight")))); - default_weight->signal_clicked() - .connect(sigc::mem_fun(*this, &LPEBSpline::toDefaultWeight)); - buttons->pack_start(*default_weight, true, true, 2); - Gtk::Button *make_cusp = - Gtk::manage(new Gtk::Button(Glib::ustring(_("Make cusp")))); - make_cusp->signal_clicked() - .connect(sigc::mem_fun(*this, &LPEBSpline::toMakeCusp)); - buttons->pack_start(*make_cusp, true, true, 2); - vbox->pack_start(*buttons, true, true, 2); - } - if (param->param_key == "weight" || param->param_key == "steps") { - Inkscape::UI::Widget::Scalar *widg_registered = - Gtk::manage(dynamic_cast(widg)); - widg_registered->signal_value_changed() - .connect(sigc::mem_fun(*this, &LPEBSpline::toWeight)); - widg = dynamic_cast(widg_registered); - if (widg) { - Gtk::HBox * hbox_weight_steps = dynamic_cast(widg); - std::vector< Gtk::Widget* > childList = hbox_weight_steps->get_children(); - Gtk::Entry* entry_widget = dynamic_cast(childList[1]); - entry_widget->set_width_chars(6); - } - } - if (param->param_key == "only_selected") { - Gtk::CheckButton *widg_registered = - Gtk::manage(dynamic_cast(widg)); - widg = dynamic_cast(widg_registered); - } - if (param->param_key == "ignore_cusp") { - Gtk::CheckButton *widg_registered = - Gtk::manage(dynamic_cast(widg)); - widg = dynamic_cast(widg_registered); - } - Glib::ustring *tip = param->param_getTooltip(); - if (widg) { - vbox->pack_start(*widg, true, true, 2); - if (tip) { - widg->set_tooltip_text(*tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } - } - } - - ++it; - } - return dynamic_cast(vbox); -} - -void LPEBSpline::toDefaultWeight() -{ - changeWeight(DEFAULT_START_POWER); -} - -void LPEBSpline::toMakeCusp() -{ - changeWeight(NO_POWER); -} - -void LPEBSpline::toWeight() -{ - changeWeight(weight); -} - -void LPEBSpline::changeWeight(double weight_ammount) -{ - SPPath *path = dynamic_cast(sp_lpe_item); - if(path) { - SPCurve *curve = path->get_curve_for_edit(); - doBSplineFromWidget(curve, weight_ammount); - gchar *str = sp_svg_write_path(curve->get_pathvector()); - path->getRepr()->setAttribute("inkscape:original-d", str); - } -} - void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) { using Geom::X; @@ -367,20 +356,6 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) Geom::D2 sbasis_in; Geom::D2 sbasis_out; Geom::CubicBezier const *cubic = NULL; - if (path_it->closed()) { - // if the path is closed, maybe we have to stop a bit earlier because the - // closing line segment has zerolength. - 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(); - } - } curve_n->moveto(curve_it1->initialPoint()); while (curve_it1 != curve_endit) { SPCurve *in = new SPCurve(); diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h index fc0f66353..033e85cf0 100644 --- a/src/live_effects/lpe-bspline.h +++ b/src/live_effects/lpe-bspline.h @@ -25,14 +25,13 @@ public: virtual void doOnApply(SPLPEItem const* lpeitem); virtual void doEffect(SPCurve *curve); virtual void doBeforeEffect (SPLPEItem const* lpeitem); - void drawHandle(Geom::Point p, double radiusHelperNodes); - virtual void doBSplineFromWidget(SPCurve *curve, double value); + void doBSplineFromWidget(SPCurve *curve, double value); void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector &hp_vec); virtual Gtk::Widget *newWidget(); - virtual void changeWeight(double weightValue); - virtual void toDefaultWeight(); - virtual void toMakeCusp(); - virtual void toWeight(); + void changeWeight(double weightValue); + void toDefaultWeight(); + void toMakeCusp(); + void toWeight(); // TODO make this private ScalarParam steps; @@ -42,12 +41,12 @@ private: BoolParam ignore_cusp; BoolParam only_selected; ScalarParam weight; - Geom::PathVector hp; LPEBSpline(const LPEBSpline &); LPEBSpline &operator=(const LPEBSpline &); }; +void sp_bspline_do_effect(SPCurve *curve, double helper_size); } //namespace LivePathEffect } //namespace Inkscape diff --git a/src/live_effects/lpe-spiro.cpp b/src/live_effects/lpe-spiro.cpp index eefd25c7d..0d42596b2 100644 --- a/src/live_effects/lpe-spiro.cpp +++ b/src/live_effects/lpe-spiro.cpp @@ -37,6 +37,10 @@ LPESpiro::~LPESpiro() void LPESpiro::doEffect(SPCurve * curve) { + sp_spiro_do_effect(curve); +} + +void sp_spiro_do_effect(SPCurve *curve){ using Geom::X; using Geom::Y; @@ -54,7 +58,7 @@ LPESpiro::doEffect(SPCurve * curve) // start of path { - Geom::Point p = path_it->front().pointAt(0); + Geom::Point p = path_it->initialPoint(); path[ip].x = p[X]; path[ip].y = p[Y]; path[ip].ty = '{' ; // for closed paths, this is overwritten @@ -64,17 +68,7 @@ LPESpiro::doEffect(SPCurve * curve) // midpoints Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing 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. - 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_it2 != curve_endit ) { diff --git a/src/live_effects/lpe-spiro.h b/src/live_effects/lpe-spiro.h index edce42280..c8aba53d9 100644 --- a/src/live_effects/lpe-spiro.h +++ b/src/live_effects/lpe-spiro.h @@ -27,6 +27,8 @@ private: LPESpiro& operator=(const LPESpiro&); }; +void sp_spiro_do_effect(SPCurve *curve); + }; //namespace LivePathEffect }; //namespace Inkscape -- cgit v1.2.3 From a2c91998644ae5a8096b0ee53beea16bee0a7ac7 Mon Sep 17 00:00:00 2001 From: Alvin Penner Date: Sat, 8 Aug 2015 18:08:49 -0400 Subject: for spiro converters, close path only after last segment. (Bug 1473641) Fixed bugs: - https://launchpad.net/bugs/1473641 (bzr r14285) --- src/live_effects/spiro-converters.cpp | 32 ++++++++++++++++++++------------ src/live_effects/spiro-converters.h | 24 ++++++++++++------------ src/live_effects/spiro.cpp | 15 ++++++++------- 3 files changed, 40 insertions(+), 31 deletions(-) (limited to 'src/live_effects') diff --git a/src/live_effects/spiro-converters.cpp b/src/live_effects/spiro-converters.cpp index f116d5256..ee214704c 100644 --- a/src/live_effects/spiro-converters.cpp +++ b/src/live_effects/spiro-converters.cpp @@ -21,43 +21,49 @@ namespace Spiro { void -ConverterSPCurve::moveto(double x, double y, bool is_open) +ConverterSPCurve::moveto(double x, double y) { if ( IS_FINITE(x) && IS_FINITE(y) ) { _curve.moveto(x, y); - if (!is_open) { - _curve.closepath(); - } } else { SPIRO_G_MESSAGE("Spiro: moveto not finite"); } } void -ConverterSPCurve::lineto(double x, double y) +ConverterSPCurve::lineto(double x, double y, bool close_last) { if ( IS_FINITE(x) && IS_FINITE(y) ) { _curve.lineto(x, y); + if (close_last) { + _curve.closepath(); + } } else { SPIRO_G_MESSAGE("Spiro: lineto not finite"); } } void -ConverterSPCurve::quadto(double xm, double ym, double x3, double y3) +ConverterSPCurve::quadto(double xm, double ym, double x3, double y3, bool close_last) { if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) { _curve.quadto(xm, ym, x3, y3); + if (close_last) { + _curve.closepath(); + } } else { SPIRO_G_MESSAGE("Spiro: quadto not finite"); } } void -ConverterSPCurve::curveto(double x1, double y1, double x2, double y2, double x3, double y3) +ConverterSPCurve::curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last) { if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) { _curve.curveto(x1, y1, x2, y2, x3, y3); + if (close_last) { + _curve.closepath(); + } } else { SPIRO_G_MESSAGE("Spiro: curveto not finite"); } @@ -71,41 +77,43 @@ ConverterPath::ConverterPath(Geom::Path &path) } void -ConverterPath::moveto(double x, double y, bool is_open) +ConverterPath::moveto(double x, double y) { if ( IS_FINITE(x) && IS_FINITE(y) ) { _path.start(Geom::Point(x, y)); - _path.close(!is_open); } else { SPIRO_G_MESSAGE("spiro moveto not finite"); } } void -ConverterPath::lineto(double x, double y) +ConverterPath::lineto(double x, double y, bool close_last) { if ( IS_FINITE(x) && IS_FINITE(y) ) { _path.appendNew( Geom::Point(x, y) ); + _path.close(close_last); } else { SPIRO_G_MESSAGE("spiro lineto not finite"); } } void -ConverterPath::quadto(double xm, double ym, double x3, double y3) +ConverterPath::quadto(double xm, double ym, double x3, double y3, bool close_last) { if ( IS_FINITE(xm) && IS_FINITE(ym) && IS_FINITE(x3) && IS_FINITE(y3) ) { _path.appendNew(Geom::Point(xm, ym), Geom::Point(x3, y3)); + _path.close(close_last); } else { SPIRO_G_MESSAGE("spiro quadto not finite"); } } void -ConverterPath::curveto(double x1, double y1, double x2, double y2, double x3, double y3) +ConverterPath::curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last) { if ( IS_FINITE(x1) && IS_FINITE(y1) && IS_FINITE(x2) && IS_FINITE(y2) ) { _path.appendNew(Geom::Point(x1, y1), Geom::Point(x2, y2), Geom::Point(x3, y3)); + _path.close(close_last); } else { SPIRO_G_MESSAGE("spiro curveto not finite"); } diff --git a/src/live_effects/spiro-converters.h b/src/live_effects/spiro-converters.h index 90855d2d6..6182a5dcd 100644 --- a/src/live_effects/spiro-converters.h +++ b/src/live_effects/spiro-converters.h @@ -11,10 +11,10 @@ public: ConverterBase() {}; virtual ~ConverterBase() {}; - virtual void moveto(double x, double y, bool is_open) = 0; - virtual void lineto(double x, double y) = 0; - virtual void quadto(double x1, double y1, double x2, double y2) = 0; - virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3) = 0; + virtual void moveto(double x, double y) = 0; + virtual void lineto(double x, double y, bool close_last) = 0; + virtual void quadto(double x1, double y1, double x2, double y2, bool close_last) = 0; + virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last) = 0; }; @@ -27,10 +27,10 @@ public: : _curve(curve) {} - virtual void moveto(double x, double y, bool is_open); - virtual void lineto(double x, double y); - virtual void quadto(double x1, double y1, double x2, double y2); - virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3); + virtual void moveto(double x, double y); + virtual void lineto(double x, double y, bool close_last); + virtual void quadto(double x1, double y1, double x2, double y2, bool close_last); + virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last); private: SPCurve &_curve; @@ -47,10 +47,10 @@ class ConverterPath : public ConverterBase { public: ConverterPath(Geom::Path &path); - virtual void moveto(double x, double y, bool is_open); - virtual void lineto(double x, double y); - virtual void quadto(double x1, double y1, double x2, double y2); - virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3); + virtual void moveto(double x, double y); + virtual void lineto(double x, double y, bool close_last); + virtual void quadto(double x1, double y1, double x2, double y2, bool close_last); + virtual void curveto(double x1, double y1, double x2, double y2, double x3, double y3, bool close_last); private: Geom::Path &_path; diff --git a/src/live_effects/spiro.cpp b/src/live_effects/spiro.cpp index 46e53a0da..0ac2815bf 100644 --- a/src/live_effects/spiro.cpp +++ b/src/live_effects/spiro.cpp @@ -847,13 +847,13 @@ solve_spiro(spiro_seg *s, const int nseg) static void spiro_seg_to_otherpath(const double ks[4], double x0, double y0, double x1, double y1, - ConverterBase &bc, int depth) + ConverterBase &bc, int depth, bool close_last) { double bend = fabs(ks[0]) + fabs(.5 * ks[1]) + fabs(.125 * ks[2]) + fabs((1./48) * ks[3]); if (!(bend > 1e-8)) { - bc.lineto(x1, y1); + bc.lineto(x1, y1, close_last); } else { double seg_ch = hypot(x1 - x0, y1 - y0); double seg_th = atan2(y1 - y0, x1 - x0); @@ -876,7 +876,7 @@ spiro_seg_to_otherpath(const double ks[4], vl = (scale * (1./3)) * sin(th_even - th_odd); ur = (scale * (1./3)) * cos(th_even + th_odd); vr = (scale * (1./3)) * sin(th_even + th_odd); - bc.curveto(x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1); + bc.curveto(x0 + ul, y0 + vl, x1 - ur, y1 - vr, x1, y1, close_last); } else { /* subdivide */ double ksub[4]; @@ -895,11 +895,11 @@ spiro_seg_to_otherpath(const double ks[4], integrate_spiro(ksub, xysub); xmid = x0 + cth * xysub[0] - sth * xysub[1]; ymid = y0 + cth * xysub[1] + sth * xysub[0]; - spiro_seg_to_otherpath(ksub, x0, y0, xmid, ymid, bc, depth + 1); + spiro_seg_to_otherpath(ksub, x0, y0, xmid, ymid, bc, depth + 1, false); ksub[0] += .25 * ks[1] + (1./384) * ks[3]; ksub[1] += .125 * ks[2]; ksub[2] += (1./16) * ks[3]; - spiro_seg_to_otherpath(ksub, xmid, ymid, x1, y1, bc, depth + 1); + spiro_seg_to_otherpath(ksub, xmid, ymid, x1, y1, bc, depth + 1, close_last); } } } @@ -933,9 +933,10 @@ spiro_to_otherpath(const spiro_seg *s, int n, ConverterBase &bc) double y1 = s[i + 1].y; if (i == 0) { - bc.moveto(x0, y0, s[0].ty == '{'); + bc.moveto(x0, y0); } - spiro_seg_to_otherpath(s[i].ks, x0, y0, x1, y1, bc, 0); + // on the last segment, set the 'close_last' flag if path is closed + spiro_seg_to_otherpath(s[i].ks, x0, y0, x1, y1, bc, 0, (nsegs == n) && (i == n - 1)); } } -- cgit v1.2.3 From 439df6b61c37528b2ca6210f77a4bb50aa692906 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 14 Aug 2015 10:20:45 +0200 Subject: A bit more refactor of BSPline tool. Still the bug duplicating end node :( (bzr r14301) --- src/live_effects/lpe-bspline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/live_effects') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index d2da33aa9..019584943 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -16,7 +16,7 @@ namespace Inkscape { namespace LivePathEffect { -const double HANDLE_CUBIC_GAP = 0.01; +const double HANDLE_CUBIC_GAP = 0.001; const double NO_POWER = 0.0; const double DEFAULT_START_POWER = 0.3334; const double DEFAULT_END_POWER = 0.6667; -- cgit v1.2.3 From 87dcc5957e93f5cf891bc2032c759b98df44f17f Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sat, 22 Aug 2015 19:07:52 +0200 Subject: Simplify a bit BSpline code (bzr r14316) --- src/live_effects/lpe-bspline.cpp | 83 +++++++++++----------------------------- 1 file changed, 22 insertions(+), 61 deletions(-) (limited to 'src/live_effects') diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index 019584943..0cae1dcb6 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -365,91 +365,52 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weight_ammount) point_at0 = in->first_segment()->initialPoint(); point_at3 = in->first_segment()->finalPoint(); sbasis_in = in->first_segment()->toSBasis(); - if (!only_selected) { - if (cubic) { - if (!ignore_cusp || !Geom::are_near((*cubic)[1], point_at0)) { + if (cubic) { + if (!ignore_cusp || !Geom::are_near((*cubic)[1], point_at0)) { + if (isNodePointSelected(point_at0) || !only_selected) { point_at1 = sbasis_in.valueAt(weight_ammount); if (weight_ammount != NO_POWER) { point_at1 = Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP); } } else { - point_at1 = in->first_segment()->initialPoint(); - } - if (!ignore_cusp || !Geom::are_near((*cubic)[2], point_at3)) { - point_at2 = sbasis_in.valueAt(1 - weight_ammount); - if (weight_ammount != NO_POWER) { - point_at2 = - Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP); - } - } else { - point_at2 = in->first_segment()->finalPoint(); + point_at1 = (*cubic)[1]; } } else { - if (!ignore_cusp && weight_ammount != NO_POWER) { - point_at1 = sbasis_in.valueAt(weight_ammount); - if (weight_ammount != NO_POWER) { - point_at1 = - Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP); - } + point_at1 = in->first_segment()->initialPoint(); + } + if (!ignore_cusp || !Geom::are_near((*cubic)[2], point_at3)) { + if (isNodePointSelected(point_at3) || !only_selected) { point_at2 = sbasis_in.valueAt(1 - weight_ammount); if (weight_ammount != NO_POWER) { point_at2 = Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP); } } else { - point_at1 = in->first_segment()->initialPoint(); - point_at2 = in->first_segment()->finalPoint(); + point_at2 = (*cubic)[2]; } + } else { + point_at2 = in->first_segment()->finalPoint(); } } else { - if (cubic) { - if (!ignore_cusp || !Geom::are_near((*cubic)[1], point_at0)) { - if (isNodePointSelected(point_at0)) { - point_at1 = sbasis_in.valueAt(weight_ammount); - if (weight_ammount != NO_POWER) { - point_at1 = - Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP); - } - } else { - point_at1 = (*cubic)[1]; - } + if (!ignore_cusp && weight_ammount != NO_POWER) { + if (isNodePointSelected(point_at0) || !only_selected) { + point_at1 = sbasis_in.valueAt(weight_ammount); + point_at1 = + Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP); } else { point_at1 = in->first_segment()->initialPoint(); } - if (!ignore_cusp || !Geom::are_near((*cubic)[2], point_at3)) { - if (isNodePointSelected(point_at3)) { - point_at2 = sbasis_in.valueAt(1 - weight_ammount); - if (weight_ammount != NO_POWER) { - point_at2 = - Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP); - } - } else { - point_at2 = (*cubic)[2]; - } + if (isNodePointSelected(point_at3) || !only_selected) { + point_at2 = sbasis_in.valueAt(weight_ammount); + point_at2 = + Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP); } else { point_at2 = in->first_segment()->finalPoint(); } } else { - if (!ignore_cusp && weight_ammount != NO_POWER) { - if (isNodePointSelected(point_at0)) { - point_at1 = sbasis_in.valueAt(weight_ammount); - point_at1 = - Geom::Point(point_at1[X] + HANDLE_CUBIC_GAP, point_at1[Y] + HANDLE_CUBIC_GAP); - } else { - point_at1 = in->first_segment()->initialPoint(); - } - if (isNodePointSelected(point_at3)) { - point_at2 = sbasis_in.valueAt(weight_ammount); - point_at2 = - Geom::Point(point_at2[X] + HANDLE_CUBIC_GAP, point_at2[Y] + HANDLE_CUBIC_GAP); - } else { - point_at2 = in->first_segment()->finalPoint(); - } - } else { - point_at1 = in->first_segment()->initialPoint(); - point_at2 = in->first_segment()->finalPoint(); - } + point_at1 = in->first_segment()->initialPoint(); + point_at2 = in->first_segment()->finalPoint(); } } in->reset(); -- cgit v1.2.3