lpe-roughen.cpp revision dbe3e7dacd7d4490ef69cc21314dc718b4706ae5
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * Roughen LPE implementation. Creates roughen paths.
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * Jabier Arraiza Cenoz <jabier.arraiza@marker.es>
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * Thanks to all people involved specialy to Josh Andler for the idea and to the
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * original extensions authors.
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof * Copyright (C) 2014 Authors
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof * Released under GNU GPL, read the file 'COPYING' for more information
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxofstatic const Util::EnumData<DivisionMethod> DivisionMethodData[DM_END] = {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof { DM_SEGMENTS, N_("By number of segments"), "segments" },
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxofstatic const Util::EnumDataConverter<DivisionMethod>
60db347ea19e568bd09c35a0248a9f78d7931ca0JabiertxofLPERoughen::LPERoughen(LivePathEffectObject *lpeobject)
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof // initialise your parameters here:
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof method(_("Method"), _("Division method"), "method", DMConverter, &wr,
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof max_segment_size(_("Max. segment size"), _("Max. segment size"),
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof segments(_("Number of segments"), _("Number of segments"), "segments",
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof displace_x(_("Max. displacement in X"), _("Max. displacement in X"),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof displace_y(_("Max. displacement in Y"), _("Max. displacement in Y"),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof global_randomize(_("Global randomize"), _("Global randomize"),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof shift_nodes(_("Shift nodes"), _("Shift nodes"), "shift_nodes", &wr, this,
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof shift_handles(_("Shift node handles"), _("Shift node handles"),
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof shift_handles_sym(_("Sym shift node handles"), _("Sym shift node handles"),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof displace_x.param_set_range(0., Geom::infinity());
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof displace_y.param_set_range(0., Geom::infinity());
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof global_randomize.param_set_range(0., Geom::infinity());
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof max_segment_size.param_set_range(0., Geom::infinity());
2ce2003d5713154f99c32af18fb904a1af109031Jabiertxofvoid LPERoughen::doBeforeEffect(SPLPEItem const *lpeitem)
2ce2003d5713154f99c32af18fb904a1af109031Jabiertxof SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget()));
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof std::vector<Parameter *>::iterator it = param_vector.begin();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Gtk::Widget *widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget());
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Gtk::Label *method_label = Gtk::manage(new Gtk::Label(
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Glib::ustring(_("<b>Add nodes</b> Subdivide each segment")),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof vbox->pack_start(*method_label, false, false, 2);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Gtk::Label *displace_x_label = Gtk::manage(new Gtk::Label(
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Glib::ustring(_("<b>Jitter nodes</b> Move nodes/handles")),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof vbox->pack_start(*displace_x_label, false, false, 2);
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Gtk::Label *global_rand = Gtk::manage(new Gtk::Label(
de641d2613f4eea940ba6eb6c52ea9bcda516ba2Jabiertxof Glib::ustring(_("<b>Extra roughen</b> Add a extra layer of rough")),
721286d6ce40a27fcd8b9483667a43ed09023b17Jabiertxof vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()),
0b159142b0b5738b20883b411fe8233657cf8b4fJabiertxof double displace_x_parsed = displace_x * global_randomize;
0b159142b0b5738b20883b411fe8233657cf8b4fJabiertxof double displace_y_parsed = displace_y * global_randomize;
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof Geom::Point output = Geom::Point(sign(displace_x_parsed), sign(displace_y_parsed));
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof pathv_to_linear_and_cubic_beziers(curve->get_pathvector());
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof for (Geom::PathVector::const_iterator path_it = original_pathv.begin();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::Path::const_iterator curve_it1 = path_it->begin();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::Path::const_iterator curve_it2 = ++(path_it->begin());
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::Path::const_iterator curve_endit = path_it->end_default();
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::Point initialPoint = curve_it1->initialPoint() + initialMove;
a0623d30f399827fa8c9cf5edad86bbc8e72c063Jabiertxof bool first = true;
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Curve const * original = nCurve->last_segment()->duplicate() ;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof bool last = false;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof double time = Geom::nearest_time(original->pointAt((1. / (double)splits) * t), *nCurve->last_segment());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof tmp = addNodesAndJitter(nCurve->last_segment(), prev, time, last);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof if(shift_handles_sym && curve_it2 == curve_endit){
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::CubicBezier const *cubic_start = dynamic_cast<Geom::CubicBezier const *>(nCurve->first_segment());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(nCurve->last_segment());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Point oposite = nCurve->first_segment()->initialPoint();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof Geom::Ray ray((*cubic_start)[1], (*cubic_start)[0]);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof double dist = Geom::distance((*cubic_start)[1], (*cubic_start)[0]);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof oposite = Geom::Point::polar(ray.angle(),dist) + (*cubic_start)[0];
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof out->moveto(nCurve->last_segment()->initialPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof out->curveto(nCurve->last_segment()->initialPoint(), oposite, nCurve->last_segment()->finalPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxofSPCurve const * LPERoughen::addNodesAndJitter(Geom::Curve const * A, Geom::Point &prev, double t, bool last)
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*A);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof double dist = Geom::distance(prev, A->initialPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof std::pair<Geom::CubicBezier, Geom::CubicBezier> div = cubic->subdivide(t);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof std::vector<Geom::Point> seg1 = div.first.controlPoints(),
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof double dist = Geom::distance(seg1[1], A->initialPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof double dist = Geom::distance(A->pointAt(t / 3) + randomize(), A->initialPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point1 = Geom::Point::polar(ray.angle(),dist) + A->initialPoint();
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof double dist2 = Geom::distance(A->pointAt(t + ((t / 3) * 2)) + point_b2, point3);
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point_b1 = Geom::Point::polar(ray2.angle(),dist2) + point3;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof point_b2 = A->pointAt(t + ((t / 3) * 2)) + point_b2;
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof out->curveto(point_b1, point_b2, A->finalPoint());
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof } else if (cubic) {
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof std::pair<Geom::CubicBezier, Geom::CubicBezier> div = cubic->subdivide(t);
76addc201c409e81eaaa73fe27cc0f79c4db097cKrzysztof Kosiński std::vector<Geom::Point> seg1 = div.first.controlPoints(),
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof out->curveto(seg1[1] + point1, seg1[2] + point2, seg1[3] + point3);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof out->curveto(seg2[1] + point_b1, seg2[2], seg2[3]);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof out->curveto(A->pointAt(t / 3) + point1, A->pointAt((t / 3) * 2) + point2,
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxof out->curveto(A->pointAt(t + (t / 3)) + point_b1, A->pointAt(t + ((t / 3) * 2)) + point_b2,
dbe3e7dacd7d4490ef69cc21314dc718b4706ae5jabiertxofSPCurve *LPERoughen::jitter(Geom::Curve const * A)
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*A);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof out->curveto((*cubic)[1] + point1, (*cubic)[2] + point2, (*cubic)[3] + point3);
163aa8601274792f2afe8e24a061fed96b7a6599Jabiertxof out->curveto(A->pointAt(0.3333) + point1, A->pointAt(0.6666) + point2,
163aa8601274792f2afe8e24a061fed96b7a6599JabiertxofGeom::Point LPERoughen::tPoint(Geom::Point A, Geom::Point B, double t)
ccbee7d45f91658e83a602a9a28ee26162a261f9Jabiertxof return Geom::Point(A[X] + t * (B[X] - A[X]), A[Y] + t * (B[Y] - A[Y]));
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof}; //namespace LivePathEffect
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof}; /* namespace Inkscape */
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof Local Variables:
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof c-file-style:"stroustrup"
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof indent-tabs-mode:nil
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof fill-column:99
60db347ea19e568bd09c35a0248a9f78d7931ca0Jabiertxof// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :