diff options
| author | root <root@jtx.marker.es> | 2013-03-11 23:48:05 +0000 |
|---|---|---|
| committer | root <root@jtx.marker.es> | 2013-03-11 23:48:05 +0000 |
| commit | b2981a3b8f54bccfa45c76f57b38c9c93808d2fc (patch) | |
| tree | 59eae63d752f70b5ad26acc2852f82ebbb9f1563 /src/live_effects | |
| parent | Merge from trunk (diff) | |
| download | inkscape-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.cpp | 135 | ||||
| -rw-r--r-- | src/live_effects/lpe-bspline.h | 5 |
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&); }; |
