From a230b9d6684f01ded46fd530ba0cc74ce9696e2d Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Thu, 19 Feb 2015 21:53:20 +0100 Subject: Basic filleting using pointwise (bzr r13645.1.16) --- .../parameter/filletchamferpointarray.cpp | 881 --------------------- 1 file changed, 881 deletions(-) delete mode 100644 src/live_effects/parameter/filletchamferpointarray.cpp (limited to 'src/live_effects/parameter/filletchamferpointarray.cpp') diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp deleted file mode 100644 index 2ebe11b4b..000000000 --- a/src/live_effects/parameter/filletchamferpointarray.cpp +++ /dev/null @@ -1,881 +0,0 @@ -/* - * Copyright (C) Jabiertxo Arraiza Cenoz - * Special thanks to Johan Engelen for the base of the effect -powerstroke- - * Also to ScislaC for point me to the idea - * Also su_v for his construvtive feedback and time - * and finaly to Liam P. White for his big help on coding, that save me a lot of - * hours - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include <2geom/piecewise.h> -#include <2geom/sbasis-to-bezier.h> -#include <2geom/sbasis-geometric.h> -#include <2geom/svg-elliptical-arc.h> -#include <2geom/line.h> -#include <2geom/path-intersection.h> - -#include "ui/dialog/lpe-fillet-chamfer-properties.h" -#include "live_effects/parameter/filletchamferpointarray.h" -#include "live_effects/effect.h" -#include "svg/svg.h" -#include "svg/stringstream.h" -#include "knotholder.h" -#include "sp-lpe-item.h" -#include "selection.h" - -// needed for on-canvas editting: -#include "desktop.h" -#include "live_effects/lpeobject.h" -#include "helper/geom-nodetype.h" -#include "helper/geom-curves.h" -#include "ui/tools/node-tool.h" - -// TODO due to internal breakage in glibmm headers, -// this has to be included last. -#include - - -using namespace Geom; - -namespace Inkscape { - -namespace LivePathEffect { - -FilletChamferPointArrayParam::FilletChamferPointArrayParam( - const Glib::ustring &label, const Glib::ustring &tip, - const Glib::ustring &key, Inkscape::UI::Widget::Registry *wr, - Effect *effect) - : ArrayParam(label, tip, key, wr, effect, 0) -{ - knot_shape = SP_KNOT_SHAPE_DIAMOND; - knot_mode = SP_KNOT_MODE_XOR; - knot_color = 0x00ff0000; -} - -FilletChamferPointArrayParam::~FilletChamferPointArrayParam() {} - -Gtk::Widget *FilletChamferPointArrayParam::param_newWidget() -{ - return NULL; - /* - Inkscape::UI::Widget::RegisteredTransformedPoint * pointwdg = - Gtk::manage( - new Inkscape::UI::Widget::RegisteredTransformedPoint( - param_label, - param_tooltip, - param_key, - *param_wr, - param_effect->getRepr(), - param_effect->getSPDoc() - ) ); - // TODO: fix to get correct desktop (don't use SP_ACTIVE_DESKTOP) - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - Affine transf = desktop->doc2dt(); - pointwdg->setTransform(transf); - pointwdg->setValue( *this ); - pointwdg->clearProgrammatically(); - pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, - _("Change point parameter")); - - Gtk::HBox * hbox = Gtk::manage( new Gtk::HBox() ); - static_cast(hbox)->pack_start(*pointwdg, true, true); - static_cast(hbox)->show_all_children(); - - return dynamic_cast (hbox); - */ -} - -void -FilletChamferPointArrayParam::param_transform_multiply(Affine const &postmul, - bool /*set*/) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - if (prefs->getBool("/options/transform/rectcorners", true) && - _vector[1][X] <= 0) { - std::vector result; - for (std::vector::const_iterator point_it = _vector.begin(); - point_it != _vector.end(); ++point_it) { - Coord A = - (*point_it)[X] * ((postmul.expansionX() + postmul.expansionY()) / 2); - result.push_back(Point(A, (*point_it)[Y])); - } - param_set_and_write_new_value(result); - } - - // param_set_and_write_new_value( (*this) * postmul ); -} - -/** call this method to recalculate the controlpoints such that they stay at the - * same location relative to the new path. Useful after adding/deleting nodes to - * the path.*/ -void FilletChamferPointArrayParam::recalculate_controlpoints_for_new_pwd2( - Piecewise > const &pwd2_in) -{ - if (!last_pwd2.empty()) { - PathVector const pathv = - path_from_piecewise(remove_short_cuts(pwd2_in, 0.1), 0.001); - PathVector last_pathv = - path_from_piecewise(remove_short_cuts(last_pwd2, 0.1), 0.001); - std::vector result; - unsigned long counter = 0; - unsigned long counterPaths = 0; - unsigned long counterCurves = 0; - long offset = 0; - long offsetPaths = 0; - Geom::NodeType nodetype; - for (PathVector::const_iterator path_it = pathv.begin(); - path_it != pathv.end(); ++path_it) { - if (path_it->empty()) { - counterPaths++; - counter++; - 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(); - if (path_it->closed() && path_it->back_closed().isDegenerate()) { - const Curve &closingline = path_it->back_closed(); - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - curve_endit = path_it->end_open(); - } - } - counterCurves = 0; - while (curve_it1 != curve_endit) { - //if start a path get node type - if (counterCurves == 0) { - if (path_it->closed()) { - if (path_it->back_closed().isDegenerate()) { - nodetype = get_nodetype(path_it->back_open(), *curve_it1); - } else { - nodetype = get_nodetype(path_it->back_closed(), *curve_it1); - } - } else { - nodetype = NODE_NONE; - } - } else { - //check node type also whith straight lines because get_nodetype - //return non cusp node in a node inserted inside a straight line - //todo: if the path remove some nodes whith the result of a straight - //line but with handles, the node inserted into dont fire the knot - // because is not handle as cusp node by get_nodetype function - bool this_is_line = true; - bool next_is_line = is_straight_curve(*curve_it1); - this_is_line = is_straight_curve((*path_it)[counterCurves - 1]); - nodetype = get_nodetype((*path_it)[counterCurves - 1], *curve_it1); - if (this_is_line || next_is_line) { - nodetype = NODE_CUSP; - } - } - if (last_pathv.size() > pathv.size() || - (last_pathv.size() > counterPaths && - last_pathv[counterPaths].size() > counter - offset && - !are_near(curve_it1->initialPoint(), - last_pathv[counterPaths][counter - offset].initialPoint(), - 0.1))) { - if ( curve_it2 == curve_endit) { - if (last_pathv[counterPaths].size() != pathv[counterPaths].size()) { - offset = (last_pathv[counterPaths].size() - pathv[counterPaths].size()) * -1; - } else { - offset = 0; - } - offsetPaths += offset; - offset = offsetPaths; - } else if (counterCurves == 0 && last_pathv.size() <= pathv.size() && - counter - offset <= last_pathv[counterPaths].size() && - are_near(curve_it1->initialPoint(), - last_pathv[counterPaths].finalPoint(), 0.1) && - !last_pathv[counterPaths].closed()) { - long e = counter - offset + 1; - std::vector tmp = _vector; - for (unsigned long i = - last_pathv[counterPaths].size() + counter - offset; - i > counterCurves - offset + 1; i--) { - - if (tmp[i - 1][X] > 0) { - double fractpart, intpart; - fractpart = modf(tmp[i - 1][X], &intpart); - _vector[e] = Point(e + fractpart, tmp[i - 1][Y]); - } else { - _vector[e] = Point(tmp[i - 1][X], tmp[i - 1][Y]); - } - e++; - } - //delete temp vector - std::vector().swap(tmp); - if (last_pathv.size() > counterPaths) { - last_pathv[counterPaths] = last_pathv[counterPaths].reverse(); - } - } else { - if (last_pathv.size() > counterPaths) { - if (last_pathv[counterPaths].size() < - pathv[counterPaths].size()) { - offset++; - } else if (last_pathv[counterPaths].size() > - pathv[counterPaths].size()) { - offset--; - continue; - } - } else { - offset++; - } - } - double xPos = 0; - if (_vector[1][X] > 0) { - xPos = nearest_point(curve_it1->initialPoint(), pwd2_in); - } - if (nodetype == NODE_CUSP) { - result.push_back(Point(xPos, 1)); - } else { - result.push_back(Point(xPos, 0)); - } - } else { - double xPos = _vector[counter - offset][X]; - if (_vector.size() <= (unsigned)(counter - offset)) { - if (_vector[1][X] > 0) { - xPos = nearest_point(curve_it1->initialPoint(), pwd2_in); - } else { - xPos = 0; - } - } - if (nodetype == NODE_CUSP) { - double vectorY = _vector[counter - offset][Y]; - if (_vector.size() <= (unsigned)(counter - offset) || vectorY == 0) { - vectorY = 1; - } - result.push_back(Point(xPos, vectorY)); - } else { - if (_vector[1][X] < 0) { - xPos = 0; - } - result.push_back(Point(floor(xPos), 0)); - } - } - ++curve_it1; - if (curve_it2 != curve_endit) { - ++curve_it2; - } - counter++; - counterCurves++; - } - counterPaths++; - } - _vector = result; - write_to_SVG(); - } -} - -void FilletChamferPointArrayParam::recalculate_knots( - Piecewise > const &pwd2_in) -{ - bool change = false; - PathVector pathv = path_from_piecewise(pwd2_in, 0.001); - if (!pathv.empty()) { - std::vector result; - int counter = 0; - int counterCurves = 0; - Geom::NodeType nodetype; - for (PathVector::const_iterator path_it = pathv.begin(); - path_it != pathv.end(); ++path_it) { - if (path_it->empty()) { - counter++; - 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(); - if (path_it->closed() && path_it->back_closed().isDegenerate()) { - const Curve &closingline = path_it->back_closed(); - if (are_near(closingline.initialPoint(), closingline.finalPoint())) { - curve_endit = path_it->end_open(); - } - } - counterCurves = 0; - while (curve_it1 != curve_endit) { - //if start a path get node type - if (counterCurves == 0) { - if (path_it->closed()) { - if (path_it->back_closed().isDegenerate()) { - nodetype = get_nodetype(path_it->back_open(), *curve_it1); - } else { - nodetype = get_nodetype(path_it->back_closed(), *curve_it1); - } - } else { - nodetype = NODE_NONE; - } - } else { - bool this_is_line = true; - bool next_is_line = is_straight_curve(*curve_it1); - this_is_line = is_straight_curve((*path_it)[counterCurves - 1]); - nodetype = get_nodetype((*path_it)[counterCurves - 1], *curve_it1); - if (this_is_line || next_is_line) { - nodetype = NODE_CUSP; - } - } - if (nodetype == NODE_CUSP) { - double vectorY = _vector[counter][Y]; - if (vectorY == 0) { - vectorY = 1; - change = true; - } - result.push_back(Point(_vector[counter][X], vectorY)); - } else { - double xPos = floor(_vector[counter][X]); - if (_vector[1][X] < 0) { - xPos = 0; - } - double vectorY = _vector[counter][Y]; - if (vectorY != 0) { - change = true; - } - result.push_back(Point(xPos, 0)); - } - ++curve_it1; - counter++; - if (curve_it2 != curve_endit) { - ++curve_it2; - } - counterCurves++; - } - } - if (change) { - _vector = result; - write_to_SVG(); - } - } -} - -void FilletChamferPointArrayParam::set_pwd2( - Piecewise > const &pwd2_in, - Piecewise > const &pwd2_normal_in) -{ - last_pwd2 = pwd2_in; - last_pwd2_normal = pwd2_normal_in; -} - -void FilletChamferPointArrayParam::set_document_unit(Glib::ustring const * value_document_unit) -{ - documentUnit = value_document_unit; -} - -void FilletChamferPointArrayParam::set_helper_size(int hs) -{ - helper_size = hs; -} - -void FilletChamferPointArrayParam::set_chamfer_steps(int value_chamfer_steps) -{ - chamfer_steps = value_chamfer_steps; -} - -void FilletChamferPointArrayParam::set_use_distance(bool use_knot_distance ) -{ - use_distance = use_knot_distance; -} - -void FilletChamferPointArrayParam::set_unit(const gchar *abbr) -{ - unit = abbr; -} - -void FilletChamferPointArrayParam::updateCanvasIndicators() -{ - std::vector ts = data(); - hp.clear(); - unsigned int i = 0; - for (std::vector::const_iterator point_it = ts.begin(); - point_it != ts.end(); ++point_it) { - double Xvalue = to_time(i, (*point_it)[X]) -i; - if (Xvalue == 0) { - i++; - continue; - } - Geom::Point ptA = last_pwd2[i].valueAt(Xvalue); - Geom::Point derivA = unit_vector(derivative(last_pwd2[i]).valueAt(Xvalue)); - Geom::Rotate rot(Geom::Rotate::from_degrees(-90)); - derivA = derivA * rot; - Geom::Point C = ptA - derivA * helper_size; - Geom::Point D = ptA + derivA * helper_size; - Geom::Ray ray1(C, D); - char const * svgd = "M 1,0.25 0.5,0 1,-0.25 M 1,0.5 0,0 1,-0.5"; - Geom::PathVector pathv = sp_svg_read_pathv(svgd); - Geom::Affine aff = Geom::Affine(); - aff *= Geom::Scale(helper_size); - aff *= Geom::Rotate(ray1.angle() - deg_to_rad(270)); - pathv *= aff; - pathv += last_pwd2[i].valueAt(Xvalue); - hp.push_back(pathv[0]); - hp.push_back(pathv[1]); - i++; - } -} - -void FilletChamferPointArrayParam::addCanvasIndicators( - SPLPEItem const */*lpeitem*/, std::vector &hp_vec) -{ - hp_vec.push_back(hp); -} - -double FilletChamferPointArrayParam::rad_to_len(int index, double rad) -{ - double len = 0; - std::vector subpaths = path_from_piecewise(last_pwd2, 0.1); - std::pair positions = get_positions(index, subpaths); - D2 A = last_pwd2[last_index(index, subpaths)]; - if(positions.second != 0){ - A = last_pwd2[index-1]; - }else{ - if(!subpaths[positions.first].closed()){ - return len; - } - } - D2 B = last_pwd2[index]; - Piecewise > offset_curve0 = Piecewise >(A)+rot90(unitVector(derivative(A)))*(rad); - Piecewise > offset_curve1 = Piecewise >(B)+rot90(unitVector(derivative(B)))*(rad); - Geom::Path p0 = path_from_piecewise(offset_curve0, 0.1)[0]; - Geom::Path p1 = path_from_piecewise(offset_curve1, 0.1)[0]; - Geom::Crossings cs = Geom::crossings(p0, p1); - if(cs.size() > 0){ - Point cp =p0(cs[0].ta); - double p0pt = nearest_point(cp, B); - len = time_to_len(index,p0pt); - } else { - if(rad < 0){ - len = rad_to_len(index, rad * -1); - } - } - return len; -} - -double FilletChamferPointArrayParam::len_to_rad(int index, double len) -{ - double rad = 0; - double tmp_len = _vector[index][X]; - _vector[index] = Geom::Point(len,_vector[index][Y]); - std::vector subpaths = path_from_piecewise(last_pwd2, 0.1); - std::pair positions = get_positions(index, subpaths); - Piecewise > u; - u.push_cut(0); - u.push(last_pwd2[last_index(index, subpaths)], 1); - Geom::Curve * A = path_from_piecewise(u, 0.1)[0][0].duplicate(); - Geom::Curve * B = subpaths[positions.first][positions.second].duplicate(); - std::vector times; - if(positions.second != 0){ - A = subpaths[positions.first][positions.second-1].duplicate(); - times = get_times(index-1, subpaths, false); - }else{ - if(!subpaths[positions.first].closed()){ - return rad; - } - times = get_times(last_index(index, subpaths), subpaths, true); - } - _vector[index] = Geom::Point(tmp_len,_vector[index][Y]); - Geom::Point startArcPoint = A->toSBasis().valueAt(times[1]); - Geom::Point endArcPoint = B->toSBasis().valueAt(times[2]); - Curve *knotCurve1 = A->portion(times[0], times[1]); - Curve *knotCurve2 = B->portion(times[2], 1); - Geom::CubicBezier const *cubic1 = dynamic_cast(&*knotCurve1); - Ray ray1(startArcPoint, A->finalPoint()); - if (cubic1) { - ray1.setPoints((*cubic1)[2], startArcPoint); - } - Geom::CubicBezier const *cubic2 = dynamic_cast(&*knotCurve2); - Ray ray2(B->initialPoint(), endArcPoint); - if (cubic2) { - ray2.setPoints(endArcPoint, (*cubic2)[1]); - } - bool ccwToggle = cross(A->finalPoint() - startArcPoint, endArcPoint - startArcPoint) < 0; - double distanceArc = Geom::distance(startArcPoint,middle_point(startArcPoint,endArcPoint)); - double angleBetween = angle_between(ray1, ray2, ccwToggle); - rad = distanceArc/sin(angleBetween/2.0); - return rad * -1; -} - -std::vector FilletChamferPointArrayParam::get_times(int index, std::vector subpaths, bool last) -{ - const double tolerance = 0.001; - const double gapHelper = 0.00001; - std::pair positions = get_positions(index, subpaths); - Curve *curve_it1; - curve_it1 = subpaths[positions.first][positions.second].duplicate(); - Coord it1_length = (*curve_it1).length(tolerance); - double time_it1, time_it2, time_it1_B, intpart; - time_it1 = modf(to_time(index, _vector[index][X]), &intpart); - if (_vector[index][Y] == 0) { - time_it1 = 0; - } - double resultLenght = 0; - time_it1_B = 1; - if (subpaths[positions.first].closed() && last) { - time_it2 = modf(to_time(index - positions.second , _vector[index - positions.second ][X]), &intpart); - resultLenght = it1_length + to_len(index - positions.second, _vector[index - positions.second ][X]); - } else if (!subpaths[positions.first].closed() && last){ - time_it2 = 0; - resultLenght = 0; - } else { - time_it2 = modf(to_time(index + 1, _vector[index + 1][X]), &intpart); - resultLenght = it1_length + to_len( index + 1, _vector[index + 1][X]); - } - if (resultLenght > 0 && time_it2 != 0) { - time_it1_B = modf(to_time(index, -resultLenght), &intpart); - } else { - if (time_it2 == 0) { - time_it1_B = 1; - } else { - time_it1_B = gapHelper; - } - } - - if ((subpaths[positions.first].closed() && last && _vector[index - positions.second][Y] == 0) || (subpaths[positions.first].size() > positions.second + 1 && _vector[index + 1][Y] == 0)) { - time_it1_B = 1; - time_it2 = 0; - } - if (time_it1_B < time_it1) { - time_it1_B = time_it1 + gapHelper; - } - std::vector out; - out.push_back(time_it1); - out.push_back(time_it1_B); - out.push_back(time_it2); - return out; -} - -std::pair FilletChamferPointArrayParam::get_positions(int index, std::vector subpaths) -{ - int counter = -1; - std::size_t first = 0; - std::size_t second = 0; - for (PathVector::const_iterator path_it = subpaths.begin(); path_it != subpaths.end(); ++path_it) { - if (path_it->empty()) - continue; - Geom::Path::const_iterator curve_it1 = 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(); - // 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(); - } - } - first++; - second = 0; - while (curve_it1 != curve_endit) { - counter++; - second++; - if(counter == index){ - break; - } - ++curve_it1; - } - if(counter == index){ - break; - } - } - first--; - second--; - std::pair out(first, second); - return out; -} - -int FilletChamferPointArrayParam::last_index(int index, std::vector subpaths) -{ - int counter = -1; - bool inSubpath = false; - for (PathVector::const_iterator path_it = subpaths.begin(); path_it != subpaths.end(); ++path_it) { - if (path_it->empty()) - continue; - Geom::Path::const_iterator curve_it1 = 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_it1 != curve_endit) { - counter++; - if(counter == index){ - inSubpath = true; - } - ++curve_it1; - } - if(inSubpath){ - break; - } - } - if(!inSubpath){ - counter = -1; - } - return counter; -} - - -double FilletChamferPointArrayParam::len_to_time(int index, double len) -{ - double t = 0; - if (last_pwd2.size() > (unsigned) index) { - if (len != 0) { - if (last_pwd2[index][0].degreesOfFreedom() != 2) { - Piecewise > u; - u.push_cut(0); - u.push(last_pwd2[index], 1); - std::vector t_roots = roots(arcLengthSb(u) - std::abs(len)); - if (t_roots.size() > 0) { - t = t_roots[0]; - } - } else { - double lenghtPart = 0; - if (last_pwd2.size() > (unsigned) index) { - lenghtPart = length(last_pwd2[index], EPSILON); - } - if (std::abs(len) < lenghtPart && lenghtPart != 0) { - t = std::abs(len) / lenghtPart; - } - } - } - t = double(index) + t; - } else { - t = double(last_pwd2.size() - 1); - } - - return t; -} - -double FilletChamferPointArrayParam::time_to_len(int index, double time) -{ - double intpart; - double len = 0; - time = modf(time, &intpart); - double lenghtPart = 0; - if (last_pwd2.size() <= (unsigned) index || time == 0) { - return len; - } - if (last_pwd2[index][0].degreesOfFreedom() != 2) { - Piecewise > u; - u.push_cut(0); - u.push(last_pwd2[index], 1); - u = portion(u, 0, time); - return length(u, 0.001) * -1; - } - lenghtPart = length(last_pwd2[index], EPSILON); - return (time * lenghtPart) * -1; -} - -double FilletChamferPointArrayParam::to_time(int index, double A) -{ - if (A > 0) { - return A; - } else { - return len_to_time(index, A); - } -} - -double FilletChamferPointArrayParam::to_len(int index, double A) -{ - if (A > 0) { - return time_to_len(index, A); - } else { - return A; - } -} - -void FilletChamferPointArrayParam::set_oncanvas_looks(SPKnotShapeType shape, - SPKnotModeType mode, - guint32 color) -{ - knot_shape = shape; - knot_mode = mode; - knot_color = color; -} - -FilletChamferPointArrayParamKnotHolderEntity:: -FilletChamferPointArrayParamKnotHolderEntity( - FilletChamferPointArrayParam *p, unsigned int index) - : _pparam(p), _index(index) {} - -void FilletChamferPointArrayParamKnotHolderEntity::knot_set(Point const &p, - Point const &/*origin*/, - guint state) -{ - using namespace Geom; - - if (!valid_index(_index)) { - return; - } - Piecewise > const &pwd2 = _pparam->get_pwd2(); - double t = nearest_point(p, pwd2[_index]); - Geom::Point const s = snap_knot_position(pwd2[_index].valueAt(t), state); - t = nearest_point(s, pwd2[_index]); - if (t == 1) { - t = 0.9999; - } - t += _index; - - if (_pparam->_vector.at(_index)[X] <= 0) { - _pparam->_vector.at(_index) = - Point(_pparam->time_to_len(_index, t), _pparam->_vector.at(_index)[Y]); - } else { - _pparam->_vector.at(_index) = Point(t, _pparam->_vector.at(_index)[Y]); - } - sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); -} - -Point FilletChamferPointArrayParamKnotHolderEntity::knot_get() const -{ - using namespace Geom; - - if (!valid_index(_index)) { - return Point(infinity(), infinity()); - } - - Piecewise > const &pwd2 = _pparam->get_pwd2(); - - double time_it = _pparam->to_time(_index, _pparam->_vector.at(_index)[X]); - Point canvas_point = pwd2.valueAt(time_it); - - _pparam->updateCanvasIndicators(); - return canvas_point; - -} - -void FilletChamferPointArrayParamKnotHolderEntity::knot_click(guint state) -{ - if (state & GDK_CONTROL_MASK) { - if (state & GDK_MOD1_MASK) { - _pparam->_vector.at(_index) = Point(_index, _pparam->_vector.at(_index)[Y]); - _pparam->param_set_and_write_new_value(_pparam->_vector); - sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); - }else{ - using namespace Geom; - int type = (int)_pparam->_vector.at(_index)[Y]; - if (type >=3000 && type < 4000){ - type = 3; - } - if (type >=4000 && type < 5000){ - type = 4; - } - switch(type){ - case 1: - type = 2; - break; - case 2: - type = _pparam->chamfer_steps + 3000; - break; - case 3: - type = _pparam->chamfer_steps + 4000; - break; - default: - type = 1; - break; - } - _pparam->_vector.at(_index) = Point(_pparam->_vector.at(_index)[X], (double)type); - _pparam->param_set_and_write_new_value(_pparam->_vector); - sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); - const gchar *tip; - if (type >=3000 && type < 4000){ - tip = _("Chamfer: Ctrl+Click toggle type, " - "Shift+Click open dialog, " - "Ctrl+Alt+Click reset"); - } else if (type >=4000 && type < 5000) { - tip = _("Inverse Chamfer: Ctrl+Click toggle type, " - "Shift+Click open dialog, " - "Ctrl+Alt+Click reset"); - } else if (type == 2) { - tip = _("Inverse Fillet: Ctrl+Click toggle type, " - "Shift+Click open dialog, " - "Ctrl+Alt+Click reset"); - } else { - tip = _("Fillet: Ctrl+Click toggle type, " - "Shift+Click open dialog, " - "Ctrl+Alt+Click reset"); - } - this->knot->tip = g_strdup(tip); - this->knot->show(); - } - } else if (state & GDK_SHIFT_MASK) { - double xModified = _pparam->_vector.at(_index).x(); - if(xModified < 0 && !_pparam->use_distance){ - xModified = _pparam->len_to_rad(_index, _pparam->_vector.at(_index).x()); - } - std::vector subpaths = path_from_piecewise(_pparam->last_pwd2, 0.1); - std::pair positions = _pparam->get_positions(_index, subpaths); - D2 A = _pparam->last_pwd2[_pparam->last_index(_index, subpaths)]; - if(positions.second != 0){ - A = _pparam->last_pwd2[_index-1]; - } - D2 B = _pparam->last_pwd2[_index]; - bool aprox = (A[0].degreesOfFreedom() != 2 || B[0].degreesOfFreedom() != 2) && !_pparam->use_distance?true:false; - Geom::Point offset = Geom::Point(xModified, _pparam->_vector.at(_index).y()); - Inkscape::UI::Dialogs::FilletChamferPropertiesDialog::showDialog( - this->desktop, offset, this, _pparam->unit, _pparam->use_distance, aprox, _pparam->documentUnit); - } - -} - -void FilletChamferPointArrayParamKnotHolderEntity::knot_set_offset( - Geom::Point offset) -{ - double xModified = offset.x(); - if(xModified < 0 && !_pparam->use_distance){ - xModified = _pparam->rad_to_len(_index, offset.x()); - } - _pparam->_vector.at(_index) = Geom::Point(xModified, offset.y()); - this->parent_holder->knot_ungrabbed_handler(this->knot, 0); -} - -void FilletChamferPointArrayParam::addKnotHolderEntities(KnotHolder *knotholder, - SPDesktop *desktop, - SPItem *item) -{ - recalculate_knots(get_pwd2()); - for (unsigned int i = 0; i < _vector.size(); ++i) { - if (_vector[i][Y] <= 0) { - continue; - } - const gchar *tip; - if (_vector[i][Y] >=3000 && _vector[i][Y] < 4000){ - tip = _("Chamfer: Ctrl+Click toggle type, " - "Shift+Click open dialog, " - "Ctrl+Alt+Click reset"); - } else if (_vector[i][Y] >=4000 && _vector[i][Y] < 5000) { - tip = _("Inverse Chamfer: Ctrl+Click toggle type, " - "Shift+Click open dialog, " - "Ctrl+Alt+Click reset"); - } else if (_vector[i][Y] == 2) { - tip = _("Inverse Fillet: Ctrl+Click toggle type, " - "Shift+Click open dialog, " - "Ctrl+Alt+Click reset"); - } else { - tip = _("Fillet: Ctrl+Click toggle type, " - "Shift+Click open dialog, " - "Ctrl+Alt+Click reset"); - } - FilletChamferPointArrayParamKnotHolderEntity *e = - new FilletChamferPointArrayParamKnotHolderEntity(this, i); - e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _(tip), - knot_shape, knot_mode, knot_color); - knotholder->add(e); - } - updateCanvasIndicators(); -} - -} /* namespace LivePathEffect */ - -} /* namespace Inkscape */ - -/* - Local Variables: - mode:c++ - c-file-style:"stroustrup" - c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) - indent-tabs-mode:nil - fill-column:99 - End: -*/ -// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : -- cgit v1.2.3