diff options
Diffstat (limited to 'src/live_effects/lpe-patternalongpath.cpp')
| -rw-r--r-- | src/live_effects/lpe-patternalongpath.cpp | 107 |
1 files changed, 105 insertions, 2 deletions
diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index ed65a0d50..9397d848f 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -18,6 +18,9 @@ #include <2geom/d2.h> #include <2geom/piecewise.h> +#include "knot-holder-entity.h" +#include "knotholder.h" + #include <algorithm> using std::vector; @@ -45,6 +48,16 @@ first) but I think we can first forget about them. namespace Inkscape { namespace LivePathEffect { +Geom::PathVector pap_helper_path; + +namespace WPAP { + class KnotHolderEntityWidthPatternAlongPath : public LPEKnotHolderEntity { + public: + KnotHolderEntityWidthPatternAlongPath(LPEPatternAlongPath * effect) : LPEKnotHolderEntity(effect) {} + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); + virtual Geom::Point knot_get() const; + }; +} // WPAP static const Util::EnumData<PAPCopyType> PAPCopyTypeData[PAPCT_END] = { {PAPCT_SINGLE, N_("Single"), "single"}, @@ -57,9 +70,10 @@ static const Util::EnumDataConverter<PAPCopyType> PAPCopyTypeConverter(PAPCopyTy LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : Effect(lpeobject), pattern(_("Pattern source:"), _("Path to put along the skeleton path"), "pattern", &wr, this, "M0,0 L1,0"), + original_height(0), + prop_scale(_("_Width:"), _("Width of the pattern"), "prop_scale", &wr, this, 1.0), copytype(_("Pattern copies:"), _("How many pattern copies to place along the skeleton path"), "copytype", PAPCopyTypeConverter, &wr, this, PAPCT_SINGLE_STRETCHED), - prop_scale(_("_Width:"), _("Width of the pattern"), "prop_scale", &wr, this, 1), scale_y_rel(_("Wid_th in units of length"), _("Scale the width of the pattern in units of its length"), "scale_y_rel", &wr, this, false), @@ -87,9 +101,11 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : registerParameter( dynamic_cast<Parameter *>(&prop_units) ); registerParameter( dynamic_cast<Parameter *>(&vertical_pattern) ); registerParameter( dynamic_cast<Parameter *>(&fuse_tolerance) ); - prop_scale.param_set_digits(3); prop_scale.param_set_increments(0.01, 0.10); + + _provides_knotholder_entities = true; + } LPEPatternAlongPath::~LPEPatternAlongPath() @@ -97,6 +113,16 @@ LPEPatternAlongPath::~LPEPatternAlongPath() } +void +LPEPatternAlongPath::doBeforeEffect (SPLPEItem const* lpeitem) +{ + // get the pattern bounding box + Geom::OptRect bbox = pattern.get_pathvector().boundsFast(); + if (bbox) { + original_height = (*bbox)[Geom::Y].max() - (*bbox)[Geom::Y].min(); + } +} + Geom::Piecewise<Geom::D2<Geom::SBasis> > LPEPatternAlongPath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in) { @@ -238,6 +264,83 @@ LPEPatternAlongPath::transform_multiply(Geom::Affine const& postmul, bool set) } } +void +LPEPatternAlongPath::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec) +{ + hp_vec.push_back(pap_helper_path); +} + + +void +LPEPatternAlongPath::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) +{ + KnotHolderEntity *e = new WPAP::KnotHolderEntityWidthPatternAlongPath(this); + e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE); + knotholder->add(e); +} + +namespace WPAP { + +void +KnotHolderEntityWidthPatternAlongPath::knot_set(Geom::Point const &p, Geom::Point const& /*origin*/, guint state) +{ + LPEPatternAlongPath *lpe = dynamic_cast<LPEPatternAlongPath *> (_effect); + + Geom::Point const s = snap_knot_position(p, state); + SPShape const *sp_shape = dynamic_cast<SPShape const *>(SP_LPE_ITEM(item)); + if (sp_shape) { + Geom::Path const *path_in = sp_shape->getCurveBeforeLPE()->first_path(); + Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); + Geom::Point B = path_in->pointAt(Geom::PathTime(1, 0.0)); + Geom::Curve const *first_curve = &path_in->curveAt(Geom::PathTime(0, 0.0)); + Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*first_curve); + Geom::Ray ray(ptA, B); + if (cubic) { + ray.setPoints(ptA, (*cubic)[1]); + } + ray.setAngle(ray.angle() + Geom::rad_from_deg(90)); + Geom::Point knot_pos = this->knot->pos * item->i2dt_affine().inverse(); + Geom::Coord nearest_to_ray = ray.nearestTime(knot_pos); + if(nearest_to_ray == 0){ + lpe->prop_scale.param_set_value(-Geom::distance(s , ptA)/(lpe->original_height/2.0)); + } else { + lpe->prop_scale.param_set_value(Geom::distance(s , ptA)/(lpe->original_height/2.0)); + } + + } + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); +} + +Geom::Point +KnotHolderEntityWidthPatternAlongPath::knot_get() const +{ + LPEPatternAlongPath *lpe = dynamic_cast<LPEPatternAlongPath *> (_effect); + + SPShape const *sp_shape = dynamic_cast<SPShape const *>(SP_LPE_ITEM(item)); + if (sp_shape) { + Geom::Path const *path_in = sp_shape->getCurveBeforeLPE()->first_path(); + Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); + Geom::Point B = path_in->pointAt(Geom::PathTime(1, 0.0)); + Geom::Curve const *first_curve = &path_in->curveAt(Geom::PathTime(0, 0.0)); + Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*first_curve); + Geom::Ray ray(ptA, B); + if (cubic) { + ray.setPoints(ptA, (*cubic)[1]); + } + ray.setAngle(ray.angle() + Geom::rad_from_deg(90)); + Geom::Point result_point = Geom::Point::polar(ray.angle(), (lpe->original_height/2.0) * lpe->prop_scale) + ptA; + + pap_helper_path.clear(); + Geom::Path hp(result_point); + hp.appendNew<Geom::LineSegment>(ptA); + pap_helper_path.push_back(hp); + hp.clear(); + + return result_point; + } + return Geom::Point(); +} +} // namespace WPAP } // namespace LivePathEffect } /* namespace Inkscape */ |
