summaryrefslogtreecommitdiffstats
path: root/src/live_effects
diff options
context:
space:
mode:
authorLiam P. White <inkscapebrony@gmail.com>2014-08-30 15:49:40 +0000
committerLiam P. White <inkscapebrony@gmail.com>2014-08-30 15:49:40 +0000
commit18770eebe339cdc673812a48c5e05c7cdcb3a82e (patch)
tree1e3846a72decad64d24100cdbe0a2e0d42f252b8 /src/live_effects
parentUpdate to experimental r13464 (diff)
parentFix paint-selector orientation (diff)
downloadinkscape-18770eebe339cdc673812a48c5e05c7cdcb3a82e.tar.gz
inkscape-18770eebe339cdc673812a48c5e05c7cdcb3a82e.zip
Update to experimental r13527
(bzr r13341.5.15)
Diffstat (limited to 'src/live_effects')
-rw-r--r--src/live_effects/CMakeLists.txt2
-rw-r--r--src/live_effects/Makefile_insert4
-rw-r--r--src/live_effects/effect-enum.h2
-rw-r--r--src/live_effects/effect.cpp13
-rw-r--r--src/live_effects/lpe-bspline.cpp21
-rw-r--r--src/live_effects/lpe-envelope-perspective.cpp18
-rw-r--r--src/live_effects/lpe-interpolate_points.cpp94
-rw-r--r--src/live_effects/lpe-interpolate_points.h51
-rw-r--r--src/live_effects/lpe-perspective_path.cpp106
-rw-r--r--src/live_effects/lpe-perspective_path.h3
-rw-r--r--src/live_effects/lpe-powerstroke-interpolators.h88
-rw-r--r--src/live_effects/lpe-powerstroke.cpp3
-rw-r--r--src/live_effects/lpe-roughen.cpp16
-rw-r--r--src/live_effects/lpe-show_handles.cpp211
-rw-r--r--src/live_effects/lpe-show_handles.h61
-rw-r--r--src/live_effects/lpe-simplify.cpp56
-rw-r--r--src/live_effects/parameter/filletchamferpointarray.cpp86
-rw-r--r--src/live_effects/parameter/parameter.cpp8
-rw-r--r--src/live_effects/parameter/parameter.h2
-rw-r--r--src/live_effects/parameter/togglebutton.cpp8
20 files changed, 756 insertions, 97 deletions
diff --git a/src/live_effects/CMakeLists.txt b/src/live_effects/CMakeLists.txt
index 3c64e5c8e..d126aca9f 100644
--- a/src/live_effects/CMakeLists.txt
+++ b/src/live_effects/CMakeLists.txt
@@ -31,6 +31,7 @@ set(live_effects_SRC
lpe-recursiveskeleton.cpp
lpe-rough-hatches.cpp
lpe-ruler.cpp
+ lpe-show_handles.cpp
lpe-simplify.cpp
# lpe-skeleton.cpp
lpe-sketch.cpp
@@ -99,6 +100,7 @@ set(live_effects_SRC
lpe-rough-hatches.h
lpe-ruler.h
lpe-simplify.h
+ lpe-show_handles.h
lpe-skeleton.h
lpe-sketch.h
lpe-spiro.h
diff --git a/src/live_effects/Makefile_insert b/src/live_effects/Makefile_insert
index 91651a7c8..1b8f587e1 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 \
@@ -48,6 +50,8 @@ ink_common_sources += \
live_effects/lpe-lattice2.h \
live_effects/lpe-roughen.cpp \
live_effects/lpe-roughen.h \
+ live_effects/lpe-show_handles.cpp \
+ live_effects/lpe-show_handles.h \
live_effects/lpe-simplify.cpp \
live_effects/lpe-simplify.h \
live_effects/lpe-envelope.cpp \
diff --git a/src/live_effects/effect-enum.h b/src/live_effects/effect-enum.h
index dac44981c..30dbf4092 100644
--- a/src/live_effects/effect-enum.h
+++ b/src/live_effects/effect-enum.h
@@ -30,6 +30,7 @@ enum EffectType {
LATTICE,
LATTICE2,
ROUGHEN,
+ SHOW_HANDLES,
SIMPLIFY,
ENVELOPE,
CONSTRUCT_GRID,
@@ -44,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 5a9b6c7a2..b012e3ab1 100644
--- a/src/live_effects/effect.cpp
+++ b/src/live_effects/effect.cpp
@@ -28,6 +28,7 @@
#include "live_effects/lpe-lattice.h"
#include "live_effects/lpe-lattice2.h"
#include "live_effects/lpe-roughen.h"
+#include "live_effects/lpe-show_handles.h"
#include "live_effects/lpe-simplify.h"
#include "live_effects/lpe-envelope.h"
#include "live_effects/lpe-constructgrid.h"
@@ -42,6 +43,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"
@@ -126,13 +128,16 @@ const Util::EnumData<EffectType> LPETypeData[] = {
/* 0.91 */
{POWERSTROKE, N_("Power stroke"), "powerstroke"},
{CLONE_ORIGINAL, N_("Clone original path"), "clone_original"},
- {ROUGHEN, N_("Roughen"), "roughen"},
+/* EXPERIMENTAL */
+ {SHOW_HANDLES, N_("Show handles"), "show_handles"},
+ {ROUGHEN, N_("Roughen"), "roughen"},
{BSPLINE, N_("BSpline"), "bspline"},
{SIMPLIFY, N_("Simplify"), "simplify"},
{LATTICE2, N_("Lattice Deformation 2"), "lattice2"},
// TRANSLATORS: "Envelope Perspective" should be equivalent to "perspective transformation"
{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));
@@ -229,6 +234,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;
@@ -274,6 +282,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj)
case ROUGHEN:
neweffect = static_cast<Effect*> ( new LPERoughen(lpeobj) );
break;
+ case SHOW_HANDLES:
+ neweffect = static_cast<Effect*> ( new LPEShowHandles(lpeobj) );
+ break;
default:
g_warning("LivePathEffect::Effect::New called with invalid patheffect type (%d)", lpenr);
neweffect = NULL;
diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp
index 0a5d8eca5..3a6dca795 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-envelope-perspective.cpp b/src/live_effects/lpe-envelope-perspective.cpp
index d9bf20752..6d3441d93 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-perspective_path.cpp b/src/live_effects/lpe-perspective_path.cpp
index a7748c5a8..fb5ac5363 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:
@@ -60,8 +63,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(SP_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 +87,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 +146,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 +194,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 6f5b75af8..986bd3544 100644
--- a/src/live_effects/lpe-powerstroke-interpolators.h
+++ b/src/live_effects/lpe-powerstroke-interpolators.h
@@ -27,7 +27,8 @@ enum InterpolatorType {
INTERP_LINEAR,
INTERP_CUBICBEZIER,
INTERP_CUBICBEZIER_JOHAN,
- INTERP_SPIRO
+ INTERP_SPIRO,
+ INTERP_CENTRIPETAL_CATMULLROM
};
class Interpolator {
@@ -168,7 +169,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:
@@ -179,6 +261,8 @@ Interpolator::create(InterpolatorType type) {
return new Geom::Interpolate::CubicBezierJohan();
case INTERP_SPIRO:
return new Geom::Interpolate::SpiroInterpolator();
+ 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 90b01aaa4..5bfe88ed1 100644
--- a/src/live_effects/lpe-powerstroke.cpp
+++ b/src/live_effects/lpe-powerstroke.cpp
@@ -188,7 +188,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/lpe-show_handles.cpp b/src/live_effects/lpe-show_handles.cpp
new file mode 100644
index 000000000..7b2b445b7
--- /dev/null
+++ b/src/live_effects/lpe-show_handles.cpp
@@ -0,0 +1,211 @@
+/*
+ * Authors:
+ * Jabier Arraiza Cenoz
+*
+* Copyright (C) Jabier Arraiza Cenoz 2014 <jabier.arraiza@marker.es>
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtkmm.h>
+#include <glibmm/i18n.h>
+#include "live_effects/lpe-show_handles.h"
+#include "live_effects/parameter/parameter.h"
+#include <2geom/sbasis-to-bezier.h>
+#include <2geom/svg-path-parser.h>
+#include "helper/geom.h"
+#include "desktop-style.h"
+#include "style.h"
+#include "svg/svg.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+LPEShowHandles::LPEShowHandles(LivePathEffectObject *lpeobject)
+ : Effect(lpeobject),
+ nodes(_("Show nodes"), _("Show nodes"), "nodes", &wr, this, true),
+ handles(_("Show handles"), _("Show handles"), "handles", &wr, this, true),
+ originalPath(_("Show path"), _("Show path"), "originalPath", &wr, this, true),
+ scaleNodesAndHandles(_("Scale nodes and handles"), _("Scale nodes and handles"), "scaleNodesAndHandles", &wr, this, 10)
+{
+ registerParameter(dynamic_cast<Parameter *>(&nodes));
+ registerParameter(dynamic_cast<Parameter *>(&handles));
+ registerParameter(dynamic_cast<Parameter *>(&originalPath));
+ registerParameter(dynamic_cast<Parameter *>(&scaleNodesAndHandles));
+ scaleNodesAndHandles.param_set_range(0, 500.);
+ scaleNodesAndHandles.param_set_increments(1, 1);
+ scaleNodesAndHandles.param_set_digits(2);
+ strokeWidth = 1.0;
+}
+
+bool LPEShowHandles::alertsOff = false;
+
+/**
+ * Sets default styles to element
+ * this permanently remove.some styles of the element
+ */
+
+void LPEShowHandles::doOnApply(SPLPEItem const* lpeitem)
+{
+ if(!alertsOff) {
+ char *msg = _("The \"show handles\" path effect will remove any custom style on the object you are applying it to. If this is not what you want, click Cancel.");
+ Gtk::MessageDialog dialog(msg, false, Gtk::MESSAGE_QUESTION, Gtk::BUTTONS_OK_CANCEL, true);
+ gint response = dialog.run();
+ alertsOff = true;
+ if(response == GTK_RESPONSE_CANCEL) {
+ SPLPEItem* item = const_cast<SPLPEItem*>(lpeitem);
+ item->removeCurrentPathEffect(false);
+ return;
+ }
+ }
+ SPLPEItem* item = const_cast<SPLPEItem*>(lpeitem);
+ SPCSSAttr *css = sp_repr_css_attr_new ();
+ sp_repr_css_set_property (css, "stroke", "black");
+ sp_repr_css_set_property (css, "stroke-width", "1");
+ sp_repr_css_set_property (css, "stroke-linecap", "butt");
+ sp_repr_css_set_property(css, "fill", "none");
+
+ sp_desktop_apply_css_recursive(item, css, true);
+ sp_repr_css_attr_unref (css);
+}
+
+void LPEShowHandles::doBeforeEffect (SPLPEItem const* lpeitem)
+{
+ SPItem const* item = SP_ITEM(lpeitem);
+ strokeWidth = item->style->stroke_width.computed;
+}
+
+std::vector<Geom::Path> LPEShowHandles::doEffect_path (std::vector<Geom::Path> const & path_in)
+{
+ std::vector<Geom::Path> path_out;
+ Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in);
+ if(originalPath) {
+ for (unsigned int i=0; i < path_in.size(); i++) {
+ path_out.push_back(path_in[i]);
+ }
+ }
+ if(!outlinepath.empty()) {
+ outlinepath.clear();
+ }
+ generateHelperPath(original_pathv);
+ for (unsigned int i=0; i < outlinepath.size(); i++) {
+ path_out.push_back(outlinepath[i]);
+ }
+ return path_out;
+}
+
+void
+LPEShowHandles::generateHelperPath(Geom::PathVector result)
+{
+ if(!handles && !nodes) {
+ return;
+ }
+
+ Geom::CubicBezier const *cubic = NULL;
+ for (Geom::PathVector::iterator path_it = result.begin(); path_it != result.end(); ++path_it) {
+ //Si está vacío...
+ if (path_it->empty()) {
+ continue;
+ }
+ //Itreadores
+ Geom::Path::const_iterator curve_it1 = path_it->begin(); // incoming curve
+ Geom::Path::const_iterator curve_it2 = ++(path_it->begin()); // outgoing curve
+ Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop
+
+ if (path_it->closed()) {
+ // if the path is closed, maybe we have to stop a bit earlier because the
+ // closing line segment has zerolength.
+ const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type
+ // Geom::LineSegment.
+ if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
+ // closingline.isDegenerate() did not work, because it only checks for
+ // *exact* zero length, which goes wrong for relative coordinates and
+ // rounding errors...
+ // the closing line segment has zero-length. So stop before that one!
+ curve_endit = path_it->end_open();
+ }
+ }
+ if(nodes) {
+ drawNode(curve_it1->initialPoint());
+ }
+ while (curve_it1 != curve_endit) {
+ cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
+ if (cubic) {
+ if(handles) {
+ if(!are_near((*cubic)[0],(*cubic)[1])){
+ drawHandle((*cubic)[1]);
+ drawHandleLine((*cubic)[0],(*cubic)[1]);
+ }
+ if(!are_near((*cubic)[3],(*cubic)[2])){
+ drawHandle((*cubic)[2]);
+ drawHandleLine((*cubic)[3],(*cubic)[2]);
+ }
+ }
+ }
+ if(nodes) {
+ drawNode(curve_it1->finalPoint());
+ }
+ ++curve_it1;
+ if(curve_it2 != curve_endit){
+ ++curve_it2;
+ }
+ }
+ }
+}
+
+void
+LPEShowHandles::drawNode(Geom::Point p)
+{
+ if(strokeWidth * scaleNodesAndHandles > 0.0) {
+ double diameter = strokeWidth * scaleNodesAndHandles;
+ char const * svgd;
+ svgd = "M 0.55,0.5 A 0.05,0.05 0 0 1 0.5,0.55 0.05,0.05 0 0 1 0.45,0.5 0.05,0.05 0 0 1 0.5,0.45 0.05,0.05 0 0 1 0.55,0.5 Z M 0,0 1,0 1,1 0,1 Z";
+ Geom::PathVector pathv = sp_svg_read_pathv(svgd);
+ pathv *= Geom::Affine(diameter,0,0,diameter,0,0);
+ pathv += p - Geom::Point(diameter/2,diameter/2);
+ outlinepath.push_back(pathv[0]);
+ outlinepath.push_back(pathv[1]);
+ }
+}
+
+void
+LPEShowHandles::drawHandle(Geom::Point p)
+{
+ if(strokeWidth * scaleNodesAndHandles > 0.0) {
+ double diameter = strokeWidth * scaleNodesAndHandles;
+ char const * svgd;
+ svgd = "M 0.7,0.35 A 0.35,0.35 0 0 1 0.35,0.7 0.35,0.35 0 0 1 0,0.35 0.35,0.35 0 0 1 0.35,0 0.35,0.35 0 0 1 0.7,0.35 Z";
+ Geom::PathVector pathv = sp_svg_read_pathv(svgd);
+ pathv *= Geom::Affine(diameter,0,0,diameter,0,0);
+ pathv += p - Geom::Point(diameter * 0.35,diameter * 0.35);
+ outlinepath.push_back(pathv[0]);
+ }
+}
+
+
+void
+LPEShowHandles::drawHandleLine(Geom::Point p,Geom::Point p2)
+{
+ Geom::Path path;
+ double diameter = strokeWidth * scaleNodesAndHandles;
+ if(diameter > 0.0 && Geom::distance(p,p2) > (diameter * 0.35)){
+ Geom::Ray ray2(p, p2);
+ p2 = p2 - Geom::Point::polar(ray2.angle(),(diameter * 0.35));
+ }
+ path.start( p );
+ path.appendNew<Geom::LineSegment>( p2 );
+ outlinepath.push_back(path);
+}
+
+}; //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-show_handles.h b/src/live_effects/lpe-show_handles.h
new file mode 100644
index 000000000..278908bb5
--- /dev/null
+++ b/src/live_effects/lpe-show_handles.h
@@ -0,0 +1,61 @@
+#ifndef INKSCAPE_LPE_SHOW_HANDLES_H
+#define INKSCAPE_LPE_SHOW_HANDLES_H
+
+/*
+ * Authors:
+ * Jabier Arraiza Cenoz
+*
+* Copyright (C) Jabier Arraiza Cenoz 2014 <jabier.arraiza@marker.es>
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include "live_effects/effect.h"
+#include "live_effects/lpegroupbbox.h"
+#include "live_effects/parameter/bool.h"
+
+namespace Inkscape {
+namespace LivePathEffect {
+
+class LPEShowHandles : public Effect , GroupBBoxEffect {
+
+public:
+ LPEShowHandles(LivePathEffectObject *lpeobject);
+ virtual ~LPEShowHandles(){}
+
+ virtual void doOnApply(SPLPEItem const* lpeitem);
+
+ virtual void doBeforeEffect (SPLPEItem const* lpeitem);
+
+ virtual void generateHelperPath(Geom::PathVector result);
+
+ virtual void drawNode(Geom::Point p);
+
+ virtual void drawHandle(Geom::Point p);
+
+ virtual void drawHandleLine(Geom::Point p,Geom::Point p2);
+
+protected:
+
+ virtual std::vector<Geom::Path> doEffect_path (std::vector<Geom::Path> const & path_in);
+
+private:
+
+ BoolParam nodes;
+ BoolParam handles;
+ BoolParam originalPath;
+ ScalarParam scaleNodesAndHandles;
+ double strokeWidth;
+ static bool alertsOff;
+
+ Geom::PathVector outlinepath;
+
+ LPEShowHandles(const LPEShowHandles &);
+ LPEShowHandles &operator=(const LPEShowHandles &);
+
+};
+
+}; //namespace LivePathEffect
+}; //namespace Inkscape
+#endif
+
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/live_effects/lpe-simplify.cpp b/src/live_effects/lpe-simplify.cpp
index 1a02375cd..a817f30f1 100644
--- a/src/live_effects/lpe-simplify.cpp
+++ b/src/live_effects/lpe-simplify.cpp
@@ -202,33 +202,27 @@ LPESimplify::generateHelperPath(Geom::PathVector result)
if(nodes){
drawNode(curve_it1->initialPoint());
}
- while (curve_it2 != curve_endit) {
- cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
- if (cubic) {
- if(handles){
- drawHandle((*cubic)[1]);
- drawHandle((*cubic)[2]);
- drawHandleLine((*cubic)[0],(*cubic)[1]);
- drawHandleLine((*cubic)[2],(*cubic)[3]);
+ while (curve_it1 != curve_endit) {
+ cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
+ if (cubic) {
+ if(handles) {
+ if(!are_near((*cubic)[0],(*cubic)[1])){
+ drawHandle((*cubic)[1]);
+ drawHandleLine((*cubic)[0],(*cubic)[1]);
+ }
+ if(!are_near((*cubic)[3],(*cubic)[2])){
+ drawHandle((*cubic)[2]);
+ drawHandleLine((*cubic)[3],(*cubic)[2]);
+ }
+ }
+ }
+ if(nodes) {
+ drawNode(curve_it1->finalPoint());
+ }
+ ++curve_it1;
+ if(curve_it2 != curve_endit){
+ ++curve_it2;
}
- }
- if(nodes){
- drawNode(curve_it1->finalPoint());
- }
- ++curve_it1;
- ++curve_it2;
- }
- cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
- if (cubic) {
- if(handles){
- drawHandle((*cubic)[1]);
- drawHandle((*cubic)[2]);
- drawHandleLine((*cubic)[0],(*cubic)[1]);
- drawHandleLine((*cubic)[2],(*cubic)[3]);
- }
- }
- if(nodes){
- drawNode(curve_it1->finalPoint());
}
}
}
@@ -238,13 +232,12 @@ LPESimplify::drawNode(Geom::Point p)
{
double r = helper_size/0.67;
char const * svgd;
- svgd = "M 0.999993,0.5 C 1.000065,0.7757576 0.7761859,1 0.4999926,1 0.2237994,1 -7.933901e-5,0.7757576 -7.339015e-6,0.5 -7.933901e-5,0.2242424 0.2237994,0 0.4999926,0 0.7761859,0 1.000065,0.2242424 0.999993,0.5 Z m -0.058561,0 C 0.9414949,0.74327 0.7438375,0.9416286 0.4999928,0.9416286 0.2561481,0.9416286 0.0584908,0.74327 0.0585543,0.5 0.0584908,0.25673 0.2561481,0.0583714 0.4999928,0.0583714 0.7438375,0.0583714 0.9414949,0.25673 0.9414313,0.5 Z m -0.3828447,0 c 8.5e-6,0.030303 -0.026228,0.060606 -0.058593,0.060606 -0.032366,0 -0.058603,-0.030303 -0.058593,-0.060606 -8.5e-6,-0.030303 0.026227,-0.060606 0.058593,-0.060606 0.032366,0 0.058603,0.030303 0.058593,0.060606 z";
+ svgd = "M 0.55,0.5 A 0.05,0.05 0 0 1 0.5,0.55 0.05,0.05 0 0 1 0.45,0.5 0.05,0.05 0 0 1 0.5,0.45 0.05,0.05 0 0 1 0.55,0.5 Z M 0,0 1,0 1,1 0,1 Z";
Geom::PathVector pathv = sp_svg_read_pathv(svgd);
pathv *= Geom::Affine(r,0,0,r,0,0);
pathv += p - Geom::Point(0.5*r,0.5*r);
hp.push_back(pathv[0]);
hp.push_back(pathv[1]);
- hp.push_back(pathv[2]);
}
void
@@ -252,7 +245,7 @@ LPESimplify::drawHandle(Geom::Point p)
{
double r = helper_size/0.67;
char const * svgd;
- svgd = "M 0.6999623,0.35 C 0.7000128,0.5430303 0.5433044,0.7 0.3499775,0.7 0.1566506,0.7 -5.778776e-5,0.5430303 -7.344202e-6,0.35 -5.778776e-5,0.1569697 0.1566506,0 0.3499775,0 0.5433044,0 0.7000128,0.1569697 0.6999623,0.35 Z";
+ svgd = "M 0.7,0.35 A 0.35,0.35 0 0 1 0.35,0.7 0.35,0.35 0 0 1 0,0.35 0.35,0.35 0 0 1 0.35,0 0.35,0.35 0 0 1 0.7,0.35 Z";
Geom::PathVector pathv = sp_svg_read_pathv(svgd);
pathv *= Geom::Affine(r,0,0,r,0,0);
pathv += p - Geom::Point(0.35*r,0.35*r);
@@ -265,6 +258,11 @@ LPESimplify::drawHandleLine(Geom::Point p,Geom::Point p2)
{
Geom::Path path;
path.start( p );
+ double diameter = helper_size/0.67;
+ if(helper_size > 0.0 && Geom::distance(p,p2) > (diameter * 0.35)){
+ Geom::Ray ray2(p, p2);
+ p2 = p2 - Geom::Point::polar(ray2.angle(),(diameter * 0.35));
+ }
path.appendNew<Geom::LineSegment>( p2 );
hp.push_back(path);
}
diff --git a/src/live_effects/parameter/filletchamferpointarray.cpp b/src/live_effects/parameter/filletchamferpointarray.cpp
index 457b68dd2..a89a6279b 100644
--- a/src/live_effects/parameter/filletchamferpointarray.cpp
+++ b/src/live_effects/parameter/filletchamferpointarray.cpp
@@ -8,12 +8,12 @@
* 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 "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"
@@ -332,10 +332,10 @@ void FilletChamferPointArrayParam::recalculate_knots(
result.push_back(Point(xPos, 0));
}
++curve_it1;
- ++curve_it2;
if (curve_it2 != curve_endit) {
- counter++;
+ ++curve_it2;
}
+ counter++;
counterCurves++;
}
}
@@ -552,31 +552,40 @@ Point FilletChamferPointArrayParamKnotHolderEntity::knot_get() const
void FilletChamferPointArrayParamKnotHolderEntity::knot_click(guint state)
{
if (state & GDK_CONTROL_MASK) {
- using namespace Geom;
- double type = _pparam->_vector.at(_index)[Y] + 1;
- if (type > 4) {
- type = 1;
- }
- _pparam->_vector.at(_index) = Point(_pparam->_vector.at(_index)[X], type);
- _pparam->param_set_and_write_new_value(_pparam->_vector);
- sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false);
- const gchar *tip;
- if (type == 3) {
- tip = _("<b>Chamfer</b>: <b>Ctrl+click</b> toogle type, "
- "<b>Shift+click</b> open dialog");
- } else if (type == 2) {
- tip = _("<b>Inverse Fillet</b>: <b>Ctrl+click</b> toogle type, "
- "<b>Shift+click</b> open dialog");
- } else if (type == 1) {
- tip = _("<b>Fillet</b>: <b>Ctrl+click</b> toogle type, "
- "<b>Shift+click</b> open dialog");
- } else {
- tip = _("<b>Double Chamfer</b>: <b>Ctrl+click</b> toogle type, "
- "<b>Shift+click</b> open dialog");
+ if (state & GDK_MOD1_MASK) {
+ _pparam->_vector.at(_index) = Point(_index, _pparam->_vector.at(_index)[Y]);
+ _pparam->param_set_and_write_new_value(_pparam->_vector);
+ sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false);
+ }else{
+ using namespace Geom;
+ double type = _pparam->_vector.at(_index)[Y] + 1;
+ if (type > 4) {
+ type = 1;
+ }
+ _pparam->_vector.at(_index) = Point(_pparam->_vector.at(_index)[X], type);
+ _pparam->param_set_and_write_new_value(_pparam->_vector);
+ sp_lpe_item_update_patheffect(SP_LPE_ITEM(item), false, false);
+ const gchar *tip;
+ if (type == 3) {
+ tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toogle type, "
+ "<b>Shift+Click</b> open dialog, "
+ "<b>Ctrl+Alt+Click</b> reset");
+ } else if (type == 2) {
+ tip = _("<b>Inverse Fillet</b>: <b>Ctrl+Click</b> toogle type, "
+ "<b>Shift+Click</b> open dialog, "
+ "<b>Ctrl+Alt+Click</b> reset");
+ } else if (type == 1) {
+ tip = _("<b>Fillet</b>: <b>Ctrl+Click</b> toogle type, "
+ "<b>Shift+Click</b> open dialog, "
+ "<b>Ctrl+Alt+Click</b> reset");
+ } else {
+ tip = _("<b>Double Chamfer</b>: <b>Ctrl+Click</b> toogle type, "
+ "<b>Shift+Click</b> open dialog, "
+ "<b>Ctrl+Alt+Click</b> reset");
+ }
+ this->knot->tip = g_strdup(tip);
+ this->knot->show();
}
- this->knot->tip = g_strdup(tip);
- this->knot->show();
- //}
} else if ((state & GDK_MOD1_MASK) || (state & GDK_SHIFT_MASK)) {
Geom::Point offset = Geom::Point(_pparam->_vector.at(_index).x(),
_pparam->_vector.at(_index).y());
@@ -619,18 +628,23 @@ void FilletChamferPointArrayParam::addKnotHolderEntities(KnotHolder *knotholder,
}
const gchar *tip;
if (_vector[i][Y] == 3) {
- tip = _("<b>Chamfer</b>: <b>Ctrl+click</b> toogle type, "
- "<b>Shift+click</b> open dialog");
+ tip = _("<b>Chamfer</b>: <b>Ctrl+Click</b> toogle type, "
+ "<b>Shift+Click</b> open dialog, "
+ "<b>Ctrl+Alt+Click</b> reset");
} else if (_vector[i][Y] == 2) {
- tip = _("<b>Inverse Fillet</b>: <b>Ctrl+click</b> toogle type, "
- "<b>Shift+click</b> open dialog");
+ tip = _("<b>Inverse Fillet</b>: <b>Ctrl+Click</b> toogle type, "
+ "<b>Shift+Click</b> open dialog, "
+ "<b>Ctrl+Alt+Click</b> reset");
} else if (_vector[i][Y] == 1) {
- tip = _("<b>Fillet</b>: <b>Ctrl+click</b> toogle type, "
- "<b>Shift+click</b> open dialog");
+ tip = _("<b>Fillet</b>: <b>Ctrl+Click</b> toogle type, "
+ "<b>Shift+Click</b> open dialog, "
+ "<b>Ctrl+Alt+Click</b> reset");
} else {
- tip = _("<b>Double Chamfer</b>: <b>Ctrl+click</b> toogle type, "
- "<b>Shift+click</b> open dialog");
+ tip = _("<b>Double Chamfer</b>: <b>Ctrl+Click</b> toogle type, "
+ "<b>Shift+Click</b> open dialog, "
+ "<b>Ctrl+Alt+Click</b> reset");
}
+
FilletChamferPointArrayParamKnotHolderEntity *e =
new FilletChamferPointArrayParamKnotHolderEntity(this, i);
e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _(tip),
diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp
index 7732eee76..7a2fd9769 100644
--- a/src/live_effects/parameter/parameter.cpp
+++ b/src/live_effects/parameter/parameter.cpp
@@ -36,14 +36,12 @@ Parameter::Parameter( const Glib::ustring& label, const Glib::ustring& tip,
{
}
-
void
Parameter::param_write_to_repr(const char * svgd)
{
param_effect->getRepr()->setAttribute(param_key.c_str(), svgd);
}
-
// In gtk2, this wasn't an issue; we could toss around
// G_MAXDOUBLE and not worry about size allocations. But
// in gtk3, it is an issue: it allocates widget size for the maxmium
@@ -51,6 +49,12 @@ Parameter::param_write_to_repr(const char * svgd)
// If you need this to be more, please be conservative about it.
const double SCALARPARAM_G_MAXDOUBLE = 10000000000;
+void Parameter::write_to_SVG(void)
+{
+ gchar * str = param_getSVGValue();
+ param_write_to_repr(str);
+ g_free(str);
+}
/*###########################################
* REAL PARAM
diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h
index 785ada92e..2e6cae49f 100644
--- a/src/live_effects/parameter/parameter.h
+++ b/src/live_effects/parameter/parameter.h
@@ -49,7 +49,7 @@ public:
virtual bool param_readSVGValue(const gchar * strvalue) = 0; // returns true if new value is valid / accepted.
virtual gchar * param_getSVGValue() const = 0;
- void write_to_SVG() { param_write_to_repr(param_getSVGValue()); }
+ void write_to_SVG();
virtual void param_set_default() = 0;
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()){