diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2015-08-23 21:03:12 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2015-08-23 21:03:12 +0000 |
| commit | 4f78e3e4289b52ba4b7a3fbe24fd0d6fcb6f2250 (patch) | |
| tree | 80a9350590d7ef0ccbde1f1826a9c9f905e12772 /src | |
| parent | remove couts (diff) | |
| download | inkscape-4f78e3e4289b52ba4b7a3fbe24fd0d6fcb6f2250.tar.gz inkscape-4f78e3e4289b52ba4b7a3fbe24fd0d6fcb6f2250.zip | |
satellites in curves
(bzr r13645.1.110)
Diffstat (limited to 'src')
| -rw-r--r-- | src/helper/geom-pointwise.cpp | 61 | ||||
| -rw-r--r-- | src/helper/geom-pointwise.h | 6 | ||||
| -rw-r--r-- | src/helper/geom-satellite.cpp | 163 | ||||
| -rw-r--r-- | src/helper/geom-satellite.h | 25 | ||||
| -rw-r--r-- | src/live_effects/lpe-fillet-chamfer.cpp | 102 | ||||
| -rw-r--r-- | src/live_effects/parameter/satellitearray.cpp | 127 |
6 files changed, 209 insertions, 275 deletions
diff --git a/src/helper/geom-pointwise.cpp b/src/helper/geom-pointwise.cpp index 8a0db6258..8ae2125a4 100644 --- a/src/helper/geom-pointwise.cpp +++ b/src/helper/geom-pointwise.cpp @@ -23,76 +23,25 @@ pwd2sb Pointwise::getPwd2() const void Pointwise::setPwd2(pwd2sb const &pwd2_in) { + _pathvector = path_from_piecewise(Geom::remove_short_cuts(_pwd2,0.01),0.01); _pwd2 = pwd2_in; } -std::vector<Satellite> Pointwise::getSatellites(bool curve_based) +std::vector<Satellite> Pointwise::getSatellites(e) { - if(curve_based){ - size_t global_counter = 0; - size_t satellite_gap = 0; - Geom::PathVector pathvector = path_from_piecewise(Geom::remove_short_cuts(_pwd2,0.01),0.01); - for (Geom::PathVector::const_iterator path_it = pathvector.begin(); - path_it != pathvector.end(); ++path_it) { - if (path_it->empty()) { - continue; - } - size_t counter = 0; - for (Geom::Path::const_iterator curve_it = path_it->begin(); - curve_it != path_it->end_closed(); ++curve_it) { - if(!path_it->closed()){ - if(path_it->size_closed()-1 == counter){ - _satellites.erase(_satellites.begin() + (global_counter - 1 - satellite_gap)); - satellite_gap++; - } - } - counter++; - global_counter++; - } - } - } return _satellites; } -void Pointwise::setSatellites(std::vector<Satellite> const &sats, bool curve_based) +void Pointwise::setSatellites(std::vector<Satellite> const &sats) { _satellites = sats; - if(curve_based){ - size_t global_counter = 0; - Geom::PathVector pathvector = path_from_piecewise(Geom::remove_short_cuts(_pwd2,0.01),0.01); - for (Geom::PathVector::const_iterator path_it = pathvector.begin(); - path_it != pathvector.end(); ++path_it) { - if (path_it->empty()) { - continue; - } - size_t counter = 0; - size_t start = global_counter; - for (Geom::Path::const_iterator curve_it = path_it->begin(); - curve_it != path_it->end_closed(); ++curve_it) { - if(!path_it->closed()){ - if(path_it->size_closed()-1 == counter){ - if(global_counter == _satellites.size()){ - _satellites.push_back(_satellites[start]); - } else { - _satellites.insert(_satellites.begin() + global_counter + 1,_satellites[start]); - } - } - } - counter++; - global_counter++; - } - } - } } - - void Pointwise::setStart() { - Geom::PathVector pointwise_pv = path_from_piecewise(Geom::remove_short_cuts(_pwd2,0.01),0.01); int counter = 0; - for (Geom::PathVector::const_iterator path_it = pointwise_pv.begin(); - path_it != pointwise_pv.end(); ++path_it) { + for (Geom::PathVector::const_iterator path_it = _pathvector.begin(); + path_it != _pathvector.end(); ++path_it) { if (path_it->empty()) { continue; } diff --git a/src/helper/geom-pointwise.h b/src/helper/geom-pointwise.h index fe8f6f157..9d2993a23 100644 --- a/src/helper/geom-pointwise.h +++ b/src/helper/geom-pointwise.h @@ -33,13 +33,13 @@ class Pointwise { public: pwd2sb getPwd2() const; void setPwd2(pwd2sb const &pwd2_in); - /** * @parameter curve_based allow the use of a satellite on last node of open paths * if not curve based */ - std::vector<Satellite> getSatellites(bool curve_based = true); - void setSatellites(std::vector<Satellite> const &sats, bool curve_based = true); + std::vector<Satellite> getSatellites(); + void setSatellites(std::vector<Satellite> const &sats); + /** Update the start satellite on open/closed paths. */ void setStart(); diff --git a/src/helper/geom-satellite.cpp b/src/helper/geom-satellite.cpp index 9b2691a33..10afca725 100644 --- a/src/helper/geom-satellite.cpp +++ b/src/helper/geom-satellite.cpp @@ -36,53 +36,88 @@ Satellite::Satellite(SatelliteType satellite_type) Satellite::~Satellite() {} /** - * Calculate the time in d2_in with a size of A + * Calculate the time in curve_in with a size of A * TODO: find a better place to it */ -double timeAtArcLength(double A, Geom::D2<Geom::SBasis> const d2_in) +double timeAtArcLength(double const A, Geom::Curve const &curve_in, size_t cache_limit) { - if (!d2_in.isFinite() || d2_in.isZero() || A == 0) { + if ( A == 0 || curve_in.isDegenerate()) { return 0; } + + //using "d2_in" for curve comparation, using directly "curve_in" crash in bezier compare function- dynamic_cast- + Geom::D2<Geom::SBasis> d2_in = curve_in.toSBasis(); + static std::deque<std::pair<double, std::pair<double, Geom::D2<Geom::SBasis> > > > deque_cache; + if(cache_limit > 0 && deque_cache.size() > cache_limit){ + std::deque<std::pair<double, std::pair<double, Geom::D2<Geom::SBasis> > > > deque_cache_split(deque_cache.begin(), deque_cache.begin() + cache_limit); + deque_cache = deque_cache_split; + } + if(cache_limit > 0){ + return 1; + } + std::deque<std::pair<double, std::pair<double, Geom::D2<Geom::SBasis> > > >::iterator it; + for (it = deque_cache.begin() ; it != deque_cache.end(); ++it){ + if(it->second.first == A){ + if(it->second.second == d2_in){ + return it->first; + } + } + } + double t = 0; - double length_part = Geom::length(d2_in, Geom::EPSILON); - if (A >= length_part || d2_in[0].degreesOfFreedom() == 2) { + double length_part = curve_in.length(); + if (A >= length_part || curve_in.isLineSegment()) { if (length_part != 0) { t = A / length_part; } - } else if (d2_in[0].degreesOfFreedom() != 2) { - Geom::Piecewise<Geom::D2<Geom::SBasis> > u; - u.push_cut(0); - u.push(d2_in, 1); - std::vector<double> t_roots = roots(arcLengthSb(u) - A); + } else if (!curve_in.isLineSegment()) { + + std::vector<double> t_roots = roots(Geom::arcLengthSb(d2_in) - A); if (t_roots.size() > 0) { t = t_roots[0]; } } - + deque_cache.push_front(std::make_pair(t, std::make_pair(A, d2_in))); return t; } /** - * Calculate the size in d2_in with a point at A + * Calculate the size in curve_in with a point at A * TODO: find a better place to it */ -double arcLengthAt(double A, Geom::D2<Geom::SBasis> const d2_in) +double arcLengthAt(double const A, Geom::Curve const &curve_in, size_t cache_limit) { - if (!d2_in.isFinite() || d2_in.isZero() || A == 0) { + if ( A == 0 || curve_in.isDegenerate()) { return 0; } + + //using "d2_in" for curve comparation, using directly "curve_in" crash in bezier compare function- dynamic_cast- + Geom::D2<Geom::SBasis> d2_in = curve_in.toSBasis(); + static std::deque<std::pair<double, std::pair<double, Geom::D2<Geom::SBasis> > > > deque_cache; + if(cache_limit > 0 && deque_cache.size() > cache_limit){ + std::deque<std::pair<double, std::pair<double, Geom::D2<Geom::SBasis> > > > deque_cache_split(deque_cache.begin(), deque_cache.begin() + cache_limit); + deque_cache = deque_cache_split; + } + if(cache_limit > 0){ + return 1; + } + std::deque<std::pair<double, std::pair<double, Geom::D2<Geom::SBasis> > > >::iterator it; + for (it = deque_cache.begin() ; it != deque_cache.end(); ++it){ + if(it->second.first == A){ + if(it->second.second == d2_in){ + return it->first; + } + } + } double s = 0; - double length_part = Geom::length(d2_in, Geom::EPSILON); - if (A > length_part || d2_in[0].degreesOfFreedom() == 2) { + double length_part = curve_in.length(); + if (A > length_part || curve_in.isLineSegment()) { s = (A * length_part); - } else if (d2_in[0].degreesOfFreedom() != 2) { - Geom::Piecewise<Geom::D2<Geom::SBasis> > u; - u.push_cut(0); - u.push(d2_in, 1); - u = Geom::portion(u, 0.0, A); - s = Geom::length(u, 0.001); + } else if (!curve_in.isLineSegment()) { + Geom::Curve *curve = curve_in.portion(0.0, A); + s = curve->length(0.001); } + deque_cache.push_front(std::make_pair(s, std::make_pair(A, d2_in))); return s; } @@ -90,10 +125,12 @@ double arcLengthAt(double A, Geom::D2<Geom::SBasis> const d2_in) * Convert a arc radius of a fillet/chamfer to his satellite length -point position where fillet/chamfer knot be on original curve */ double Satellite::radToLen( - double A, Geom::D2<Geom::SBasis> const d2_in, - Geom::D2<Geom::SBasis> const d2_out) const + double const A, Geom::Curve const &curve_in, + Geom::Curve const &curve_out) const { double len = 0; + Geom::D2<Geom::SBasis> d2_in = curve_in.toSBasis(); + Geom::D2<Geom::SBasis> d2_out = curve_out.toSBasis(); Geom::Piecewise<Geom::D2<Geom::SBasis> > offset_curve0 = Geom::Piecewise<Geom::D2<Geom::SBasis> >(d2_in) + rot90(unitVector(derivative(d2_in))) * (A); @@ -105,11 +142,11 @@ double Satellite::radToLen( Geom::Crossings cs = Geom::crossings(p0, p1); if (cs.size() > 0) { Geom::Point cp = p0(cs[0].ta); - double p0pt = nearest_time(cp, d2_out); - len = arcLengthAt(p0pt, d2_out); + double p0pt = nearest_time(cp, curve_out); + len = arcLengthAt(p0pt, curve_out); } else { if (A > 0) { - len = radToLen(A * -1, d2_in, d2_out); + len = radToLen(A * -1, curve_in, curve_out); } } return len; @@ -119,37 +156,29 @@ double Satellite::radToLen( * Convert a satelite length -point position where fillet/chamfer knot be on original curve- to a arc radius of fillet/chamfer */ double Satellite::lenToRad( - double A, Geom::D2<Geom::SBasis> const d2_in, - Geom::D2<Geom::SBasis> const d2_out, + double const A, Geom::Curve const &curve_in, + Geom::Curve const &curve_out, Satellite const previousSatellite) const { - double time_in = (previousSatellite).time(A, true, d2_in); - double time_out = timeAtArcLength(A, d2_out); - Geom::Point startArcPoint = (d2_in).valueAt(time_in); - Geom::Point endArcPoint = d2_out.valueAt(time_out); - Geom::Piecewise<Geom::D2<Geom::SBasis> > u; - u.push_cut(0); - u.push(d2_in, 1); - Geom::Curve *C = path_from_piecewise(u, 0.1)[0][0].duplicate(); - Geom::Piecewise<Geom::D2<Geom::SBasis> > u2; - u2.push_cut(0); - u2.push(d2_out, 1); - Geom::Curve *D = path_from_piecewise(u2, 0.1)[0][0].duplicate(); - Geom::Curve *knotCurve1 = C->portion(0, time_in); - Geom::Curve *knotCurve2 = D->portion(time_out, 1); + double time_in = (previousSatellite).time(A, true, curve_in); + double time_out = timeAtArcLength(A, curve_out); + Geom::Point startArcPoint = curve_in.pointAt(time_in); + Geom::Point endArcPoint = curve_out.pointAt(time_out); + Geom::Curve *knotCurve1 = curve_in.portion(0, time_in); + Geom::Curve *knotCurve2 = curve_out.portion(time_out, 1); Geom::CubicBezier const *cubic1 = dynamic_cast<Geom::CubicBezier const *>(&*knotCurve1); - Geom::Ray ray1(startArcPoint, (d2_in).valueAt(1)); + Geom::Ray ray1(startArcPoint, curve_in.pointAt(1)); if (cubic1) { ray1.setPoints((*cubic1)[2], startArcPoint); } Geom::CubicBezier const *cubic2 = dynamic_cast<Geom::CubicBezier const *>(&*knotCurve2); - Geom::Ray ray2(d2_out.valueAt(0), endArcPoint); + Geom::Ray ray2(curve_out.pointAt(0), endArcPoint); if (cubic2) { ray2.setPoints(endArcPoint, (*cubic2)[1]); } - bool ccwToggle = cross((d2_in).valueAt(1) - startArcPoint, + bool ccwToggle = cross(curve_in.pointAt(1) - startArcPoint, endArcPoint - startArcPoint) < 0; double distanceArc = Geom::distance(startArcPoint, middle_point(startArcPoint, endArcPoint)); @@ -162,13 +191,15 @@ double Satellite::lenToRad( } /** - * Get the time position of the satellite in d2_in + * Get the time position of the satellite in curve_in */ -double Satellite::time(Geom::D2<Geom::SBasis> d2_in) const +double Satellite::time(Geom::Curve const &curve_in, bool const I) const { double t = amount; if (!is_time) { - t = timeAtArcLength(t, d2_in); + t = time(t, I, curve_in); + } else if (I) { + t = 1-t; } if (t > 1) { t = 1; @@ -179,8 +210,8 @@ double Satellite::time(Geom::D2<Geom::SBasis> d2_in) const /**. * Get the time from a length A in other curve, a bolean I gived to reverse time */ -double Satellite::time(double A, bool I, - Geom::D2<Geom::SBasis> d2_in) const +double Satellite::time(double A, bool const I, + Geom::Curve const &curve_in) const { if (A == 0 && I) { return 1; @@ -189,21 +220,21 @@ double Satellite::time(double A, bool I, return 0; } if (!I) { - return timeAtArcLength(A, d2_in); + return timeAtArcLength(A, curve_in); } - double length_part = Geom::length(d2_in, Geom::EPSILON); + double length_part = curve_in.length(); A = length_part - A; - return timeAtArcLength(A, d2_in); + return timeAtArcLength(A, curve_in); } /** - * Get the length of the satellite in d2_in + * Get the length of the satellite in curve_in */ -double Satellite::arcDistance(Geom::D2<Geom::SBasis> d2_in) const +double Satellite::arcDistance(Geom::Curve const &curve_in) const { double s = amount; if (is_time) { - s = arcLengthAt(s, d2_in); + s = arcLengthAt(s, curve_in); } return s; } @@ -211,22 +242,26 @@ double Satellite::arcDistance(Geom::D2<Geom::SBasis> d2_in) const /** * Get the point position of the satellite */ -Geom::Point Satellite::getPosition(Geom::D2<Geom::SBasis> d2_in) const +Geom::Point Satellite::getPosition(Geom::Curve const &curve_in, bool const I) const { - double t = time(d2_in); - return d2_in.valueAt(t); + double t = time(curve_in, I); + return curve_in.pointAt(t); } /** * Set the position of the satellite from a gived point P */ -void Satellite::setPosition(Geom::Point p, Geom::D2<Geom::SBasis> d2_in) +void Satellite::setPosition(Geom::Point const p, Geom::Curve const &curve_in, bool const I) { - double A = Geom::nearest_time(p, d2_in); + Geom::Curve * curve = const_cast<Geom::Curve *>(&curve_in); + if (I) { + curve = curve->reverse(); + } + double A = Geom::nearest_time(p, *curve); if (!is_time) { - A = arcLengthAt(A, d2_in); + A = arcLengthAt(A, *curve); } - amount = A; + this->setAmount(A); } /** diff --git a/src/helper/geom-satellite.h b/src/helper/geom-satellite.h index ef76060c4..ed1ec221b 100644 --- a/src/helper/geom-satellite.h +++ b/src/helper/geom-satellite.h @@ -11,7 +11,6 @@ #ifndef SEEN_SATELLITE_H #define SEEN_SATELLITE_H -#include <2geom/d2.h> #include <map> #include <boost/assign.hpp> #include <2geom/sbasis-geometric.h> @@ -64,18 +63,18 @@ public: { steps = set_steps; } - double lenToRad(double A, Geom::D2<Geom::SBasis> d2_in, - Geom::D2<Geom::SBasis> d2_out, - Satellite previousSatellite) const; - double radToLen(double A, Geom::D2<Geom::SBasis> d2_in, - Geom::D2<Geom::SBasis> d2_out) const; + double lenToRad(double const A, Geom::Curve const &curve_in, + Geom::Curve const &curve_out, + Satellite const previousSatellite) const; + double radToLen(double const A, Geom::Curve const &curve_in, + Geom::Curve const &curve_out) const; - double time(Geom::D2<Geom::SBasis> d2_in) const; - double time(double A, bool I, Geom::D2<Geom::SBasis> d2_in) const; - double arcDistance(Geom::D2<Geom::SBasis> d2_in) const; + double time(Geom::Curve const &curve_in, bool const I = false) const; + double time(double A, bool const I, Geom::Curve const &curve_in) const; + double arcDistance(Geom::Curve const &curve_in) const; - void setPosition(Geom::Point p, Geom::D2<Geom::SBasis> d2_in); - Geom::Point getPosition(Geom::D2<Geom::SBasis> d2_in) const; + void setPosition(Geom::Point const p, Geom::Curve const &curve_in, bool const I = false); + Geom::Point getPosition(Geom::Curve const &curve_in, bool const I = false) const; void setSatelliteType(gchar const *A); gchar const *getSatelliteTypeGchar() const; @@ -88,8 +87,8 @@ public: double angle; size_t steps; }; -double timeAtArcLength(double A, Geom::D2<Geom::SBasis> const d2_in); -double arcLengthAt(double A, Geom::D2<Geom::SBasis> const d2_in); +double timeAtArcLength(double const A, Geom::Curve const &curve_in, size_t cache_limit = 0); +double arcLengthAt(double const A, Geom::Curve const &curve_in, size_t cache_limit = 0); #endif // SEEN_SATELLITE_H diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 8998279a6..385e9ce28 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -85,19 +85,16 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) SPLPEItem *splpeitem = const_cast<SPLPEItem *>(lpeItem); SPShape *shape = dynamic_cast<SPShape *>(splpeitem); if (shape) { - Geom::PathVector const original_pathv = - pathv_to_linear_and_cubic_beziers(shape->getCurve()->get_pathvector()); - Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in = paths_to_pw(original_pathv); - pwd2_in = remove_short_cuts(pwd2_in, 0.01); + 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 = original_pathv.begin(); - path_it != original_pathv.end(); ++path_it) { + for (Geom::PathVector::const_iterator path_it = pathv.begin(); + path_it != pathv.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(); + Geom::Path::const_iterator curve_endit = path_it->end_closed(); int counter = 0; size_t steps = chamfer_steps; while (curve_it1 != curve_endit) { @@ -106,6 +103,7 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) if (counter == 0) { if (!path_it->closed()) { active = false; + hidden = true; } } Satellite satellite(FILLET); @@ -123,9 +121,9 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) } } pointwise = new Pointwise(); - pointwise->setPwd2(pwd2_in); - pointwise->setSatellites(satellites); - pointwise->setStart(); + pointwise->setPathVector(pathv); + pointwise->setSatellites(satellites, false); + //pointwise->setStart(); satellites_param.setPointwise(pointwise); } else { g_warning("LPE Fillet/Chamfer can only be applied to shapes (not groups)."); @@ -262,11 +260,14 @@ void LPEFilletChamfer::updateAmount() power = radius / 100; } std::vector<Satellite> satellites = pointwise->getSatellites(); + Geom::PathVector const pathv = pointwise->getPathVector(); + //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(); for (std::vector<Satellite>::iterator it = satellites.begin(); it != satellites.end(); ++it) { - Geom::Path sat_path = pathvector_before_effect.pathAt(it - satellites.begin()); - size_t sat_curve_time = Geom::nearest_time(pathvector_before_effect.curveAt(it - satellites.begin()).initialPoint() , pwd2); + 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; @@ -282,25 +283,12 @@ void LPEFilletChamfer::updateAmount() } else if(!sat_path.closed() || sat_curve_time != first) { previous = sat_curve_time - 1; } - if (only_selected) { - Geom::Point satellite_point = pwd2.valueAt(it - satellites.begin()); - if (isNodePointSelected(satellite_point)) { - if (!use_knot_distance && !flexible) { - if(previous) { - it->amount = it->radToLen(power, pwd2[*previous], - pwd2[it - satellites.begin()]); - } else { - it->amount = 0.0; - } - } else { - it->amount = power; - } - } - } else { + 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, pwd2[*previous], - pwd2[it - satellites.begin()]); + it->amount = it->radToLen(power, pathv.curveAt(*previous), + pathv.curveAt(it - satellites.begin())); } else { it->amount = 0.0; } @@ -375,31 +363,36 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) //mandatory call satellites_param.setEffectType(effectType()); - Geom::PathVector const original_pathv = + Geom::PathVector const pathv = pathv_to_linear_and_cubic_beziers(c->get_pathvector()); - Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2_in = paths_to_pw(original_pathv); - pwd2_in = remove_short_cuts(pwd2_in, 0.01); - std::vector<Satellite> sats = satellites_param.data(); + Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = paths_to_pw(pathv); + pwd2 = remove_short_cuts(pwd2, 0.01); + std::vector<Satellite> sats = normalizeSatellites(pathv, satellites_param.data()); if(sats.empty()) { doOnApply(lpeItem); - sats = satellites_param.data(); + sats = normalizeSatellites(pathv, satellites_param.data()); } if (hide_knots) { satellites_param.setHelperSize(0); } else { satellites_param.setHelperSize(helper_size); } + Geom::Curve const &first_curve = pathv.curveAt(0); + size_t number_curves = pathv.curveCount(); + //Activete cache + timeAtArcLength(1, first_curve, number_curves * 3); + arcLengthAt(1, first_curve, number_curves * 3); 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::D2<Geom::SBasis> d2_in = pwd2_in[it - sats.begin()]; + Geom::Curve const &curve_in = pathv.curveAt(it - sats.begin()); if (it->is_time) { - double time = timeAtArcLength(amount, d2_in); + double time = timeAtArcLength(amount, curve_in); it->amount = time; } else { - double size = arcLengthAt(amount, d2_in); + double size = arcLengthAt(amount, curve_in); it->amount = size; } } @@ -409,7 +402,6 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) it->hidden = hide_knots; ++it; } - size_t number_curves = original_pathv.curveCount(); //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 @@ -423,10 +415,10 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) sat.setAmount(0.0); sat.setAngle(0.0); sat.setSteps(0); - pointwise->recalculateForNewPwd2(pwd2_in, original_pathv, sat); + pointwise->recalculateForNewPwd2(pwd2, pathv, sat); } else { pointwise = new Pointwise(); - pointwise->setPwd2(pwd2_in); + pointwise->setPwd2(pwd2); pointwise->setSatellites(sats); } pointwise->setStart(); @@ -519,16 +511,16 @@ LPEFilletChamfer::doEffect_path(Geom::PathVector const &path_in) if (first == counter) { if (sats.size() > first && sats[first].active) { time0 = - sats[first].time(path_it->begin()->duplicate()->toSBasis()); + sats[first].time(*path_it->begin()); } else { time0 = 0; } } - + Geom::Curve const &curve_it2_fixed_ref = *curve_it2_fixed; bool last = curve_it2 == curve_endit; - double s = satellite.arcDistance(curve_it2_fixed->toSBasis()); - double time1 = satellite.time(s, true, (*curve_it1).toSBasis()); - double time2 = satellite.time(curve_it2_fixed->toSBasis()); + double s = satellite.arcDistance(curve_it2_fixed_ref); + double time1 = satellite.time(s, true, (*curve_it1)); + double time2 = satellite.time(curve_it2_fixed_ref); if (!satellite.active) { time1 = 1; time2 = 0; @@ -552,15 +544,15 @@ LPEFilletChamfer::doEffect_path(Geom::PathVector const &path_in) } Geom::Point start_arc_point = knot_curve_1->finalPoint(); - Geom::Point end_arc_point = curve_it2_fixed->pointAt(times[2]); + Geom::Point end_arc_point = curve_it2_fixed_ref.pointAt(times[2]); if (times[2] == 1) { - end_arc_point = curve_it2_fixed->pointAt(times[2] - GAP_HELPER); + end_arc_point = curve_it2_fixed_ref.pointAt(times[2] - GAP_HELPER); } if (times[1] == times[0]) { start_arc_point = curve_it1->pointAt(times[0] + GAP_HELPER); } double k1 = distance(start_arc_point, curve_it1->finalPoint()) * K; - double k2 = distance(end_arc_point, curve_it2_fixed->initialPoint()) * K; + double k2 = distance(end_arc_point, curve_it2_fixed_ref.initialPoint()) * K; Geom::CubicBezier const *cubic_1 = dynamic_cast<Geom::CubicBezier const *>(&*knot_curve_1); Geom::Ray ray_1(start_arc_point, curve_it1->finalPoint()); @@ -571,10 +563,10 @@ LPEFilletChamfer::doEffect_path(Geom::PathVector const &path_in) if (time0 == 1) { handle_1 = start_arc_point; } - Geom::Curve *knot_curve_2 = curve_it2_fixed->portion(times[2], 1); + Geom::Curve *knot_curve_2 = curve_it2_fixed_ref.portion(times[2], 1); Geom::CubicBezier const *cubic_2 = dynamic_cast<Geom::CubicBezier const *>(&*knot_curve_2); - Geom::Ray ray_2(curve_it2_fixed->initialPoint(), end_arc_point); + Geom::Ray ray_2(curve_it2_fixed_ref.initialPoint(), end_arc_point); if (cubic_2) { ray_2.setPoints(end_arc_point, (*cubic_2)[1]); } @@ -597,7 +589,7 @@ LPEFilletChamfer::doEffect_path(Geom::PathVector const &path_in) } Geom::Point inverse_handle_2 = end_arc_point - Geom::Point::polar(handleAngle, k2); if (times[2] == 1) { - end_arc_point = curve_it2_fixed->pointAt(times[2]); + end_arc_point = curve_it2_fixed_ref.pointAt(times[2]); } if (times[1] == times[0]) { start_arc_point = curve_it1->pointAt(times[0]); @@ -625,7 +617,7 @@ LPEFilletChamfer::doEffect_path(Geom::PathVector const &path_in) Geom::Path path_chamfer; path_chamfer.start(tmp_path.finalPoint()); if ((is_straight_curve(*curve_it1) && - is_straight_curve(*curve_it2_fixed) && method != FM_BEZIER) || + is_straight_curve(curve_it2_fixed_ref) && method != FM_BEZIER) || method == FM_ARC) { ccw_toggle = ccw_toggle ? 0 : 1; path_chamfer.appendNew<Geom::EllipticalArc>(rx, ry, arc_angle, 0, @@ -644,7 +636,7 @@ LPEFilletChamfer::doEffect_path(Geom::PathVector const &path_in) Geom::Path path_chamfer; path_chamfer.start(tmp_path.finalPoint()); if ((is_straight_curve(*curve_it1) && - is_straight_curve(*curve_it2_fixed) && method != FM_BEZIER) || + is_straight_curve(curve_it2_fixed_ref) && method != FM_BEZIER) || method == FM_ARC) { path_chamfer.appendNew<Geom::EllipticalArc>(rx, ry, arc_angle, 0, ccw_toggle, end_arc_point); @@ -661,7 +653,7 @@ LPEFilletChamfer::doEffect_path(Geom::PathVector const &path_in) tmp_path.appendNew<Geom::LineSegment>(end_arc_point); } else if (type == INVERSE_FILLET) { if ((is_straight_curve(*curve_it1) && - is_straight_curve(*curve_it2_fixed) && method != FM_BEZIER) || + is_straight_curve(curve_it2_fixed_ref) && method != FM_BEZIER) || method == FM_ARC) { tmp_path.appendNew<Geom::EllipticalArc>(rx, ry, arc_angle, 0, ccw_toggle, end_arc_point); @@ -671,7 +663,7 @@ LPEFilletChamfer::doEffect_path(Geom::PathVector const &path_in) } } else if (type == FILLET) { if ((is_straight_curve(*curve_it1) && - is_straight_curve(*curve_it2_fixed) && method != FM_BEZIER) || + is_straight_curve(curve_it2_fixed_ref) && method != FM_BEZIER) || method == FM_ARC) { ccw_toggle = ccw_toggle ? 0 : 1; tmp_path.appendNew<Geom::EllipticalArc>(rx, ry, arc_angle, 0, ccw_toggle, diff --git a/src/live_effects/parameter/satellitearray.cpp b/src/live_effects/parameter/satellitearray.cpp index 9c22741ff..ba1338daa 100644 --- a/src/live_effects/parameter/satellitearray.cpp +++ b/src/live_effects/parameter/satellitearray.cpp @@ -73,8 +73,9 @@ void SatelliteArrayParam::updateCanvasIndicators(bool mirror) if (!_last_pointwise) { return; } + Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = _last_pointwise->getPwd2(); - Geom::PathVector pointwise_pv = path_from_piecewise(Geom::remove_short_cuts(pwd2,0.01),0.01); + Geom::PathVector pathv = path_from_piecewise(Geom::remove_short_cuts(pwd2,0.01),0.01); if (mirror == true) { _hp.clear(); } @@ -86,21 +87,21 @@ void SatelliteArrayParam::updateCanvasIndicators(bool mirror) continue; } double pos = 0; - if (pwd2.size() <= i) { + if (pathv.size() <= i) { break; } - Geom::D2<Geom::SBasis> d2 = pwd2[i]; + Geom::Curve &curve = const_cast<Geom::Curve &>(pathv.curveAt(i)); bool overflow = false; - double size_out = _vector[i].arcDistance(pwd2[i]); - double lenght_out = Geom::length(pwd2[i], Geom::EPSILON); + double size_out = _vector[i].arcDistance(pathv.curveAt(i)); + double lenght_out = pathv.curveAt(i).length( Geom::EPSILON); double lenght_in = 0; - Geom::Path sat_path = pointwise_pv.pathAt(i); + Geom::Path sat_path = pathv.pathAt(i); boost::optional<size_t> d2_prev_index = boost::none; - size_t sat_curve_time = Geom::nearest_time(pointwise_pv.curveAt(i).initialPoint() , pwd2); + 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) { - sat_curve_time = Geom::nearest_time(sat_path.initialPoint(),pwd2); + //sat_curve_time = Geom::nearest_time(sat_path.initialPoint(),pwd2); d2_prev_index = sat_curve_time + sat_path.size() - 1; } else if(!sat_path.closed() || sat_curve_time != first) { d2_prev_index = sat_curve_time - 1; @@ -110,14 +111,14 @@ void SatelliteArrayParam::updateCanvasIndicators(bool mirror) } if (mirror == true) { if (d2_prev_index) { - d2 = pwd2[*d2_prev_index]; - pos = _vector[i].time(size_out, true, d2); + curve = pathv.curveAt(*d2_prev_index); + pos = _vector[i].time(size_out, true, curve); if (lenght_out < size_out) { overflow = true; } } } else { - pos = _vector[i].time(d2); + pos = _vector[i].time(curve); if (lenght_in < size_out) { overflow = true; } @@ -125,8 +126,8 @@ void SatelliteArrayParam::updateCanvasIndicators(bool mirror) if (pos <= 0 || pos >= 1) { continue; } - Geom::Point point_a = d2.valueAt(pos); - Geom::Point deriv_a = unit_vector(derivative(d2).valueAt(pos)); + Geom::Point point_a = curve.pointAt(pos); + Geom::Point deriv_a = unit_vector(derivative(curve.toSBasis()).valueAt(pos)); Geom::Rotate rot(Geom::Rotate::from_degrees(-90)); deriv_a = deriv_a * rot; Geom::Point point_c = point_a - deriv_a * _helper_size; @@ -141,7 +142,7 @@ void SatelliteArrayParam::updateCanvasIndicators(bool mirror) } else { aff *= Geom::Rotate(ray_1.angle() - Geom::deg_to_rad(270)); } - aff *= Geom::Translate(d2.valueAt(pos)); + aff *= Geom::Translate(curve.pointAt(pos)); pathv *= aff; _hp.push_back(pathv[0]); _hp.push_back(pathv[1]); @@ -171,7 +172,7 @@ void SatelliteArrayParam::updateCanvasIndicators(bool mirror) } else { aff *= Geom::Rotate(ray_1.angle() - Geom::deg_to_rad(270)); } - aff *= Geom::Translate(d2.valueAt(pos)); + aff *= Geom::Translate(curve.pointAt(pos)); pathv *= aff; _hp.push_back(pathv[0]); } @@ -292,36 +293,16 @@ void FilletChamferKnotHolderEntity::knot_set(Geom::Point const &p, } Pointwise *pointwise = _pparam->_last_pointwise; Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = pointwise->getPwd2(); - Geom::PathVector pointwise_pv = path_from_piecewise(Geom::remove_short_cuts(pwd2,0.01),0.01); + Geom::PathVector pathv = path_from_piecewise(Geom::remove_short_cuts(pwd2,0.01),0.01); if (_index >= _pparam->_vector.size() ) { - Geom::Path sat_path = pointwise_pv.pathAt(index); - boost::optional<size_t> d2_prev_index = boost::none; - size_t sat_curve_time = Geom::nearest_time(pointwise_pv.curveAt(index).initialPoint(),pwd2); - size_t first = Geom::nearest_time(sat_path.initialPoint() , pwd2); - if (sat_path.closed() && sat_curve_time == first) { - sat_curve_time = Geom::nearest_time(sat_path.initialPoint(),pwd2); - d2_prev_index = sat_curve_time + sat_path.size() - 1; - } else if(!sat_path.closed() || sat_curve_time != first) { - d2_prev_index = sat_curve_time - 1; - } - if (d2_prev_index) { - Geom::D2<Geom::SBasis> d2_in = pwd2[*d2_prev_index]; - double mirror_time = Geom::nearest_time(s, d2_in); - double time_start = 0; - std::vector<Satellite> sats = pointwise->getSatellites(); - time_start = sats[*d2_prev_index].time(d2_in); - if (time_start > mirror_time) { - mirror_time = time_start; - } - double size = arcLengthAt(mirror_time, d2_in); - double amount = Geom::length(d2_in, Geom::EPSILON) - size; - if (satellite.is_time) { - amount = timeAtArcLength(amount, pwd2[index]); - } - satellite.amount = amount; + Geom::Path sat_path = pathv.pathAt(index); + if (sat_path.closed() && sat_path.front() == pathv.curveAt(index)) { + satellite.setPosition(s, sat_path.back(), true); + } else { + satellite.setPosition(s, pathv.curveAt(index-1), true); } } else { - satellite.setPosition(s, pwd2[index]); + satellite.setPosition(s, pathv.curveAt(index)); } _pparam->_vector.at(index) = satellite; SPLPEItem *splpeitem = dynamic_cast<SPLPEItem *>(item); @@ -349,41 +330,20 @@ Geom::Point FilletChamferKnotHolderEntity::knot_get() const } Pointwise *pointwise = _pparam->_last_pointwise; Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = pointwise->getPwd2(); - Geom::PathVector pointwise_pv = path_from_piecewise(Geom::remove_short_cuts(pwd2,0.01),0.01); + 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(pwd2[index]); - Geom::Path sat_path = pointwise_pv.pathAt(index); - boost::optional<size_t> d2_prev_index = boost::none; - size_t sat_curve_time = Geom::nearest_time(pointwise_pv.curveAt(index).initialPoint(),pwd2); - size_t first = Geom::nearest_time(sat_path.initialPoint() , pwd2); - if (sat_path.closed() && sat_curve_time == first) { - d2_prev_index = first + sat_path.size() - 1; - } else if(!sat_path.closed() || sat_curve_time != first) { - d2_prev_index = sat_curve_time - 1; - } - if (d2_prev_index) { - Geom::D2<Geom::SBasis> d2_in = pwd2[*d2_prev_index]; - double s = satellite.arcDistance(pwd2[index]); - double t = satellite.time(s, true, d2_in); - if (t > 1) { - t = 1; - } - if (t < 0) { - t = 0; - } - double time_start = 0; - time_start = pointwise->getSatellites()[*d2_prev_index].time(d2_in); - if (time_start > t) { - t = time_start; - } - tmp_point = (d2_in).valueAt(t); + Geom::Path sat_path = pathv.pathAt(index); + if (sat_path.closed() && sat_path.front() == pathv.curveAt(index)) { + tmp_point = satellite.getPosition(sat_path.back(), true); + } else { + tmp_point = satellite.getPosition(pathv.curveAt(index - 1), true); } } else { - tmp_point = satellite.getPosition(pwd2[index]); + tmp_point = satellite.getPosition(pathv.curveAt(index)); } Geom::Point const canvas_point = tmp_point; return canvas_point; @@ -447,11 +407,11 @@ void FilletChamferKnotHolderEntity::knot_click(guint state) } } else if (state & GDK_SHIFT_MASK) { Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = _pparam->_last_pointwise->getPwd2(); - Geom::PathVector pointwise_pv = path_from_piecewise(Geom::remove_short_cuts(pwd2,0.01),0.01); + 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 = pointwise_pv.pathAt(index); + Geom::Path sat_path = pathv.pathAt(index); boost::optional<size_t> d2_prev_index = boost::none; - size_t sat_curve_time = Geom::nearest_time(pointwise_pv.curveAt(index).initialPoint(),pwd2); + 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) { sat_curve_time = Geom::nearest_time(sat_path.initialPoint(),pwd2); @@ -462,18 +422,17 @@ void FilletChamferKnotHolderEntity::knot_click(guint state) if (!_pparam->_use_distance && !_pparam->_vector.at(index).is_time) { if (d2_prev_index) { - amount = _pparam->_vector.at(index).lenToRad(amount, pwd2[*d2_prev_index], pwd2[index],_pparam->_vector.at(*d2_prev_index)); + amount = _pparam->_vector.at(index).lenToRad(amount, pathv.curveAt(*d2_prev_index), pathv.curveAt(index),_pparam->_vector.at(*d2_prev_index)); } else { amount = 0.0; } } bool aprox = false; - Geom::D2<Geom::SBasis> d2_out = _pparam->_last_pointwise->getPwd2()[index]; + Geom::Curve const &curve_out = pathv.curveAt(index); if (d2_prev_index) { - Geom::D2<Geom::SBasis> d2_in = - _pparam->_last_pointwise->getPwd2()[*d2_prev_index]; - aprox = ((d2_in)[0].degreesOfFreedom() != 2 || - d2_out[0].degreesOfFreedom() != 2) && + Geom::Curve const &curve_in = pathv.curveAt(*d2_prev_index); + aprox = (curve_in.degreesOfFreedom() != 2 || + curve_out.degreesOfFreedom() != 2) && !_pparam->_use_distance ? true : false; @@ -498,19 +457,19 @@ void FilletChamferKnotHolderEntity::knot_set_offset(Satellite satellite) double max_amount = amount; if (!_pparam->_use_distance && !satellite.is_time) { Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = _pparam->_last_pointwise->getPwd2(); - Geom::PathVector pointwise_pv = path_from_piecewise(Geom::remove_short_cuts(pwd2,0.01),0.01); - Geom::Path sat_path = pointwise_pv.pathAt(index); + 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(pointwise_pv.curveAt(index).initialPoint(),pwd2); + 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) { - sat_curve_time = Geom::nearest_time(sat_path.initialPoint(),pwd2); + //sat_curve_time = Geom::nearest_time(sat_path.initialPoint(),pwd2); 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, pwd2[*prev], pwd2[index]); + amount = _pparam->_vector.at(index).radToLen(amount, pathv.curveAt(*prev), pathv.curveAt(index)); } else { amount = 0.0; } |
