diff options
Diffstat (limited to 'src/live_effects/lpe-fillet-chamfer.cpp')
| -rw-r--r-- | src/live_effects/lpe-fillet-chamfer.cpp | 179 |
1 files changed, 94 insertions, 85 deletions
diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 8a8f68d80..d2bdf2d8d 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -28,12 +28,7 @@ #include "live_effects/parameter/filletchamferpointarray.h" // for programmatically updating knots -#include "selection.h" #include "ui/tools-switch.h" -#include "ui/tool/control-point-selection.h" -#include "ui/tool/selectable-control-point.h" -#include "ui/tool/node.h" -#include "ui/tools/node-tool.h" #include <util/units.h> // TODO due to internal breakage in glibmm headers, this must be last: @@ -62,15 +57,18 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) : only_selected(_("Change only selected nodes"), _("Change only selected nodes"), "only_selected", &wr, this, false), flexible(_("Flexible radius size (%)"), _("Flexible radius size (%)"), "flexible", &wr, this, false), use_knot_distance(_("Use knots distance instead radius"), _("Use knots distance instead radius"), "use_knot_distance", &wr, this, false), - unit(_("Unit"), _("Unit"), "unit", &wr, this), - method(_("Method"), _("Fillets methods"), "method", FMConverter, &wr, this, FM_AUTO), - radius(_("Radius (unit or %)"), _("Radius, in unit or %"), "radius", &wr, this, 0.), - helper_size(_("Helper size with direction"), _("Helper size with direction"), "helper_size", &wr, this, 0) + unit(_("Unit:"), _("Unit"), "unit", &wr, this), + method(_("Method:"), _("Fillets methods"), "method", FMConverter, &wr, this, FM_AUTO), + radius(_("Radius (unit or %):"), _("Radius, in unit or %"), "radius", &wr, this, 0.), + chamfer_steps(_("Chamfer steps:"), _("Chamfer steps"), "chamfer_steps", &wr, this, 0), + + helper_size(_("Helper size with direction:"), _("Helper size with direction"), "helper_size", &wr, this, 0) { registerParameter(&fillet_chamfer_values); registerParameter(&unit); registerParameter(&method); registerParameter(&radius); + registerParameter(&chamfer_steps); registerParameter(&helper_size); registerParameter(&flexible); registerParameter(&use_knot_distance); @@ -81,9 +79,13 @@ LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) : radius.param_set_range(0., infinity()); radius.param_set_increments(1, 1); radius.param_set_digits(4); + chamfer_steps.param_set_range(1, 999); + chamfer_steps.param_set_increments(1, 1); + chamfer_steps.param_set_digits(0); helper_size.param_set_range(0, infinity()); helper_size.param_set_increments(5, 5); helper_size.param_set_digits(0); + fillet_chamfer_values.set_chamfer_steps(3); } LPEFilletChamfer::~LPEFilletChamfer() {} @@ -112,6 +114,16 @@ Gtk::Widget *LPEFilletChamfer::newWidget() Gtk::Entry *entryWidg = dynamic_cast<Gtk::Entry *>(childList[1]); entryWidg->set_width_chars(6); } + } else if (param->param_key == "chamfer_steps") { + Inkscape::UI::Widget::Scalar *widgRegistered = Gtk::manage(dynamic_cast<Inkscape::UI::Widget::Scalar *>(widg)); + widgRegistered->signal_value_changed().connect(sigc::mem_fun(*this, &LPEFilletChamfer::chamferSubdivisions)); + widg = widgRegistered; + if (widg) { + Gtk::HBox *scalarParameter = dynamic_cast<Gtk::HBox *>(widg); + std::vector<Gtk::Widget *> childList = scalarParameter->get_children(); + Gtk::Entry *entryWidg = dynamic_cast<Gtk::Entry *>(childList[1]); + entryWidg->set_width_chars(3); + } } else if (param->param_key == "flexible") { Gtk::CheckButton *widgRegistered = Gtk::manage(dynamic_cast<Gtk::CheckButton *>(widg)); widgRegistered->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::toggleFlexFixed)); @@ -141,27 +153,26 @@ Gtk::Widget *LPEFilletChamfer::newWidget() ++it; } - - Gtk::HBox *filletButtonsContainer = Gtk::manage(new Gtk::HBox(true, 0)); + Gtk::HBox *filletContainer = Gtk::manage(new Gtk::HBox(true, 0)); Gtk::Button *fillet = Gtk::manage(new Gtk::Button(Glib::ustring(_("Fillet")))); fillet->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::fillet)); - filletButtonsContainer->pack_start(*fillet, true, true, 2); - Gtk::Button *inverse = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse fillet")))); - inverse->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::inverse)); - filletButtonsContainer->pack_start(*inverse, true, true, 2); - - Gtk::HBox *chamferButtonsContainer = Gtk::manage(new Gtk::HBox(true, 0)); + filletContainer->pack_start(*fillet, true, true, 2); + Gtk::Button *inverseFillet = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse fillet")))); + inverseFillet->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::inverseFillet)); + filletContainer->pack_start(*inverseFillet, true, true, 2); + + Gtk::HBox *chamferContainer = Gtk::manage(new Gtk::HBox(true, 0)); Gtk::Button *chamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Chamfer")))); chamfer->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::chamfer)); - chamferButtonsContainer->pack_start(*chamfer, true, true, 2); - Gtk::Button *doubleChamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Double chamfer")))); - doubleChamfer->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::doubleChamfer)); - chamferButtonsContainer->pack_start(*doubleChamfer, true, true, 2); + chamferContainer->pack_start(*chamfer, true, true, 2); + Gtk::Button *inverseChamfer = Gtk::manage(new Gtk::Button(Glib::ustring(_("Inverse chamfer")))); + inverseChamfer->signal_clicked().connect(sigc::mem_fun(*this, &LPEFilletChamfer::inverseChamfer)); + chamferContainer->pack_start(*inverseChamfer, true, true, 2); - vbox->pack_start(*filletButtonsContainer, true, true, 2); - vbox->pack_start(*chamferButtonsContainer, true, true, 2); + vbox->pack_start(*filletContainer, true, true, 2); + vbox->pack_start(*chamferContainer, true, true, 2); return vbox; } @@ -212,8 +223,7 @@ void LPEFilletChamfer::updateFillet() { double power = 0; if (!flexible) { - Inkscape::Util::Unit const *doc_units = inkscape_active_desktop()->namedview->doc_units; - power = Inkscape::Util::Quantity::convert(radius, unit.get_abbreviation(), doc_units->abbr) * -1; + power = Inkscape::Util::Quantity::convert(radius, unit.get_abbreviation(), *defaultUnit) * -1; } else { power = radius; } @@ -227,64 +237,46 @@ void LPEFilletChamfer::fillet() doChangeType(path_from_piecewise(pwd2, tolerance), 1); } -void LPEFilletChamfer::inverse() +void LPEFilletChamfer::inverseFillet() { Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2(); doChangeType(path_from_piecewise(pwd2, tolerance), 2); } +void LPEFilletChamfer::chamferSubdivisions() +{ + fillet_chamfer_values.set_chamfer_steps(chamfer_steps); + Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2(); + doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 5000); +} + void LPEFilletChamfer::chamfer() { + fillet_chamfer_values.set_chamfer_steps(chamfer_steps); Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2(); - doChangeType(path_from_piecewise(pwd2, tolerance), 3); + doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 3000); } -void LPEFilletChamfer::doubleChamfer() +void LPEFilletChamfer::inverseChamfer() { + fillet_chamfer_values.set_chamfer_steps(chamfer_steps); Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2(); - doChangeType(path_from_piecewise(pwd2, tolerance), 4); + doChangeType(path_from_piecewise(pwd2, tolerance), chamfer_steps + 4000); } void LPEFilletChamfer::refreshKnots() { Piecewise<D2<SBasis> > const &pwd2 = fillet_chamfer_values.get_pwd2(); fillet_chamfer_values.recalculate_knots(pwd2); - SPDesktop *desktop = inkscape_active_desktop(); + SPDesktop *desktop = SP_ACTIVE_DESKTOP; if (tools_isactive(desktop, TOOLS_NODES)) { tools_switch(desktop, TOOLS_SELECT); tools_switch(desktop, TOOLS_NODES); } } -bool LPEFilletChamfer::nodeIsSelected(Geom::Point nodePoint, std::vector<Geom::Point> point) -{ - if (point.size() > 0) { - for (std::vector<Geom::Point>::iterator i = point.begin(); i != point.end(); - ++i) { - Geom::Point p = *i; - if (Geom::are_near(p, nodePoint, 2)) { - return true; - } - } - } - return false; -} void LPEFilletChamfer::doUpdateFillet(std::vector<Geom::Path> const& original_pathv, double power) { - std::vector<Geom::Point> point; - SPDesktop *desktop = inkscape_active_desktop(); - if (INK_IS_NODE_TOOL(desktop->event_context)) { - Inkscape::UI::Tools::NodeTool *nodeTool = INK_NODE_TOOL(desktop->event_context); - Inkscape::UI::ControlPointSelection::Set &selection = nodeTool->_selected_nodes->allPoints(); - std::vector<Geom::Point>::iterator pBegin; - for (Inkscape::UI::ControlPointSelection::Set::iterator i = selection.begin(); i != selection.end(); ++i) { - if ((*i)->selected()) { - Inkscape::UI::Node *n = dynamic_cast<Inkscape::UI::Node *>(*i); - pBegin = point.begin(); - point.insert(pBegin, desktop->doc2dt(n->position())); - } - } - } std::vector<Point> filletChamferData = fillet_chamfer_values.data(); std::vector<Geom::Point> result; std::vector<Geom::Path> original_pathv_processed = pathv_to_linear_and_cubic_beziers(original_pathv); @@ -319,7 +311,7 @@ void LPEFilletChamfer::doUpdateFillet(std::vector<Geom::Path> const& original_pa if (filletChamferData[counter][Y] == 0) { powerend = filletChamferData[counter][X]; } - if (only_selected && !nodeIsSelected(curve_it1->initialPoint(), point)) { + if (only_selected && !isNodePointSelected(curve_it1->initialPoint())) { powerend = filletChamferData[counter][X]; } result.push_back(Point(powerend, filletChamferData[counter][Y])); @@ -333,24 +325,6 @@ void LPEFilletChamfer::doUpdateFillet(std::vector<Geom::Path> const& original_pa void LPEFilletChamfer::doChangeType(std::vector<Geom::Path> const& original_pathv, int type) { - std::vector<Geom::Point> point; - SPDesktop *desktop = inkscape_active_desktop(); - if (INK_IS_NODE_TOOL(desktop->event_context)) { - Inkscape::UI::Tools::NodeTool *nodeTool = - INK_NODE_TOOL(desktop->event_context); - Inkscape::UI::ControlPointSelection::Set &selection = - nodeTool->_selected_nodes->allPoints(); - std::vector<Geom::Point>::iterator pBegin; - for (Inkscape::UI::ControlPointSelection::Set::iterator i = - selection.begin(); - i != selection.end(); ++i) { - if ((*i)->selected()) { - Inkscape::UI::Node *n = dynamic_cast<Inkscape::UI::Node *>(*i); - pBegin = point.begin(); - point.insert(pBegin, desktop->doc2dt(n->position())); - } - } - } std::vector<Point> filletChamferData = fillet_chamfer_values.data(); std::vector<Geom::Point> result; std::vector<Geom::Path> original_pathv_processed = pathv_to_linear_and_cubic_beziers(original_pathv); @@ -373,12 +347,18 @@ void LPEFilletChamfer::doChangeType(std::vector<Geom::Path> const& original_path bool toggle = true; if (filletChamferData[counter][Y] == 0 || (ignore_radius_0 && (filletChamferData[counter][X] == 0 || - filletChamferData[counter][X] == counter)) || - (only_selected && - !nodeIsSelected(curve_it1->initialPoint(), point))) { + filletChamferData[counter][X] == counter)) || + (only_selected && !isNodePointSelected(curve_it1->initialPoint()))) { toggle = false; } if (toggle) { + if(type >= 5000){ + if(filletChamferData[counter][Y] >= 3000 && filletChamferData[counter][Y] < 4000){ + type = type - 2000; + } else if (filletChamferData[counter][Y] >= 4000 && filletChamferData[counter][Y] < 5000){ + type = type - 1000; + } + } result.push_back(Point(filletChamferData[counter][X], type)); } else { result.push_back(filletChamferData[counter]); @@ -451,6 +431,8 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) fillet_chamfer_values.param_set_and_write_new_value(point); } else { g_warning("LPE Fillet can only be applied to shapes (not groups)."); + SPLPEItem * item = const_cast<SPLPEItem*>(lpeItem); + item->removeCurrentPathEffect(false); } } @@ -462,6 +444,7 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) } else { fillet_chamfer_values.set_helper_size(helper_size); } + fillet_chamfer_values.set_document_unit(defaultUnit); fillet_chamfer_values.set_use_distance(use_knot_distance); fillet_chamfer_values.set_unit(unit.get_abbreviation()); SPCurve *c = SP_IS_PATH(lpeItem) ? static_cast<SPPath const *>(lpeItem) @@ -597,11 +580,37 @@ LPEFilletChamfer::doEffect_path(std::vector<Geom::Path> const &path_in) } else { type = std::abs(filletChamferData[counter + 1][Y]); } - if (type == 3 || type == 4) { - if (type == 4) { - Geom::Point central = middle_point(startArcPoint, endArcPoint); - LineSegment chamferCenter(central, curve_it1->finalPoint()); - path_out.appendNew<Geom::LineSegment>(chamferCenter.pointAt(0.5)); + if(are_near(middle_point(startArcPoint,endArcPoint),curve_it1->finalPoint(), 0.0001)){ + path_out.appendNew<Geom::LineSegment>(endArcPoint); + } else if (type >= 3000 && type < 4000) { + unsigned int chamferSubs = type-3000; + Geom::Path path_chamfer; + path_chamfer.start(path_out.finalPoint()); + if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){ + path_chamfer.appendNew<SVGEllipticalArc>(rx, ry, angleArc, 0, ccwToggle, endArcPoint); + } else { + path_chamfer.appendNew<Geom::CubicBezier>(handle1, handle2, endArcPoint); + } + double chamfer_stepsTime = 1.0/chamferSubs; + for(unsigned int i = 1; i < chamferSubs; i++){ + Geom::Point chamferStep = path_chamfer.pointAt(chamfer_stepsTime * i); + path_out.appendNew<Geom::LineSegment>(chamferStep); + } + path_out.appendNew<Geom::LineSegment>(endArcPoint); + } else if (type >= 4000 && type < 5000) { + unsigned int chamferSubs = type-4000; + Geom::Path path_chamfer; + path_chamfer.start(path_out.finalPoint()); + if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){ + ccwToggle = ccwToggle?0:1; + path_chamfer.appendNew<SVGEllipticalArc>(rx, ry, angleArc, 0, ccwToggle, endArcPoint); + }else{ + path_chamfer.appendNew<Geom::CubicBezier>(inverseHandle1, inverseHandle2, endArcPoint); + } + double chamfer_stepsTime = 1.0/chamferSubs; + for(unsigned int i = 1; i < chamferSubs; i++){ + Geom::Point chamferStep = path_chamfer.pointAt(chamfer_stepsTime * i); + path_out.appendNew<Geom::LineSegment>(chamferStep); } path_out.appendNew<Geom::LineSegment>(endArcPoint); } else if (type == 2) { @@ -611,7 +620,7 @@ LPEFilletChamfer::doEffect_path(std::vector<Geom::Path> const &path_in) }else{ path_out.appendNew<Geom::CubicBezier>(inverseHandle1, inverseHandle2, endArcPoint); } - } else { + } else if (type == 1){ if((is_straight_curve(*curve_it1) && is_straight_curve(*curve_it2Fixed) && method != FM_BEZIER )|| method == FM_ARC){ path_out.appendNew<SVGEllipticalArc>(rx, ry, angleArc, 0, ccwToggle, endArcPoint); } else { |
