X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=src%2Flive_effects%2Flpe-perp_bisector.cpp;h=7c08bdb08ff07488675e944b58cc277c22f65fbb;hb=e9c4a66f3db12ac811f42b73493c1c88460f0de3;hp=c744f126856d0484293974e721cddb37ec8c799c;hpb=f4db63be4e929f4706410914295deccaceea19cd;p=inkscape.git diff --git a/src/live_effects/lpe-perp_bisector.cpp b/src/live_effects/lpe-perp_bisector.cpp index c744f1268..7c08bdb08 100644 --- a/src/live_effects/lpe-perp_bisector.cpp +++ b/src/live_effects/lpe-perp_bisector.cpp @@ -16,39 +16,185 @@ #include "live_effects/lpe-perp_bisector.h" #include "display/curve.h" #include - +#include "sp-path.h" +#include "line-geometry.h" +#include "sp-lpe-item.h" #include <2geom/path.h> namespace Inkscape { namespace LivePathEffect { +namespace PB { + +class KnotHolderEntityLeftEnd : public KnotHolderEntity +{ +public: + virtual bool isLPEParam() { return true; } + + virtual void knot_set(NR::Point const &p, NR::Point const &origin, guint state); + virtual NR::Point knot_get(); +}; + +class KnotHolderEntityRightEnd : public KnotHolderEntity +{ +public: + virtual bool isLPEParam() { return true; } + + virtual void knot_set(NR::Point const &p, NR::Point const &origin, guint state); + virtual NR::Point knot_get(); +}; + +// TODO: Make this more generic +static LPEPerpBisector * +get_effect(SPItem *item) +{ + Effect *effect = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)); + if (effect->effectType() != PERP_BISECTOR) { + g_print ("Warning: Effect is not of type LPEPerpBisector!\n"); + return NULL; + } + return static_cast(effect); +} + +NR::Point +KnotHolderEntityLeftEnd::knot_get() { + Inkscape::LivePathEffect::LPEPerpBisector *lpe = get_effect(item); + return NR::Point(lpe->C); +} + +NR::Point +KnotHolderEntityRightEnd::knot_get() { + Inkscape::LivePathEffect::LPEPerpBisector *lpe = get_effect(item); + return NR::Point(lpe->D); +} + +void +bisector_end_set(SPItem *item, NR::Point const &p, bool left) { + Inkscape::LivePathEffect::LPEPerpBisector *lpe = + dynamic_cast (sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item))); + + if (!lpe) + return; + + double lambda = Geom::nearest_point(p.to_2geom(), lpe->M, lpe->perp_dir); + if (left) { + lpe->C = lpe->M + lpe->perp_dir * lambda; + lpe->length_left.param_set_value(lambda); + } else { + lpe->D = lpe->M + lpe->perp_dir * lambda; + lpe->length_right.param_set_value(-lambda); + } + + // FIXME: this should not directly ask for updating the item. It should write to SVG, which triggers updating. + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), true, true); +} + +void +KnotHolderEntityLeftEnd::knot_set(NR::Point const &p, NR::Point const &/*origin*/, guint /*state*/) { + bisector_end_set(item, p); +} + +void +KnotHolderEntityRightEnd::knot_set(NR::Point const &p, NR::Point const &/*origin*/, guint /*state*/) { + bisector_end_set(item, p, false); +} + +/** +NR::Point path_start_get(SPItem *item) { + Inkscape::LivePathEffect::LPEPerpBisector *lpe = + dynamic_cast (sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item))); + + if (lpe) + return NR::Point(lpe->A); + else + return NR::Point(0,0); +} + +NR::Point path_end_get(SPItem *item) { + Inkscape::LivePathEffect::LPEPerpBisector *lpe = + dynamic_cast (sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item))); + + if (lpe) + return NR::Point(lpe->B); + else + return NR::Point(0,0); +} + +void +path_set_start_end(SPItem *item, NR::Point const &p, bool start) { + SPCurve* curve = sp_path_get_curve_for_edit (SP_PATH(item)); // TODO: Should we use sp_shape_get_curve()? + Geom::Matrix const i2d (sp_item_i2d_affine (SP_ITEM(item))); + + Geom::Point A, B; + if (start) { + A = p.to_2geom(); + B = (curve->last_point()).to_2geom(); + } else { + A = (curve->first_point()).to_2geom(); + B = (p.to_2geom()); + } + + SPCurve *c = new SPCurve(); + c->moveto(A); + c->lineto(B); + sp_path_set_original_curve(SP_PATH(item), c, TRUE, true); + c->unref(); +} +**/ + +//void path_start_set(SPItem *item, NR::Point const &p, NR::Point const &/*origin*/, guint /*state*/) { +// path_set_start_end(item, p); +//} + +//void path_end_set(SPItem *item, NR::Point const &p, NR::Point const &/*origin*/, guint /*state*/) { +// path_set_start_end(item, p, false); +//} + +} //namescape PB LPEPerpBisector::LPEPerpBisector(LivePathEffectObject *lpeobject) : Effect(lpeobject), - length_left(_("Length left"), _(""), "length-left", &wr, this, 200), - length_right(_("Length right"), _(""), "length-right", &wr, this, 200) + length_left(_("Length left"), _("Specifies the left end of the bisector"), "length-left", &wr, this, 200), + length_right(_("Length right"), _("Specifies the right end of the bisector"), "length-right", &wr, this, 200), + A(0,0), B(0,0), M(0,0), C(0,0), D(0,0), perp_dir(0,0) { + // register all your parameters here, so Inkscape knows which parameters this effect has: registerParameter( dynamic_cast(&length_left) ); registerParameter( dynamic_cast(&length_right) ); + + registerKnotHolderHandle(new PB::KnotHolderEntityLeftEnd(), _("Lala")); + registerKnotHolderHandle(new PB::KnotHolderEntityRightEnd(), _("Lolo")); +/** + registerKnotHolderHandle(path_start_set, path_start_get); + registerKnotHolderHandle(path_end_set, path_end_get); + registerKnotHolderHandle(bisector_left_end_set, bisector_left_end_get); + registerKnotHolderHandle(bisector_right_end_set, bisector_right_end_get); +**/ } LPEPerpBisector::~LPEPerpBisector() { - } -Geom::Point LPEPerpBisector::left_end(Geom::Piecewise > const & pwd2_in) { - Geom::Point A(pwd2_in.firstValue()); - Geom::Point B(pwd2_in.lastValue()); - Geom::Point M((A + B)/2); - - Geom::Point dir1((B - M).ccw()); - - if (dir1.length() > Geom::EPSILON) - dir1 = Geom::unit_vector(dir1) * length_left; - - return M + dir1; +void +LPEPerpBisector::doOnApply (SPLPEItem */*lpeitem*/) +{ + /* make the path a straight line */ + /** + SPCurve* curve = sp_path_get_curve_for_edit (SP_PATH(lpeitem)); // TODO: Should we use sp_shape_get_curve()? + + Geom::Point A((curve->first_point()).to_2geom()); + Geom::Point B((curve->last_point()).to_2geom()); + + SPCurve *c = new SPCurve(); + c->moveto(A); + c->lineto(B); + // TODO: Why doesn't sp_path_set_original_curve(SP_PATH(lpeitem), c, TRUE, true) work? + SP_PATH(lpeitem)->original_curve = c->ref(); + c->unref(); + **/ } + Geom::Piecewise > LPEPerpBisector::doEffect_pwd2 (Geom::Piecewise > const & pwd2_in) { @@ -56,21 +202,14 @@ LPEPerpBisector::doEffect_pwd2 (Geom::Piecewise > const & Piecewise > output; - Point A(pwd2_in.firstValue()); - Point B(pwd2_in.lastValue()); - Point M((A + B)/2); - - Point dir1((B - M).ccw()); - Point dir2((A - M).ccw()); - - if (dir1.length() > EPSILON) - dir1 = unit_vector(dir1) * length_left; + A = pwd2_in.firstValue(); + B = pwd2_in.lastValue(); + M = (A + B)/2; - if (dir2.length() > EPSILON) - dir2 = unit_vector(dir2) * length_right; + perp_dir = unit_vector((B - A).ccw()); - Point C(M + dir1); - Point D(M + dir2); + C = M + perp_dir * length_left; + D = M - perp_dir * length_right; output = Piecewise >(D2(Linear(C[X], D[X]), Linear(C[Y], D[Y])));