diff options
Diffstat (limited to 'src/live_effects')
| -rw-r--r-- | src/live_effects/Makefile_insert | 2 | ||||
| -rw-r--r-- | src/live_effects/effect-enum.h | 1 | ||||
| -rw-r--r-- | src/live_effects/effect.cpp | 7 | ||||
| -rw-r--r-- | src/live_effects/lpe-bspline.cpp | 21 | ||||
| -rw-r--r-- | src/live_effects/lpe-copy_rotate.cpp | 1 | ||||
| -rw-r--r-- | src/live_effects/lpe-envelope-perspective.cpp | 18 | ||||
| -rw-r--r-- | src/live_effects/lpe-interpolate_points.cpp | 94 | ||||
| -rw-r--r-- | src/live_effects/lpe-interpolate_points.h | 51 | ||||
| -rw-r--r-- | src/live_effects/lpe-knot.cpp | 1 | ||||
| -rw-r--r-- | src/live_effects/lpe-perspective_path.cpp | 107 | ||||
| -rw-r--r-- | src/live_effects/lpe-perspective_path.h | 3 | ||||
| -rw-r--r-- | src/live_effects/lpe-powerstroke-interpolators.h | 88 | ||||
| -rw-r--r-- | src/live_effects/lpe-powerstroke.cpp | 3 | ||||
| -rw-r--r-- | src/live_effects/lpe-roughen.cpp | 16 | ||||
| -rw-r--r-- | src/live_effects/lpeobject-reference.h | 6 | ||||
| -rw-r--r-- | src/live_effects/lpeobject.h | 4 | ||||
| -rw-r--r-- | src/live_effects/parameter/filletchamferpointarray.cpp | 4 | ||||
| -rw-r--r-- | src/live_effects/parameter/togglebutton.cpp | 8 |
18 files changed, 399 insertions, 36 deletions
diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert index f6e5125e3..f18dcdef0 100644 --- a/src/live_effects/Makefile_insert +++ b/src/live_effects/Makefile_insert @@ -38,6 +38,8 @@ ink_common_sources += \ live_effects/lpe-gears.h \ live_effects/lpe-interpolate.cpp \ live_effects/lpe-interpolate.h \ + live_effects/lpe-interpolate_points.cpp \ + live_effects/lpe-interpolate_points.h \ live_effects/lpe-test-doEffect-stack.cpp \ live_effects/lpe-test-doEffect-stack.h \ live_effects/lpe-bspline.cpp \ diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h index 422b95910..c53f1a5b9 100644 --- a/src/live_effects/effect-enum.h +++ b/src/live_effects/effect-enum.h @@ -45,6 +45,7 @@ enum EffectType { RULER, BOOLOPS, INTERPOLATE, + INTERPOLATE_POINTS, TEXT_LABEL, PATH_LENGTH, LINE_SEGMENT, diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index 4e1b4bffa..895408707 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -44,6 +44,7 @@ #include "live_effects/lpe-ruler.h" #include "live_effects/lpe-boolops.h" #include "live_effects/lpe-interpolate.h" +#include "live_effects/lpe-interpolate_points.h" #include "live_effects/lpe-text_label.h" #include "live_effects/lpe-path_length.h" #include "live_effects/lpe-line_segment.h" @@ -136,6 +137,7 @@ const Util::EnumData<EffectType> LPETypeData[] = { /* 0.91 */ {POWERSTROKE, N_("Power stroke"), "powerstroke"}, {CLONE_ORIGINAL, N_("Clone original path"), "clone_original"}, +/* EXPERIMENTAL */ {SHOW_HANDLES, N_("Show handles"), "show_handles"}, {ROUGHEN, N_("Roughen"), "roughen"}, {BSPLINE, N_("BSpline"), "bspline"}, @@ -151,6 +153,8 @@ const Util::EnumData<EffectType> LPETypeData[] = { {SIMPLIFY, N_("Simplify"), "simplify"}, {LATTICE2, N_("Lattice Deformation 2"), "lattice2"}, {ENVELOPE_PERSPECTIVE, N_("Envelope-Perspective"), "envelope-perspective"}, + {FILLET_CHAMFER, N_("Fillet/Chamfer"), "fillet-chamfer"}, + {INTERPOLATE_POINTS, N_("Interpolate points"), "interpolate_points"}, }; const Util::EnumDataConverter<EffectType> LPETypeConverter(LPETypeData, sizeof(LPETypeData)/sizeof(*LPETypeData)); @@ -247,6 +251,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case INTERPOLATE: neweffect = static_cast<Effect*> ( new LPEInterpolate(lpeobj) ); break; + case INTERPOLATE_POINTS: + neweffect = static_cast<Effect*> ( new LPEInterpolatePoints(lpeobj) ); + break; case TEXT_LABEL: neweffect = static_cast<Effect*> ( new LPETextLabel(lpeobj) ); break; diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp index a004b8490..433696aab 100644 --- a/src/live_effects/lpe-bspline.cpp +++ b/src/live_effects/lpe-bspline.cpp @@ -1,5 +1,3 @@ -#define INKSCAPE_LPE_BSPLINE_C - /* * Released under GNU GPL, read the file 'COPYING' for more information */ @@ -8,23 +6,19 @@ # include <config.h> #endif -#if WITH_GLIBMM_2_32 && HAVE_GLIBMM_THREADS_H +#include <gtkmm.h> + +#if WITH_GLIBMM_2_32 # include <glibmm/threads.h> #endif -#include <2geom/bezier-curve.h> -#include <2geom/point.h> - -#include <gtkmm/box.h> -#include <gtkmm/entry.h> -#include <gtkmm/box.h> -#include <gtkmm/button.h> -#include <gtkmm/checkbutton.h> - #include <glib.h> #include <glibmm/i18n.h> + #include "display/curve.h" +#include <2geom/bezier-curve.h> +#include <2geom/point.h> #include "helper/geom-curves.h" #include "live_effects/lpe-bspline.h" #include "live_effects/lpeobject.h" @@ -48,8 +42,7 @@ #include "display/sp-canvas.h" #include <typeinfo> #include <vector> - -// For handling non-contiguous paths: +// For handling un-continuous paths: #include "message-stack.h" #include "inkscape.h" #include "desktop.h" diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index 65bbcdad1..e466093d3 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -12,6 +12,7 @@ */ #include <glibmm/i18n.h> +#include <gdk/gdk.h> #include "live_effects/lpe-copy_rotate.h" #include "sp-shape.h" diff --git a/src/live_effects/lpe-envelope-perspective.cpp b/src/live_effects/lpe-envelope-perspective.cpp index 02cb67db3..3b91eb183 100644 --- a/src/live_effects/lpe-envelope-perspective.cpp +++ b/src/live_effects/lpe-envelope-perspective.cpp @@ -14,12 +14,11 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include <gtkmm.h> #include "live_effects/lpe-envelope-perspective.h" #include "helper/geom.h" #include "display/curve.h" #include "svg/svg.h" -#include <gtkmm/separator.h> -#include <gtkmm/stock.h> #include <tools-switch.h> #include <gsl/gsl_linalg.h> #include "desktop.h" @@ -286,12 +285,20 @@ LPEEnvelopePerspective::newWidget() Gtk::Label* handles = Gtk::manage(new Gtk::Label(Glib::ustring(_("Handles:")),Gtk::ALIGN_START)); vbox->pack_start(*handles, false, false, 2); hboxUpHandles->pack_start(*widg, true, true, 2); +#if WITH_GTKMM_3_0 + hboxUpHandles->pack_start(*Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_VERTICAL)), Gtk::PACK_EXPAND_WIDGET); +#else hboxUpHandles->pack_start(*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_EXPAND_WIDGET); +#endif }else if(param->param_key == "Up_Right_Point"){ hboxUpHandles->pack_start(*widg, true, true, 2); }else if(param->param_key == "Down_Left_Point"){ hboxDownHandles->pack_start(*widg, true, true, 2); +#if WITH_GTKMM_3_0 + hboxDownHandles->pack_start(*Gtk::manage(new Gtk::Separator(Gtk::ORIENTATION_VERTICAL)), Gtk::PACK_EXPAND_WIDGET); +#else hboxDownHandles->pack_start(*Gtk::manage(new Gtk::VSeparator()), Gtk::PACK_EXPAND_WIDGET); +#endif }else{ hboxDownHandles->pack_start(*widg, true, true, 2); } @@ -320,8 +327,13 @@ LPEEnvelopePerspective::newWidget() } vbox->pack_start(*hboxUpHandles,true, true, 2); Gtk::HBox * hboxMiddle = Gtk::manage(new Gtk::HBox(true,2)); +#if WITH_GTKMM_3_0 + hboxMiddle->pack_start(*Gtk::manage(new Gtk::Separator()), Gtk::PACK_EXPAND_WIDGET); + hboxMiddle->pack_start(*Gtk::manage(new Gtk::Separator()), Gtk::PACK_EXPAND_WIDGET); +#else hboxMiddle->pack_start(*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET); hboxMiddle->pack_start(*Gtk::manage(new Gtk::HSeparator()), Gtk::PACK_EXPAND_WIDGET); +#endif vbox->pack_start(*hboxMiddle, false, true, 2); vbox->pack_start(*hboxDownHandles, true, true, 2); Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false,0)); @@ -422,4 +434,4 @@ LPEEnvelopePerspective::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::v fill-column:99 End: */ -// vim: file_type=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-interpolate_points.cpp b/src/live_effects/lpe-interpolate_points.cpp new file mode 100644 index 000000000..865b46ca7 --- /dev/null +++ b/src/live_effects/lpe-interpolate_points.cpp @@ -0,0 +1,94 @@ +/** \file + * LPE interpolate_points implementation + * Interpolates between knots of the input path. + */ +/* + * Authors: + * Johan Engelen + * + * Copyright (C) Johan Engelen 2014 <j.b.c.engelen@alumnus.utwente.nl> + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-interpolate_points.h" + +#include <2geom/path.h> + +#include "live_effects/lpe-powerstroke-interpolators.h" + +namespace Inkscape { +namespace LivePathEffect { + + +static const Util::EnumData<unsigned> InterpolatorTypeData[] = { + {Geom::Interpolate::INTERP_LINEAR , N_("Linear"), "Linear"}, + {Geom::Interpolate::INTERP_CUBICBEZIER , N_("CubicBezierFit"), "CubicBezierFit"}, + {Geom::Interpolate::INTERP_CUBICBEZIER_JOHAN , N_("CubicBezierJohan"), "CubicBezierJohan"}, + {Geom::Interpolate::INTERP_SPIRO , N_("SpiroInterpolator"), "SpiroInterpolator"}, + {Geom::Interpolate::INTERP_CENTRIPETAL_CATMULLROM, N_("Centripetal Catmull-Rom"), "CentripetalCatmullRom"} +}; +static const Util::EnumDataConverter<unsigned> InterpolatorTypeConverter(InterpolatorTypeData, sizeof(InterpolatorTypeData)/sizeof(*InterpolatorTypeData)); + + +LPEInterpolatePoints::LPEInterpolatePoints(LivePathEffectObject *lpeobject) + : Effect(lpeobject) + , interpolator_type( + _("Interpolator type:"), + _("Determines which kind of interpolator will be used to interpolate between stroke width along the path"), + "interpolator_type", InterpolatorTypeConverter, &wr, this, Geom::Interpolate::INTERP_CENTRIPETAL_CATMULLROM) +{ + show_orig_path = false; + + registerParameter( dynamic_cast<Parameter *>(&interpolator_type) ); +} + +LPEInterpolatePoints::~LPEInterpolatePoints() +{ +} + + +Geom::PathVector +LPEInterpolatePoints::doEffect_path (Geom::PathVector const & path_in) +{ + Geom::PathVector path_out; + + std::auto_ptr<Geom::Interpolate::Interpolator> interpolator( Geom::Interpolate::Interpolator::create(static_cast<Geom::Interpolate::InterpolatorType>(interpolator_type.get_value())) ); + + for(Geom::PathVector::const_iterator path_it = path_in.begin(); path_it != path_in.end(); ++path_it) { + if (path_it->empty()) + continue; + + if (path_it->closed()) { + g_warning("Interpolate points LPE currently ignores whether path is closed or not."); + } + + std::vector<Geom::Point> pts; + pts.push_back(path_it->initialPoint()); + + for (Geom::Path::const_iterator it = path_it->begin(), e = path_it->end_default(); it != e; ++it) { + pts.push_back((*it).finalPoint()); + } + + Geom::Path path = interpolator->interpolateToPath(pts); + + path_out.push_back(path); + } + + return path_out; +} + + +} //namespace LivePathEffect +} /* namespace Inkscape */ + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-interpolate_points.h b/src/live_effects/lpe-interpolate_points.h new file mode 100644 index 000000000..7a3364747 --- /dev/null +++ b/src/live_effects/lpe-interpolate_points.h @@ -0,0 +1,51 @@ +#ifndef INKSCAPE_LPE_INTERPOLATEPOINTS_H +#define INKSCAPE_LPE_INTERPOLATEPOINTS_H + +/** \file + * LPE interpolate_points implementation, see lpe-interpolate_points.cpp. + */ + +/* + * Authors: + * Johan Engelen + * + * Copyright (C) Johan Engelen 2014 <j.b.c.engelen@alumnus.utwente.nl> + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/parameter/enum.h" +#include "live_effects/effect.h" + +namespace Inkscape { +namespace LivePathEffect { + +class LPEInterpolatePoints : public Effect { +public: + LPEInterpolatePoints(LivePathEffectObject *lpeobject); + virtual ~LPEInterpolatePoints(); + + virtual std::vector<Geom::Path> doEffect_path (std::vector<Geom::Path> const & path_in); + +private: + EnumParam<unsigned> interpolator_type; + + LPEInterpolatePoints(const LPEInterpolatePoints&); + LPEInterpolatePoints& operator=(const LPEInterpolatePoints&); +}; + +} //namespace LivePathEffect +} //namespace Inkscape + +#endif // INKSCAPE_LPE_INTERPOLATEPOINTS_H + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp index 7e5006b3b..3876aa24b 100644 --- a/src/live_effects/lpe-knot.cpp +++ b/src/live_effects/lpe-knot.cpp @@ -22,6 +22,7 @@ #include "knotholder.h" #include <glibmm/i18n.h> +#include <gdk/gdk.h> #include <2geom/sbasis-to-bezier.h> #include <2geom/sbasis.h> diff --git a/src/live_effects/lpe-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp index c255f8665..9e21f5d25 100644 --- a/src/live_effects/lpe-perspective_path.cpp +++ b/src/live_effects/lpe-perspective_path.cpp @@ -10,17 +10,19 @@ * * Released under GNU GPL, read the file 'COPYING' for more information */ - +#include <gtkmm.h> #include <glibmm/i18n.h> #include "persp3d.h" //#include "transf_mat_3x4.h" #include "document.h" - +#include "document-private.h" #include "live_effects/lpe-perspective_path.h" +#include "live_effects/lpeobject.h" #include "sp-item-group.h" #include "knot-holder-entity.h" #include "knotholder.h" +#include "desktop.h" #include "inkscape.h" @@ -41,6 +43,7 @@ public: } // namespace PP +static Glib::ustring perspectiveID = _("First perspective"); LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) : Effect(lpeobject), // initialise your parameters here: @@ -59,9 +62,18 @@ LPEPerspectivePath::LPEPerspectivePath(LivePathEffectObject *lpeobject) : concatenate_before_pwd2 = true; // don't split the path into its subpaths _provides_knotholder_entities = true; - - Persp3D *persp = persp3d_document_first_persp(inkscape_active_document()); + unapply = false; + Persp3D *persp = persp3d_document_first_persp(lpeobject->document); + if(persp == 0 ){ + char *msg = _("You need a BOX 3D object"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK, true); + dialog.run(); + unapply = true; + return; + } Proj::TransfMat3x4 pmat = persp->perspective_impl->tmat; + pmat = pmat * SP_ACTIVE_DESKTOP->doc2dt(); pmat.copy_tmat(tmat); } @@ -74,8 +86,50 @@ void LPEPerspectivePath::doBeforeEffect (SPLPEItem const* lpeitem) { original_bbox(lpeitem, true); + if(unapply){ + SP_LPE_ITEM(lpeitem)->removeCurrentPathEffect(false); + return; + } } +void LPEPerspectivePath::refresh(Gtk::Entry* perspective) { + perspectiveID = perspective->get_text(); + Persp3D *first = 0; + Persp3D *persp = 0; + for ( SPObject *child = this->lpeobj->document->getDefs()->firstChild(); child && !persp; child = child->getNext() ) { + if (SP_IS_PERSP3D(child) && first == 0) { + first = SP_PERSP3D(child); + } + if (SP_IS_PERSP3D(child) && strcmp(child->getId(), const_cast<const gchar *>(perspectiveID.c_str())) == 0) { + persp = SP_PERSP3D(child); + break; + } + } + if(first == 0 ){ + char *msg = _("You need a BOX 3D object"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK, true); + dialog.run(); + return; + } + if(persp == 0){ + persp = first; + char *msg = _("First perspective selected"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK, true); + dialog.run(); + perspectiveID = _("First perspective"); + }else{ + char *msg = _("Perspective changed"); + Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_INFO, + Gtk::BUTTONS_OK, true); + dialog.run(); + } + Proj::TransfMat3x4 pmat = persp->perspective_impl->tmat; + pmat = pmat * SP_ACTIVE_DESKTOP->doc2dt(); + pmat.copy_tmat(tmat); +}; + Geom::Piecewise<Geom::D2<Geom::SBasis> > LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in) { @@ -91,7 +145,7 @@ LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > cons Piecewise<SBasis> preimage[4]; //Geom::Point orig = Geom::Point(bounds_X.min(), bounds_Y.middle()); - //orig = Geom::Point(orig[X], sp_document_height(inkscape_active_document()) - orig[Y]); + //orig = Geom::Point(orig[X], sp_document_height(this->lpeobj->document) - orig[Y]); //double offset = uses_plane_xy ? boundingbox_X.extent() : 0.0; @@ -139,6 +193,49 @@ LPEPerspectivePath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > cons return output; } +Gtk::Widget * +LPEPerspectivePath::newWidget() +{ + // use manage here, because after deletion of Effect object, others might still be pointing to this widget. + Gtk::VBox * vbox = Gtk::manage( new Gtk::VBox(Effect::newWidget()) ); + + vbox->set_border_width(5); + std::vector<Parameter *>::iterator it = param_vector.begin(); + while (it != param_vector.end()) { + if ((*it)->widget_is_visible) { + Parameter * param = *it; + Gtk::Widget * widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget()); + Glib::ustring * tip = param->param_getTooltip(); + if (widg) { + vbox->pack_start(*widg, true, true, 2); + if (tip) { + widg->set_tooltip_text(*tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + + ++it; + } + Gtk::HBox * perspectiveId = Gtk::manage(new Gtk::HBox(true,0)); + Gtk::Label* labelPerspective = Gtk::manage(new Gtk::Label("Perspective ID:", 0., 0.)); + Gtk::Entry* perspective = Gtk::manage(new Gtk::Entry()); + perspective->set_text(perspectiveID); + perspective->set_tooltip_text("Set the perspective ID to apply"); + perspectiveId->pack_start(*labelPerspective, true, true, 2); + perspectiveId->pack_start(*perspective, true, true, 2); + vbox->pack_start(*perspectiveId, true, true, 2); + Gtk::Button* apply3D = Gtk::manage(new Gtk::Button(Glib::ustring(_("Refresh perspective")))); + apply3D->set_alignment(0.0, 0.5); + apply3D->signal_clicked().connect(sigc::bind<Gtk::Entry*>(sigc::mem_fun(*this,&LPEPerspectivePath::refresh),perspective)); + Gtk::Widget* apply3DWidget = dynamic_cast<Gtk::Widget *>(apply3D); + apply3DWidget->set_tooltip_text("Refresh perspective"); + vbox->pack_start(*apply3DWidget, true, true,2); + return dynamic_cast<Gtk::Widget *>(vbox); +} + void LPEPerspectivePath::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) { KnotHolderEntity *e = new PP::KnotHolderEntityOffset(this); e->create( desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, diff --git a/src/live_effects/lpe-perspective_path.h b/src/live_effects/lpe-perspective_path.h index a9ee004f9..6ccac4a51 100644 --- a/src/live_effects/lpe-perspective_path.h +++ b/src/live_effects/lpe-perspective_path.h @@ -38,6 +38,8 @@ public: virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in); + virtual void refresh(Gtk::Entry* perspective); + virtual Gtk::Widget * newWidget(); /* the knotholder entity classes must be declared friends */ friend class PP::KnotHolderEntityOffset; void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); @@ -52,6 +54,7 @@ private: BoolParam uses_plane_xy; // there are all kinds of parameters. Check the /live_effects/parameter directory which types exist! + bool unapply; Geom::Point orig; LPEPerspectivePath(const LPEPerspectivePath&); diff --git a/src/live_effects/lpe-powerstroke-interpolators.h b/src/live_effects/lpe-powerstroke-interpolators.h index f080b06e6..3cde0b4b3 100644 --- a/src/live_effects/lpe-powerstroke-interpolators.h +++ b/src/live_effects/lpe-powerstroke-interpolators.h @@ -28,7 +28,8 @@ enum InterpolatorType { INTERP_CUBICBEZIER, INTERP_CUBICBEZIER_JOHAN, INTERP_SPIRO, - INTERP_CUBICBEZIER_SMOOTH + INTERP_CUBICBEZIER_SMOOTH, + INTERP_CENTRIPETAL_CATMULLROM }; class Interpolator { @@ -206,7 +207,88 @@ private: }; -Interpolator* +// Quick mockup for testing the behavior for powerstroke controlpoint interpolation +class CentripetalCatmullRomInterpolator : public Interpolator { +public: + CentripetalCatmullRomInterpolator() {}; + virtual ~CentripetalCatmullRomInterpolator() {}; + + virtual Path interpolateToPath(std::vector<Point> const &points) const { + unsigned int n_points = points.size(); + + Geom::Path fit(points.front()); + + if (n_points < 3) return fit; // TODO special cases for 0,1 and 2 input points + + // return n_points-1 cubic segments + + // duplicate first point + fit.append(calc_bezier(points[0],points[0],points[1],points[2])); + + for (std::size_t i = 0; i < n_points-2; ++i) { + Point p0 = points[i]; + Point p1 = points[i+1]; + Point p2 = points[i+2]; + Point p3 = (i < n_points-3) ? points[i+3] : points[i+2]; + + fit.append(calc_bezier(p0, p1, p2, p3)); + } + + return fit; + }; + +private: + CubicBezier calc_bezier(Point p0, Point p1, Point p2, Point p3) const { + // create interpolating bezier between p1 and p2 + + // Part of the code comes from StackOverflow user eriatarka84 + // http://stackoverflow.com/a/23980479/2929337 + + // calculate time coords (deltas) of points + // the factor 0.25 can be generalized for other Catmull-Rom interpolation types + // see alpha in Yuksel et al. "On the Parameterization of Catmull-Rom Curves", + // --> http://www.cemyuksel.com/research/catmullrom_param/catmullrom.pdf + double dt0 = powf(distanceSq(p0, p1), 0.25); + double dt1 = powf(distanceSq(p1, p2), 0.25); + double dt2 = powf(distanceSq(p2, p3), 0.25); + + + // safety check for repeated points + double eps = Geom::EPSILON; + if (dt1 < eps) + dt1 = 1.0; + if (dt0 < eps) + dt0 = dt1; + if (dt2 < eps) + dt2 = dt1; + + // compute tangents when parameterized in [t1,t2] + Point tan1 = (p1 - p0) / dt0 - (p2 - p0) / (dt0 + dt1) + (p2 - p1) / dt1; + Point tan2 = (p2 - p1) / dt1 - (p3 - p1) / (dt1 + dt2) + (p3 - p2) / dt2; + // rescale tangents for parametrization in [0,1] + tan1 *= dt1; + tan2 *= dt1; + + // create bezier from tangents (this is already in 2geom somewhere, or should be moved to it) + // the tangent of a bezier curve is: B'(t) = 3(1-t)^2 (b1 - b0) + 6(1-t)t(b2-b1) + 3t^2(b3-b2) + // So we have to make sure that B'(0) = tan1 and B'(1) = tan2, and we already know that b0=p1 and b3=p2 + // tan1 = B'(0) = 3 (b1 - p1) --> p1 + (tan1)/3 = b1 + // tan2 = B'(1) = 3 (p2 - b2) --> p2 - (tan2)/3 = b2 + + Point b0 = p1; + Point b1 = p1 + tan1 / 3; + Point b2 = p2 - tan2 / 3; + Point b3 = p2; + + return CubicBezier(b0, b1, b2, b3); + } + + CentripetalCatmullRomInterpolator(const CentripetalCatmullRomInterpolator&); + CentripetalCatmullRomInterpolator& operator=(const CentripetalCatmullRomInterpolator&); +}; + + +inline Interpolator* Interpolator::create(InterpolatorType type) { switch (type) { case INTERP_LINEAR: @@ -219,6 +301,8 @@ Interpolator::create(InterpolatorType type) { return new Geom::Interpolate::SpiroInterpolator(); case INTERP_CUBICBEZIER_SMOOTH: return new Geom::Interpolate::CubicBezierSmooth(); + case INTERP_CENTRIPETAL_CATMULLROM: + return new Geom::Interpolate::CentripetalCatmullRomInterpolator(); default: return new Geom::Interpolate::Linear(); } diff --git a/src/live_effects/lpe-powerstroke.cpp b/src/live_effects/lpe-powerstroke.cpp index f7516677d..b1951d978 100644 --- a/src/live_effects/lpe-powerstroke.cpp +++ b/src/live_effects/lpe-powerstroke.cpp @@ -194,7 +194,8 @@ static const Util::EnumData<unsigned> InterpolatorTypeData[] = { {Geom::Interpolate::INTERP_LINEAR , N_("Linear"), "Linear"}, {Geom::Interpolate::INTERP_CUBICBEZIER , N_("CubicBezierFit"), "CubicBezierFit"}, {Geom::Interpolate::INTERP_CUBICBEZIER_JOHAN , N_("CubicBezierJohan"), "CubicBezierJohan"}, - {Geom::Interpolate::INTERP_SPIRO , N_("SpiroInterpolator"), "SpiroInterpolator"} + {Geom::Interpolate::INTERP_SPIRO , N_("SpiroInterpolator"), "SpiroInterpolator"}, + {Geom::Interpolate::INTERP_CENTRIPETAL_CATMULLROM, N_("Centripetal Catmull-Rom"), "CentripetalCatmullRom"} }; static const Util::EnumDataConverter<unsigned> InterpolatorTypeConverter(InterpolatorTypeData, sizeof(InterpolatorTypeData)/sizeof(*InterpolatorTypeData)); diff --git a/src/live_effects/lpe-roughen.cpp b/src/live_effects/lpe-roughen.cpp index 9af849530..5f6acd6f4 100644 --- a/src/live_effects/lpe-roughen.cpp +++ b/src/live_effects/lpe-roughen.cpp @@ -2,9 +2,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <gtkmm.h> - #include "live_effects/lpe-roughen.h" +#include <gtkmm/separator.h> + #include "display/curve.h" #include "live_effects/parameter/parameter.h" #include "helper/geom.h" @@ -82,7 +82,11 @@ Gtk::Widget *LPERoughen::newWidget() { Glib::ustring(_("<b>Roughen unit</b>")), Gtk::ALIGN_START)); unitLabel->set_use_markup(true); vbox->pack_start(*unitLabel, false, false, 2); +#if WITH_GTKMM_3_0 + vbox->pack_start(*Gtk::manage(new Gtk::Separator()), +#else vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), +#endif Gtk::PACK_EXPAND_WIDGET); } if (param->param_key == "method") { @@ -91,7 +95,11 @@ Gtk::Widget *LPERoughen::newWidget() { Gtk::ALIGN_START)); methodLabel->set_use_markup(true); vbox->pack_start(*methodLabel, false, false, 2); +#if WITH_GTKMM_3_0 + vbox->pack_start(*Gtk::manage(new Gtk::Separator()), +#else vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), +#endif Gtk::PACK_EXPAND_WIDGET); } if (param->param_key == "displaceX") { @@ -100,7 +108,11 @@ Gtk::Widget *LPERoughen::newWidget() { Gtk::ALIGN_START)); displaceXLabel->set_use_markup(true); vbox->pack_start(*displaceXLabel, false, false, 2); +#if WITH_GTKMM_3_0 + vbox->pack_start(*Gtk::manage(new Gtk::Separator()), +#else vbox->pack_start(*Gtk::manage(new Gtk::HSeparator()), +#endif Gtk::PACK_EXPAND_WIDGET); } Glib::ustring *tip = param->param_getTooltip(); diff --git a/src/live_effects/lpeobject-reference.h b/src/live_effects/lpeobject-reference.h index b1ba1ee4e..374e715ec 100644 --- a/src/live_effects/lpeobject-reference.h +++ b/src/live_effects/lpeobject-reference.h @@ -9,10 +9,10 @@ * Released under GNU GPL, read the file 'COPYING' for more information. */ -#include <uri-references.h> -#include <stddef.h> #include <sigc++/sigc++.h> +#include "uri-references.h" + namespace Inkscape { namespace XML { class Node; @@ -33,7 +33,7 @@ public: SPObject *owner; // concerning the LPEObject that is refered to: - gchar *lpeobject_href; + char *lpeobject_href; Inkscape::XML::Node *lpeobject_repr; LivePathEffectObject *lpeobject; diff --git a/src/live_effects/lpeobject.h b/src/live_effects/lpeobject.h index 9700024fe..2e62707e3 100644 --- a/src/live_effects/lpeobject.h +++ b/src/live_effects/lpeobject.h @@ -47,9 +47,9 @@ protected: virtual void build(SPDocument* doc, Inkscape::XML::Node* repr); virtual void release(); - virtual void set(unsigned int key, const gchar* value); + virtual void set(unsigned int key, char const* value); - virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, guint flags); + virtual Inkscape::XML::Node* write(Inkscape::XML::Document* doc, Inkscape::XML::Node* repr, unsigned int flags); }; #endif diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp index 47cdd27cc..1a32e04e7 100644 --- a/src/live_effects/parameter/filletchamferpointarray.cpp +++ b/src/live_effects/parameter/filletchamferpointarray.cpp @@ -8,13 +8,13 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ +#include "ui/dialog/lpe-fillet-chamfer-properties.h" +#include "live_effects/parameter/filletchamferpointarray.h" #include <2geom/piecewise.h> #include <2geom/sbasis-to-bezier.h> #include <2geom/sbasis-geometric.h> #include <gtkmm.h> -#include "ui/dialog/lpe-fillet-chamfer-properties.h" -#include "live_effects/parameter/filletchamferpointarray.h" #include "live_effects/effect.h" #include "svg/svg.h" #include "svg/stringstream.h" diff --git a/src/live_effects/parameter/togglebutton.cpp b/src/live_effects/parameter/togglebutton.cpp index 5658d238f..c5da8b858 100644 --- a/src/live_effects/parameter/togglebutton.cpp +++ b/src/live_effects/parameter/togglebutton.cpp @@ -5,10 +5,9 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ -#include <gtkmm.h> +#include "ui/widget/registered-widget.h" #include <glibmm/i18n.h> -#include "ui/widget/registered-widget.h" #include "live_effects/parameter/togglebutton.h" #include "live_effects/effect.h" #include "svg/svg.h" @@ -75,7 +74,12 @@ ToggleButtonParam::param_newWidget() false, param_effect->getRepr(), param_effect->getSPDoc()) ); +#if GTK_CHECK_VERSION(3,0,0) + GtkWidget * boxButton = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_set_homogeneous(GTK_BOX(boxButton), false); +#else GtkWidget * boxButton = gtk_hbox_new (false, 0); +#endif GtkWidget * labelButton = gtk_label_new (""); if (!param_label.empty()) { if(value || inactiveLabel.empty()){ |
