From c7a58fa3190e53b2aaf2886ef3eb4dd0c7524bcd Mon Sep 17 00:00:00 2001 From: Diederik van Lierop Date: Sat, 25 Jul 2015 21:52:00 +0200 Subject: =?UTF-8?q?Fix=20snapping=20of=20start=20point=20of=20path=20when?= =?UTF-8?q?=20holding=20the=20CTRL=20key=20in=20the=20B=C3=A9zier=20tool?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixed bugs: - https://launchpad.net/bugs/1432354 (bzr r14257) --- src/ui/tools/pen-tool.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/ui/tools/pen-tool.cpp') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 827dbf5c3..d924d8773 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -268,6 +268,9 @@ void PenTool::_endpointSnap(Geom::Point &p, guint const state) const { if ((state & GDK_CONTROL_MASK) && !this->polylines_paraxial) { //CTRL enables angular snapping if (this->npoints > 0) { spdc_endpoint_snap_rotation(this, p, this->p[0], state); + } else { + boost::optional origin = boost::optional(); + spdc_endpoint_snap_free(this, p, origin, state); } } else { // We cannot use shift here to disable snapping because the shift-key is already used -- 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/ui/tools/pen-tool.cpp | 255 +--------------------------------------------- 1 file changed, 2 insertions(+), 253 deletions(-) (limited to 'src/ui/tools/pen-tool.cpp') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index d924d8773..6a3928f27 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -1717,9 +1717,9 @@ void PenTool::_bsplineSpiroBuild() //Effect *spr = static_cast ( new LPEbspline(lpeobj) ); //spr->doEffect(curve); if(this->bspline){ - this->_bsplineDoEffect(curve); + LivePathEffect::sp_bspline_do_effect(curve, 0); }else{ - this->_spiroDoEffect(curve); + LivePathEffect::sp_spiro_do_effect(curve); } sp_canvas_bpath_set_bpath(SP_CANVAS_BPATH(this->blue_bpath), curve); @@ -1743,257 +1743,6 @@ void PenTool::_bsplineSpiroBuild() } } -//from LPE BSPLINE: -void PenTool::_bsplineDoEffect(SPCurve * curve) -{ - //const double NO_POWER = 0.0; - const double DEFAULT_START_POWER = 0.3334; - const double DEFAULT_END_POWER = 0.6667; - 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(); - - for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); - path_it != original_pathv.end(); ++path_it) { - if (path_it->empty()) { - continue; - } - Geom::Path::const_iterator curve_it1 = path_it->begin(); - Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); - Geom::Path::const_iterator curve_endit = path_it->end_default(); - SPCurve *curve_n = new SPCurve(); - Geom::Point previousNode(0, 0); - Geom::Point node(0, 0); - Geom::Point point_at1(0, 0); - Geom::Point point_at2(0, 0); - Geom::Point next_point_at1(0, 0); - Geom::D2 sbasis_in; - 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(); - in->moveto(curve_it1->initialPoint()); - in->lineto(curve_it1->finalPoint()); - cubic = dynamic_cast(&*curve_it1); - if (cubic) { - sbasis_in = in->first_segment()->toSBasis(); - if(are_near((*cubic)[1],(*cubic)[0]) && !are_near((*cubic)[2],(*cubic)[3])) { - point_at1 = sbasis_in.valueAt(DEFAULT_START_POWER); - } else { - point_at1 = sbasis_in.valueAt(Geom::nearest_time((*cubic)[1], *in->first_segment())); - } - if(are_near((*cubic)[2],(*cubic)[3]) && !are_near((*cubic)[1],(*cubic)[0])) { - point_at2 = sbasis_in.valueAt(DEFAULT_END_POWER); - } else { - point_at2 = sbasis_in.valueAt(Geom::nearest_time((*cubic)[2], *in->first_segment())); - } - } else { - point_at1 = in->first_segment()->initialPoint(); - point_at2 = in->first_segment()->finalPoint(); - } - in->reset(); - delete in; - if ( curve_it2 != curve_endit ) { - SPCurve *out = new SPCurve(); - out->moveto(curve_it2->initialPoint()); - out->lineto(curve_it2->finalPoint()); - cubic = dynamic_cast(&*curve_it2); - if (cubic) { - sbasis_out = out->first_segment()->toSBasis(); - if(are_near((*cubic)[1],(*cubic)[0]) && !are_near((*cubic)[2],(*cubic)[3])) { - next_point_at1 = sbasis_in.valueAt(DEFAULT_START_POWER); - } else { - next_point_at1 = sbasis_out.valueAt(Geom::nearest_time((*cubic)[1], *out->first_segment())); - } - } else { - next_point_at1 = out->first_segment()->initialPoint(); - } - out->reset(); - delete out; - } - if (path_it->closed() && curve_it2 == curve_endit) { - SPCurve *start = new SPCurve(); - start->moveto(path_it->begin()->initialPoint()); - start->lineto(path_it->begin()->finalPoint()); - Geom::D2 sbasis_start = start->first_segment()->toSBasis(); - SPCurve *line_helper = new SPCurve(); - cubic = dynamic_cast(&*path_it->begin()); - if (cubic) { - line_helper->moveto(sbasis_start.valueAt( - Geom::nearest_time((*cubic)[1], *start->first_segment()))); - } else { - line_helper->moveto(start->first_segment()->initialPoint()); - } - start->reset(); - delete start; - - SPCurve *end = new SPCurve(); - end->moveto(curve_it1->initialPoint()); - end->lineto(curve_it1->finalPoint()); - Geom::D2 sbasis_end = end->first_segment()->toSBasis(); - cubic = dynamic_cast(&*curve_it1); - if (cubic) { - line_helper->lineto(sbasis_end.valueAt( - Geom::nearest_time((*cubic)[2], *end->first_segment()))); - } else { - line_helper->lineto(end->first_segment()->finalPoint()); - } - end->reset(); - delete end; - sbasis_helper = line_helper->first_segment()->toSBasis(); - line_helper->reset(); - delete line_helper; - node = sbasis_helper.valueAt(0.5); - curve_n->curveto(point_at1, point_at2, node); - curve_n->move_endpoints(node, node); - } else if ( curve_it2 == curve_endit) { - curve_n->curveto(point_at1, point_at2, curve_it1->finalPoint()); - curve_n->move_endpoints(path_it->begin()->initialPoint(), curve_it1->finalPoint()); - } else { - SPCurve *line_helper = new SPCurve(); - line_helper->moveto(point_at2); - line_helper->lineto(next_point_at1); - sbasis_helper = line_helper->first_segment()->toSBasis(); - line_helper->reset(); - delete line_helper; - previousNode = node; - node = sbasis_helper.valueAt(0.5); - Geom::CubicBezier const *cubic2 = dynamic_cast(&*curve_it1); - if((cubic && are_near((*cubic)[0],(*cubic)[1])) || (cubic2 && are_near((*cubic2)[2],(*cubic2)[3]))) { - node = curve_it1->finalPoint(); - } - curve_n->curveto(point_at1, point_at2, node); - } - ++curve_it1; - ++curve_it2; - } - //y cerramos la curva - if (path_it->closed()) { - curve_n->closepath_current(); - } - curve->append(curve_n, false); - curve_n->reset(); - delete curve_n; - } -} - -//Spiro function cloned from lpe-spiro.cpp -// commenting the function "doEffect" from src/live_effects/lpe-spiro.cpp -void PenTool::_spiroDoEffect(SPCurve * curve) -{ - using Geom::X; - using Geom::Y; - - Geom::PathVector const original_pathv = curve->get_pathvector(); - guint len = curve->get_segment_count() + 2; - - curve->reset(); - Spiro::spiro_cp *path = g_new (Spiro::spiro_cp, len); - int ip = 0; - - for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { - if (path_it->empty()) - continue; - - { - Geom::Point p = path_it->front().pointAt(0); - path[ip].x = p[X]; - path[ip].y = p[Y]; - path[ip].ty = '{' ; - ip++; - } - - Geom::Path::const_iterator curve_it1 = path_it->begin(); - Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); - - Geom::Path::const_iterator curve_endit = path_it->end_default(); - if (path_it->closed()) { - const Geom::Curve &closingline = path_it->back_closed(); - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - curve_endit = path_it->end_open(); - } - } - - while ( curve_it2 != curve_endit ) - { - Geom::Point p = curve_it1->finalPoint(); - path[ip].x = p[X]; - path[ip].y = p[Y]; - - bool this_is_line = is_straight_curve(*curve_it1); - bool next_is_line = is_straight_curve(*curve_it2); - - Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, *curve_it2); - - if ( nodetype == Geom::NODE_SMOOTH || nodetype == Geom::NODE_SYMM ) - { - if (this_is_line && !next_is_line) { - path[ip].ty = ']'; - } else if (next_is_line && !this_is_line) { - path[ip].ty = '['; - } else { - path[ip].ty = 'c'; - } - } else { - path[ip].ty = 'v'; - } - - ++curve_it1; - ++curve_it2; - ip++; - } - - Geom::Point p = curve_it1->finalPoint(); - path[ip].x = p[X]; - path[ip].y = p[Y]; - if (path_it->closed()) { - Geom::NodeType nodetype = Geom::get_nodetype(*curve_it1, path_it->front()); - switch (nodetype) { - case Geom::NODE_NONE: - path[ip].ty = '}'; - ip++; - break; - case Geom::NODE_CUSP: - path[0].ty = path[ip].ty = 'v'; - break; - case Geom::NODE_SMOOTH: - case Geom::NODE_SYMM: - path[0].ty = path[ip].ty = 'c'; - break; - } - } else { - path[ip].ty = '}'; - ip++; - } - - int sp_len = ip; - Spiro::spiro_run(path, sp_len, *curve); - ip = 0; - } - - g_free (path); -} - void PenTool::_setSubsequentPoint(Geom::Point const p, bool statusbar, guint status) { g_assert( this->npoints != 0 ); -- cgit v1.2.3 From 0932ef5feb3707d94b527890bab29ed67d20b384 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Fri, 14 Aug 2015 01:23:05 +0200 Subject: Refactor of BSPline code attemping to fix the duplicate end node bug, not sure if fixed jet (bzr r14300) --- src/ui/tools/pen-tool.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/ui/tools/pen-tool.cpp') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 6a3928f27..69068f2a7 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -382,11 +382,12 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) { if( anchor && anchor == this->sa && this->green_curve->is_empty()){ //remove the following line to avoid having one node on top of another _finishSegment(event_dt, bevent.state); - _finish( false); + _finish(true); return true; } return false; } + bool ret = false; if (bevent.button == 1 && !this->space_panning // make sure this is not the last click for a waiting LPE (otherwise we want to finish the path) @@ -860,7 +861,7 @@ bool PenTool::_handleButtonRelease(GdkEventButton const &revent) { bool PenTool::_handle2ButtonPress(GdkEventButton const &bevent) { bool ret = false; // only end on LMB double click. Otherwise horizontal scrolling causes ending of the path - if (this->npoints != 0 && bevent.button == 1) { + if (this->npoints != 0 && bevent.button == 1 && this->state != PenTool::CLOSE) { this->_finish(false); ret = true; } -- 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/ui/tools/pen-tool.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/ui/tools/pen-tool.cpp') diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp index 69068f2a7..2ed366a7d 100644 --- a/src/ui/tools/pen-tool.cpp +++ b/src/ui/tools/pen-tool.cpp @@ -84,7 +84,7 @@ namespace Tools { static Geom::Point pen_drag_origin_w(0, 0); static bool pen_within_tolerance = false; static int pen_last_paraxial_dir = 0; // last used direction in horizontal/vertical mode; 0 = horizontal, 1 = vertical -const double HANDLE_CUBIC_GAP = 0.01; +const double HANDLE_CUBIC_GAP = 0.001; const std::string& PenTool::getPrefsPath() { return PenTool::prefsPath; -- cgit v1.2.3