summaryrefslogtreecommitdiffstats
path: root/src/live_effects
diff options
context:
space:
mode:
authorroot <root@jtx.marker.es>2013-03-11 23:48:05 +0000
committerroot <root@jtx.marker.es>2013-03-11 23:48:05 +0000
commitb2981a3b8f54bccfa45c76f57b38c9c93808d2fc (patch)
tree59eae63d752f70b5ad26acc2852f82ebbb9f1563 /src/live_effects
parentMerge from trunk (diff)
downloadinkscape-b2981a3b8f54bccfa45c76f57b38c9c93808d2fc.tar.gz
inkscape-b2981a3b8f54bccfa45c76f57b38c9c93808d2fc.zip
~sub fix, double click to reset default handles and control to 10% step
(bzr r11950.1.51)
Diffstat (limited to 'src/live_effects')
-rw-r--r--src/live_effects/lpe-bspline.cpp135
-rw-r--r--src/live_effects/lpe-bspline.h5
2 files changed, 137 insertions, 3 deletions
diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp
index d91f7297e..fcca38e4c 100644
--- a/src/live_effects/lpe-bspline.cpp
+++ b/src/live_effects/lpe-bspline.cpp
@@ -11,7 +11,7 @@
#include <2geom/affine.h>
#include <2geom/bezier-curve.h>
#include "helper/geom-curves.h"
-
+#include <glibmm/i18n.h>
// For handling un-continuous paths:
#include "message-stack.h"
#include "inkscape.h"
@@ -21,8 +21,11 @@ namespace Inkscape {
namespace LivePathEffect {
LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) :
- Effect(lpeobject)
+ Effect(lpeobject),unify_weights(_("Unify weights:"),
+ _("Percent of the with for all poinrs"), "unify_weights", &wr, this, 33.)
{
+ registerParameter( dynamic_cast<Parameter *>(&unify_weights) );
+ unify_weights.param_set_range(0, 100.);
}
LPEBSpline::~LPEBSpline()
@@ -205,6 +208,134 @@ LPEBSpline::doEffect(SPCurve * curve)
}
}
+std::vector<Geom::Path>
+LPEBSpline::doEffect_path (std::vector<Geom::Path> const &path_in)
+{
+ Geom::PathVector const original_pathv = path_in;
+ SPCurve *curve = new SPCurve();
+ //Recorremos todos los paths a los que queremos aplicar el efecto, hasta el penúltimo
+ for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.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
+ //Creamos las lineas rectas que unen todos los puntos del trazado y donde se calcularán
+ //los puntos clave para los manejadores.
+ //Esto hace que la curva BSpline no pierda su condición aunque se trasladen
+ //dichos manejadores
+ SPCurve *nCurve = new SPCurve();
+ Geom::Point previousNode(0,0);
+ Geom::Point node(0,0);
+ Geom::Point pointAt0(0,0);
+ Geom::Point pointAt1(0,0);
+ Geom::Point pointAt2(0,0);
+ Geom::Point pointAt3(0,0);
+ double pos1 = 0;
+ double pos2 = 0;
+ Geom::Point nextPointAt1(0,0);
+ Geom::Point nextPointAt2(0,0);
+ Geom::Point nextPointAt3(0,0);
+ Geom::D2< Geom::SBasis > SBasisIn;
+ Geom::D2< Geom::SBasis > SBasisOut;
+ Geom::D2< Geom::SBasis > SBasisHelper;
+ Geom::CubicBezier const *cubic = NULL;
+ 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();
+ }
+ }
+ //Si la curva está cerrada calculamos el punto donde
+ //deveria estar el nodo BSpline de cierre/inicio de la curva
+ //en posible caso de que se cierre con una linea recta creando un nodo BSPline
+
+ //Recorremos todos los segmentos menos el último
+ while ( curve_it2 != curve_endit )
+ {
+ //previousPointAt3 = pointAt3;
+ //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida
+ SPCurve * in = new SPCurve();
+ in->moveto(curve_it1->initialPoint());
+ in->lineto(curve_it1->finalPoint());
+ cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
+ if(cubic){
+ SBasisIn = in->first_segment()->toSBasis();
+ pointAt0 = in->first_segment()->initialPoint();
+ pos1 = unify_weights/100;
+ pos2 = 1-unify_weights/100;
+ pointAt1 = SBasisIn.valueAt(pos1);
+ pointAt2 = SBasisIn.valueAt(pos2);
+ pointAt3 = in->first_segment()->finalPoint();
+ }else{
+ pointAt0 = in->first_segment()->initialPoint();
+ pointAt1 = in->first_segment()->initialPoint();
+ pointAt2 = in->first_segment()->finalPoint();
+ pointAt3 = in->first_segment()->finalPoint();
+ }
+ in->reset();
+ delete in;
+ //Y hacemos lo propio con el path de salida
+ //nextPointAt0 = curveOut.valueAt(0);
+ SPCurve * out = new SPCurve();
+ out->moveto(curve_it2->initialPoint());
+ out->lineto(curve_it2->finalPoint());
+ cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2);
+ if(cubic){
+ SBasisOut = out->first_segment()->toSBasis();
+ pos1 = unify_weights/100;
+ pos2 = 1-unify_weights/100;
+ nextPointAt1 = SBasisOut.valueAt(pos1);
+ nextPointAt2 = SBasisOut.valueAt(pos2);
+ nextPointAt3 = (*cubic)[3];
+ }else{
+ nextPointAt1 = out->first_segment()->initialPoint();
+ nextPointAt2 = out->first_segment()->finalPoint();
+ nextPointAt3 = out->first_segment()->finalPoint();
+ }
+ out->reset();
+ delete out;
+ //Y este hará de final de curva
+ SPCurve *curveHelper = new SPCurve();
+ curveHelper->moveto(pointAt0);
+ curveHelper->curveto(pointAt1, pointAt2, pointAt3);
+ //añadimos la curva generada a la curva pricipal
+ nCurve->append_continuous(curveHelper, 0.0625);
+ curveHelper->reset();
+ delete curveHelper;
+ //aumentamos los valores para el siguiente paso en el bucle
+ ++curve_it1;
+ ++curve_it2;
+ }
+ //Aberiguamos la ultima parte de la curva correspondiente al último segmento
+ SPCurve *curveHelper = new SPCurve();
+ curveHelper->moveto(node);
+ //Si está cerrada la curva, la cerramos sobre el valor guardado previamente
+ //Si no finalizamos en el punto final
+ Geom::Point startNode(0,0);
+ startNode = path_it->begin()->initialPoint();
+ curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3);
+ nCurve->append_continuous(curveHelper, 0.0625);
+ nCurve->move_endpoints(startNode,nextPointAt3);
+ curveHelper->reset();
+ delete curveHelper;
+ //y cerramos la curva
+ if (path_it->closed()) {
+ nCurve->closepath_current();
+ }
+ curve->append(nCurve,false);
+ nCurve->reset();
+ delete nCurve;
+ }
+ return curve->get_pathvector();
+}
+
}; //namespace LivePathEffect
}; /* namespace Inkscape */
diff --git a/src/live_effects/lpe-bspline.h b/src/live_effects/lpe-bspline.h
index d983a7654..27c79f040 100644
--- a/src/live_effects/lpe-bspline.h
+++ b/src/live_effects/lpe-bspline.h
@@ -8,7 +8,7 @@
*/
#include "live_effects/effect.h"
-
+#include "live_effects/parameter/parameter.h"
namespace Inkscape {
namespace LivePathEffect {
@@ -18,11 +18,14 @@ public:
LPEBSpline(LivePathEffectObject *lpeobject);
virtual ~LPEBSpline();
+ virtual std::vector<Geom::Path> doEffect_path (std::vector<Geom::Path> const & input_path);
+
virtual LPEPathFlashType pathFlashType() const { return SUPPRESS_FLASH; }
virtual void doEffect(SPCurve * curve);
private:
+ ScalarParam unify_weights;
LPEBSpline(const LPEBSpline&);
LPEBSpline& operator=(const LPEBSpline&);
};