diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2015-03-01 00:18:02 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2015-03-01 00:18:02 +0000 |
| commit | 00d08a0f4bca11e775bbacf3d512676a0493c1a3 (patch) | |
| tree | f69813c299df49dcf00ae5467aa277a1d13df41a /src | |
| parent | improving code (diff) | |
| download | inkscape-00d08a0f4bca11e775bbacf3d512676a0493c1a3.tar.gz inkscape-00d08a0f4bca11e775bbacf3d512676a0493c1a3.zip | |
adding mirror knot
(bzr r13645.1.25)
Diffstat (limited to 'src')
| -rw-r--r-- | src/2geom/pointwise.cpp | 61 | ||||
| -rw-r--r-- | src/2geom/pointwise.h | 9 | ||||
| -rw-r--r-- | src/2geom/satellite.cpp | 42 | ||||
| -rw-r--r-- | src/2geom/satellite.h | 28 | ||||
| -rw-r--r-- | src/live_effects/lpe-fillet-chamfer.cpp | 25 | ||||
| -rw-r--r-- | src/live_effects/parameter/array.cpp | 10 | ||||
| -rw-r--r-- | src/live_effects/parameter/array.h | 4 | ||||
| -rw-r--r-- | src/live_effects/parameter/satellitepairarray.cpp | 62 | ||||
| -rw-r--r-- | src/live_effects/parameter/satellitepairarray.h | 11 |
9 files changed, 195 insertions, 57 deletions
diff --git a/src/2geom/pointwise.cpp b/src/2geom/pointwise.cpp index aa1620e8a..bc468343c 100644 --- a/src/2geom/pointwise.cpp +++ b/src/2geom/pointwise.cpp @@ -45,6 +45,67 @@ Pointwise::getSatellites(){ return _satellites; } +void +Pointwise::setSatellites(std::vector<std::pair<int,Satellite> > sat){ + _satellites = sat; +} + +Piecewise<D2<SBasis> > +Pointwise::getPwd2(){ + return _pwd2; +} + +void +Pointwise::setPwd2(Piecewise<D2<SBasis> > pwd2_in){ + _pwd2 = pwd2_in; +} + +boost::optional<Geom::D2<Geom::SBasis> > +Pointwise::getCurveIn(std::pair<int,Satellite> sat){ + //curve out = sat.first; + std::vector<Geom::Path> path_in_processed = pathv_to_linear_and_cubic_beziers(path_from_piecewise(_pwd2, 0.001)); + int counterTotal = 0; + for (PathVector::const_iterator path_it = path_in_processed.begin(); path_it != path_in_processed.end(); ++path_it) { + if (path_it->empty()){ + continue; + } + Geom::Path::const_iterator curve_it1 = path_it->begin(); + Geom::Path::const_iterator curve_endit = path_it->end_default(); + if (path_it->closed()) { + const Curve &closingline = path_it->back_closed(); + // the closing line segment is always of type + // LineSegment. + if (are_near(closingline.initialPoint(), closingline.finalPoint())) { + // closingline.isDegenerate() did not work, because it only checks for + // *exact* zero length, which goes wrong for relative coordinates and + // rounding errors... + // the closing line segment has zero-length. So stop before that one! + curve_endit = path_it->end_open(); + } + } + Geom::Path::const_iterator curve_end = curve_endit; + --curve_end; + int counter = 0; + while (curve_it1 != curve_endit) { + if(counterTotal == sat.first){ + if (counter==0) { + if (path_it->closed()) { + return (*curve_end).toSBasis(); + } else { + return boost::none; + } + } else { + return (*path_it)[counter - 1].toSBasis(); + } + } + ++curve_it1; + counter++; + counterTotal++; + } + } + return boost::none; +} + std::vector<Satellite> Pointwise::findSatellites(int A, int B) const { diff --git a/src/2geom/pointwise.h b/src/2geom/pointwise.h index e7646d96c..5937264ad 100644 --- a/src/2geom/pointwise.h +++ b/src/2geom/pointwise.h @@ -50,6 +50,10 @@ #include <2geom/sbasis-2d.h> #include <2geom/piecewise.h> #include <2geom/satellite.h> +#include <2geom/sbasis-to-bezier.h> +#include <2geom/path.h> +#include "helper/geom.h" +#include <boost/optional.hpp> namespace Geom { /** @@ -64,7 +68,10 @@ class Pointwise virtual ~Pointwise(); std::vector<Satellite> findSatellites(int A, int B = -1) const; std::vector<std::pair<int,Satellite> > getSatellites(); - + void setSatellites(std::vector<std::pair<int,Satellite> > sat); + Piecewise<D2<SBasis> > getPwd2(); + void setPwd2(Piecewise<D2<SBasis> > pwd2_in); + boost::optional<Geom::D2<Geom::SBasis> > getCurveIn(std::pair<int,Satellite> sat); Pointwise recalculate_for_new_pwd2(Piecewise<D2<SBasis> > A); Pointwise pwd2_reverse(int index); Pointwise pwd2_append(int index); diff --git a/src/2geom/satellite.cpp b/src/2geom/satellite.cpp index 5b362d87f..21361147c 100644 --- a/src/2geom/satellite.cpp +++ b/src/2geom/satellite.cpp @@ -40,17 +40,16 @@ namespace Geom { Satellite::Satellite(){}; -Satellite::Satellite(SatelliteType satellitetype, bool isTime, bool active, bool hasMirror, bool hidden, double size, double time) - : _satellitetype(satellitetype), _isTime(isTime), _active(active), _hasMirror(hasMirror), _hidden(hidden), _size(size), _time(time){}; +Satellite::Satellite(SatelliteType satellitetype, bool isTime, bool active, bool hasMirror, bool hidden, double ammount, double angle) + : _satellitetype(satellitetype), _isTime(isTime), _active(active), _hasMirror(hasMirror), _hidden(hidden), _ammount(ammount), _angle(angle){}; Satellite::~Satellite() {}; double Satellite::toTime(double A,Geom::D2<Geom::SBasis> d2_in) { - if(!d2_in.isFinite() || d2_in.isZero()){ - _time = 0; - _size = 0; + if(!d2_in.isFinite() || d2_in.isZero() || A == 0){ + _ammount = 0; return 0; } double t = 0; @@ -80,9 +79,8 @@ Satellite::toTime(double A,Geom::D2<Geom::SBasis> d2_in) double Satellite::toSize(double A,Geom::D2<Geom::SBasis> d2_in) { - if(!d2_in.isFinite() || d2_in.isZero()){ - _time = 0; - _size = 0; + if(!d2_in.isFinite() || d2_in.isZero() || A == 0){ + _ammount = 0; return 0; } double s = 0; @@ -102,7 +100,10 @@ Satellite::toSize(double A,Geom::D2<Geom::SBasis> d2_in) double Satellite::getOpositeTime(Geom::D2<Geom::SBasis> d2_in) { - double s = getSize(); + double s = getAmmount(); + if(getIsTime()){ + s = toSize(s, d2_in); + } if(s == 0){ return 1; } @@ -111,20 +112,29 @@ Satellite::getOpositeTime(Geom::D2<Geom::SBasis> d2_in) return toTime(size, d2_in); } +double +Satellite::getTime(Geom::D2<Geom::SBasis> d2_in){ + double t = getAmmount(); + if(!getIsTime()){ + t = toTime(t, d2_in); + } + return t; +} + + Geom::Point Satellite::getPosition(Geom::D2<Geom::SBasis> d2_in){ - double t = getTime(); - if(!_isTime){ - t = toTime(getSize(), d2_in); - } - return d2_in.valueAt(t); + return d2_in.valueAt(getTime(d2_in)); } void Satellite::setPosition(Geom::Point p, Geom::D2<Geom::SBasis> d2_in) { - setTime(Geom::nearest_point(p, d2_in)); - setSize(toSize(getTime(),d2_in)); + double A = Geom::nearest_point(p, d2_in); + if(!getIsTime()){ + A = toSize(A, d2_in); + } + setAmmount(A); } } // end namespace Geom diff --git a/src/2geom/satellite.h b/src/2geom/satellite.h index dd8e4d9d0..c66770bb6 100644 --- a/src/2geom/satellite.h +++ b/src/2geom/satellite.h @@ -45,7 +45,7 @@ class Satellite public: Satellite(); - Satellite(SatelliteType satellitetype, bool isTime, bool active, bool hasMirror, bool hidden, double size, double time); + Satellite(SatelliteType satellitetype, bool isTime, bool active, bool hasMirror, bool hidden, double ammount, double angle); virtual ~Satellite(); @@ -79,14 +79,14 @@ class Satellite { _hidden = A; } - void setTime(double A) + void setAmmount(double A) { - _time = A; + _ammount = A; } - void setSize(double A) + void setAngle(double A) { - _size = A; + _angle = A; } SatelliteType getSatelliteType() const @@ -120,23 +120,23 @@ class Satellite return _hidden; } - double getSize() const + double getAmmount() const { - return _size; + return _ammount; } - double getTime() const + double getAngle() const { - return _time; + return _angle; } - void setPosition(Geom::Point p, Geom::D2<Geom::SBasis> curve); - + void setPosition(Geom::Point p, Geom::D2<Geom::SBasis> d2_in); Geom::Point getPosition(Geom::D2<Geom::SBasis> curve); - + double getTime(Geom::D2<Geom::SBasis> d2_in); double getOpositeTime(Geom::D2<Geom::SBasis> SBasisCurve); double toSize(double A,Geom::D2<Geom::SBasis> d2_in); double toTime(double A,Geom::D2<Geom::SBasis> d2_in); + private: SatelliteType _satellitetype; @@ -144,8 +144,8 @@ class Satellite bool _active; bool _hasMirror; bool _hidden; - double _size; - double _time; + double _ammount; + double _angle; }; } // end namespace Geom diff --git a/src/live_effects/lpe-fillet-chamfer.cpp b/src/live_effects/lpe-fillet-chamfer.cpp index 39acdca80..41c6a7090 100644 --- a/src/live_effects/lpe-fillet-chamfer.cpp +++ b/src/live_effects/lpe-fillet-chamfer.cpp @@ -65,8 +65,7 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) if (shape) { PathVector const &original_pathv = pathv_to_linear_and_cubic_beziers(shape->getCurve()->get_pathvector()); Piecewise<D2<SBasis> > pwd2_in = paths_to_pw(original_pathv); - pwd2_in = remove_short_cuts(pwd2_in, .01); - satellitepairarrayparam_values.set_pwd2(pwd2_in); + pwd2_in = remove_short_cuts(pwd2_in, 0.01); int counterTotal = 0; std::vector<std::pair<int,Geom::Satellite> > satellites; for (PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { @@ -110,6 +109,7 @@ void LPEFilletChamfer::doOnApply(SPLPEItem const *lpeItem) counterTotal++; } } + pointwise = new Pointwise( pwd2_in,satellites); satellitepairarrayparam_values.param_set_and_write_new_value(satellites); } else { g_warning("LPE Fillet/Chamfer can only be applied to shapes (not groups)."); @@ -130,20 +130,31 @@ void LPEFilletChamfer::doBeforeEffect(SPLPEItem const *lpeItem) } PathVector const &original_pathv = pathv_to_linear_and_cubic_beziers(c->get_pathvector()); Piecewise<D2<SBasis> > pwd2_in = paths_to_pw(pathv_to_linear_and_cubic_beziers(original_pathv)); - pwd2_in = remove_short_cuts(pwd2_in, .01); + pwd2_in = remove_short_cuts(pwd2_in, 0.01); //wating to recalculate //recalculate_controlpoints_for_new_pwd2(pwd2_in); - satellitepairarrayparam_values.set_pwd2(pwd2_in); std::vector<std::pair<int,Geom::Satellite> > satellites = satellitepairarrayparam_values.data(); - pointwise = new Pointwise( pwd2_in,satellites); + pointwise->setPwd2(pwd2_in); + pointwise->setSatellites(satellites); + satellitepairarrayparam_values.set_pointwise(pointwise); bool changed = false; for (std::vector<std::pair<int,Geom::Satellite> >::iterator it = satellites.begin(); it != satellites.end(); ++it) { if(it->second.getIsTime() != flexible){ it->second.setIsTime(flexible); + double ammount = it->second.getAmmount(); + D2<SBasis> d2_in = pwd2_in[it->first]; + if(it->second.getIsTime()){ + double time = it->second.toTime(ammount,d2_in); + it->second.setAmmount(time); + } else { + double size = it->second.toSize(ammount,d2_in); + it->second.setAmmount(size); + } changed = true; } } if(changed){ + pointwise->setSatellites(satellites); satellitepairarrayparam_values.param_set_and_write_new_value(satellites); } } else { @@ -207,13 +218,13 @@ LPEFilletChamfer::doEffect_path(std::vector<Geom::Path> const &path_in) if(first == counter){ satVector = pointwise->findSatellites(first,1); if(satVector.size()>0){ - time0 = satVector[0].getTime(); + time0 = satVector[0].getTime(curve_it2Fixed->toSBasis()); } } bool last = curve_it2 == curve_endit; double time1 = sat.getOpositeTime((*curve_it1).toSBasis()); - double time2 = sat.getTime(); + double time2 = sat.getTime(curve_it2Fixed->toSBasis()); if(time1 <= time0){ time1 = time0; } diff --git a/src/live_effects/parameter/array.cpp b/src/live_effects/parameter/array.cpp index 6dad9fcc8..2c3d823a5 100644 --- a/src/live_effects/parameter/array.cpp +++ b/src/live_effects/parameter/array.cpp @@ -60,11 +60,11 @@ sp_svg_satellite_read_d(gchar const *str, Geom::Satellite *sat){ sat->setActive(strncmp(strarray[2],"1",1) == 0); sat->setHasMirror(strncmp(strarray[3],"1",1) == 0); sat->setHidden(strncmp(strarray[4],"1",1) == 0); - double time,size; - sp_svg_number_read_d(strarray[5], &size); - sp_svg_number_read_d(strarray[6], &time); - sat->setSize(size); - sat->setTime(time); + double ammount,angle; + sp_svg_number_read_d(strarray[5], &ammount); + sp_svg_number_read_d(strarray[6], &angle); + sat->setAmmount(ammount); + sat->setAngle(angle); g_strfreev (strarray); return 1; } diff --git a/src/live_effects/parameter/array.h b/src/live_effects/parameter/array.h index ff406d792..1a5823199 100644 --- a/src/live_effects/parameter/array.h +++ b/src/live_effects/parameter/array.h @@ -125,9 +125,9 @@ protected: str << "*"; str << nVector.second.getHidden(); str << "*"; - str << nVector.second.getSize(); + str << nVector.second.getAmmount(); str << "*"; - str <<nVector.second.getTime(); + str << nVector.second.getAngle(); } StorageType readsvg(const gchar * str); diff --git a/src/live_effects/parameter/satellitepairarray.cpp b/src/live_effects/parameter/satellitepairarray.cpp index bb72830d6..e6f0c03f9 100644 --- a/src/live_effects/parameter/satellitepairarray.cpp +++ b/src/live_effects/parameter/satellitepairarray.cpp @@ -44,10 +44,9 @@ void SatellitePairArrayParam::set_oncanvas_looks(SPKnotShapeType shape, knot_color = color; } -void SatellitePairArrayParam::set_pwd2( - Piecewise<D2<SBasis> > const &pwd2_in) +void SatellitePairArrayParam::set_pointwise(Geom::Pointwise *pointwise) { - last_pwd2 = pwd2_in; + last_pointwise = pointwise; } void SatellitePairArrayParam::addKnotHolderEntities(KnotHolder *knotholder, @@ -55,6 +54,7 @@ void SatellitePairArrayParam::addKnotHolderEntities(KnotHolder *knotholder, SPItem *item) { for (unsigned int i = 0; i < _vector.size(); ++i) { + addKnotHolderEntitieMirrored(knotholder, desktop, item, i); const gchar *tip; tip = _("<b>Fillet</b>: <b>Ctrl+Click</b> toggle type, " "<b>Shift+Click</b> open dialog, " @@ -67,6 +67,19 @@ void SatellitePairArrayParam::addKnotHolderEntities(KnotHolder *knotholder, } } +void SatellitePairArrayParam::addKnotHolderEntitieMirrored(KnotHolder *knotholder, + SPDesktop *desktop, + SPItem *item, int i) +{ + const gchar *tip; + tip = _("<b>Mirror</b> ppp"); + SatellitePairArrayParamKnotHolderEntity *e = + new SatellitePairArrayParamKnotHolderEntity(this, i + _vector.size()); + e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _(tip), + knot_shape, knot_mode, knot_color); + knotholder->add(e); +} + SatellitePairArrayParamKnotHolderEntity::SatellitePairArrayParamKnotHolderEntity(SatellitePairArrayParam *p, unsigned int index) : _pparam(p), @@ -80,8 +93,28 @@ void SatellitePairArrayParamKnotHolderEntity::knot_set(Point const &p, Point const &/*origin*/, guint state) { - Geom::Point const s = snap_knot_position(p, state); - _pparam->_vector.at(_index).second.setPosition(s,_pparam->last_pwd2[_pparam->_vector.at(_index).first]); + Geom::Point s = snap_knot_position(p, state); + int index = _index; + if( _index >= _pparam->_vector.size()){ + index = _index-_pparam->_vector.size(); + } + std::pair<int,Geom::Satellite> satellite = _pparam->_vector.at(index); + Geom::Pointwise* pointwise = _pparam->last_pointwise; + Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = pointwise->getPwd2(); + if(_pparam->_vector.size() <= _index){ + boost::optional<Geom::D2<Geom::SBasis> > d2_in = pointwise->getCurveIn(satellite); + if(d2_in){ + double mirrorTime = Geom::nearest_point(s, *d2_in); + double size = satellite.second.toSize(mirrorTime, *d2_in); + double lenght = Geom::length(*d2_in, Geom::EPSILON) - size; + double time = satellite.second.toTime(lenght,pwd2[satellite.first]); + s = pwd2[satellite.first].valueAt(time); + satellite.second.setPosition(s,pwd2[satellite.first]); + } + } else { + satellite.second.setPosition(s,pwd2[satellite.first]); + } + _pparam->_vector.at(index) = satellite; SPLPEItem * splpeitem = dynamic_cast<SPLPEItem *>(item); if(splpeitem){ sp_lpe_item_update_patheffect(splpeitem, false, false); @@ -91,7 +124,24 @@ void SatellitePairArrayParamKnotHolderEntity::knot_set(Point const &p, Geom::Point SatellitePairArrayParamKnotHolderEntity::knot_get() const { - Geom::Point const canvas_point = _pparam->_vector.at(_index).second.getPosition(_pparam->last_pwd2[_pparam->_vector.at(_index).first]); + Geom::Point tmpPoint; + int index = _index; + if( _index >= _pparam->_vector.size()){ + index = _index-_pparam->_vector.size(); + } + std::pair<int,Geom::Satellite> satellite = _pparam->_vector.at(index); + Geom::Pointwise* pointwise = _pparam->last_pointwise; + Geom::Piecewise<Geom::D2<Geom::SBasis> > pwd2 = pointwise->getPwd2(); + if( _index >= _pparam->_vector.size()){ + tmpPoint = satellite.second.getPosition(pwd2[satellite.first]); + boost::optional<Geom::D2<Geom::SBasis> > d2_in = pointwise->getCurveIn(satellite); + if(d2_in){ + tmpPoint = (*d2_in).valueAt(satellite.second.getOpositeTime(*d2_in)); + } + } else { + tmpPoint = satellite.second.getPosition(pwd2[satellite.first]); + } + Geom::Point const canvas_point = tmpPoint; return canvas_point; } diff --git a/src/live_effects/parameter/satellitepairarray.h b/src/live_effects/parameter/satellitepairarray.h index ff1924829..dde844fd1 100644 --- a/src/live_effects/parameter/satellitepairarray.h +++ b/src/live_effects/parameter/satellitepairarray.h @@ -21,6 +21,7 @@ #include <glib.h> #include "live_effects/parameter/array.h" #include "knot-holder-entity.h" +#include <2geom/pointwise.h> namespace Inkscape { @@ -47,10 +48,8 @@ public: return true; } virtual void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); - void set_pwd2(Geom::Piecewise<Geom::D2<Geom::SBasis> > const &pwd2_in); - Geom::Piecewise<Geom::D2<Geom::SBasis> > const &get_pwd2() const { - return last_pwd2; - } + virtual void addKnotHolderEntitieMirrored(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item, int i); + void set_pointwise(Geom::Pointwise *pointwise); friend class SatellitePairArrayParamKnotHolderEntity; private: @@ -60,8 +59,8 @@ private: SPKnotShapeType knot_shape; SPKnotModeType knot_mode; guint32 knot_color; - - Geom::Piecewise<Geom::D2<Geom::SBasis> > last_pwd2; + + Geom::Pointwise *last_pointwise; }; |
