summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabiertxof <jabier.arraiza@marker.es>2019-07-16 14:37:19 +0000
committerJabier Arraiza <jabier.arraiza@marker.es>2019-07-19 21:33:23 +0000
commite2f4af7eb9d6a497308925930e89d2a403c3a5c9 (patch)
treef1abd09c7996dc93dbb09d79b91e70e3a5f0847d /src
parentFix maren pointed bugs (diff)
downloadinkscape-e2f4af7eb9d6a497308925930e89d2a403c3a5c9.tar.gz
inkscape-e2f4af7eb9d6a497308925930e89d2a403c3a5c9.zip
Improvemets to power pencil
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/effect.cpp3
-rw-r--r--src/live_effects/effect.h1
-rw-r--r--src/live_effects/lpe-powerstroke.cpp16
-rw-r--r--src/live_effects/lpe-powerstroke.h17
-rwxr-xr-xsrc/object/sp-lpe-item.cpp2
-rw-r--r--src/ui/toolbar/pencil-toolbar.cpp195
-rw-r--r--src/ui/toolbar/pencil-toolbar.h11
-rw-r--r--src/ui/tools/freehand-base.cpp48
-rw-r--r--src/ui/tools/pencil-tool.cpp109
-rw-r--r--src/ui/tools/pencil-tool.h3
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: