From 83e726c8fb391f0cbbccc9b286bfecefc730dbc7 Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Mon, 23 Feb 2015 23:16:39 +0100 Subject: Added flexible/fixed to fillet chamfer and fix bugs (bzr r13645.1.20) --- src/2geom/pointwise.cpp | 5 ++ src/2geom/pointwise.h | 3 + src/2geom/satellite.cpp | 89 +++++++++++++++++++++++++--- src/2geom/satellite.h | 6 +- src/live_effects/lpe-fillet-chamfer.cpp | 100 ++++++++++++++++++++++---------- src/live_effects/lpe-fillet-chamfer.h | 3 + src/live_effects/parameter/array.h | 10 ++-- 7 files changed, 166 insertions(+), 50 deletions(-) (limited to 'src') diff --git a/src/2geom/pointwise.cpp b/src/2geom/pointwise.cpp index d7d5afc63..aa1620e8a 100644 --- a/src/2geom/pointwise.cpp +++ b/src/2geom/pointwise.cpp @@ -40,6 +40,11 @@ Pointwise::Pointwise(Piecewise > pwd2, std::vector > +Pointwise::getSatellites(){ + return _satellites; +} + std::vector Pointwise::findSatellites(int A, int B) const { diff --git a/src/2geom/pointwise.h b/src/2geom/pointwise.h index d48321832..e7646d96c 100644 --- a/src/2geom/pointwise.h +++ b/src/2geom/pointwise.h @@ -63,6 +63,8 @@ class Pointwise Pointwise(Piecewise > pwd2, std::vector > satellites); virtual ~Pointwise(); std::vector findSatellites(int A, int B = -1) const; + std::vector > getSatellites(); + Pointwise recalculate_for_new_pwd2(Piecewise > A); Pointwise pwd2_reverse(int index); Pointwise pwd2_append(int index); @@ -71,6 +73,7 @@ class Pointwise Pointwise pwd2_del(int index); Pointwise satellite_add(int index,Satellite sat); Pointwise satellite_del(int index,Satellite sat); + private: Piecewise > _pwd2; diff --git a/src/2geom/satellite.cpp b/src/2geom/satellite.cpp index b8ddd040b..9a2fa0a10 100644 --- a/src/2geom/satellite.cpp +++ b/src/2geom/satellite.cpp @@ -46,7 +46,14 @@ Satellite::Satellite(SatelliteType satellitetype, bool isTime, bool active, bool Satellite::~Satellite() {}; void -Satellite::setPosition(Geom::Point p, Geom::D2 d2_in){ +Satellite::setPosition(Geom::Point p, Geom::D2 d2_in) +{ + if(!d2_in.isFinite() || d2_in.isZero()){ + _time = 0; + _size = 0; + return; + } + double lenghtPart = Geom::length(d2_in, Geom::EPSILON); _time = Geom::nearest_point(p, d2_in); if (d2_in[0].degreesOfFreedom() != 2) { Geom::Piecewise > u; @@ -55,23 +62,24 @@ Satellite::setPosition(Geom::Point p, Geom::D2 d2_in){ u = Geom::portion(u, 0.0, _time); _size = Geom::length(u, 0.001); } else { - double lenghtPart = Geom::length(d2_in, Geom::EPSILON); _size = (_time * lenghtPart); } + if(_time > 0.998){ + _time = 1; + } } -Geom::Point -Satellite::getPosition(Geom::D2 d2_in){ - return d2_in.valueAt(_time); -} - double -Satellite::getOpositeTime(Geom::D2 d2_in){ +Satellite::getOpositeTime(Geom::D2 d2_in) +{ + if(!d2_in.isFinite() || d2_in.isZero()){ + return 1; + } double t = 0; + double lenghtPart = Geom::length(d2_in, Geom::EPSILON); if(_size == 0){ return 1; } - double lenghtPart = Geom::length(d2_in, Geom::EPSILON); double size = lenghtPart - _size; if (d2_in[0].degreesOfFreedom() != 2) { Geom::Piecewise > u; @@ -86,9 +94,72 @@ Satellite::getOpositeTime(Geom::D2 d2_in){ t = size / lenghtPart; } } + if(_time > 0.999){ + _time = 1; + } return t; } +void +Satellite::updateSizeTime(Geom::D2 d2_in) +{ + if(!d2_in.isFinite() || d2_in.isZero()){ + _time = 0; + _size = 0; + return; + } + double lenghtPart = Geom::length(d2_in, Geom::EPSILON); + if(!_isTime){ + if (_size != 0) { + if(lenghtPart <= _size){ + _time = 1; + _size = lenghtPart; + } else if (d2_in[0].degreesOfFreedom() != 2) { + Piecewise > u; + u.push_cut(0); + u.push(d2_in, 1); + std::vector t_roots = roots(arcLengthSb(u) - _size); + if (t_roots.size() > 0) { + _time = t_roots[0]; + } + } else { + if (_size < lenghtPart && lenghtPart != 0) { + _time = _size / lenghtPart; + } + } + } else { + _time = 0; + } + } else { + if (_time != 0) { + if (d2_in[0].degreesOfFreedom() != 2) { + Piecewise > u; + u.push_cut(0); + u.push(d2_in, 1); + u = portion(u, 0, _time); + _size = length(u, 0.001); + } else { + lenghtPart = length(d2_in, EPSILON); + _size = _time * lenghtPart; + } + } else { + _size = 0; + } + } + if(_time > 0.999){ + _time = 1; + } +} + +Geom::Point +Satellite::getPosition(Geom::D2 d2_in){ + if(!d2_in.isFinite() || d2_in.isZero()){ + return Geom::Point(9999999999.0,9999999999.0); + } + updateSizeTime(d2_in); + return d2_in.valueAt(_time); +} + } // end namespace Geom /* diff --git a/src/2geom/satellite.h b/src/2geom/satellite.h index 7b524f912..105297f48 100644 --- a/src/2geom/satellite.h +++ b/src/2geom/satellite.h @@ -131,11 +131,7 @@ class Satellite return _time; } - double getTime(Geom::D2 curve) const - { - //todo make the process - return _time; - } + void updateSizeTime(Geom::D2 d2_in); void setPosition(Geom::Point p, Geom::D2 curve); diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 0ef8b5a0e..73c504deb 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -45,10 +45,13 @@ FMConverter(FilletMethodData, FM_END); LPEFilletChamfer::LPEFilletChamfer(LivePathEffectObject *lpeobject) : Effect(lpeobject), satellitepairarrayparam_values(_("Fillet point"), _("Fillet point"), "satellitepairarrayparam_values", &wr, this), - method(_("Method:"), _("Fillets methods"), "method", FMConverter, &wr, this, FM_AUTO) + method(_("Method:"), _("Fillets methods"), "method", FMConverter, &wr, this, FM_AUTO), + flexible(_("Flexible radius size (%)"), _("Flexible radius size (%)"), "flexible", &wr, this, false), + pointwise() { registerParameter(&satellitepairarrayparam_values); registerParameter(&method); + registerParameter(&flexible); } LPEFilletChamfer::~LPEFilletChamfer() {} @@ -60,11 +63,11 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) SPShape * shape = dynamic_cast(splpeitem); if (shape) { PathVector const &original_pathv = pathv_to_linear_and_cubic_beziers(shape->getCurve()->get_pathvector()); - std::vector > satellites; Piecewise > pwd2_in = paths_to_pw(original_pathv); pwd2_in = remove_short_cuts(pwd2_in, .01); satellitepairarrayparam_values.set_pwd2(pwd2_in); int counterTotal = 0; + std::vector > satellites; for (PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { if (path_it->empty()){ continue; @@ -87,7 +90,7 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) --curve_end; int counter = 0; while (curve_it1 != curve_endit) { - Satellite satellite(F, true, true, false, false, 0.0, 0.0); + Satellite satellite(F, flexible, true, false, false, 0.0, 0.0); Geom::NodeType nodetype; if (counter==0) { if (path_it->closed()) { @@ -114,7 +117,6 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) } } - void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) { SPLPEItem * splpeitem = const_cast(lpeItem); @@ -126,9 +128,23 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) c = path->get_original_curve(); } PathVector const &original_pathv = pathv_to_linear_and_cubic_beziers(c->get_pathvector()); - Piecewise > pwd2_in = paths_to_pw(original_pathv); + Piecewise > pwd2_in = paths_to_pw(pathv_to_linear_and_cubic_beziers(original_pathv)); pwd2_in = remove_short_cuts(pwd2_in, .01); + //wating to recalculate + //recalculate_controlpoints_for_new_pwd2(pwd2_in); satellitepairarrayparam_values.set_pwd2(pwd2_in); + std::vector > satellites = satellitepairarrayparam_values.data(); + pointwise = new Pointwise( pwd2_in,satellites); + bool changed = false; + for (std::vector >::iterator it = satellites.begin(); it != satellites.end(); ++it) { + if(it->second.getIsTime() != flexible){ + it->second.setIsTime(flexible); + changed = true; + } + } + if(changed){ + satellitepairarrayparam_values.param_set_and_write_new_value(satellites); + } } else { g_warning("LPE Fillet can only be applied to shapes (not groups)."); } @@ -140,18 +156,14 @@ LPEFilletChamfer::doEffect_path(std::vector const &path_in) { const double gapHelper = 0.00001; std::vector pathvector_out; - Piecewise > pwd2_in = paths_to_pw(pathv_to_linear_and_cubic_beziers(path_in)); - pwd2_in = remove_short_cuts(pwd2_in, .01); - satellitepairarrayparam_values.set_pwd2(pwd2_in); - std::vector > filletChamferData = satellitepairarrayparam_values.data(); - Pointwise *pointwise = new Pointwise( pwd2_in, filletChamferData); unsigned int counter = 0; const double K = (4.0 / 3.0) * (sqrt(2.0) - 1.0); std::vector path_in_processed = pathv_to_linear_and_cubic_beziers(path_in); for (PathVector::const_iterator path_it = path_in_processed.begin(); path_it != path_in_processed.end(); ++path_it) { - if (path_it->empty()) + if (path_it->empty()){ continue; + } Geom::Path path_out; Geom::Path::const_iterator curve_it1 = path_it->begin(); Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); @@ -172,9 +184,13 @@ LPEFilletChamfer::doEffect_path(std::vector const &path_in) unsigned int first = counter; double time0 = 0; while (curve_it1 != curve_endit) { + if((*curve_it1).isDegenerate() || (*curve_it1).isDegenerate()){ + g_warning("LPE Fillet not handle degenerate curves."); + return path_in; + } std::vector satVector; - Satellite sat(F, true, true, false, false, 0.0, 0.0); - Curve *curve_it2Fixed = (*path_it->begin()).duplicate(); + Satellite sat; + Curve *curve_it2Fixed = path_it->begin()->duplicate(); if(!path_it->closed() || curve_it2 != curve_endit){ curve_it2Fixed = (*curve_it2).duplicate(); satVector = pointwise->findSatellites(counter+1,1); @@ -193,33 +209,38 @@ LPEFilletChamfer::doEffect_path(std::vector const &path_in) time0 = satVector[0].getTime(); } } + bool last = curve_it2 == curve_endit; double time1 = sat.getOpositeTime((*curve_it1).toSBasis()); double time2 = sat.getTime(); if(time1 <= time0){ - time1 = time0 + gapHelper; - } - if(time0 == 1){ - time0 = time0 - gapHelper; - } - if(time2 == 1){ - time2 = time2 - gapHelper; + time1 = time0; } std::vector times; times.push_back(time0); times.push_back(time1); times.push_back(time2); + std::cout << ":::" << counter << ":::::::::::::::\n"; + std::cout << time0 << "::Time 0\n"; + std::cout << time1 << "::Time 1\n"; + std::cout << time2 << "::Time 2\n"; Curve *knotCurve1 = curve_it1->portion(times[0], times[1]); if (counterCurves > 0) { knotCurve1->setInitial(path_out.finalPoint()); } else { path_out.start((*curve_it1).pointAt(times[0])); } - Curve *knotCurve2 = curve_it2Fixed->portion(times[2], 1); + Point startArcPoint = knotCurve1->finalPoint(); Point endArcPoint = curve_it2Fixed->pointAt(times[2]); + if(times[2] == 1){ + endArcPoint = curve_it2Fixed->pointAt(times[2]-gapHelper); + } + if(times[1] == times[0]){ + startArcPoint = knotCurve1->pointAt(1-gapHelper); + } double k1 = distance(startArcPoint, curve_it1->finalPoint()) * K; - double k2 = distance(endArcPoint, curve_it1->finalPoint()) * K; + double k2 = distance(endArcPoint, curve_it2Fixed->initialPoint()) * K; Geom::CubicBezier const *cubic1 = dynamic_cast(&*knotCurve1); Ray ray1(startArcPoint, curve_it1->finalPoint()); if (cubic1) { @@ -229,13 +250,14 @@ LPEFilletChamfer::doEffect_path(std::vector const &path_in) if(time0 == 1){ handle1 = startArcPoint; } - Geom::CubicBezier const *cubic2 = - dynamic_cast(&*knotCurve2); - Ray ray2(curve_it1->finalPoint(), endArcPoint); + Curve *knotCurve2 = curve_it2Fixed->portion(times[2], 1); + Geom::CubicBezier const *cubic2 = dynamic_cast(&*knotCurve2); + Ray ray2(curve_it2Fixed->initialPoint(), endArcPoint); if (cubic2) { ray2.setPoints(endArcPoint, (*cubic2)[1]); } Point handle2 = endArcPoint - Point::polar(ray2.angle(),k2); + bool ccwToggle = cross(curve_it1->finalPoint() - startArcPoint, endArcPoint - startArcPoint) < 0; double angle = angle_between(ray1, ray2, ccwToggle); double handleAngle = ray1.angle() - angle; @@ -251,21 +273,28 @@ LPEFilletChamfer::doEffect_path(std::vector const &path_in) handleAngle = ray2.angle() - angle; } Point inverseHandle2 = endArcPoint - Point::polar(handleAngle,k2); + if(times[2] == 1){ + endArcPoint = curve_it2Fixed->pointAt(times[2]); + } + if(times[1] == times[0]){ + startArcPoint = knotCurve1->pointAt(1); + } Line const x_line(Geom::Point(0,0),Geom::Point(1,0)); Line const angled_line(startArcPoint,endArcPoint); double angleArc = Geom::angle_between( x_line,angled_line); double radius = Geom::distance(startArcPoint,middle_point(startArcPoint,endArcPoint))/sin(angle/2.0); Coord rx = radius; Coord ry = rx; - - if (times[1] != 1 || (times[1] == 1 && times[0] == times[1] - gapHelper )) { - if (times[1] != times[0] + gapHelper) { - path_out.append(*knotCurve1); + if (times[1] != 1) { + if (times[1] != times[0] || times[1] == times[0] == 1) { + if(!knotCurve1->isDegenerate()){ + path_out.append(*knotCurve1); + } } SatelliteType type = F; type = sat.getSatelliteType(); if(are_near(middle_point(startArcPoint,endArcPoint),curve_it1->finalPoint(), 0.0001)){ - //path_out.appendNew(endArcPoint); + // path_out.appendNew(endArcPoint); } else if (type == C) { /* unsigned int chamferSubs = type-3000; @@ -316,11 +345,20 @@ LPEFilletChamfer::doEffect_path(std::vector const &path_in) } } } else { - path_out.append(*knotCurve1); + if(!knotCurve1->isDegenerate()){ + path_out.append(*knotCurve1); + } } if (path_it->closed() && last) { path_out.close(); } + /* + if(!path_it->closed() || curve_it2 != curve_endit){ + satellites[counter + 1] = std::make_pair(counter + 1, sat); + } else { + satellites[first] = std::make_pair(first, sat); + } + */ ++curve_it1; if (curve_it2 != curve_endit) { ++curve_it2; diff --git a/src/live_effects/lpe-fillet-chamfer.h b/src/live_effects/lpe-fillet-chamfer.h index 2c0dfcaab..f5c4f14ea 100644 --- a/src/live_effects/lpe-fillet-chamfer.h +++ b/src/live_effects/lpe-fillet-chamfer.h @@ -42,6 +42,9 @@ public: private: EnumParam method; + BoolParam flexible; + Geom::Pointwise *pointwise; + LPEFilletChamfer(const LPEFilletChamfer &); LPEFilletChamfer &operator=(const LPEFilletChamfer &); diff --git a/src/live_effects/parameter/array.h b/src/live_effects/parameter/array.h index 8145d62a3..e9775da24 100644 --- a/src/live_effects/parameter/array.h +++ b/src/live_effects/parameter/array.h @@ -115,15 +115,15 @@ protected: void writesvgData(SVGOStringStream &str, std::pair const &nVector) const { str << nVector.first; str << ","; - str << nVector.second.getSatelliteTypeGchar(); + str << nVector.second.getSatelliteTypeGchar(); str << "*"; - str << nVector.second.getIsTime(); + str << g_strdup(nVector.second.getIsTime() ? "true" : "false"); str << "*"; - str << nVector.second.getActive(); + str << g_strdup(nVector.second.getActive() ? "true" : "false"); str << "*"; - str << nVector.second.getHasMirror(); + str << g_strdup(nVector.second.getHasMirror() ? "true" : "false"); str << "*"; - str << nVector.second.getHidden(); + str << g_strdup(nVector.second.getHidden() ? "true" : "false"); str << "*"; str << nVector.second.getSize(); str << "*"; -- cgit v1.2.3