diff options
| author | Jabiertxof <jabier.arraiza@marker.es> | 2019-07-16 14:37:19 +0000 |
|---|---|---|
| committer | Jabier Arraiza <jabier.arraiza@marker.es> | 2019-07-19 21:33:23 +0000 |
| commit | e2f4af7eb9d6a497308925930e89d2a403c3a5c9 (patch) | |
| tree | f1abd09c7996dc93dbb09d79b91e70e3a5f0847d | |
| parent | Fix maren pointed bugs (diff) | |
| download | inkscape-e2f4af7eb9d6a497308925930e89d2a403c3a5c9.tar.gz inkscape-e2f4af7eb9d6a497308925930e89d2a403c3a5c9.zip | |
Improvemets to power pencil
| -rw-r--r-- | src/live_effects/effect.cpp | 3 | ||||
| -rw-r--r-- | src/live_effects/effect.h | 1 | ||||
| -rw-r--r-- | src/live_effects/lpe-powerstroke.cpp | 16 | ||||
| -rw-r--r-- | src/live_effects/lpe-powerstroke.h | 17 | ||||
| -rwxr-xr-x | src/object/sp-lpe-item.cpp | 2 | ||||
| -rw-r--r-- | src/ui/toolbar/pencil-toolbar.cpp | 195 | ||||
| -rw-r--r-- | src/ui/toolbar/pencil-toolbar.h | 11 | ||||
| -rw-r--r-- | src/ui/tools/freehand-base.cpp | 48 | ||||
| -rw-r--r-- | src/ui/tools/pencil-tool.cpp | 109 | ||||
| -rw-r--r-- | src/ui/tools/pencil-tool.h | 3 |
10 files changed, 213 insertions, 192 deletions
diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 03f482190..b4aa42e0e 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -1067,7 +1067,7 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) neweffect = nullptr; break; } - + if (neweffect) { neweffect->readallParameters(lpeobj->getRepr()); } @@ -1262,6 +1262,7 @@ void Effect::doOnApply_impl(SPLPEItem const* lpeitem) sp_lpe_item = const_cast<SPLPEItem *>(lpeitem); doOnApply(lpeitem); setReady(); + has_exception = false; } void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index 9cdb17c02..725aae6c4 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -113,6 +113,7 @@ public: void addHandles(KnotHolder *knotholder, SPItem *item); std::vector<Geom::PathVector> getCanvasIndicators(SPLPEItem const* lpeitem); void update_helperpath(); + bool has_exception; inline bool providesOwnFlashPaths() const { return provides_own_flash_paths || show_orig_path; diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index e7700ba78..0a13e4661 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -133,22 +133,6 @@ static const Util::EnumData<unsigned> InterpolatorTypeData[] = { }; static const Util::EnumDataConverter<unsigned> InterpolatorTypeConverter(InterpolatorTypeData, sizeof(InterpolatorTypeData)/sizeof(*InterpolatorTypeData)); -enum LineCapType { - LINECAP_BUTT, - LINECAP_SQUARE, - LINECAP_ROUND, - LINECAP_PEAK, - LINECAP_ZERO_WIDTH -}; -static const Util::EnumData<unsigned> LineCapTypeData[] = { - {LINECAP_BUTT, N_("Butt"), "butt"}, - {LINECAP_SQUARE, N_("Square"), "square"}, - {LINECAP_ROUND, N_("Round"), "round"}, - {LINECAP_PEAK, N_("Peak"), "peak"}, - {LINECAP_ZERO_WIDTH, N_("Zero width"), "zerowidth"} -}; -static const Util::EnumDataConverter<unsigned> LineCapTypeConverter(LineCapTypeData, sizeof(LineCapTypeData)/sizeof(*LineCapTypeData)); - enum LineJoinType { LINEJOIN_BEVEL, LINEJOIN_ROUND, diff --git a/src/live_effects/lpe-powerstroke.h b/src/live_effects/lpe-powerstroke.h index 9ac4a65a5..bbb5a88a9 100644 --- a/src/live_effects/lpe-powerstroke.h +++ b/src/live_effects/lpe-powerstroke.h @@ -21,6 +21,23 @@ namespace Inkscape { namespace LivePathEffect { +enum LineCapType { + LINECAP_BUTT, + LINECAP_SQUARE, + LINECAP_ROUND, + LINECAP_PEAK, + LINECAP_ZERO_WIDTH +}; + +static const Util::EnumData<unsigned> LineCapTypeData[] = { + {LINECAP_BUTT, N_("Butt"), "butt"}, + {LINECAP_SQUARE, N_("Square"), "square"}, + {LINECAP_ROUND, N_("Round"), "round"}, + {LINECAP_PEAK, N_("Peak"), "peak"}, + {LINECAP_ZERO_WIDTH, N_("Zero width"), "zerowidth"} +}; +static const Util::EnumDataConverter<unsigned> LineCapTypeConverter(LineCapTypeData, sizeof(LineCapTypeData)/sizeof(*LineCapTypeData)); + class LPEPowerStroke : public Effect { public: LPEPowerStroke(LivePathEffectObject *lpeobject); diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index 2e1e2c9f0..6be373925 100755 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -250,6 +250,7 @@ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape: try { lpe->doEffect(curve); + lpe->has_exception = false; } catch (std::exception & e) { @@ -258,6 +259,7 @@ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape: SP_ACTIVE_DESKTOP->messageStack()->flash( Inkscape::WARNING_MESSAGE, _("An exception occurred during execution of the Path Effect.") ); } + lpe->has_exception = true; return false; } diff --git a/src/ui/toolbar/pencil-toolbar.cpp b/src/ui/toolbar/pencil-toolbar.cpp index 54463336a..cce9fefc9 100644 --- a/src/ui/toolbar/pencil-toolbar.cpp +++ b/src/ui/toolbar/pencil-toolbar.cpp @@ -104,88 +104,76 @@ PencilToolbar::PencilToolbar(SPDesktop *desktop, add(* Gtk::manage(new Gtk::SeparatorToolItem())); - if (pencil_mode) { - /* Use pressure */ - { - _pressure_item = add_toggle_button(_("Use pressure input"), _("Use pressure input")); - _pressure_item->set_icon_name(INKSCAPE_ICON("draw-use-pressure")); - bool pressure = prefs->getBool(freehand_tool_name() + "/pressure", false); - _pressure_item->set_active(pressure); - _pressure_item->signal_toggled().connect(sigc::mem_fun(*this, &PencilToolbar::use_pencil_pressure)); - } - /* min pressure */ - { - auto minpressure_val = prefs->getDouble("/tools/freehand/pencil/minpressure", 10); - _minpressure_adj = Gtk::Adjustment::create(minpressure_val, 0, 100, 1, 0); - _minpressure = Gtk::manage(new UI::Widget::SpinButtonToolItem("pencil-minpressure", _("Min:"), _minpressure_adj, 0, 0)); - _minpressure->set_tooltip_text(_("Min percent of pressure")); - _minpressure->set_focus_widget(Glib::wrap(GTK_WIDGET(desktop->canvas))); - _minpressure_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PencilToolbar::minpressure_value_changed)); - add(*_minpressure); - } - /* max pressure */ - { - auto maxpressure_val = prefs->getDouble("/tools/freehand/pencil/maxpressure", 40); - _maxpressure_adj = Gtk::Adjustment::create(maxpressure_val, 0, 100, 1, 0); - _maxpressure = Gtk::manage(new UI::Widget::SpinButtonToolItem("pencil-maxpressure", _("Max:"), _maxpressure_adj, 0, 0)); - _maxpressure->set_tooltip_text(_("Max percent of pressure")); - _maxpressure->set_focus_widget(Glib::wrap(GTK_WIDGET(desktop->canvas))); - _maxpressure_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PencilToolbar::maxpressure_value_changed)); - add(*_maxpressure); - } - /* pressure steps */ - { - auto pressurestep_val = prefs->getDouble("/tools/freehand/pencil/pressurestep", 2.0); - _pressurestep_adj = Gtk::Adjustment::create(pressurestep_val, 0.0, 100.0, 1.0, 0.0); - _pressurestep = Gtk::manage( - new UI::Widget::SpinButtonToolItem("pencil-pressurestep", _("Knot gap:"), _pressurestep_adj, 1.0, 2)); - _pressurestep->set_tooltip_text(_("Pressure steps for new knot")); - _pressurestep->set_focus_widget(Glib::wrap(GTK_WIDGET(desktop->canvas))); - _pressurestep_adj->signal_value_changed().connect( - sigc::mem_fun(*this, &PencilToolbar::pressurestep_value_changed)); - add(*_pressurestep); - } - + /* Use pressure */ + { + _pressure_item = add_toggle_button(_("Use pressure input"), _("Use pressure input")); + _pressure_item->set_icon_name(INKSCAPE_ICON("draw-use-pressure")); + bool pressure = prefs->getBool(freehand_tool_name() + "/pressure", false); + _pressure_item->set_active(pressure); + _pressure_item->signal_toggled().connect(sigc::mem_fun(*this, &PencilToolbar::use_pencil_pressure)); + } + /* min pressure */ + { + auto minpressure_val = prefs->getDouble("/tools/freehand/pencil/minpressure", 10); + _minpressure_adj = Gtk::Adjustment::create(minpressure_val, 0, 100, 1, 0); + _minpressure = Gtk::manage(new UI::Widget::SpinButtonToolItem("pencil-minpressure", _("Min:"), _minpressure_adj, 0, 0)); + _minpressure->set_tooltip_text(_("Min percent of pressure")); + _minpressure->set_focus_widget(Glib::wrap(GTK_WIDGET(desktop->canvas))); + _minpressure_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PencilToolbar::minpressure_value_changed)); + add(*_minpressure); + } + /* max pressure */ + { + auto maxpressure_val = prefs->getDouble("/tools/freehand/pencil/maxpressure", 40); + _maxpressure_adj = Gtk::Adjustment::create(maxpressure_val, 0, 100, 1, 0); + _maxpressure = Gtk::manage(new UI::Widget::SpinButtonToolItem("pencil-maxpressure", _("Max:"), _maxpressure_adj, 0, 0)); + _maxpressure->set_tooltip_text(_("Max percent of pressure")); + _maxpressure->set_focus_widget(Glib::wrap(GTK_WIDGET(desktop->canvas))); + _maxpressure_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PencilToolbar::maxpressure_value_changed)); + add(*_maxpressure); + } - add(* Gtk::manage(new Gtk::SeparatorToolItem())); + add(* Gtk::manage(new Gtk::SeparatorToolItem())); - /* Tolerance */ - { - std::vector<Glib::ustring> labels = {_("(many nodes, rough)"), _("(default)"), "", "", "", "", _("(few nodes, smooth)")}; - std::vector<double> values = { 1, 10, 20, 30, 50, 75, 100}; - auto tolerance_val = prefs->getDouble("/tools/freehand/pencil/tolerance", 3.0); - _tolerance_adj = Gtk::Adjustment::create(tolerance_val, 1, 100.0, 0.5, 1.0); - auto tolerance_item = Gtk::manage(new UI::Widget::SpinButtonToolItem("pencil-tolerance", _("Smoothing:"), _tolerance_adj, 1, 2)); - tolerance_item->set_tooltip_text(_("How much smoothing (simplifying) is applied to the line")); - tolerance_item->set_custom_numeric_menu_data(values, labels); - tolerance_item->set_focus_widget(Glib::wrap(GTK_WIDGET(desktop->canvas))); - _tolerance_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PencilToolbar::tolerance_value_changed)); - // ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - add(*tolerance_item); - } + /* Tolerance */ + { + std::vector<Glib::ustring> labels = {_("(many nodes, rough)"), _("(default)"), "", "", "", "", _("(few nodes, smooth)")}; + std::vector<double> values = { 1, 10, 20, 30, 50, 75, 100}; + auto tolerance_val = prefs->getDouble("/tools/freehand/pencil/tolerance", 3.0); + _tolerance_adj = Gtk::Adjustment::create(tolerance_val, 1, 100.0, 0.5, 1.0); + auto tolerance_item = Gtk::manage(new UI::Widget::SpinButtonToolItem("pencil-tolerance", _("Smoothing:"), _tolerance_adj, 1, 2)); + tolerance_item->set_tooltip_text(_("How much smoothing (simplifying) is applied to the line")); + tolerance_item->set_custom_numeric_menu_data(values, labels); + tolerance_item->set_focus_widget(Glib::wrap(GTK_WIDGET(desktop->canvas))); + _tolerance_adj->signal_value_changed().connect(sigc::mem_fun(*this, &PencilToolbar::tolerance_value_changed)); + // ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); + add(*tolerance_item); + } - /* LPE simplify based tolerance */ - { - _simplify = add_toggle_button(_("LPE based interactive simplify"), - _("LPE based interactive simplify")); - _simplify->set_icon_name(INKSCAPE_ICON("interactive_simplify")); - _simplify->set_active(prefs->getInt("/tools/freehand/pencil/simplify", 0)); - _simplify->signal_toggled().connect(sigc::mem_fun(*this, &PencilToolbar::simplify_lpe)); - } + /* powerstoke */ + add_powerstroke_cap(pencil_mode); - /* LPE simplify flatten */ - { - _flatten_simplify = Gtk::manage(new Gtk::ToolButton(_("LPE simplify flatten"))); - _flatten_simplify->set_tooltip_text(_("LPE simplify flatten")); - _flatten_simplify->set_icon_name(INKSCAPE_ICON("flatten")); - _flatten_simplify->signal_clicked().connect(sigc::mem_fun(*this, &PencilToolbar::simplify_flatten)); - add(*_flatten_simplify); - } + /* LPE simplify based tolerance */ + { + _simplify = add_toggle_button(_("LPE based interactive simplify"), + _("LPE based interactive simplify")); + _simplify->set_icon_name(INKSCAPE_ICON("interactive_simplify")); + _simplify->set_active(prefs->getInt("/tools/freehand/pencil/simplify", 0)); + _simplify->signal_toggled().connect(sigc::mem_fun(*this, &PencilToolbar::simplify_lpe)); + } - add(* Gtk::manage(new Gtk::SeparatorToolItem())); + /* LPE simplify flatten */ + { + _flatten_simplify = Gtk::manage(new Gtk::ToolButton(_("LPE simplify flatten"))); + _flatten_simplify->set_tooltip_text(_("LPE simplify flatten")); + _flatten_simplify->set_icon_name(INKSCAPE_ICON("flatten")); + _flatten_simplify->signal_clicked().connect(sigc::mem_fun(*this, &PencilToolbar::simplify_flatten)); + add(*_flatten_simplify); } + add(* Gtk::manage(new Gtk::SeparatorToolItem())); + /* advanced shape options */ add_advanced_shape_options(pencil_mode); @@ -339,17 +327,6 @@ PencilToolbar::maxpressure_value_changed() prefs->setDouble( "/tools/freehand/pencil/maxpressure", _maxpressure_adj->get_value()); } -void PencilToolbar::pressurestep_value_changed() -{ - // quit if run by the attr_changed listener - if (_freeze) { - return; - } - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/freehand/pencil/pressurestep", _pressurestep_adj->get_value()); -} - void PencilToolbar::use_pencil_pressure() { bool pressure = _pressure_item->get_active(); @@ -358,7 +335,7 @@ PencilToolbar::use_pencil_pressure() { if (pressure) { _minpressure->set_visible(true); _maxpressure->set_visible(true); - _pressurestep->set_visible(true); + _cap_item->set_visible(true); _shape_item->set_visible(false); _simplify->set_visible(false); _flatten_simplify->set_visible(false); @@ -371,7 +348,7 @@ PencilToolbar::use_pencil_pressure() { _minpressure->set_visible(false); _maxpressure->set_visible(false); - _pressurestep->set_visible(false); + _cap_item->set_visible(false); _shape_item->set_visible(true); _simplify->set_visible(true); _flatten_simplify->set_visible(true); @@ -434,6 +411,50 @@ PencilToolbar::change_shape() { } void +PencilToolbar::add_powerstroke_cap(bool tool_is_pencil) +{ + /*advanced shape options */ + _cap_item = Gtk::manage(new Gtk::ToolItem()); + auto hbox = Gtk::manage(new Gtk::Box()); + _cap_item->add(*hbox); + + auto label = Gtk::manage(new UI::Widget::LabelToolItem(_("Caps:"))); + hbox->add(*label); + + _cap_combo = Gtk::manage(new Gtk::ComboBoxText()); + + auto prefs = Inkscape::Preferences::get(); + + std::vector<gchar*> powerstroke_cap_items_list = { + const_cast<gchar *>(C_("Cap", "Butt")), + _("Square"), + _("Round"), + _("Peak"), + _("Zero width") + }; + for (auto item:powerstroke_cap_items_list) { + _cap_combo->append(item); + } + + _cap_combo->set_tooltip_text(_("Cap for powerstroke pressure")); + int cap = prefs->getInt( "/live_effects/powerstroke/powerpencilcap", 4); + _cap_combo->set_active( cap ); + + hbox->add(*_cap_combo); + + _cap_combo->signal_changed().connect(sigc::mem_fun(*this, &PencilToolbar::change_cap)); + + add(*_cap_item); +} + +void +PencilToolbar::change_cap() { + auto prefs = Inkscape::Preferences::get(); + auto cap = _cap_combo->get_active_row_number(); + prefs->setInt("/live_effects/powerstroke/powerpencilcap", cap); +} + +void PencilToolbar::simplify_lpe() { bool simplify = _simplify->get_active(); diff --git a/src/ui/toolbar/pencil-toolbar.h b/src/ui/toolbar/pencil-toolbar.h index 9022d32da..42cc64af9 100644 --- a/src/ui/toolbar/pencil-toolbar.h +++ b/src/ui/toolbar/pencil-toolbar.h @@ -53,7 +53,6 @@ private: Gtk::ToggleToolButton *_pressure_item; UI::Widget::SpinButtonToolItem *_minpressure; UI::Widget::SpinButtonToolItem *_maxpressure; - UI::Widget::SpinButtonToolItem *_pressurestep; XML::Node *_repr; Gtk::ToolButton *_flatten_spiro_bspline; @@ -62,6 +61,9 @@ private: Gtk::ToolItem *_shape_item; Gtk::ComboBoxText *_shape_combo; + Gtk::ToolItem *_cap_item; + Gtk::ComboBoxText *_cap_combo; + Gtk::ToggleToolButton *_simplify; @@ -69,7 +71,6 @@ private: Glib::RefPtr<Gtk::Adjustment> _minpressure_adj; Glib::RefPtr<Gtk::Adjustment> _maxpressure_adj; - Glib::RefPtr<Gtk::Adjustment> _pressurestep_adj; Glib::RefPtr<Gtk::Adjustment> _tolerance_adj; void add_freehand_mode_toggle(bool tool_is_pencil); @@ -77,18 +78,18 @@ private: Glib::ustring const freehand_tool_name(); void minpressure_value_changed(); void maxpressure_value_changed(); - void pressurestep_value_changed(); void use_pencil_pressure(); void tolerance_value_changed(); void add_advanced_shape_options(bool tool_is_pencil); + void add_powerstroke_cap(bool tool_is_pencil); void change_shape(); + void change_cap(); void simplify_lpe(); void simplify_flatten(); void flatten_spiro_bspline(); protected: - PencilToolbar(SPDesktop *desktop, - bool pencil_mode); + PencilToolbar(SPDesktop *desktop, bool pencil_mode); ~PencilToolbar() override; public: diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 88a0fcf2c..961410c6b 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -281,43 +281,17 @@ static void spdc_apply_powerstroke_shape(std::vector<Geom::Point> points, Freeha if (dc->tablet_enabled) { SPObject *elemref = nullptr; if ((elemref = document->getObjectById("power_stroke_preview"))) { - if (SP_SHAPE(elemref)->getCurve() != pt->curvepressure) { - elemref->getRepr()->setAttribute("style", nullptr); - SPItem *successor = dynamic_cast<SPItem *>(elemref); - sp_desktop_apply_style_tool(desktop, successor->getRepr(), - Glib::ustring("/tools/freehand/pencil").data(), false); - spdc_apply_style(successor); - item->deleteObject(true); - item = successor; - dc->selection->set(item); - item->setLocked(false); - dc->white_item = item; - rename_id(SP_OBJECT(item), "path-1"); - } else { - using namespace Inkscape::LivePathEffect; - Effect *lpe = SP_LPE_ITEM(elemref)->getCurrentLPE(); - if (lpe) { - SP_LPE_ITEM(elemref)->removeCurrentPathEffect(true); - LivePathEffectObject *lpeobj = lpe->getLPEObj(); - if (lpeobj) { - SP_OBJECT(lpeobj)->deleteObject(true); - lpeobj = nullptr; - } - } - elemref->deleteObject(true); - elemref = nullptr; - maxrecursion++; - if (maxrecursion < 5) { - pt->addPowerStrokePencil(true); - spdc_apply_powerstroke_shape(points, dc, item, maxrecursion); - } - } - } else { - maxrecursion++; - if (maxrecursion < 5) { - pt->addPowerStrokePencil(true); - spdc_apply_powerstroke_shape(points, dc, item, maxrecursion); - } + elemref->getRepr()->setAttribute("style", nullptr); + SPItem *successor = dynamic_cast<SPItem *>(elemref); + sp_desktop_apply_style_tool(desktop, successor->getRepr(), + Glib::ustring("/tools/freehand/pencil").data(), false); + spdc_apply_style(successor); + item->deleteObject(true); + item = successor; + dc->selection->set(item); + item->setLocked(false); + dc->white_item = item; + rename_id(SP_OBJECT(item), "path-1"); } return; } diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 05a289c45..ba601d044 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -93,7 +93,7 @@ void PencilTool::setup() { this->enableSelectionCue(); } this->_curve = new SPCurve(); - this->curvepressure = new SPCurve(); + FreehandBase::setup(); this->_is_drawing = false; @@ -106,9 +106,6 @@ PencilTool::~PencilTool() { if (this->_curve) { this->_curve->unref(); } - if (this->curvepressure) { - this->curvepressure->unref(); - } } void PencilTool::_extinput(GdkEvent *event) { @@ -694,11 +691,11 @@ void PencilTool::_finishEndpoint() { static inline double square(double const x) { return x * x; } -void PencilTool::addPowerStrokePencil(bool force) +void PencilTool::addPowerStrokePencil(bool force, gint tolsimplify) { - static int pscounter = 21; - if (pscounter > 20 || force) { + static int pscounter = 16; + if (pscounter > 15 || force) { pscounter = 0; } else { pscounter++; @@ -743,7 +740,8 @@ void PencilTool::addPowerStrokePencil(bool force) // worst case gives us a segment per point int max_segs = 4 * n_points; std::vector<Geom::Point> b(max_segs); - curvepressure->reset(); + SPCurve *curvepressure = new SPCurve(); + int const n_segs = Geom::bezier_fit_cubic_r(b.data(), this->ps.data(), n_points, tolerance_sq, max_segs); if (n_segs > 0) { /* Fit and draw and reset state */ @@ -753,7 +751,7 @@ void PencilTool::addPowerStrokePencil(bool force) } } Geom::Path path = curvepressure->get_pathvector()[0]; - + int original_size = path.size(); if (!path.empty()) { Geom::Affine transform_coordinate = SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->i2dt_affine().inverse(); path *= transform_coordinate; @@ -784,7 +782,9 @@ void PencilTool::addPowerStrokePencil(bool force) return; // return true; } - tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0) / 400; + + tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 0.0, 100.0) + tolsimplify; + tol = tol/(100.0*(102.0-tol)); std::ostringstream threshold; threshold << tol; Effect::createAndApply(SIMPLIFY, desktop->doc(), SP_ITEM(lpeitem)); @@ -793,7 +793,7 @@ void PencilTool::addPowerStrokePencil(bool force) Glib::ustring pref_path = "/live_effects/simplify/smooth_angles"; bool valid = prefs->getEntry(pref_path).isValid(); if (!valid) { - lpe->getRepr()->setAttribute("smooth_angles", "360"); + lpe->getRepr()->setAttribute("smooth_angles", "0"); } lpe->getRepr()->setAttribute("threshold", threshold.str()); } @@ -807,44 +807,48 @@ void PencilTool::addPowerStrokePencil(bool force) Effect::createAndApply(POWERSTROKE, SP_ACTIVE_DESKTOP->doc(), lpeitem); lpe = lpeitem->getCurrentLPE(); Inkscape::LivePathEffect::LPEPowerStroke *pspreview = static_cast<LPEPowerStroke *>(lpe); - sp_lpe_item_enable_path_effects(lpeitem, false); if (pspreview) { + sp_lpe_item_enable_path_effects(lpeitem, false); Glib::ustring pref_path = "/live_effects/powerstroke/interpolator_type"; bool valid = prefs->getEntry(pref_path).isValid(); if (!valid) { pspreview->getRepr()->setAttribute("interpolator_type", "CentripetalCatmullRom"); } + gint cap = prefs->getInt("/live_effects/powerstroke/powerpencilcap", 4); + pspreview->getRepr()->setAttribute("start_linecap_type", LineCapTypeConverter.get_key(cap)); + pspreview->getRepr()->setAttribute("end_linecap_type", LineCapTypeConverter.get_key(cap)); pspreview->getRepr()->setAttribute("sort_points", "true"); pspreview->offset_points.param_set_and_write_new_value(this->points); - if (powerpreview->getCurve() != curvepressure) { + sp_lpe_item_enable_path_effects(lpeitem, true); + sp_lpe_item_update_patheffect(lpeitem, false, true); + if (toremove) { + using namespace Inkscape::LivePathEffect; + Effect *lpe = SP_LPE_ITEM(toremove)->getCurrentLPE(); + SP_LPE_ITEM(toremove)->removeCurrentPathEffect(true); + LivePathEffectObject *lpeobj = lpe->getLPEObj(); + if (lpeobj) { + SP_OBJECT(lpeobj)->deleteObject(true); + lpeobj = nullptr; + } + lpe = SP_LPE_ITEM(toremove)->getCurrentLPE(); + SP_LPE_ITEM(toremove)->removeCurrentPathEffect(true); + lpeobj = lpe->getLPEObj(); + if (lpeobj) { + SP_OBJECT(lpeobj)->deleteObject(true); + lpeobj = nullptr; + } + toremove->deleteObject(true); + toremove = nullptr; + } + if (!pspreview->has_exception && path.size() != powerpreview->getCurve()->get_pathvector()[0].size()) { pp->setAttribute("style", "fill:#888888;opacity:1;fill-rule:nonzero;stroke:none;"); - } else if (toremove) { - toremove->getRepr()->setAttribute("id", "power_stroke_preview"); - toremove = powerpreview; + } else if (tolsimplify < 61) { // run 3 times + addPowerStrokePencil(true, tolsimplify + 10); } } - sp_lpe_item_enable_path_effects(lpeitem, true); - - if (toremove) { - using namespace Inkscape::LivePathEffect; - Effect *lpe = SP_LPE_ITEM(toremove)->getCurrentLPE(); - SP_LPE_ITEM(toremove)->removeCurrentPathEffect(true); - LivePathEffectObject *lpeobj = lpe->getLPEObj(); - if (lpeobj) { - SP_OBJECT(lpeobj)->deleteObject(true); - lpeobj = nullptr; - } - lpe = SP_LPE_ITEM(toremove)->getCurrentLPE(); - SP_LPE_ITEM(toremove)->removeCurrentPathEffect(true); - lpeobj = lpe->getLPEObj(); - if (lpeobj) { - SP_OBJECT(lpeobj)->deleteObject(true); - lpeobj = nullptr; - } - toremove->deleteObject(true); - toremove = nullptr; + if (curvepressure) { + curvepressure->unref(); } - prefs->setBool(pref_path_pp, false); // return true; // }); @@ -878,7 +882,7 @@ void PencilTool::_addFreehandPoint(Geom::Point const &p, guint /*state*/) { double pressure_shrunk = (((this->pressure - 0.25) * 1.25) * (max - min)) + min; double pressure_computed = pressure_shrunk * (dezoomify_factor/5.0); this->_wps.push_back(pressure_computed); - this->addPowerStrokePencil(false); + this->addPowerStrokePencil(false, 30); sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), nullptr); for (auto i:this->green_bpaths) { sp_canvas_item_destroy(i); @@ -898,26 +902,43 @@ void PencilTool::powerStrokeInterpolate(Geom::Path path) using Geom::X; using Geom::Y; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - double step = prefs->getDoubleLimited("/tools/freehand/pencil/pressurestep", 1.0, 0, 100.0); - SPItem *item = selection ? selection->singleItem() : nullptr; gint points_size = this->_wps.size(); gint path_size = path.size(); std::vector<Geom::Point> tmp_points; Geom::Point previous = Geom::Point(Geom::infinity(), 0); size_t i = 0; + size_t previ = 0; + bool increase = true; for (auto pressure : this->_wps) { Geom::Point pp = Geom::Point(); pp[Geom::X] = (path_size / (double)points_size) * i; pp[Geom::Y] = pressure; - if (pressure == 0 || path_size > 2 && (pp[Geom::X] < 1 || pp[Geom::X] > path_size - 2)) { + if (pressure == 0 || + (path_size > 1 && + (pp[Geom::X] < 1 || pp[Geom::X] > path_size - 1))) + { ++i; continue; } - if (std::abs(previous[Geom::Y] - pp[Geom::Y]) > step) { - tmp_points.push_back(pp); + if (std::abs(pp[Geom::X] - previous[Geom::X]) > 0.2 && + std::abs(pp[Geom::Y] - previous[Geom::Y]) > 0.5) + { + if (previous[Geom::Y] < pp[Geom::Y]) { + if (increase && tmp_points.size() > 1) { + tmp_points.pop_back(); + } + increase = true; + } else { + if (!increase && tmp_points.size() > 1) { + tmp_points.pop_back(); + } + increase = false; + } previous = pp; + tmp_points.push_back(pp); } + ++i; } this->points = tmp_points; @@ -938,7 +959,7 @@ void PencilTool::_interpolate() { bool simplify = prefs->getInt("/tools/freehand/pencil/simplify", 0); if(simplify){ double tol2 = prefs->getDoubleLimited("/tools/freehand/pencil/base-simplify", 25.0, 0.0, 100.0) * 0.4; - tol = tol > tol2 ? tol : tol2; + tol = std::min(tol,tol2); } this->green_curve->reset(); this->red_curve->reset(); diff --git a/src/ui/tools/pencil-tool.h b/src/ui/tools/pencil-tool.h index 063cfa124..60edd3f78 100644 --- a/src/ui/tools/pencil-tool.h +++ b/src/ui/tools/pencil-tool.h @@ -48,12 +48,11 @@ public: Geom::Point p[16]; std::vector<Geom::Point> ps; std::vector<Geom::Point> points; - void addPowerStrokePencil(bool force); + void addPowerStrokePencil(bool force, gint tolsimplify); void powerStrokeInterpolate(Geom::Path); Geom::Piecewise<Geom::D2<Geom::SBasis> > sketch_interpolation; // the current proposal from the sketched paths unsigned sketch_n; // number of sketches done static const std::string prefsPath; - SPCurve *curvepressure; const std::string& getPrefsPath() override; protected: |
