diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2015-10-19 09:13:44 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx.marker.es> | 2015-10-19 09:13:44 +0000 |
| commit | 58dd8e4f061599778f4c6d8c958b13f0fc99f06f (patch) | |
| tree | f18c4fc4687a8a685c729879b19c07e3712e1861 /src | |
| parent | Added "Spray Friendly" Parameter to roughen LPE (diff) | |
| download | inkscape-58dd8e4f061599778f4c6d8c958b13f0fc99f06f.tar.gz inkscape-58dd8e4f061599778f4c6d8c958b13f0fc99f06f.zip | |
Change oprions of handles to a enum widget
Add parameter to limit angle in mode smooth
Bug fixes and improvements to "Spray Friendly" option
(bzr r14421)
Diffstat (limited to 'src')
| -rw-r--r-- | src/live_effects/lpe-roughen.cpp | 135 | ||||
| -rw-r--r-- | src/live_effects/lpe-roughen.h | 22 |
2 files changed, 113 insertions, 44 deletions
diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 136190b8f..d40d549a7 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -33,13 +33,22 @@ static const Util::EnumData<DivisionMethod> DivisionMethodData[DM_END] = { static const Util::EnumDataConverter<DivisionMethod> DMConverter(DivisionMethodData, DM_END); +static const Util::EnumData<HandlesMethod> HandlesMethodData[HM_END] = { + { HM_ALONG_NODES, N_("Along nodes"), "along" }, + { HM_RAND, N_("Rand"), "rand" }, + { HM_RETRACT, N_("Retract"), "retract" }, + { HM_SMOOTH, N_("Smooth"), "smooth" } +}; +static const Util::EnumDataConverter<HandlesMethod> +HMConverter(HandlesMethodData, HM_END); + LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) : Effect(lpeobject), // initialise your parameters here: method(_("Method"), _("Division method"), "method", DMConverter, &wr, this, DM_SEGMENTS), max_segment_size(_("Max. segment size"), _("Max. segment size"), - "max_segment_size", &wr, this, 10.), + "max_segment_size", &wr, this, 10), segments(_("Number of segments"), _("Number of segments"), "segments", &wr, this, 2), displace_x(_("Max. displacement in X"), _("Max. displacement in X"), @@ -48,14 +57,12 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) "displace_y", &wr, this, 10.), global_randomize(_("Global randomize"), _("Global randomize"), "global_randomize", &wr, this, 1.), + handles(_("Handles"), _("Handles options"), "handles", HMConverter, &wr, + this, HM_ALONG_NODES), + max_smooth_angle(_("Max. smooth handle angle"), _("Max. smooth handle angle"), + "max_smooth_angle", &wr, this, 20), shift_nodes(_("Shift nodes"), _("Shift nodes"), "shift_nodes", &wr, this, true), - shift_handles(_("Shift node handles"), _("Shift node handles"), - "shift_handles", &wr, this, true), - retract_handles(_("Retract node handles"), _("Retract node handles"), - "retract_handles", &wr, this, false), - shift_handles_sym(_("Sym shift node handles"), _("Sym shift node handles"), - "shift_handles_sym", &wr, this, false), fixed_displacement(_("Fixed displacement"), _("Fixed displacement, 1/3 of segment lenght"), "fixed_displacement", &wr, this, false), spray_tool_friendly(_("Spray Tool friendly"), _("For use with spray tool"), @@ -67,10 +74,9 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) registerParameter(&displace_x); registerParameter(&displace_y); registerParameter(&global_randomize); + registerParameter(&handles); + registerParameter(&max_smooth_angle); registerParameter(&shift_nodes); - registerParameter(&shift_handles); - registerParameter(&retract_handles); - registerParameter(&shift_handles_sym); registerParameter(&fixed_displacement); registerParameter(&spray_tool_friendly); displace_x.param_set_range(0., Geom::infinity()); @@ -82,20 +88,24 @@ LPERoughen::LPERoughen(LivePathEffectObject *lpeobject) segments.param_set_range(1, Geom::infinity()); segments.param_set_increments(1, 1); segments.param_set_digits(0); + max_smooth_angle.param_set_range(0, 359); + max_smooth_angle.param_set_increments(1, 1); + max_smooth_angle.param_set_digits(0); + seed = 0; } LPERoughen::~LPERoughen() {} void LPERoughen::doBeforeEffect(SPLPEItem const *lpeitem) { + if(spray_tool_friendly && seed == 0){ + std::string id_item(SP_OBJECT(lpeitem)->getId()); + long seed = static_cast<long>(boost::hash_value(id_item)); + global_randomize.param_set_value(global_randomize.get_value(), seed); + } displace_x.resetRandomizer(); displace_y.resetRandomizer(); - if(!spray_tool_friendly){ - global_randomize.resetRandomizer(); - } else { - boost::hash<std::string> string_hash; - global_randomize.param_set_value(global_randomize.get_value(), static_cast<long>(string_hash(lpeitem->getId()))); - } + global_randomize.resetRandomizer(); srand(1); SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); item->apply_to_clippath(item); @@ -140,7 +150,7 @@ Gtk::Widget *LPERoughen::newWidget() vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET); } - if (param->param_key == "shift_nodes") { + if (param->param_key == "handles") { Gtk::Label *options = Gtk::manage(new Gtk::Label( Glib::ustring(_("<b>Options</b> Modify options to rough")), Gtk::ALIGN_START)); @@ -173,11 +183,19 @@ double LPERoughen::sign(double random_number) return random_number; } -Geom::Point LPERoughen::randomize(double max_lenght) +Geom::Point LPERoughen::randomize(double max_lenght, double direction) { double displace_x_parsed = displace_x * global_randomize; double displace_y_parsed = displace_y * global_randomize; Geom::Point output = Geom::Point(sign(displace_x_parsed), sign(displace_y_parsed)); + if( direction != 0){ + int angle = (int)max_smooth_angle; + if (angle == 0){ + angle = 1; + } + double dist = Geom::distance(Geom::Point(0,0),output); + output = Geom::Point::polar(direction + sign(Geom::deg_to_rad(rand() % angle)), dist); + } if( fixed_displacement ){ Geom::Ray ray(Geom::Point(0,0),output); output = Geom::Point::polar(ray.angle(), max_lenght); @@ -199,6 +217,7 @@ void LPERoughen::doEffect(SPCurve *curve) Geom::Path::const_iterator curve_endit = path_it->end_default(); SPCurve *nCurve = new SPCurve(); Geom::Point prev(0, 0); + Geom::Point last_move(0, 0); nCurve->moveto(curve_it1->initialPoint()); while (curve_it1 != curve_endit) { Geom::CubicBezier const *cubic = NULL; @@ -222,14 +241,14 @@ void LPERoughen::doEffect(SPCurve *curve) } SPCurve const * tmp; if (splits == 1) { - tmp = jitter(nCurve->last_segment(), prev); + tmp = jitter(nCurve->last_segment(), prev, last_move); } else { bool last = false; if(t == splits-1){ last = true; } double time = Geom::nearest_time(original->pointAt((1. / (double)splits) * t), *nCurve->last_segment()); - tmp = addNodesAndJitter(nCurve->last_segment(), prev, time, last); + tmp = addNodesAndJitter(nCurve->last_segment(), prev, last_move, time, last); } if (nCurve->get_segment_count() > 1) { nCurve->backspace(); @@ -243,7 +262,7 @@ void LPERoughen::doEffect(SPCurve *curve) ++curve_it2; } if (path_it->closed()) { - if(shift_handles_sym && curve_it1 == curve_endit && !retract_handles){ + if(handles == HM_SMOOTH && curve_it1 == curve_endit){ SPCurve *out = new SPCurve(); nCurve = nCurve->create_reverse(); Geom::CubicBezier const *cubic_start = dynamic_cast<Geom::CubicBezier const *>(nCurve->first_segment()); @@ -265,6 +284,18 @@ void LPERoughen::doEffect(SPCurve *curve) nCurve->append_continuous(out, 0.001); nCurve = nCurve->create_reverse(); } + if(handles == HM_ALONG_NODES && curve_it1 == curve_endit){ + SPCurve *out = new SPCurve(); + nCurve = nCurve->create_reverse(); + Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(nCurve->last_segment()); + if(cubic){ + out->moveto((*cubic)[0]); + out->curveto((*cubic)[1], (*cubic)[2] - last_move, (*cubic)[3]); + nCurve->backspace(); + nCurve->append_continuous(out, 0.001); + } + nCurve = nCurve->create_reverse(); + } nCurve->move_endpoints(nCurve->last_segment()->finalPoint(), nCurve->last_segment()->finalPoint()); nCurve->closepath_current(); } @@ -274,7 +305,7 @@ void LPERoughen::doEffect(SPCurve *curve) } } -SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, double t, bool last) +SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move, double t, bool last) { SPCurve *out = new SPCurve(); Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*A); @@ -291,7 +322,7 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point point_b3 = randomize(max_lenght); } } - if (shift_handles || shift_handles_sym) { + if (handles == HM_RAND || handles == HM_SMOOTH) { point_a1 = randomize(max_lenght); point_a2 = randomize(max_lenght); point_b1 = randomize(max_lenght); @@ -305,7 +336,7 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point point_b2 = point_b3; } } - if(retract_handles){ + if(handles == HM_RETRACT){ out->moveto(A->initialPoint()); out->lineto(A->pointAt(t) + point_a3); if(cubic && !last){ @@ -315,7 +346,7 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point } else { out->lineto(A->finalPoint() + point_b3); } - } else if(shift_handles_sym && cubic) { + } else if(handles == HM_SMOOTH && cubic) { std::pair<Geom::CubicBezier, Geom::CubicBezier> div = cubic->subdivide(t); std::vector<Geom::Point> seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); @@ -324,6 +355,12 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point if(prev == Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } + ray.setPoints(seg1[3] + point_a3, seg2[1] + point_a3); + point_b1 = randomize(max_lenght, ray.angle()); + if(last){ + ray.setPoints(seg2[3] + point_b3, A->pointAt(1 - (t / 3)) + point_b3); + point_b2 = randomize(max_lenght, ray.angle()); + } ray.setPoints(seg2[1] + point_a3 + point_b1, seg2[0] + point_a3); point_a2 = Geom::Point::polar(ray.angle(), max_lenght); if(last){ @@ -338,12 +375,18 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point } else { out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3); } - } else if(shift_handles_sym && !cubic) { + } else if(handles == HM_SMOOTH && !cubic) { Geom::Ray ray(prev,A->initialPoint()); point_a1 = Geom::Point::polar(ray.angle(), max_lenght); if(prev==Geom::Point(0,0)){ point_a1 = randomize(max_lenght); } + ray.setPoints(A->pointAt(t) + point_a3, A->pointAt(t + (t / 3)) + point_a3); + point_b1 = randomize(max_lenght, ray.angle()); + if(last){ + ray.setPoints(A->finalPoint() + point_b3, A->pointAt(t +((t / 3) * 2)) + point_b3); + point_b2 = randomize(max_lenght, ray.angle()); + } ray.setPoints(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t) + point_a3); point_a2 = Geom::Point::polar(ray.angle(), max_lenght); if(last){ @@ -359,9 +402,18 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point std::vector<Geom::Point> seg1 = div.first.controlPoints(), seg2 = div.second.controlPoints(); out->moveto(seg1[0]); - out->curveto(seg1[1] + point_a1, seg1[2] + point_a2 + point_a3, seg1[3] + point_a3); - out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3); - } else if (shift_handles) { + if(handles == HM_ALONG_NODES){ + out->curveto(seg1[1] + last_move, seg1[2] + point_a3, seg1[3] + point_a3); + last_move = point_a3; + if(last){ + last_move = point_b3; + } + out->curveto(seg2[1] + point_a3, seg2[2] + point_b3, seg2[3] + point_b3); + } else { + out->curveto(seg1[1] + point_a1, seg1[2] + point_a2 + point_a3, seg1[3] + point_a3); + out->curveto(seg2[1] + point_a3 + point_b1, seg2[2] + point_b2 + point_b3, seg2[3] + point_b3); + } + } else if (handles == HM_RAND) { out->moveto(A->initialPoint()); out->curveto(A->pointAt(t / 3) + point_a1, A->pointAt((t / 3) * 2) + point_a2 + point_a3, A->pointAt(t) + point_a3); out->curveto(A->pointAt(t + (t / 3)) + point_a3 + point_b1, A->pointAt(t +((t / 3) * 2)) + point_b2 + point_b3, A->finalPoint() + point_b3); @@ -373,7 +425,7 @@ SPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point return out; } -SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev) +SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move) { SPCurve *out = new SPCurve(); Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*A); @@ -384,35 +436,44 @@ SPCurve *LPERoughen::jitter(Geom::Curve const * A, Geom::Point &prev) if (shift_nodes) { point_a3 = randomize(max_lenght); } - if (shift_handles || shift_handles_sym) { + if (handles == HM_RAND || handles == HM_SMOOTH) { point_a1 = randomize(max_lenght); point_a2 = randomize(max_lenght); } - if(retract_handles){ + if(handles == HM_RETRACT){ out->moveto(A->initialPoint()); out->lineto(A->finalPoint() + point_a3); - } else if(shift_handles_sym && cubic) { + } else if(handles == HM_SMOOTH && cubic) { Geom::Ray ray(prev,A->initialPoint()); point_a1 = Geom::Point::polar(ray.angle(), max_lenght); if(prev == Geom::Point(0,0)){ point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght); } + ray.setPoints((*cubic)[3] + point_a3, (*cubic)[2] + point_a3); + point_a2 = randomize(max_lenght, ray.angle()); prev = (*cubic)[2] + point_a2; out->moveto((*cubic)[0]); out->curveto((*cubic)[0] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3); - } else if(shift_handles_sym && !cubic) { + } else if(handles == HM_SMOOTH && !cubic) { Geom::Ray ray(prev,A->initialPoint()); point_a1 = Geom::Point::polar(ray.angle(), max_lenght); if(prev==Geom::Point(0,0)){ point_a1 = A->pointAt(1.0/3.0) + randomize(max_lenght); } - prev = A->pointAt((1.0/3.0) * 2) + point_a2; + ray.setPoints(A->finalPoint() + point_a3, A->pointAt((1.0/3.0) * 2) + point_a3); + point_a2 = randomize(max_lenght, ray.angle()); + prev = A->pointAt((1.0/3.0) * 2) + point_a2 + point_a3; out->moveto(A->initialPoint()); out->curveto(A->initialPoint() + point_a1, A->pointAt((1.0/3.0) * 2) + point_a2 + point_a3, A->finalPoint() + point_a3); } else if (cubic) { out->moveto((*cubic)[0]); - out->curveto((*cubic)[1] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3); - } else if (shift_handles) { + if(handles == HM_ALONG_NODES){ + out->curveto((*cubic)[1] + last_move, (*cubic)[2] + point_a3, (*cubic)[3] + point_a3); + last_move = point_a3; + } else { + out->curveto((*cubic)[1] + point_a1, (*cubic)[2] + point_a2 + point_a3, (*cubic)[3] + point_a3); + } + } else if (handles == HM_RAND) { out->moveto(A->initialPoint()); out->curveto(A->pointAt(0.3333) + point_a1, A->pointAt(0.6666) + point_a2 + point_a3, A->finalPoint() + point_a3); diff --git a/src/live_effects/lpe-roughen.h b/src/live_effects/lpe-roughen.h index 178c3b657..e3ede2c2d 100644 --- a/src/live_effects/lpe-roughen.h +++ b/src/live_effects/lpe-roughen.h @@ -28,6 +28,15 @@ enum DivisionMethod { DM_END }; +enum HandlesMethod { + HM_ALONG_NODES, + HM_RAND, + HM_RETRACT, + HM_SMOOTH, + HM_END +}; + + class LPERoughen : public Effect { public: @@ -36,10 +45,10 @@ public: virtual void doEffect(SPCurve *curve); virtual double sign(double randNumber); - virtual Geom::Point randomize(double max_lenght); + virtual Geom::Point randomize(double max_lenght, double direction = 0); virtual void doBeforeEffect(SPLPEItem const * lpeitem); - virtual SPCurve const * addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, double t, bool last); - virtual SPCurve *jitter(Geom::Curve const * A, Geom::Point &prev); + virtual SPCurve const * addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move, double t, bool last); + virtual SPCurve *jitter(Geom::Curve const * A, Geom::Point &prev, Geom::Point &last_move); virtual Geom::Point tPoint(Geom::Point A, Geom::Point B, double t = 0.5); virtual Gtk::Widget *newWidget(); @@ -50,13 +59,12 @@ private: RandomParam displace_x; RandomParam displace_y; RandomParam global_randomize; + EnumParam<HandlesMethod> handles; + ScalarParam max_smooth_angle; BoolParam shift_nodes; - BoolParam shift_handles; - BoolParam retract_handles; - BoolParam shift_handles_sym; BoolParam fixed_displacement; BoolParam spray_tool_friendly; - + long seed; LPERoughen(const LPERoughen &); LPERoughen &operator=(const LPERoughen &); |
