diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2016-05-08 20:57:37 +0000 |
|---|---|---|
| committer | jabiertxof <info@marker.es> | 2016-05-08 20:57:37 +0000 |
| commit | 97bd182d6a2113eab1dd5faf51402ebd5382791c (patch) | |
| tree | 272e95fb4951a821dbd5f416cd19250dcc278819 /src/live_effects | |
| parent | update to trunk (diff) | |
| download | inkscape-97bd182d6a2113eab1dd5faf51402ebd5382791c.tar.gz inkscape-97bd182d6a2113eab1dd5faf51402ebd5382791c.zip | |
First attempt to make fixed tweenk review
(bzr r13645.1.128)
Diffstat (limited to 'src/live_effects')
| -rw-r--r-- | src/live_effects/lpe-fillet-chamfer.cpp | 240 | ||||
| -rw-r--r-- | src/live_effects/lpe-fillet-chamfer.h | 4 | ||||
| -rw-r--r-- | src/live_effects/parameter/Makefile_insert | 4 | ||||
| -rw-r--r-- | src/live_effects/parameter/array.cpp | 71 | ||||
| -rw-r--r-- | src/live_effects/parameter/array.h | 35 | ||||
| -rw-r--r-- | src/live_effects/parameter/satellitearray.cpp | 550 | ||||
| -rw-r--r-- | src/live_effects/parameter/satellitesarray.cpp | 527 | ||||
| -rw-r--r-- | src/live_effects/parameter/satellitesarray.h (renamed from src/live_effects/parameter/satellitearray.h) | 17 |
8 files changed, 704 insertions, 744 deletions
diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 956395623..bcab1c055 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -91,39 +91,30 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) SPShape *shape = dynamic_cast<SPShape *>(splpeitem); if (shape) { Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(shape->getCurve()->get_pathvector()); - int global_counter = 0; - std::vector<Satellite> satellites; - for (Geom::PathVector::const_iterator path_it = pathv.begin(); - path_it != pathv.end(); ++path_it) { + Satellites satellites; + for (Geom::PathVector::const_iterator path_it = pathv.begin(); path_it != pathv.end(); ++path_it) { if (path_it->empty()) { continue; } + std::vector<Satellite> subpath_satellites; Geom::Path::const_iterator curve_it1 = path_it->begin(); Geom::Path::const_iterator curve_endit = path_it->end_default(); - int counter = 0; - size_t steps = chamfer_steps; + bool start = true; while (curve_it1 != curve_endit) { - bool active = true; bool hidden = false; - if (counter == 0) { + if (start) { if (!path_it->closed()) { - active = false; hidden = true; } + start = false; } Satellite satellite(FILLET); - satellite.setIsTime(flexible); - satellite.setActive(active); - satellite.setHasMirror(mirror_knots); satellite.setHidden(hidden); - satellite.setAmount(0.0); - satellite.setAngle(0.0); - satellite.setSteps(steps); - satellites.push_back(satellite); + satellite.setSteps(chamfer_steps); + subpath_satellites.push_back(satellite); ++curve_it1; - counter++; - global_counter++; } + satellites.push_back(subpath_satellites); } pointwise = new Pointwise(); pointwise->setPwd2(paths_to_pw(pathv)); @@ -264,42 +255,36 @@ void LPEFilletChamfer::updateAmount() } else { power = radius / 100; } - std::vector<Satellite> satellites = pointwise->getSatellites(); - //todo 2GEOM I want to substiturte all Piecewise<D2<SBasis> > whith a PathVector - //but is very dificult know the index of a curve inside a pathvector with current API - Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = pointwise->getPwd2(); - Geom::PathVector pathv = path_from_piecewise(Geom::remove_short_cuts(pwd2,0.01),0.01); - for (std::vector<Satellite>::iterator it = satellites.begin(); - it != satellites.end(); ++it) { - Geom::Path sat_path = pathv.pathAt(it - satellites.begin()); - size_t sat_curve_time = Geom::nearest_time(pathv.curveAt(it - satellites.begin()).initialPoint() , pwd2); - size_t first = Geom::nearest_time(sat_path.initialPoint() , pwd2); - if (!sat_path.closed() && sat_curve_time == first) { - it->amount = 0; - continue; - } - if ((!apply_no_radius && it->amount == 0) || - (!apply_with_radius && it->amount != 0)) - { - continue; - } - boost::optional<size_t> previous = boost::none; - if (sat_path.closed() && sat_curve_time == first) { - previous = sat_curve_time + sat_path.size() - 1; - } else if(!sat_path.closed() || sat_curve_time != first) { - previous = sat_curve_time - 1; - } - Geom::Point satellite_point = pwd2.valueAt(it - satellites.begin()); - if (isNodePointSelected(satellite_point) || !only_selected) { - if (!use_knot_distance && !flexible) { - if(previous) { - it->amount = it->radToLen(power, pathv.curveAt(*previous), - pathv.curveAt(it - satellites.begin())); + Satellites satellites = pointwise->getSatellites(); + Geom::PathVector pathv = pointwise->getPV(); + for (size_t i = 0; i < satellites.size(); ++i) { + for (size_t j = 0; j < satellites[i].size(); ++j) { + boost::optional<size_t> curve_prev_index = boost::none; + if(j == 0 && pathv[i].closed()){ + curve_prev_index = pathv[pathv[i].size() - 1]; + } else if(!pathv[i].closed() || j != 0) { + curve_prev_index = j - 1; + } + if (!pathv[i].closed() && sat_curve_time == 0) { + it->amount = 0; + continue; + } + if ((!apply_no_radius && it->amount == 0) || + (!apply_with_radius && it->amount != 0)) + { + continue; + } + Geom::Point satellite_point = pwd2.valueAt(it - satellites.begin()); + if (isNodePointSelected(satellite_point) || !only_selected) { + if (!use_knot_distance && !flexible) { + if(curve_prev_index) { + it->amount = it->radToLen(power, pathv[i][*curve_prev_index], pathv[i][j]); + } else { + it->amount = 0.0; + } } else { - it->amount = 0.0; + it->amount = power; } - } else { - it->amount = power; } } } @@ -310,21 +295,22 @@ void LPEFilletChamfer::updateAmount() void LPEFilletChamfer::updateChamferSteps() { std::vector<Satellite> satellites = pointwise->getSatellites(); - Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = pointwise->getPwd2(); - for (std::vector<Satellite>::iterator it = satellites.begin(); - it != satellites.end(); ++it) { - if ((!apply_no_radius && it->amount == 0) || - (!apply_with_radius && it->amount != 0)) - { - continue; - } - if (only_selected) { - Geom::Point satellite_point = pwd2.valueAt(it - satellites.begin()); - if (isNodePointSelected(satellite_point)) { - it->steps = chamfer_steps; + Geom::PathVector pathv = pointwise->getPV(); + for (size_t i = 0; i < satellites.size(); ++i) { + for (size_t j = 0; j < satellites[i].size(); ++j) { + if ((!apply_no_radius && satellites[i][j]->amount == 0) || + (!apply_with_radius && satellites[i][j]->amount != 0)) + { + continue; + } + if (only_selected) { + Geom::Point satellite_point = pathv[i].pointAt(j); + if (isNodePointSelected(satellite_point)) { + satellites[i][j]->steps = chamfer_steps; + } + } else { + satellites[i][j]->steps = chamfer_steps; } - } else { - it->steps = chamfer_steps; } } pointwise->setSatellites(satellites); @@ -334,21 +320,22 @@ void LPEFilletChamfer::updateChamferSteps() void LPEFilletChamfer::updateSatelliteType(SatelliteType satellitetype) { std::vector<Satellite> satellites = pointwise->getSatellites(); - Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = pointwise->getPwd2(); - for (std::vector<Satellite>::iterator it = satellites.begin(); - it != satellites.end(); ++it) { - if ((!apply_no_radius && it->amount == 0) || - (!apply_with_radius && it->amount != 0)) - { - continue; - } - if (only_selected) { - Geom::Point satellite_point = pwd2.valueAt(it - satellites.begin()); - if (isNodePointSelected(satellite_point)) { - it->satellite_type = satellitetype; + Geom::PathVector pathv = pointwise->getPV(); + for (size_t i = 0; i < satellites.size(); ++i) { + for (size_t j = 0; j < satellites[i].size(); ++j) { + if ((!apply_no_radius && satellites[i][j]->amount == 0) || + (!apply_with_radius && satellites[i][j]->amount != 0)) + { + continue; + } + if (only_selected) { + Geom::Point satellite_point = pathv[i].pointAt(j); + if (isNodePointSelected(satellite_point)) { + satellites[i][j]->satellite_type = satellitetype; + } + } else { + satellites[i][j]->satellite_type = satellitetype; } - } else { - it->satellite_type = satellitetype; } } pointwise->setSatellites(satellites); @@ -373,14 +360,13 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) //mandatory call satellites_param.setEffectType(effectType()); - Geom::PathVector const pathv = - pathv_to_linear_and_cubic_beziers(c->get_pathvector()); + Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(c->get_pathvector()); Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = paths_to_pw(pathv); pwd2 = remove_short_cuts(pwd2, 0.01); - std::vector<Satellite> sats = satellites_param.data(); - if(sats.empty()) { + Satellites satelites = satellites_param.data(); + if(satelites.empty()) { doOnApply(lpeItem); - sats = satellites_param.data(); + satelites = satellites_param.data(); } if (hide_knots) { satellites_param.setHelperSize(0); @@ -388,44 +374,39 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) satellites_param.setHelperSize(helper_size); } size_t number_curves = pathv.curveCount(); - for (std::vector<Satellite>::iterator it = sats.begin(); - it != sats.end();) { - if (it->is_time != flexible) { - it->is_time = flexible; - double amount = it->amount; - Geom::Curve const &curve_in = pathv.curveAt(it - sats.begin()); - if (it->is_time) { - double time = timeAtArcLength(amount, curve_in); - it->amount = time; - } else { - double size = arcLengthAt(amount, curve_in); - it->amount = size; + for (size_t i = 0; i < satellites.size(); ++i) { + for (size_t j = 0; j < satellites[i].size(); ++j) { + if (satellites[i][j]->is_time != flexible) { + satellites[i][j]->is_time = flexible; + double amount = satellites[i][j]->amount; + Geom::Curve const &curve_in = pathv[i][j]; + if (satellites[i][j]->is_time) { + double time = timeAtArcLength(amount, curve_in); + satellites[i][j]->amount = time; + } else { + double size = arcLengthAt(amount, curve_in); + satellites[i][j]->amount = size; + } } + if (satellites[i][j]->has_mirror != mirror_knots) { + satellites[i][j]->has_mirror = mirror_knots; + } + satellites[i][j]->hidden = hide_knots; } - if (it->has_mirror != mirror_knots) { - it->has_mirror = mirror_knots; - } - it->hidden = hide_knots; - ++it; } //if are diferent sizes call to poinwise recalculate //todo: fire a reverse satellites on reverse path. Maybe a new method //like "are_similar" to avoid precission issues on reverse a pointwise //and after convert to Pathvector - if (pointwise && number_curves != sats.size()) { - Satellite sat(sats[0].satellite_type); - sat.setIsTime(sats[0].is_time); - sat.setActive(true); - sat.setHasMirror( sats[0].has_mirror); - sat.setHidden(false); - sat.setAmount(0.0); - sat.setAngle(0.0); - sat.setSteps(0); - pointwise->recalculateForNewPwd2(pwd2, pathv, sat); + if (pointwise && number_curves != pointwise->getTotalSatellites()) { + Satellite satellite(satellites[0][0].satellite_type); + satellite.setIsTime(satellites[0][0].is_time); + satellite.setHasMirror(satellites[0][0].has_mirror); + pointwise->recalculateForNewPwd2(pwd2, pathv, satellite); } else { pointwise = new Pointwise(); pointwise->setPwd2(pwd2); - pointwise->setSatellites(sats); + pointwise->setSatellites(satellites); } pointwise->setStart(); satellites_param.setPointwise(pointwise); @@ -446,12 +427,10 @@ LPEFilletChamfer::doEffect_path(Geom::PathVector const &path_in) { const double GAP_HELPER = 0.00001; Geom::PathVector path_out; - size_t counter = 0; + size_t counter_paths = 0; const double K = (4.0 / 3.0) * (sqrt(2.0) - 1.0); - Geom::PathVector path_in_processed = - pathv_to_linear_and_cubic_beziers(path_in); - for (Geom::PathVector::const_iterator path_it = path_in_processed.begin(); - path_it != path_in_processed.end(); ++path_it) { + Geom::PathVector path_in_processed = pathv_to_linear_and_cubic_beziers(path_in); + for (Geom::PathVector::const_iterator path_it = path_in_processed.begin(); path_it != path_in_processed.end(); ++path_it) { if (path_it->empty()) { continue; } @@ -470,14 +449,13 @@ LPEFilletChamfer::doEffect_path(Geom::PathVector const &path_in) size_t counter_curves = 0; size_t first = counter; double time0 = 0; - std::vector<Satellite> sats = pointwise->getSatellites(); + Satellites satelites = pointwise->getSatellites(); while (curve_it1 != curve_endit) { if (curve_it2 != curve_endit && (*curve_it2).isDegenerate()) { ++curve_it2; } if ((*curve_it1).isDegenerate()) { ++curve_it1; - counter++; counter_curves++; time0 = 0.0; continue; @@ -487,8 +465,8 @@ LPEFilletChamfer::doEffect_path(Geom::PathVector const &path_in) if (!path_it->closed()) { if (curve_it2 != curve_endit) { curve_it2_fixed = (*curve_it2).duplicate(); - if (sats.size() > counter + 1) { - satellite = sats[counter + 1]; + if (satellites[counter_paths].size() > counter_curves + 1) { + satellite = satellites[counter_paths][counter_curves + 1]; } } else { if (time0 != 1) { @@ -497,27 +475,25 @@ LPEFilletChamfer::doEffect_path(Geom::PathVector const &path_in) tmp_path.append(*last_curve); } ++curve_it1; - counter++; counter_curves++; continue; } } else { if (curve_it2 != curve_endit) { curve_it2_fixed = (*curve_it2).duplicate(); - if (sats.size() > counter + 1) { - satellite = sats[counter + 1]; + if (satellites[counter_paths].size() > counter_curves + 1) { + satellite = satellites[counter_paths][counter_curves + 1];; } } else { - if (sats.size() > first) { - satellite = sats[first]; + if (satellites[counter_paths].size() > 0) { + satellite = satellites[counter_paths][0]; } } } - if (first == counter) { - if (sats.size() > first && sats[first].active) { - time0 = - sats[first].time(*path_it->begin()); + if (counter_curves == 0) { + if (satellites[counter_paths].size() > 0 && satellites[counter_paths][0].active) { + time0 = satellites[counter_paths][0].time(*path_it->begin()); } else { time0 = 0; } @@ -691,10 +667,10 @@ LPEFilletChamfer::doEffect_path(Geom::PathVector const &path_in) if (curve_it2 != curve_endit) { ++curve_it2; } - counter++; counter_curves++; time0 = times[2]; } + counter_paths++; path_out.push_back(tmp_path); } return path_out; diff --git a/src/live_effects/lpe-fillet-chamfer.h b/src/live_effects/lpe-fillet-chamfer.h index 638e8c6af..a209971dd 100644 --- a/src/live_effects/lpe-fillet-chamfer.h +++ b/src/live_effects/lpe-fillet-chamfer.h @@ -13,7 +13,7 @@ */ #include "live_effects/parameter/enum.h" -#include "live_effects/parameter/satellitearray.h" +#include "live_effects/parameter/satellitesarray.h" #include "live_effects/effect.h" #include "helper/geom-pointwise.h" @@ -45,7 +45,7 @@ public: void fillet(); void inverseFillet(); - SatelliteArrayParam satellites_param; + SatellitesArrayParam satellites_param; private: EnumParam<FilletMethod> method; diff --git a/src/live_effects/parameter/Makefile_insert b/src/live_effects/parameter/Makefile_insert index 9a0ebe235..ab4a8eb4e 100644 --- a/src/live_effects/parameter/Makefile_insert +++ b/src/live_effects/parameter/Makefile_insert @@ -22,8 +22,8 @@ ink_common_sources += \ live_effects/parameter/originalpatharray.h \ live_effects/parameter/powerstrokepointarray.cpp \ live_effects/parameter/powerstrokepointarray.h \ - live_effects/parameter/satellitearray.cpp \ - live_effects/parameter/satellitearray.h \ + live_effects/parameter/satellitesarray.cpp \ + live_effects/parameter/satellitesarray.h \ live_effects/parameter/text.cpp \ live_effects/parameter/text.h \ live_effects/parameter/transformedpoint.cpp \ diff --git a/src/live_effects/parameter/array.cpp b/src/live_effects/parameter/array.cpp index 0abcd4b9b..0bbe39293 100644 --- a/src/live_effects/parameter/array.cpp +++ b/src/live_effects/parameter/array.cpp @@ -13,35 +13,43 @@ namespace Inkscape { namespace LivePathEffect { -//TODO: move maybe to svg-lenght.cpp +//TODO: move maybe unsigned int -sp_svg_satellite_read_d(gchar const *str, Satellite *sat){ +sp_svg_satellite_vector_read_d(gchar const *str, std::vector<Satellite> *satellites){ if (!str) { return 0; } - gchar ** strarray = g_strsplit(str, ",", 8); - if(strlen(str) > 0 && strarray[7] && !strarray[8]){ - sat->setSatelliteType(g_strstrip(strarray[0])); - sat->is_time = strncmp(strarray[1],"1",1) == 0; - sat->active = strncmp(strarray[2],"1",1) == 0; - sat->has_mirror = strncmp(strarray[3],"1",1) == 0; - sat->hidden = strncmp(strarray[4],"1",1) == 0; - double amount,angle; - float stepsTmp; - sp_svg_number_read_d(strarray[5], &amount); - sp_svg_number_read_d(strarray[6], &angle); - sp_svg_number_read_f(strarray[7], &stepsTmp); - unsigned int steps = (unsigned int)stepsTmp; - sat->amount = amount; - sat->angle = angle; - sat->steps = steps; - g_strfreev (strarray); - return 1; + gchar ** strarray = g_strsplit(str, "@", 0); + for (size_t i = 0; i < strarray.size(); ++i) { + gchar ** strsubarray = g_strsplit(strarray[i], ",", 7); + if(strlen(str) > 0 && strsubarray[6] && !strsubarray[7]){ + Satellite sat; + sat->setSatelliteType(g_strstrip(strsubarray[0])); + sat->is_time = strncmp(strsubarray[1],"1",1) == 0; + sat->has_mirror = strncmp(strsubarray[2],"1",1) == 0; + sat->hidden = strncmp(strsubarray[3],"1",1) == 0; + double amount,angle; + float stepsTmp; + sp_svg_number_read_d(strsubarray[4], &amount); + sp_svg_number_read_d(strsubarray[5], &angle); + sp_svg_number_read_f(strsubarray[6], &stepsTmp); + unsigned int steps = (unsigned int)stepsTmp; + sat->amount = amount; + sat->angle = angle; + sat->steps = steps; + g_strfreev (strsubarray); + satellites.push_back(sat); + } + g_strfreev (strsubarray); } g_strfreev (strarray); + if (!sat.empty()){ + return 1; + } return 0; } + template <> double ArrayParam<double>::readsvg(const gchar * str) @@ -75,25 +83,20 @@ ArrayParam<Geom::Point>::readsvg(const gchar * str) return Geom::Point(Geom::infinity(),Geom::infinity()); } + template <> -Satellite -ArrayParam<Satellite >::readsvg(const gchar * str) +std::vector<Satellite> +ArrayParam<std::vector<Satellite > >::readsvg(const gchar * str) { - Satellite sat; - if (sp_svg_satellite_read_d(str, &sat)) { - return sat; + std::vector<Satellite > satellites; + if (sp_svg_satellite_vector_read_d(str, &satellites)) { + return satellites; } - Satellite satellite(FILLET); - satellite.setIsTime(true); - satellite.setActive(false); - satellite.setHasMirror(false); - satellite.setHidden(true); - satellite.setAmount(0.0); - satellite.setAngle(0.0); - satellite.setSteps(0); - return satellite; + satellites.push_back(Satellite satellite(FILLET)); + return satellites; } + } /* namespace LivePathEffect */ } /* namespace Inkscape */ diff --git a/src/live_effects/parameter/array.h b/src/live_effects/parameter/array.h index 66ed6344b..7076a465f 100644 --- a/src/live_effects/parameter/array.h +++ b/src/live_effects/parameter/array.h @@ -110,22 +110,25 @@ protected: str << nVector; } - void writesvgData(SVGOStringStream &str, Satellite const &nVector) const { - str << nVector.getSatelliteTypeGchar(); - str << ","; - str << nVector.is_time; - str << ","; - str << nVector.active; - str << ","; - str << nVector.has_mirror; - str << ","; - str << nVector.hidden; - str << ","; - str << nVector.amount; - str << ","; - str << nVector.angle; - str << ","; - str << nVector.steps; + void writesvgData(SVGOStringStream &str, std::vector<Satellite> const &nVector) const { + for (size_t i = 0; i < nVector.size(); ++i) { + str << nVector[i].getSatelliteTypeGchar(); + str << ","; + str << nVector[i].is_time; + str << ","; + str << nVector[i].has_mirror; + str << ","; + str << nVector[i].hidden; + str << ","; + str << nVector[i].amount; + str << ","; + str << nVector[i].angle; + str << ","; + str << nVector[i].steps; + if (i != nVector.size()-1) { + str << "@"; + } + } } StorageType readsvg(const gchar * str); diff --git a/src/live_effects/parameter/satellitearray.cpp b/src/live_effects/parameter/satellitearray.cpp deleted file mode 100644 index 1615f33e2..000000000 --- a/src/live_effects/parameter/satellitearray.cpp +++ /dev/null @@ -1,550 +0,0 @@ -/* - * Author(s): - * Jabiertxo Arraiza Cenoz <jabier.arraiza@marker.es> - * - * Copyright (C) 2014 Author(s) - * Released under GNU GPL, read the file 'COPYING' for more information - */ - -#include "knotholder.h" -#include "ui/dialog/lpe-fillet-chamfer-properties.h" -#include "live_effects/parameter/satellitearray.h" -#include "live_effects/effect.h" -#include "sp-lpe-item.h" -#include <preferences.h> -#include <boost/optional.hpp> -// TODO due to internal breakage in glibmm headers, -// this has to be included last. -#include <glibmm/i18n.h> - -namespace Inkscape { - -namespace LivePathEffect { - -SatelliteArrayParam::SatelliteArrayParam(const Glib::ustring &label, - const Glib::ustring &tip, - const Glib::ustring &key, - Inkscape::UI::Widget::Registry *wr, - Effect *effect) - : ArrayParam<Satellite>(label, tip, key, wr, effect, 0), knoth(NULL) -{ - _knot_shape = SP_KNOT_SHAPE_DIAMOND; - _knot_mode = SP_KNOT_MODE_XOR; - _knot_color = 0xAAFF8800; - _helper_size = 0; - _use_distance = false; - _effectType = FILLET_CHAMFER; - _last_pointwise = NULL; -} - -void SatelliteArrayParam::set_oncanvas_looks(SPKnotShapeType shape, - SPKnotModeType mode, - guint32 color) -{ - _knot_shape = shape; - _knot_mode = mode; - _knot_color = color; -} - -void SatelliteArrayParam::setPointwise(Pointwise *pointwise) -{ - _last_pointwise = pointwise; - param_set_and_write_new_value(_last_pointwise->getSatellites()); -} - -void SatelliteArrayParam::setUseDistance(bool use_knot_distance) -{ - _use_distance = use_knot_distance; -} - -void SatelliteArrayParam::setEffectType(EffectType et) -{ - _effectType = et; -} - -void SatelliteArrayParam::setHelperSize(int hs) -{ - _helper_size = hs; - updateCanvasIndicators(); -} - -void SatelliteArrayParam::updateCanvasIndicators(bool mirror) -{ - if (!_last_pointwise) { - return; - } - - Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = _last_pointwise->getPwd2(); - Geom::PathVector pathv = path_from_piecewise(Geom::remove_short_cuts(pwd2,0.01),0.01); - if (mirror == true) { - _hp.clear(); - } - for (size_t i = 0; i < _vector.size(); ++i) { - if (!_vector[i].active || _vector[i].hidden) { - continue; - } - if ((!_vector[i].has_mirror && mirror == true) || _vector[i].amount == 0) { - continue; - } - double pos = 0; - if (pwd2.size() <= i) { - break; - } - Geom::Curve *curve_in = pathv.curveAt(i).duplicate(); - bool overflow = false; - double size_out = _vector[i].arcDistance(*curve_in); - double lenght_out = curve_in->length(); - double lenght_in = 0; - - Geom::Path sat_path = pathv.pathAt(i); - boost::optional<size_t> curve_prev_index = boost::none; - size_t sat_curve_time = Geom::nearest_time(pathv.curveAt(i).initialPoint() , pwd2); - size_t first = Geom::nearest_time(sat_path.initialPoint() , pwd2); - if (sat_path.closed() && sat_curve_time == first) { - curve_prev_index = sat_curve_time + sat_path.size() - 1; - } else if(!sat_path.closed() || sat_curve_time != first) { - curve_prev_index = sat_curve_time - 1; - } - if (curve_prev_index) { - lenght_in = pathv.curveAt(*curve_prev_index).length(); - } - if (mirror == true) { - if (curve_prev_index) { - curve_in = const_cast<Geom::Curve *>(&pathv.curveAt(*curve_prev_index)); - pos = _vector[i].time(size_out, true, *curve_in); - if (lenght_out < size_out) { - overflow = true; - } - } - } else { - pos = _vector[i].time(*curve_in); - if (lenght_in < size_out) { - overflow = true; - } - } - if (pos <= 0 || pos >= 1) { - continue; - } - Geom::Point point_a = curve_in->pointAt(pos); - Geom::Point deriv_a = unit_vector(derivative(curve_in->toSBasis()).pointAt(pos)); - Geom::Rotate rot(Geom::Rotate::from_degrees(-90)); - deriv_a = deriv_a * rot; - Geom::Point point_c = point_a - deriv_a * _helper_size; - Geom::Point point_d = point_a + deriv_a * _helper_size; - Geom::Ray ray_1(point_c, point_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); - if (mirror == true) { - aff *= Geom::Rotate(ray_1.angle() - Geom::rad_from_deg(90)); - } else { - aff *= Geom::Rotate(ray_1.angle() - Geom::rad_from_deg(270)); - } - aff *= Geom::Translate(curve_in->pointAt(pos)); - pathv *= aff; - _hp.push_back(pathv[0]); - _hp.push_back(pathv[1]); - if (overflow) { - double diameter = _helper_size; - if (_helper_size == 0) { - diameter = 15; - char const *svgd; - svgd = "M 0.7,0.35 A 0.35,0.35 0 0 1 0.35,0.7 0.35,0.35 0 0 1 0,0.35 " - "0.35,0.35 0 0 1 0.35,0 0.35,0.35 0 0 1 0.7,0.35 Z"; - Geom::PathVector pathv = sp_svg_read_pathv(svgd); - aff = Geom::Affine(); - aff *= Geom::Scale(diameter); - aff *= Geom::Translate(point_a - Geom::Point(diameter * 0.35, diameter * 0.35)); - pathv *= aff; - _hp.push_back(pathv[0]); - } else { - char const *svgd; - svgd = "M 0 -1.32 A 1.32 1.32 0 0 0 -1.32 0 A 1.32 1.32 0 0 0 0 1.32 A " - "1.32 1.32 0 0 0 1.18 0.59 L 0 0 L 1.18 -0.59 A 1.32 1.32 0 0 0 " - "0 -1.32 z"; - Geom::PathVector pathv = sp_svg_read_pathv(svgd); - aff = Geom::Affine(); - aff *= Geom::Scale(_helper_size / 2.0); - if (mirror == true) { - aff *= Geom::Rotate(ray_1.angle() - Geom::rad_from_deg(90)); - } else { - aff *= Geom::Rotate(ray_1.angle() - Geom::rad_from_deg(270)); - } - aff *= Geom::Translate(curve_in->pointAt(pos)); - pathv *= aff; - _hp.push_back(pathv[0]); - } - } - } - if (mirror == true) { - updateCanvasIndicators(false); - } -} -void SatelliteArrayParam::updateCanvasIndicators() -{ - updateCanvasIndicators(true); -} - -void SatelliteArrayParam::addCanvasIndicators( - SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec) -{ - hp_vec.push_back(_hp); -} - -void SatelliteArrayParam::param_transform_multiply(Geom::Affine const &postmul, - bool /*set*/) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - if (prefs->getBool("/options/transform/rectcorners", true)) { - for (size_t i = 0; i < _vector.size(); ++i) { - if (!_vector[i].is_time && _vector[i].amount > 0) { - _vector[i].amount = _vector[i].amount * - ((postmul.expansionX() + postmul.expansionY()) / 2); - } - } - param_set_and_write_new_value(_vector); - } -} - -void SatelliteArrayParam::addKnotHolderEntities(KnotHolder *knotholder, - SPDesktop *desktop, - SPItem *item, bool mirror) -{ - for (size_t i = 0; i < _vector.size(); ++i) { - size_t iPlus = i; - if (mirror == true) { - iPlus = i + _vector.size(); - } - if (!_vector[i].active) { - continue; - } - if (!_vector[i].has_mirror && mirror == true) { - continue; - } - using namespace Geom; - SatelliteType type = _vector[i].satellite_type; - //IF is for filletChamfer effect... - if (_effectType == FILLET_CHAMFER) { - const gchar *tip; - if (type == CHAMFER) { - tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toggle type, " - "<b>Shift+Click</b> open dialog, " - "<b>Ctrl+Alt+Click</b> reset"); - } else if (type == INVERSE_CHAMFER) { - tip = _("<b>Inverse Chamfer</b>: <b>Ctrl+Click</b> toggle type, " - "<b>Shift+Click</b> open dialog, " - "<b>Ctrl+Alt+Click</b> reset"); - } else if (type == INVERSE_FILLET) { - tip = _("<b>Inverse Fillet</b>: <b>Ctrl+Click</b> toggle type, " - "<b>Shift+Click</b> open dialog, " - "<b>Ctrl+Alt+Click</b> reset"); - } else { - tip = _("<b>Fillet</b>: <b>Ctrl+Click</b> toggle type, " - "<b>Shift+Click</b> open dialog, " - "<b>Ctrl+Alt+Click</b> reset"); - } - FilletChamferKnotHolderEntity *e = - new FilletChamferKnotHolderEntity(this, iPlus); - e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _(tip), - _knot_shape, _knot_mode, _knot_color); - knotholder->add(e); - } - } - if (mirror == true) { - addKnotHolderEntities(knotholder, desktop, item, false); - } -} - -void SatelliteArrayParam::addKnotHolderEntities(KnotHolder *knotholder, - SPDesktop *desktop, - SPItem *item) -{ - knoth = knotholder; - addKnotHolderEntities(knotholder, desktop, item, true); -} - -FilletChamferKnotHolderEntity::FilletChamferKnotHolderEntity( - SatelliteArrayParam *p, size_t index) - : _pparam(p), _index(index) {} - -void FilletChamferKnotHolderEntity::knot_set(Geom::Point const &p, - Geom::Point const &/*origin*/, - guint state) -{ - Geom::Point s = snap_knot_position(p, state); - size_t index = _index; - if (_index >= _pparam->_vector.size()) { - index = _index - _pparam->_vector.size(); - } - if (!valid_index(index)) { - return; - } - - if (!_pparam->_last_pointwise) { - return; - } - - Satellite satellite = _pparam->_vector.at(index); - if (!satellite.active || satellite.hidden) { - return; - } - Pointwise *pointwise = _pparam->_last_pointwise; - Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = pointwise->getPwd2(); - Geom::PathVector pathv = path_from_piecewise(Geom::remove_short_cuts(pwd2,0.01),0.01); - if (_index >= _pparam->_vector.size() ) { - //I want to remplace this whith patvectorTime but need a way to know the index of a curve in a pathvector - //Geom::Path sat_path = pathv.pathAt(index); - //PathTime sat_time = sat_path.nearestTime(pathv.curveAt(index).initialPoint()); - //boost::optional<size_t> previous_index = boost::none; - //if (sat_path.closed() && sat_time.curve_index == 0) { - // previous_index = sat_path.size(); - //} else if(!sat_path.closed() || sat_time.curve_index != 0) { - // previous_index = sat_time.curve_index - 1; - //} - //if (previous_index) { - Geom::Path sat_path = pathv.pathAt(index); - boost::optional<size_t> curve_prev_index = boost::none; - size_t sat_curve_time = Geom::nearest_time(pathv.curveAt(index).initialPoint(),pwd2); - size_t first = Geom::nearest_time(sat_path.initialPoint() , pwd2); - if (sat_path.closed() && sat_curve_time == first) { - curve_prev_index = sat_curve_time + sat_path.size() - 1; - } else if(!sat_path.closed() || sat_curve_time != first) { - curve_prev_index = sat_curve_time - 1; - } - if (curve_prev_index) { - Geom::Curve const &curve_in = pathv.curveAt(*curve_prev_index); - double mirror_time = Geom::nearest_time(s, curve_in); - double time_start = 0; - std::vector<Satellite> sats = pointwise->getSatellites(); - time_start = sats[*curve_prev_index].time(curve_in); - if (time_start > mirror_time) { - mirror_time = time_start; - } - double size = arcLengthAt(mirror_time, curve_in); - double amount = curve_in.length() - size; - if (satellite.is_time) { - amount = timeAtArcLength(amount, pathv.curveAt(index)); - } - satellite.amount = amount; - } - } else { - satellite.setPosition(s, pathv.curveAt(index)); - } - _pparam->_vector.at(index) = satellite; - SPLPEItem *splpeitem = dynamic_cast<SPLPEItem *>(item); - if (splpeitem) { - sp_lpe_item_update_patheffect(splpeitem, false, false); - } -} - -Geom::Point FilletChamferKnotHolderEntity::knot_get() const -{ - Geom::Point tmp_point; - size_t index = _index; - if (_index >= _pparam->_vector.size()) { - index = _index - _pparam->_vector.size(); - } - if (!valid_index(index)) { - return Geom::Point(Geom::infinity(), Geom::infinity()); - } - Satellite satellite = _pparam->_vector.at(index); - if (!_pparam->_last_pointwise) { - return Geom::Point(Geom::infinity(), Geom::infinity()); - } - if (!satellite.active || satellite.hidden) { - return Geom::Point(Geom::infinity(), Geom::infinity()); - } - Pointwise *pointwise = _pparam->_last_pointwise; - Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = pointwise->getPwd2(); - Geom::PathVector pathv = path_from_piecewise(Geom::remove_short_cuts(pwd2,0.01),0.01); - if (pwd2.size() <= index) { - return Geom::Point(Geom::infinity(), Geom::infinity()); - } - this->knot->show(); - if (_index >= _pparam->_vector.size()) { - tmp_point = satellite.getPosition(pathv.curveAt(index)); - Geom::Path sat_path = pathv.pathAt(index); - boost::optional<size_t> curve_prev_index = boost::none; - size_t sat_curve_time = Geom::nearest_time(pathv.curveAt(index).initialPoint(),pwd2); - size_t first = Geom::nearest_time(sat_path.initialPoint(), pwd2); - if (sat_path.closed() && sat_curve_time == first) { - curve_prev_index = sat_curve_time + sat_path.size() - 1; - } else if(!sat_path.closed() || sat_curve_time != first) { - curve_prev_index = sat_curve_time - 1; - } - if (curve_prev_index) { - Geom::Curve const &curve_in = pathv.curveAt(*curve_prev_index); - double s = satellite.arcDistance(pathv.curveAt(index)); - double t = satellite.time(s, true, curve_in); - if (t > 1) { - t = 1; - } - if (t < 0) { - t = 0; - } - double time_start = 0; - time_start = pointwise->getSatellites()[*curve_prev_index].time(curve_in); - if (time_start > t) { - t = time_start; - } - tmp_point = (curve_in).pointAt(t); - } - } else { - tmp_point = satellite.getPosition(pathv.curveAt(index)); - } - Geom::Point const canvas_point = tmp_point; - return canvas_point; -} - -void FilletChamferKnotHolderEntity::knot_click(guint state) -{ - if (!_pparam->_last_pointwise) { - return; - } - - size_t index = _index; - if (_index >= _pparam->_vector.size()) { - index = _index - _pparam->_vector.size(); - } - if (state & GDK_CONTROL_MASK) { - if (state & GDK_MOD1_MASK) { - _pparam->_vector.at(index).amount = 0.0; - _pparam->param_set_and_write_new_value(_pparam->_vector); - sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); - } else { - using namespace Geom; - SatelliteType type = _pparam->_vector.at(index).satellite_type; - switch (type) { - case FILLET: - type = INVERSE_FILLET; - break; - case INVERSE_FILLET: - type = CHAMFER; - break; - case CHAMFER: - type = INVERSE_CHAMFER; - break; - default: - type = FILLET; - break; - } - _pparam->_vector.at(index).satellite_type = 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 == CHAMFER) { - tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toggle type, " - "<b>Shift+Click</b> open dialog, " - "<b>Ctrl+Alt+Click</b> reset"); - } else if (type == INVERSE_CHAMFER) { - tip = _("<b>Inverse Chamfer</b>: <b>Ctrl+Click</b> toggle type, " - "<b>Shift+Click</b> open dialog, " - "<b>Ctrl+Alt+Click</b> reset"); - } else if (type == INVERSE_FILLET) { - tip = _("<b>Inverse Fillet</b>: <b>Ctrl+Click</b> toggle type, " - "<b>Shift+Click</b> open dialog, " - "<b>Ctrl+Alt+Click</b> reset"); - } else { - tip = _("<b>Fillet</b>: <b>Ctrl+Click</b> toggle type, " - "<b>Shift+Click</b> open dialog, " - "<b>Ctrl+Alt+Click</b> reset"); - } - this->knot->tip = g_strdup(tip); - this->knot->show(); - } - } else if (state & GDK_SHIFT_MASK) { - Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = _pparam->_last_pointwise->getPwd2(); - Geom::PathVector pathv = path_from_piecewise(Geom::remove_short_cuts(pwd2,0.01),0.01); - double amount = _pparam->_vector.at(index).amount; - Geom::Path sat_path = pathv.pathAt(index); - boost::optional<size_t> curve_prev_index = boost::none; - size_t sat_curve_time = Geom::nearest_time(pathv.curveAt(index).initialPoint(),pwd2); - size_t first = Geom::nearest_time(sat_path.initialPoint() , pwd2); - if (sat_path.closed() && sat_curve_time == first) { - curve_prev_index = sat_curve_time + sat_path.size() - 1; - } else if(!sat_path.closed() || sat_curve_time != first) { - curve_prev_index = sat_curve_time - 1; - } - if (!_pparam->_use_distance && !_pparam->_vector.at(index).is_time) { - if (curve_prev_index) { - amount = _pparam->_vector.at(index).lenToRad(amount, pathv.curveAt(*curve_prev_index), pathv.curveAt(index), _pparam->_vector.at(*curve_prev_index)); - } else { - amount = 0.0; - } - } - bool aprox = false; - Geom::D2<Geom::SBasis> d2_out = _pparam->_last_pointwise->getPwd2()[index]; - if (curve_prev_index) { - Geom::D2<Geom::SBasis> d2_in = - _pparam->_last_pointwise->getPwd2()[*curve_prev_index]; - aprox = ((d2_in)[0].degreesOfFreedom() != 2 || - d2_out[0].degreesOfFreedom() != 2) && - !_pparam->_use_distance - ? true - : false; - } - Inkscape::UI::Dialogs::FilletChamferPropertiesDialog::showDialog( - this->desktop, amount, this, _pparam->_use_distance, - aprox, _pparam->_vector.at(index)); - - } -} - -void FilletChamferKnotHolderEntity::knot_set_offset(Satellite satellite) -{ - if (!_pparam->_last_pointwise) { - return; - } - size_t index = _index; - if (_index >= _pparam->_vector.size()) { - index = _index - _pparam->_vector.size(); - } - double amount = satellite.amount; - double max_amount = amount; - if (!_pparam->_use_distance && !satellite.is_time) { - Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = _pparam->_last_pointwise->getPwd2(); - Geom::PathVector pathv = path_from_piecewise(Geom::remove_short_cuts(pwd2,0.01),0.01); - Geom::Path sat_path = pathv.pathAt(index); - boost::optional<size_t> prev = boost::none; - size_t sat_curve_time = Geom::nearest_time(pathv.curveAt(index).initialPoint(),pwd2); - size_t first = Geom::nearest_time(sat_path.initialPoint() , pwd2); - if (sat_path.closed() && sat_curve_time == first) { - prev = sat_curve_time + sat_path.size() - 1; - } else if(!sat_path.closed() || sat_curve_time != first) { - prev = sat_curve_time - 1; - } - if (prev) { - amount = _pparam->_vector.at(index).radToLen(amount, pathv.curveAt(*prev), pathv.curveAt(index)); - } else { - amount = 0.0; - } - if (max_amount > 0 && amount == 0) { - amount = _pparam->_vector.at(index).amount; - } - } - satellite.amount = amount; - _pparam->_vector.at(index) = satellite; - this->parent_holder->knot_ungrabbed_handler(this->knot, 0); - _pparam->param_set_and_write_new_value(_pparam->_vector); - SPLPEItem *splpeitem = dynamic_cast<SPLPEItem *>(item); - if (splpeitem) { - sp_lpe_item_update_patheffect(splpeitem, false, false); - } -} - -} /* 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 : diff --git a/src/live_effects/parameter/satellitesarray.cpp b/src/live_effects/parameter/satellitesarray.cpp new file mode 100644 index 000000000..9274a4aff --- /dev/null +++ b/src/live_effects/parameter/satellitesarray.cpp @@ -0,0 +1,527 @@ +/* + * Author(s): + * Jabiertxo Arraiza Cenoz <jabier.arraiza@marker.es> + * + * Copyright (C) 2014 Author(s) + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "knotholder.h" +#include "ui/dialog/lpe-fillet-chamfer-properties.h" +#include "live_effects/parameter/satellitesarray.h" +#include "live_effects/effect.h" +#include "sp-lpe-item.h" +#include <preferences.h> +#include <boost/optional.hpp> +// TODO due to internal breakage in glibmm headers, +// this has to be included last. +#include <glibmm/i18n.h> + +namespace Inkscape { + +namespace LivePathEffect { + +SatellitesArrayParam::SatellitesArrayParam(const Glib::ustring &label, + const Glib::ustring &tip, + const Glib::ustring &key, + Inkscape::UI::Widget::Registry *wr, + Effect *effect) + : ArrayArrayParam<ArrayArrayParam<Satellite> >(label, tip, key, wr, effect, 0), knoth(NULL) +{ + _knot_shape = SP_KNOT_SHAPE_DIAMOND; + _knot_mode = SP_KNOT_MODE_XOR; + _knot_color = 0xAAFF8800; + _helper_size = 0; + _use_distance = false; + _effectType = FILLET_CHAMFER; + _last_pointwise = NULL; +} + +void SatellitesArrayParam::set_oncanvas_looks(SPKnotShapeType shape, + SPKnotModeType mode, + guint32 color) +{ + _knot_shape = shape; + _knot_mode = mode; + _knot_color = color; +} + +void SatellitesArrayParam::setPointwise(Pointwise *pointwise) +{ + _last_pointwise = pointwise; + param_set_and_write_new_value(_last_pointwise->getSatellites()); +} + +void SatellitesArrayParam::setUseDistance(bool use_knot_distance) +{ + _use_distance = use_knot_distance; +} + +void SatellitesArrayParam::setEffectType(EffectType et) +{ + _effectType = et; +} + +void SatellitesArrayParam::setHelperSize(int hs) +{ + _helper_size = hs; + updateCanvasIndicators(); +} + +void SatellitesArrayParam::updateCanvasIndicators(bool mirror) +{ + if (!_last_pointwise) { + return; + } + Geom::PathVector pathv = _last_pointwise->getPV(); + if (mirror == true) { + _hp.clear(); + } + for (size_t i = 0; i < _vector.size(); ++i) { + for (size_t j = 0; j < _vector[i].size(); ++j) { + if (!_vector[i][j].active || _vector[i][j].hidden) { + continue; + } + if ((!_vector[i][j].has_mirror && mirror == true) || _vector[i][j].amount == 0) { + continue; + } + double pos = 0; + if (pathv.size() <= i || pathv[i].size() <= j) { + break; + } + Geom::Curve *curve_in = pathv[i][j].duplicate(); + bool overflow = false; + double size_out = _vector[i][j].arcDistance(*curve_in); + double lenght_out = curve_in->length(); + double lenght_in = 0; + + boost::optional<size_t> curve_prev_index = boost::none; + if(j == 0 && pathv[i].closed()){ + curve_prev_index = pathv[pathv[i].size() - 1]; + } else if(!pathv[i].closed() || j != 0) { + curve_prev_index = j - 1; + } + if (curve_prev_index) { + lenght_in = pathv.curveAt(*curve_prev_index).length(); + } + if (mirror == true) { + if (curve_prev_index) { + curve_in = const_cast<Geom::Curve *>(&pathv.curveAt(*curve_prev_index)); + pos = _vector[i][j].time(size_out, true, *curve_in); + if (lenght_out < size_out) { + overflow = true; + } + } + } else { + pos = _vector[i][j].time(*curve_in); + if (lenght_in < size_out) { + overflow = true; + } + } + if (pos <= 0 || pos >= 1) { + continue; + } + Geom::Point point_a = curve_in->pointAt(pos); + Geom::Point deriv_a = unit_vector(derivative(curve_in->toSBasis()).pointAt(pos)); + Geom::Rotate rot(Geom::Rotate::from_degrees(-90)); + deriv_a = deriv_a * rot; + Geom::Point point_c = point_a - deriv_a * _helper_size; + Geom::Point point_d = point_a + deriv_a * _helper_size; + Geom::Ray ray_1(point_c, point_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); + if (mirror == true) { + aff *= Geom::Rotate(ray_1.angle() - Geom::rad_from_deg(90)); + } else { + aff *= Geom::Rotate(ray_1.angle() - Geom::rad_from_deg(270)); + } + aff *= Geom::Translate(curve_in->pointAt(pos)); + pathv *= aff; + _hp.push_back(pathv[0]); + _hp.push_back(pathv[1]); + if (overflow) { + double diameter = _helper_size; + if (_helper_size == 0) { + diameter = 15; + char const *svgd; + svgd = "M 0.7,0.35 A 0.35,0.35 0 0 1 0.35,0.7 0.35,0.35 0 0 1 0,0.35 " + "0.35,0.35 0 0 1 0.35,0 0.35,0.35 0 0 1 0.7,0.35 Z"; + Geom::PathVector pathv = sp_svg_read_pathv(svgd); + aff = Geom::Affine(); + aff *= Geom::Scale(diameter); + aff *= Geom::Translate(point_a - Geom::Point(diameter * 0.35, diameter * 0.35)); + pathv *= aff; + _hp.push_back(pathv[0]); + } else { + char const *svgd; + svgd = "M 0 -1.32 A 1.32 1.32 0 0 0 -1.32 0 A 1.32 1.32 0 0 0 0 1.32 A " + "1.32 1.32 0 0 0 1.18 0.59 L 0 0 L 1.18 -0.59 A 1.32 1.32 0 0 0 " + "0 -1.32 z"; + Geom::PathVector pathv = sp_svg_read_pathv(svgd); + aff = Geom::Affine(); + aff *= Geom::Scale(_helper_size / 2.0); + if (mirror == true) { + aff *= Geom::Rotate(ray_1.angle() - Geom::rad_from_deg(90)); + } else { + aff *= Geom::Rotate(ray_1.angle() - Geom::rad_from_deg(270)); + } + aff *= Geom::Translate(curve_in->pointAt(pos)); + pathv *= aff; + _hp.push_back(pathv[0]); + } + } + } + } + if (mirror == true) { + updateCanvasIndicators(false); + } +} +void SatellitesArrayParam::updateCanvasIndicators() +{ + updateCanvasIndicators(true); +} + +void SatellitesArrayParam::addCanvasIndicators( + SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec) +{ + hp_vec.push_back(_hp); +} + +void SatellitesArrayParam::param_transform_multiply(Geom::Affine const &postmul, + bool /*set*/) +{ + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + + if (prefs->getBool("/options/transform/rectcorners", true)) { + for (size_t i = 0; i < _vector.size(); ++i) { + for (size_t j = 0; j < _vector[i].size(); ++j) { + if (!_vector[i][j].is_time && _vector[i][j].amount > 0) { + _vector[i][j].amount = _vector[i][j].amount * + ((postmul.expansionX() + postmul.expansionY()) / 2); + } + } + } + param_set_and_write_new_value(_vector); + } +} + +void SatellitesArrayParam::addKnotHolderEntities(KnotHolder *knotholder, + SPDesktop *desktop, + SPItem *item, bool mirror) +{ + for (size_t i = 0; i < _vector.size(); ++i) { + for (size_t j = 0; j < _vector[i].size(); ++j) { + size_t iPlus = j; + if (mirror == true) { + iPlus = j + _vector[i].size(); + } + if (!_vector[i][j].active) { + continue; + } + if (!_vector[i][j].has_mirror && mirror == true) { + continue; + } + using namespace Geom; + SatelliteType type = _vector[i][j].satellite_type; + //IF is for filletChamfer effect... + if (_effectType == FILLET_CHAMFER) { + const gchar *tip; + if (type == CHAMFER) { + tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toggle type, " + "<b>Shift+Click</b> open dialog, " + "<b>Ctrl+Alt+Click</b> reset"); + } else if (type == INVERSE_CHAMFER) { + tip = _("<b>Inverse Chamfer</b>: <b>Ctrl+Click</b> toggle type, " + "<b>Shift+Click</b> open dialog, " + "<b>Ctrl+Alt+Click</b> reset"); + } else if (type == INVERSE_FILLET) { + tip = _("<b>Inverse Fillet</b>: <b>Ctrl+Click</b> toggle type, " + "<b>Shift+Click</b> open dialog, " + "<b>Ctrl+Alt+Click</b> reset"); + } else { + tip = _("<b>Fillet</b>: <b>Ctrl+Click</b> toggle type, " + "<b>Shift+Click</b> open dialog, " + "<b>Ctrl+Alt+Click</b> reset"); + } + FilletChamferKnotHolderEntity *e = + new FilletChamferKnotHolderEntity(this, i, iPlus); + e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _(tip), + _knot_shape, _knot_mode, _knot_color); + knotholder->add(e); + } + } + } + if (mirror == true) { + addKnotHolderEntities(knotholder, desktop, item, false); + } +} + +void SatellitesArrayParam::addKnotHolderEntities(KnotHolder *knotholder, + SPDesktop *desktop, + SPItem *item) +{ + knoth = knotholder; + addKnotHolderEntities(knotholder, desktop, item, true); +} + +FilletChamferKnotHolderEntity::FilletChamferKnotHolderEntity( + SatellitesArrayParam *p, size_t index, size_t subindex) + : _pparam(p), _index(index), _subindex(subindex) {} + +void FilletChamferKnotHolderEntity::knot_set(Geom::Point const &p, + Geom::Point const &/*origin*/, + guint state) +{ + Geom::Point s = snap_knot_position(p, state); + size_t subindex = _subindex; + if (_subindex >= _pparam->_vector[_index].size()) { + subindex = _subindex - _pparam->_vector[_index].size(); + } + if (!valid_index(subindex)) { + return; + } + + if (!_pparam->_last_pointwise) { + return; + } + + Satellite satellite = _pparam->_vector[_index].at(subindex); + if (!satellite.active || satellite.hidden) { + return; + } + Pointwise *pointwise = _pparam->_last_pointwise; + Geom::PathVector pathv = pparam->_last_pointwise->getPV(); + if (_subindex >= _pparam->_vector[_index].size() ) { + boost::optional<size_t> curve_prev_index = boost::none; + if(_subindex == 0 && pathv[_index].closed()){ + curve_prev_index = pathv[pathv[_index].size() - 1]; + } else if(!pathv[_index].closed() || _subindex != 0) { + curve_prev_index = _subindex - 1; + } + if (curve_prev_index) { + Geom::Curve const &curve_in = pathv[_index][*curve_prev_index]; + double mirror_time = Geom::nearest_time(s, curve_in); + double time_start = 0; + Satellites sats = pointwise->getSatellites(); + time_start = sats[_index][*curve_prev_index].time(curve_in); + if (time_start > mirror_time) { + mirror_time = time_start; + } + double size = arcLengthAt(mirror_time, curve_in); + double amount = curve_in.length() - size; + if (satellite.is_time) { + amount = timeAtArcLength(amount, pathv[_index][); + } + satellite.amount = amount; + } + } else { + satellite.setPosition(s, pathv[_index]); + } + _pparam->_vector[_index][_subindex] = satellite; + SPLPEItem *splpeitem = dynamic_cast<SPLPEItem *>(item); + if (splpeitem) { + sp_lpe_item_update_patheffect(splpeitem, false, false); + } +} + +Geom::Point FilletChamferKnotHolderEntity::knot_get() const +{ + Geom::Point tmp_point; + size_t subindex = _subindex; + if (_subindex >= _pparam->_vector[_index].size()) { + subindex = _subindex - _pparam->_vector[_index].size(); + } + if (!valid_index(_subindex)) { + return Geom::Point(Geom::infinity(), Geom::infinity()); + } + Satellite satellite = _pparam->_vector[_index][_subindex]; + if (!_pparam->_last_pointwise) { + return Geom::Point(Geom::infinity(), Geom::infinity()); + } + if (!satellite.active || satellite.hidden) { + return Geom::Point(Geom::infinity(), Geom::infinity()); + } + Pointwise *pointwise = _pparam->_last_pointwise; + Geom::PathVector pathv = pparam->_last_pointwise->getPV(); + if (pathv[_index].size() <= subindex) { + return Geom::Point(Geom::infinity(), Geom::infinity()); + } + this->knot->show(); + if (_subindex >= _pparam->_vector[index].size()) { + tmp_point = satellite.getPosition(pathv[_index][_subindex]); + boost::optional<size_t> curve_prev_index = boost::none; + if(_subindex == 0 && pathv[_index].closed()){ + curve_prev_index = pathv[pathv[_index].size() - 1]; + } else if(!pathv[_index].closed() || _subindex != 0) { + curve_prev_index = _subindex - 1; + } + if (curve_prev_index) { + Geom::Curve const &curve_in = pathv[_index][*curve_prev_index]; + double s = satellite.arcDistance(pathv[_index][_subindex]); + double t = satellite.time(s, true, curve_in); + if (t > 1) { + t = 1; + } + if (t < 0) { + t = 0; + } + double time_start = 0; + time_start = pointwise->getSatellites()[_index][*curve_prev_index].time(curve_in); + if (time_start > t) { + t = time_start; + } + tmp_point = (curve_in).pointAt(t); + } + } else { + tmp_point = satellite.getPosition(pathv[_index][_subindex]); + } + Geom::Point const canvas_point = tmp_point; + return canvas_point; +} + +void FilletChamferKnotHolderEntity::knot_click(guint state) +{ + if (!_pparam->_last_pointwise) { + return; + } + + size_t subindex = _subindex; + if (_subindex >= _pparam->_vector[_index].size()) { + subindex = _subindex - _pparam->_vector[_index].size(); + } + if (state & GDK_CONTROL_MASK) { + if (state & GDK_MOD1_MASK) { + _pparam->_vector[_index][_subindex].amount = 0.0; + _pparam->param_set_and_write_new_value(_pparam->_vector); + sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false); + } else { + using namespace Geom; + SatelliteType type = _pparam->_vector[_index][_subindex].satellite_type; + switch (type) { + case FILLET: + type = INVERSE_FILLET; + break; + case INVERSE_FILLET: + type = CHAMFER; + break; + case CHAMFER: + type = INVERSE_CHAMFER; + break; + default: + type = FILLET; + break; + } + _pparam->_vector[_index][subindex].satellite_type = 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 == CHAMFER) { + tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toggle type, " + "<b>Shift+Click</b> open dialog, " + "<b>Ctrl+Alt+Click</b> reset"); + } else if (type == INVERSE_CHAMFER) { + tip = _("<b>Inverse Chamfer</b>: <b>Ctrl+Click</b> toggle type, " + "<b>Shift+Click</b> open dialog, " + "<b>Ctrl+Alt+Click</b> reset"); + } else if (type == INVERSE_FILLET) { + tip = _("<b>Inverse Fillet</b>: <b>Ctrl+Click</b> toggle type, " + "<b>Shift+Click</b> open dialog, " + "<b>Ctrl+Alt+Click</b> reset"); + } else { + tip = _("<b>Fillet</b>: <b>Ctrl+Click</b> toggle type, " + "<b>Shift+Click</b> open dialog, " + "<b>Ctrl+Alt+Click</b> reset"); + } + this->knot->tip = g_strdup(tip); + this->knot->show(); + } + } else if (state & GDK_SHIFT_MASK) { + Geom::PathVector pathv = pparam->_last_pointwise->getPV(); + double amount = _pparam->_vector[_index][_subindex].amount; + boost::optional<size_t> curve_prev_index = boost::none; + if(_subindex == 0 && pathv[_index].closed()){ + curve_prev_index = pathv[pathv[_index].size() - 1]; + } else if(!pathv[_index].closed() || _subindex != 0) { + curve_prev_index = _subindex - 1; + } + if (!_pparam->_use_distance && !_pparam->_vector[_index][subindex].is_time) { + if (curve_prev_index) { + amount = _pparam->_vector[_index][subindex].lenToRad(amount, pathv[_index][*curve_prev_index], pathv[_index][subindex], _pparam->_vector[_index][*curve_prev_index]); + } else { + amount = 0.0; + } + } + bool aprox = false; + Geom::D2<Geom::SBasis> d2_out = _pparam->_last_pointwise->getPwd2()[_index][subindex]; + if (curve_prev_index) { + Geom::D2<Geom::SBasis> d2_in = + _pparam->_last_pointwise->getPwd2()[_index][*curve_prev_index]; + aprox = ((d2_in)[0].degreesOfFreedom() != 2 || + d2_out[0].degreesOfFreedom() != 2) && + !_pparam->_use_distance + ? true + : false; + } + Inkscape::UI::Dialogs::FilletChamferPropertiesDialog::showDialog( + this->desktop, amount, this, _pparam->_use_distance, + aprox, _pparam->_vector[_index][subindex]); + + } +} + +void FilletChamferKnotHolderEntity::knot_set_offset(Satellite satellite) +{ + if (!_pparam->_last_pointwise) { + return; + } + size_t subindex = _subindex; + if (_subindex >= _pparam->_vector[_index].size()) { + subindex = _subindex - _pparam->_vector[_index].size(); + } + double amount = satellite.amount; + double max_amount = amount; + if (!_pparam->_use_distance && !satellite.is_time) { + Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = _pparam->_last_pointwise->getPwd2(); + Geom::PathVector pathv = path_from_piecewise(Geom::remove_short_cuts(pwd2,0.01),0.01); + Geom::Path sat_path = pathv.pathAt(index); + boost::optional<size_t> curve_prev_index = boost::none; + if(_subindex == 0 && pathv[_index].closed()){ + curve_prev_index = pathv[pathv[_index].size() - 1]; + } else if(!pathv[_index].closed() || _subindex != 0) { + curve_prev_index = _subindex - 1; + } + if (curve_prev_index) { + amount = _pparam->_vector[_index][subindex].radToLen(amount, pathv[_index][*prev], pathv[_index][subindex]); + } else { + amount = 0.0; + } + if (max_amount > 0 && amount == 0) { + amount = _pparam->_vector[_index][subindex].amount; + } + } + satellite.amount = amount; + _pparam->_vector[_index][subindex] = satellite; + this->parent_holder->knot_ungrabbed_handler(this->knot, 0); + _pparam->param_set_and_write_new_value(_pparam->_vector); + SPLPEItem *splpeitem = dynamic_cast<SPLPEItem *>(item); + if (splpeitem) { + sp_lpe_item_update_patheffect(splpeitem, false, false); + } +} + +} /* 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 : diff --git a/src/live_effects/parameter/satellitearray.h b/src/live_effects/parameter/satellitesarray.h index bb8bf27c8..db3776ba3 100644 --- a/src/live_effects/parameter/satellitearray.h +++ b/src/live_effects/parameter/satellitesarray.h @@ -1,5 +1,5 @@ -#ifndef INKSCAPE_LIVEPATHEFFECT_SATELLITE_PAIR_ARRAY_H -#define INKSCAPE_LIVEPATHEFFECT_SATELLITE_PAIR_ARRAY_H +#ifndef INKSCAPE_LIVEPATHEFFECT_SATELLITES_ARRAY_H +#define INKSCAPE_LIVEPATHEFFECT_SATELLITES_ARRAY_H /* * Inkscape::LivePathEffectParameters @@ -30,9 +30,9 @@ namespace LivePathEffect { class FilletChamferKnotHolderEntity; -class SatelliteArrayParam : public ArrayParam<Satellite> { +class SatellitesArrayParam : public ArrayArrayParam<Satellite> { public: - SatelliteArrayParam(const Glib::ustring &label, const Glib::ustring &tip, + SatellitesArrayParam(const Glib::ustring &label, const Glib::ustring &tip, const Glib::ustring &key, Inkscape::UI::Widget::Registry *wr, Effect *effect); @@ -67,8 +67,8 @@ protected: KnotHolder *knoth; private: - SatelliteArrayParam(const SatelliteArrayParam &); - SatelliteArrayParam &operator=(const SatelliteArrayParam &); + SatellitesArrayParam(const SatellitesArrayParam &); + SatellitesArrayParam &operator=(const SatellitesArrayParam &); SPKnotShapeType _knot_shape; SPKnotModeType _knot_mode; @@ -83,7 +83,7 @@ private: class FilletChamferKnotHolderEntity : public KnotHolderEntity { public: - FilletChamferKnotHolderEntity(SatelliteArrayParam *p, size_t index); + FilletChamferKnotHolderEntity(SatellitesArrayParam *p, size_t index, size_t subindex); virtual ~FilletChamferKnotHolderEntity() { _pparam->knoth = NULL; @@ -103,8 +103,9 @@ public: ; private: - SatelliteArrayParam *_pparam; + SatellitesArrayParam *_pparam; size_t _index; + size_t _subindex; }; } //namespace LivePathEffect |
