diff options
| -rw-r--r-- | src/live_effects/effect.cpp | 4 | ||||
| -rw-r--r-- | src/live_effects/lpe-powerstroke.cpp | 8 | ||||
| -rwxr-xr-x | src/object/sp-lpe-item.cpp | 13 | ||||
| -rw-r--r-- | src/object/sp-lpe-item.h | 1 | ||||
| -rw-r--r-- | src/snap.cpp | 4 | ||||
| -rw-r--r-- | src/ui/tools/freehand-base.cpp | 30 | ||||
| -rw-r--r-- | src/ui/tools/pencil-tool.cpp | 232 | ||||
| -rw-r--r-- | src/ui/tools/pencil-tool.h | 7 |
8 files changed, 215 insertions, 84 deletions
diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 7bfe6617a..03f482190 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -1113,7 +1113,7 @@ Effect::Effect(LivePathEffectObject *lpeobject) current_shape(nullptr), provides_own_flash_paths(true), // is automatically set to false if providesOwnFlashPaths() is not overridden defaultsopen(false), - is_ready(false) // is automatically set to false if providesOwnFlashPaths() is not overridden + is_ready(false) { registerParameter( dynamic_cast<Parameter *>(&is_visible) ); is_visible.widget_is_visible = false; @@ -1261,12 +1261,12 @@ void Effect::doOnApply_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast<SPLPEItem *>(lpeitem); doOnApply(lpeitem); + setReady(); } void Effect::doBeforeEffect_impl(SPLPEItem const* lpeitem) { sp_lpe_item = const_cast<SPLPEItem *>(lpeitem); - setReady(); doBeforeEffect(lpeitem); update_helperpath(); } diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index 79d147a69..9ca4546f1 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -566,7 +566,7 @@ LPEPowerStroke::doEffect_path (Geom::PathVector const & path_in) Geom::PathVector path_out; if (path_in.empty()) { - return path_out; + return path_in; } Geom::PathVector pathv = pathv_to_linear_and_cubic_beziers(path_in); Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in = pathv[0].toPwSb(); @@ -590,7 +590,7 @@ LPEPowerStroke::doEffect_path (Geom::PathVector const & path_in) std::vector<Geom::Point> ts_no_scale = offset_points.data(); if (ts_no_scale.empty()) { - return path_out; + return path_in; } std::vector<Geom::Point> ts; for (auto & tsp : ts_no_scale) { @@ -753,6 +753,10 @@ LPEPowerStroke::doEffect_path (Geom::PathVector const & path_in) fixed_path.close(true); path_out.push_back(fixed_path); } + if (path_out.empty()) { + return path_in; + //doEffect_path (path_in); + } return path_out; } diff --git a/src/object/sp-lpe-item.cpp b/src/object/sp-lpe-item.cpp index 47ace710b..2e1e2c9f0 100755 --- a/src/object/sp-lpe-item.cpp +++ b/src/object/sp-lpe-item.cpp @@ -45,7 +45,6 @@ #include "sp-rect.h" /* LPEItem base class */ -static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable); static void lpeobject_ref_modified(SPObject *href, guint flags, SPLPEItem *lpeitem); static void sp_lpe_item_create_original_path_recursive(SPLPEItem *lpeitem); @@ -208,7 +207,7 @@ bool SPLPEItem::performPathEffect(SPCurve *curve, SPShape *current, bool is_clip } Inkscape::LivePathEffect::Effect *lpe = lpeobj->get_lpe(); - if (!performOnePathEffect(curve, current, lpe, is_clip_or_mask)) { + if (!lpe || !performOnePathEffect(curve, current, lpe, is_clip_or_mask)) { return false; } if (path_effect_list_size != this->path_effect_list->size()) { @@ -265,7 +264,9 @@ bool SPLPEItem::performOnePathEffect(SPCurve *curve, SPShape *current, Inkscape: if (!SP_IS_GROUP(this)) { // To have processed the shape to doAfterEffect - lpe->pathvector_after_effect = curve->get_pathvector(); + if (curve) { + lpe->pathvector_after_effect = curve->get_pathvector(); + } lpe->doAfterEffect(this); } } @@ -569,9 +570,6 @@ void SPLPEItem::addPathEffect(std::string value, bool reset) sp_lpe_item_create_original_path_recursive(this); // perform this once when the effect is applied lpe->doOnApply_impl(this); - - // indicate that all necessary preparations are done and the effect can be performed - lpe->setReady(); } //Enable the path effects now that everything is ready to apply the new path effect @@ -1199,8 +1197,7 @@ bool SPLPEItem::forkPathEffectsIfNecessary(unsigned int nr_of_allowed_users, boo } // Enable or disable the path effects of the item. -// The counter allows nested calls -static void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable) +void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable) { if (enable) { lpeitem->path_effects_enabled++; diff --git a/src/object/sp-lpe-item.h b/src/object/sp-lpe-item.h index 6ebd01fe3..b055b5e97 100644 --- a/src/object/sp-lpe-item.h +++ b/src/object/sp-lpe-item.h @@ -104,6 +104,7 @@ public: void editNextParamOncanvas(SPDesktop *dt); }; void sp_lpe_item_update_patheffect (SPLPEItem *lpeitem, bool wholetree, bool write); // careful, class already has method with *very* similar name! +void sp_lpe_item_enable_path_effects(SPLPEItem *lpeitem, bool enable); #endif /* !SP_LPE_ITEM_H_SEEN */ diff --git a/src/snap.cpp b/src/snap.cpp index 210a1989e..acc600841 100644 --- a/src/snap.cpp +++ b/src/snap.cpp @@ -663,7 +663,9 @@ void SnapManager::setup(SPDesktop const *desktop, g_warning("The snapmanager has been set up before, but unSetup() hasn't been called afterwards. It possibly held invalid pointers"); } _items_to_ignore.clear(); - _items_to_ignore.push_back(item_to_ignore); + if (item_to_ignore) { + _items_to_ignore.push_back(item_to_ignore); + } _desktop = desktop; _snapindicator = snapindicator; _unselected_nodes = unselected_nodes; diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp index 4f9db3e2b..c03cfb826 100644 --- a/src/ui/tools/freehand-base.cpp +++ b/src/ui/tools/freehand-base.cpp @@ -378,10 +378,22 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if (!is_bend && previous_shape_type == BEND_CLIPBOARD && shape == BEND_CLIPBOARD) { return; } + bool shape_applied = false; + bool tabletpencil = false; + if (SP_IS_PENCIL_CONTEXT(dc)) { + if (dc->tablet_enabled) { + tabletpencil = true; + std::vector<Geom::Point> points; + spdc_apply_powerstroke_shape(points, dc, item); + shape_applied = true; + shape = NONE; + previous_shape_type = NONE; + } + } bool simplify = prefs->getInt(tool_name(dc) + "/simplify", 0); Inkscape::Preferences *prefs = Inkscape::Preferences::get(); guint mode = prefs->getInt("/tools/freehand/pencil/freehand-mode", 0); - if(simplify && mode != 2){ + if(!tabletpencil && simplify && mode != 2){ double tol = prefs->getDoubleLimited("/tools/freehand/pencil/tolerance", 10.0, 1.0, 100.0); tol = tol/(100.0*(102.0-tol)); std::ostringstream ss; @@ -389,19 +401,17 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, spdc_apply_simplify(ss.str(), dc, item); sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); } - if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { + if (!tabletpencil && prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } - if (prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { + if (!tabletpencil && prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2) { Effect::createAndApply(BSPLINE, dc->desktop->doc(), item); } SPShape *sp_shape = dynamic_cast<SPShape *>(item); if (sp_shape) { curve = sp_shape->getCurve(); } - - bool shape_applied = false; SPCSSAttr *css_item = sp_css_attr_from_object(item, SP_STYLE_FLAG_ALWAYS); const char *cstroke = sp_repr_css_property(css_item, "stroke", "none"); const char *cfill = sp_repr_css_property(css_item, "fill", "none"); @@ -412,15 +422,7 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item, if (!swidth) { swidth = swidth/2; } - if (SP_IS_PENCIL_CONTEXT(dc)) { - if (dc->tablet_enabled) { - std::vector<Geom::Point> points; - spdc_apply_powerstroke_shape(points, dc, item); - shape_applied = true; - shape = NONE; - previous_shape_type = NONE; - } - } + #define SHAPE_LENGTH 10 #define SHAPE_HEIGHT 10 diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp index 812027d58..c7134c4df 100644 --- a/src/ui/tools/pencil-tool.cpp +++ b/src/ui/tools/pencil-tool.cpp @@ -18,11 +18,9 @@ */ #include <gdk/gdkkeysyms.h> -#include <glibmm/i18n.h> #include <2geom/sbasis-to-bezier.h> #include <2geom/bezier-utils.h> - #include "ui/tools/pencil-tool.h" @@ -41,10 +39,10 @@ #include "display/curve.h" #include "display/sp-canvas.h" -#include "live_effects/lpe-powerstroke.h" #include "live_effects/lpe-powerstroke-interpolators.h" #include "object/sp-path.h" +#include "object/sp-lpe-item.h" #include "style.h" #include "ui/pixmaps/cursor-pencil.xpm" @@ -56,6 +54,9 @@ #include "xml/node.h" #include "xml/sp-css-attr.h" +#include <glibmm/i18n.h> +#include <thread> +#include <chrono> namespace Inkscape { namespace UI { @@ -270,7 +271,6 @@ bool PencilTool::_handleMotionNotify(GdkEventMotion const &mevent) { this->_is_drawing = false; return true; } - bool ret = false; if (this->space_panning || (mevent.state & GDK_BUTTON2_MASK) || (mevent.state & GDK_BUTTON3_MASK)) { @@ -356,7 +356,6 @@ bool PencilTool::_handleMotionNotify(GdkEventMotion const &mevent) { this->ps.push_back(this->p[0]); if (tablet_enabled) { this->_wps.push_back(this->pressure); - this->addPowerStrokePencil(); } } this->_addFreehandPoint(p, mevent.state); @@ -476,11 +475,12 @@ bool PencilTool::_handleButtonRelease(GdkEventButton const &revent) { this->ea = anchor; /* Write curves to object */ + desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing freehand")); if (tablet_enabled) { _powerstrokeInterpolate(true); + } else { + this->_interpolate(); } - desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Finishing freehand")); - this->_interpolate(); spdc_concat_colors_and_flush(this, FALSE); this->points.clear(); this->sa = nullptr; @@ -693,25 +693,30 @@ void PencilTool::_finishEndpoint() { } } -void +bool PencilTool::_powerStrokePreview(Geom::Path const path) { using namespace Inkscape::LivePathEffect; SPDocument * document = SP_ACTIVE_DOCUMENT; if (!document) { - return; + return true; } Inkscape::XML::Document *xml_doc = document->getReprDoc(); Geom::PathVector const pathv(path); - SPLPEItem * lpeitem = dynamic_cast<SPLPEItem *>(_powerpreview); - if (!lpeitem) { + std::vector<Geom::Point> points_preview = this->points; + points_preview.emplace_back(pathv.size() - 1, points_preview[points_preview.size()-1][Geom::Y]); +/* SPLPEItem * lpeitem = dynamic_cast<SPLPEItem *>(_powerpreview); + if (lpeitem) { + lpeitem->removeAllPathEffects(true); + delete _powerpreview; + } */ Inkscape::XML::Node *body = nullptr; body = xml_doc->createElement("svg:path"); body->setAttribute("sodipodi:insensitive", "true"); sp_desktop_apply_style_tool(desktop, body, Glib::ustring("/tools/freehand/pencil").data(), false); - _powerpreview = SP_SHAPE(SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->appendChildRepr(body)); + SPShape * powerpreview = SP_SHAPE(SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->appendChildRepr(body)); Inkscape::GC::release(body); - SPCSSAttr *css = sp_css_attr_from_object(_powerpreview, SP_STYLE_FLAG_ALWAYS); + SPCSSAttr *css = sp_css_attr_from_object(powerpreview, SP_STYLE_FLAG_ALWAYS); const gchar * stroke = sp_repr_css_property(css, "stroke", "none"); const gchar * fill = sp_repr_css_property(css, "fill", "none"); if (!strcmp(fill, "none")) { @@ -726,48 +731,68 @@ PencilTool::_powerStrokePreview(Geom::Path const path) sp_repr_css_write_string(css,css_str); body->setAttribute("style", css_str.c_str()); gchar * pvector_str = sp_svg_write_path(pathv); - _powerpreview->setAttribute("d" , pvector_str); - g_free(pvector_str); - SPLPEItem * lpeitem = dynamic_cast<SPLPEItem *>(_powerpreview); - if (!lpeitem) { - return; + if (pvector_str) { + powerpreview->setAttribute("d" , pvector_str); + g_free(pvector_str); } - Effect::createAndApply(POWERSTROKE, SP_ACTIVE_DESKTOP->doc(), SP_ITEM(_powerpreview)); - Effect* lpe = lpeitem->getCurrentLPE(); - LPEPowerStroke * ps = static_cast<LPEPowerStroke*>(lpe); - if (ps) { - ps->offset_points.param_set_and_write_new_value(this->points); - ps->getRepr()->setAttribute("sort_points", "true"); - ps->getRepr()->setAttribute("interpolator_type", "CentripetalCatmullRom"); + SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(powerpreview); + if (!lpeitem) { + return true; } - } else { + Effect::createAndApply(POWERSTROKE, SP_ACTIVE_DESKTOP->doc(), SP_ITEM(powerpreview)); Effect* lpe = lpeitem->getCurrentLPE(); - LPEPowerStroke * ps = static_cast<LPEPowerStroke*>(lpe); - if (ps) { - ps->offset_points.param_set_and_write_new_value(this->points); + _pspreview = static_cast<LPEPowerStroke*>(lpe); + if (_pspreview) { + _pspreview->offset_points.param_set_and_write_new_value(points_preview); + _pspreview->getRepr()->setAttribute("sort_points", "true"); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring pref_path = (Glib::ustring)"/live_effects/" + + Glib::ustring("powerstroke") + + (Glib::ustring)"/" + + Glib::ustring("interpolator_type"); + bool valid = prefs->getEntry(pref_path).isValid(); + if (!valid){ + _pspreview->getRepr()->setAttribute("interpolator_type", "CentripetalCatmullRom"); + } } - gchar * pvector_str = sp_svg_write_path(pathv); - _powerpreview->setAttribute("inkscape:original-d" , pvector_str); - g_free(pvector_str); - } + /* else { + Inkscape::LivePathEffect::LPEPowerStroke * pspreview = _pspreview; + SPShape *powerpreview = _powerpreview; + [points_preview, powerpreview, pspreview, pathv] { + gchar * pvector_str = sp_svg_write_path(pathv); + if (pvector_str) { + pspreview->is_visible.param_setValue(false); + powerpreview->setAttribute("inkscape:original-d", pvector_str); + pspreview->offset_points.param_set_and_write_new_value(points_preview); + pspreview->is_visible.param_setValue(true); + g_free(powerpreview); + } + } */ + return true; } void PencilTool::removePowerStrokePreview() { - if(_powerpreview) { + SPDocument * document = SP_ACTIVE_DOCUMENT; + if (!document) { + return; + } + SPObject *elemref = nullptr; + if ((elemref = document->getObjectById("power_stroke_preview"))) { using namespace Inkscape::LivePathEffect; - Effect* lpe = SP_LPE_ITEM(_powerpreview)->getCurrentLPE(); - SP_LPE_ITEM(_powerpreview)->removeCurrentPathEffect(true); + Effect* lpe = SP_LPE_ITEM(elemref)->getCurrentLPE(); + SP_LPE_ITEM(elemref)->removeCurrentPathEffect(true); LivePathEffectObject * lpeobj = lpe->getLPEObj(); if (lpeobj) { - SP_OBJECT(lpeobj)->deleteObject(); + SP_OBJECT(lpeobj)->deleteObject(true); lpeobj = nullptr; } - _powerpreview->deleteObject(); - _powerpreview = nullptr; + elemref->deleteObject(true); + elemref = nullptr; } } + void PencilTool::addPowerStrokePencil(SPCurve *& c) { @@ -775,7 +800,6 @@ PencilTool::addPowerStrokePencil(SPCurve *& c) c = this->_curve->copy(); } } - void PencilTool::addPowerStrokePencil() { @@ -802,7 +826,7 @@ PencilTool::addPowerStrokePencil() double pressure_shrunk = (last_pressure * (max - min)) + min; step = (step * (max - min)) + min; //We need half width for power stroke - double pressure_computed = pressure_shrunk * dezoomify_factor/2.0; + double pressure_computed = (pressure_shrunk * dezoomify_factor)/2.0; this->_last_point = this->ps.back(); this->_last_point *= transform_coordinate.inverse(); if (this->ps.size() == 1 || @@ -818,15 +842,111 @@ PencilTool::addPowerStrokePencil() _powerstrokeInterpolate(false); Geom::PathVector cpv = this->_curve->get_pathvector(); if (cpv.size()) { - _powerStrokePreview(cpv[0]); + std::future_status status; + if (future.valid()) { + status = future.wait_for(std::chrono::seconds(0)); + } + if (!future.valid() || status == std::future_status::ready) { + Geom::Path path = cpv[0]; + + std::vector<Geom::Point> points_preview = points; + points_preview.emplace_back(path.size() - 1, points_preview[points_preview.size()-1][Geom::Y]); + std::cout << path << points_preview.size() << "ooops" << std::endl; + future = std::async(std::launch::async, [path, points_preview] { + using namespace Inkscape::LivePathEffect; + SPDocument * document = SP_ACTIVE_DOCUMENT; + if (!document) { + return true; + } + Inkscape::XML::Document *xml_doc = document->getReprDoc(); + Geom::PathVector const pathv(path); + Inkscape::XML::Node *pp = nullptr; + pp = xml_doc->createElement("svg:path"); + SPShape * powerpreview = SP_SHAPE(SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->appendChildRepr(pp)); + /* body->setAttribute("sodipodi:insensitive", "true"); + sp_desktop_apply_style_tool(SP_ACTIVE_DESKTOP, body, Glib::ustring("/tools/freehand/pencil").data(), false); + SPShape * powerpreview = SP_SHAPE(SP_ITEM(SP_ACTIVE_DESKTOP->currentLayer())->appendChildRepr(body)); + Inkscape::GC::release(body); + SPCSSAttr *css = sp_css_attr_from_object(powerpreview, SP_STYLE_FLAG_ALWAYS); + const gchar * stroke = sp_repr_css_property(css, "stroke", "none"); + const gchar * fill = sp_repr_css_property(css, "fill", "none"); + if (!strcmp(fill, "none")) { + sp_repr_css_set_property (css, "stroke", "#000000"); + } else { + sp_repr_css_set_property (css, "stroke", fill); + } + if (!strcmp(stroke, "none")) { + sp_repr_css_set_property (css, "fill", "#000000"); + } else { + sp_repr_css_set_property (css, "fill", stroke); + } + Glib::ustring css_str; + sp_repr_css_write_string(css,css_str); */ + pp->setAttribute("style", "fill:#888"); + gchar * pvector_str = sp_svg_write_path(pathv); + if (pvector_str) { + pp->setAttribute("d" , pvector_str); + g_free(pvector_str); + } + SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(powerpreview); + if (!lpeitem) { + return true; + } + sp_lpe_item_enable_path_effects(SP_LPE_ITEM(powerpreview), false); + Effect::createAndApply(POWERSTROKE, SP_ACTIVE_DESKTOP->doc(), SP_ITEM(powerpreview)); + Effect* lpe = lpeitem->getCurrentLPE(); + Inkscape::LivePathEffect::LPEPowerStroke *pspreview = static_cast<LPEPowerStroke*>(lpe); + if (pspreview) { + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring pref_path = (Glib::ustring)"/live_effects/" + + Glib::ustring("powerstroke") + + (Glib::ustring)"/" + + Glib::ustring("interpolator_type"); + bool valid = prefs->getEntry(pref_path).isValid(); + if (!valid){ + pspreview->getRepr()->setAttribute("interpolator_type", "CentripetalCatmullRom"); + } + pspreview->getRepr()->setAttribute("sort_points", "true"); + pspreview->offset_points.param_set_and_write_new_value(points_preview); + } + pp->setAttribute("id", "tmp_power_stroke_preview"); + const gchar *toremove = "power_stroke_preview"; + if (powerpreview->getCurve() == powerpreview->getCurveBeforeLPE()) { + toremove = "tmp_power_stroke_preview"; + } + SPObject *elemref = nullptr; + if ((elemref = document->getObjectById(toremove))) { + using namespace Inkscape::LivePathEffect; + Effect* lpe = SP_LPE_ITEM(elemref)->getCurrentLPE(); + SP_LPE_ITEM(elemref)->removeCurrentPathEffect(true); + LivePathEffectObject * lpeobj = lpe->getLPEObj(); + if (lpeobj) { + SP_OBJECT(lpeobj)->deleteObject(true); + lpeobj = nullptr; + } + elemref->deleteObject(true); + elemref = nullptr; + } + if (toremove == "power_stroke_preview") { + pp->setAttribute("id", toremove); + sp_lpe_item_enable_path_effects(SP_LPE_ITEM(powerpreview), true); + } + return true; + }); + } else { + + std::cout << "stopped" << std::endl; + } + } } + } void PencilTool::_addFreehandPoint(Geom::Point const &p, guint /*state*/) { g_assert( this->_npoints > 0 ); g_return_if_fail(unsigned(this->_npoints) < G_N_ELEMENTS(this->p)); - + if ( ( p != this->p[ this->_npoints - 1 ] ) && in_svg_plane(p) ) { @@ -837,7 +957,7 @@ void PencilTool::_addFreehandPoint(Geom::Point const &p, guint /*state*/) { if (this->pressure != 0) { this->_wps.push_back(this->pressure); this->addPowerStrokePencil(); - } + } sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->red_bpath), nullptr); for (auto i:this->green_bpaths) { sp_canvas_item_destroy(i); @@ -877,7 +997,7 @@ PencilTool::_powerstrokeInterpolate(bool apply) { using namespace Inkscape::LivePathEffect; SPCurve * c = sa_overwrited->copy(); Effect* lpe = SP_LPE_ITEM(item)->getCurrentLPE(); - LPEPowerStroke* ps = static_cast<LPEPowerStroke*>(lpe); + LPEPowerStroke* ps = dynamic_cast<LPEPowerStroke*>(lpe); if (ps) { if (sa->start) { sa_points = ps->offset_points.reverse_controlpoints(false); @@ -892,7 +1012,7 @@ PencilTool::_powerstrokeInterpolate(bool apply) { this->_key_nodes.pop_back(); } size_t count = 0; - for (auto current:this->ps) { + /* for (auto current:this->ps) { current *= transform_coordinate.inverse(); Geom::Point prev = Geom::Point(0,0); if (count == ps_size - 1 || (apply && count%tol == 0 ) || (!apply && count%2 == 0)) { @@ -911,22 +1031,24 @@ PencilTool::_powerstrokeInterpolate(bool apply) { } } count++; - } + } */ + for (auto current:this->ps) { + current *= transform_coordinate.inverse(); + this->_key_nodes.push_back(current); + } Geom::Path path(this->_key_nodes.front()); if (this->_key_nodes.size() == 2) { path.appendNew<Geom::LineSegment>(this->_key_nodes.back()); } else { path = interpolator->interpolateToPath(this->_key_nodes); } - count = 0; - size_t points_size = this->_points_pos.size(); - for (auto point:this->_points_pos) { - double pos = Geom::nearest_time(point, path); - this->points[count][Geom::X] = pos; - if (count > 1 && (this->points[count-1][Geom::X] == pos || (apply && pos > path.size() - 1 ))) { - this->points.pop_back(); + gint points_size = this->_points_pos.size(); + for (gint i = points_size - 1; i >= 0; --i) { + double pos = Geom::nearest_time(this->_points_pos[i], path); + this->points[i][Geom::X] = pos; + if (points_size -1 != i && Geom::are_near(this->points[i+1][Geom::X], pos, 1/tol) ) { + this->_points_pos.erase(this->_points_pos.begin() + i); } - count++; } sa_points.insert(sa_points.end(),this->points.begin(),this->points.end()); this->points = sa_points; diff --git a/src/ui/tools/pencil-tool.h b/src/ui/tools/pencil-tool.h index f58a72a4b..019b45cce 100644 --- a/src/ui/tools/pencil-tool.h +++ b/src/ui/tools/pencil-tool.h @@ -11,13 +11,14 @@ #define SEEN_PENCIL_CONTEXT_H - +#include "live_effects/lpe-powerstroke.h" #include "ui/tools/freehand-base.h" #include <2geom/piecewise.h> #include <2geom/d2.h> #include <2geom/sbasis.h> #include <2geom/pathvector.h> +#include <future> class SPShape; @@ -68,7 +69,7 @@ private: bool _handleKeyPress(GdkEventKey const &event); bool _handleKeyRelease(GdkEventKey const &event); void _setStartpoint(Geom::Point const &p); - void _powerStrokePreview(Geom::Path const path); + bool _powerStrokePreview(Geom::Path const path); void _setEndpoint(Geom::Point const &p); void _finishEndpoint(); void _addFreehandPoint(Geom::Point const &p, guint state); @@ -86,10 +87,12 @@ private: double _previous_pressure; SPCurve * _curve; SPShape *_powerpreview; + Inkscape::LivePathEffect::LPEPowerStroke * _pspreview; Geom::Point _req_tangent; bool _is_drawing; PencilState _state; gint _npoints; + std::future<bool> future; }; } |
