diff options
Diffstat (limited to 'src/live_effects/lpe-transform_2pts.cpp')
| -rw-r--r-- | src/live_effects/lpe-transform_2pts.cpp | 116 |
1 files changed, 101 insertions, 15 deletions
diff --git a/src/live_effects/lpe-transform_2pts.cpp b/src/live_effects/lpe-transform_2pts.cpp index b70b68968..79ffd74de 100644 --- a/src/live_effects/lpe-transform_2pts.cpp +++ b/src/live_effects/lpe-transform_2pts.cpp @@ -18,6 +18,7 @@ #include <2geom/pathvector.h> #include "sp-path.h" #include "ui/icon-names.h" +#include "svg/svg.h" #include <glibmm/i18n.h> @@ -26,25 +27,39 @@ namespace LivePathEffect { LPETransform2Pts::LPETransform2Pts(LivePathEffectObject *lpeobject) : Effect(lpeobject), + elastic(_("Elastic"), _("Elastic transform mode"), "elastic", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), from_original_width(_("From original width"), _("From original width"), "from_original_width", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), + lock_lenght(_("Lock lenght"), _("Lock lenght to current distance"), "lock_lenght", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), + lock_angle(_("Lock angle"), _("Lock angle"), "lock_angle", &wr, this, false,"", INKSCAPE_ICON("on"), INKSCAPE_ICON("off")), start(_("Start"), _("Start point"), "start", &wr, this, "Start point"), end(_("End"), _("End point"), "end", &wr, this, "End point"), first_knot(_("First Knot"), _("First Knot"), "first_knot", &wr, this, 1), last_knot(_("Last Knot"), _("Last Knot"), "last_knot", &wr, this, 1), + helper_size(_("Helper size:"), _("Rotation helper size"), "helper_size", &wr, this, 3), from_original_width_toggler(false), point_a(Geom::Point()), point_b(Geom::Point()), pathvector(), - append_path(false) + append_path(false), + previous_angle(Geom::deg_to_rad(0)), + previous_start(Geom::Point()), + previous_lenght(-1) { registerParameter(&start); registerParameter(&end); registerParameter(&first_knot); registerParameter(&last_knot); + registerParameter(&helper_size); + registerParameter(&elastic); registerParameter(&from_original_width); + registerParameter(&lock_lenght); + registerParameter(&lock_angle); first_knot.param_make_integer(true); last_knot.param_make_integer(true); + helper_size.param_set_range(0, 999); + helper_size.param_set_increments(1, 1); + helper_size.param_set_digits(0); } LPETransform2Pts::~LPETransform2Pts() @@ -67,12 +82,16 @@ LPETransform2Pts::doOnApply(SPLPEItem const* lpeitem) if(!pathvector.empty()) { point_a = pathvector.initialPoint(); point_b = pathvector.finalPoint(); - if(are_near(point_a,point_b)){ + if(are_near(point_a,point_b)) { point_b = pathvector.back().finalCurve().initialPoint(); } size_t nnodes = nodeCount(pathvector); last_knot.param_set_value(nnodes); } + + previous_lenght = Geom::distance(point_a,point_b); + Geom::Ray transformed(point_a,point_b); + previous_angle = transformed.angle(); start.param_update_default(point_a); start.param_set_default(); end.param_update_default(point_b); @@ -101,7 +120,6 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) point_a = pointAtNodeIndex(pathvector,(size_t)first_knot-1); point_b = pointAtNodeIndex(pathvector,(size_t)last_knot-1); size_t nnodes = nodeCount(pathvector); - std::cout << nnodes << "nnodes\n"; first_knot.param_set_range(1, last_knot-1); last_knot.param_set_range(first_knot+1, nnodes); from_original_width.param_setValue(false); @@ -113,6 +131,24 @@ LPETransform2Pts::doBeforeEffect (SPLPEItem const* lpeitem) from_original_width.param_setValue(true); append_path = false; } + if(lock_lenght && !lock_angle && previous_lenght != -1) { + Geom::Ray transformed((Geom::Point)start,(Geom::Point)end); + if(previous_start == start || previous_angle == Geom::deg_to_rad(0)) { + previous_angle = transformed.angle(); + } + } else if(lock_angle && !lock_lenght && previous_angle != Geom::deg_to_rad(0)) { + if(previous_start == start){ + previous_lenght = Geom::distance((Geom::Point)start, (Geom::Point)end); + } + } + if(lock_lenght || lock_angle ) { + Geom::Point end_point = Geom::Point::polar(previous_angle, previous_lenght) + (Geom::Point)start; + end.param_setValue(end_point); + } + Geom::Ray transformed((Geom::Point)start,(Geom::Point)end); + previous_angle = transformed.angle(); + previous_lenght = Geom::distance((Geom::Point)start, (Geom::Point)end); + previous_start = start; splpeitem->apply_to_clippath(splpeitem); splpeitem->apply_to_mask(splpeitem); } @@ -125,7 +161,10 @@ LPETransform2Pts::updateIndex() if (sp_path) { pathvector = sp_path->get_original_curve()->get_pathvector(); } - if(!pathvector.empty() && !from_original_width) { + if(pathvector.empty()) { + return; + } + if(!from_original_width) { point_a = pointAtNodeIndex(pathvector,(size_t)first_knot-1); point_b = pointAtNodeIndex(pathvector,(size_t)last_knot-1); start.param_update_default(point_a); @@ -155,7 +194,7 @@ LPETransform2Pts::pointAtNodeIndex(Geom::PathVector pathvector, size_t index) co size_t n = 0; for (Geom::PathVector::iterator pv_it = pathvector.begin(); pv_it != pathvector.end(); ++pv_it) { for (Geom::Path::iterator curve_it = pv_it->begin(); curve_it != pv_it->end_closed(); ++curve_it) { - if(index == n){ + if(index == n) { return curve_it->initialPoint(); } n++; @@ -170,7 +209,7 @@ LPETransform2Pts::pathAtNodeIndex(Geom::PathVector pathvector, size_t index) con size_t n = 0; for (Geom::PathVector::iterator pv_it = pathvector.begin(); pv_it != pathvector.end(); ++pv_it) { for (Geom::Path::iterator curve_it = pv_it->begin(); curve_it != pv_it->end_closed(); ++curve_it) { - if(index == n){ + if(index == n) { return *pv_it; } n++; @@ -197,6 +236,9 @@ LPETransform2Pts::reset() first_knot.param_set_value(1); last_knot.param_set_value(2); } + Geom::Ray transformed(point_a, point_b); + previous_angle = transformed.angle(); + previous_lenght = Geom::distance(point_a, point_b); start.param_update_default(point_a); end.param_update_default(point_b); start.param_set_default(); @@ -214,7 +256,9 @@ Gtk::Widget *LPETransform2Pts::newWidget() vbox->set_spacing(6); std::vector<Parameter *>::iterator it = param_vector.begin(); - Gtk::HBox * button = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::HBox * button1 = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::HBox * button2 = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::HBox * button3 = Gtk::manage(new Gtk::HBox(true,0)); while (it != param_vector.end()) { if ((*it)->widget_is_visible) { Parameter *param = *it; @@ -237,10 +281,21 @@ Gtk::Widget *LPETransform2Pts::newWidget() widg->set_has_tooltip(false); } } - } else if (param->param_key == "from_original_width") { + } else if (param->param_key == "from_original_width" || param->param_key == "elastic") { + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + button1->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } else if (param->param_key == "lock_angle" || param->param_key == "lock_lenght") { Glib::ustring * tip = param->param_getTooltip(); if (widg) { - button->pack_start(*widg, true, true, 2); + button2->pack_start(*widg, true, true, 2); if (tip) { widg->set_tooltip_text(*tip); } else { @@ -263,8 +318,10 @@ Gtk::Widget *LPETransform2Pts::newWidget() } Gtk::Button *reset = Gtk::manage(new Gtk::Button(Glib::ustring(_("Reset")))); reset->signal_clicked().connect(sigc::mem_fun(*this, &LPETransform2Pts::reset)); - button->pack_start(*reset, true, true, 2); - vbox->pack_start(*button, true, true, 2); + button3->pack_start(*reset, true, true, 2); + vbox->pack_start(*button1, true, true, 2); + vbox->pack_start(*button2, true, true, 2); + vbox->pack_start(*button3, true, true, 2); return dynamic_cast<Gtk::Widget *>(vbox); } @@ -280,10 +337,23 @@ LPETransform2Pts::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const helper.start(point_a); helper.appendNew<Geom::LineSegment>(point_b); Geom::Affine m; - m *= Geom::Scale(sca); - m *= Geom::Rotate(rot); - helper *= m; - m *= Geom::Translate((Geom::Point)start - helper.initialPoint()); + if(elastic) { + Geom::Angle original_angle = original.angle(); + m *= Geom::Rotate(-original_angle); + if(sca > 1){ + m *= Geom::Scale(sca, 1.0); + } else { + m *= Geom::Scale(sca, 1.0-((1.0-sca)/2.0)); + } + m *= Geom::Rotate(transformed.angle()); + helper *= m; + m *= Geom::Translate((Geom::Point)start - helper.initialPoint()); + } else { + m *= Geom::Scale(sca); + m *= Geom::Rotate(rot); + helper *= m; + m *= Geom::Translate((Geom::Point)start - helper.initialPoint()); + } output.concat(pwd2_in * m); return output; @@ -299,6 +369,22 @@ LPETransform2Pts::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector< hp.appendNew<Geom::LineSegment>((Geom::Point)end); Geom::PathVector pathv; pathv.push_back(hp); + double r = helper_size*.1; + if(lock_lenght || lock_angle ) { + char const * svgd; + svgd = "M -5.39,8.78 -9.13,5.29 -10.38,10.28 Z M -7.22,7.07 -3.43,3.37 m -1.95,-12.16 -3.74,3.5 -1.26,-5 z m -1.83,1.71 3.78,3.7 M 5.24,8.78 8.98,5.29 10.24,10.28 Z M 7.07,7.07 3.29,3.37 M 5.24,-8.78 l 3.74,3.5 1.26,-5 z M 7.07,-7.07 3.29,-3.37"; + PathVector pathv_move = sp_svg_read_pathv(svgd); + pathv_move *= Affine(r,0,0,r,0,0) * Translate(Geom::Point(start)); + hp_vec.push_back(pathv_move); + } + if(!lock_angle && lock_lenght) { + char const * svgd; + svgd = "m 7.07,7.07 c -3.9,3.91 -10.24,3.91 -14.14,0 -3.91,-3.9 -3.91,-10.24 0,-14.14 3.9,-3.91 10.24,-3.91 14.14,0 l -2.83,-4.24 -0.7,2.12"; + PathVector pathv_turn = sp_svg_read_pathv(svgd); + pathv_turn *= Geom::Rotate(previous_angle); + pathv_turn *= Affine(r,0,0,r,0,0) * Translate(Geom::Point(end)); + hp_vec.push_back(pathv_turn); + } hp_vec.push_back(pathv); } |
