diff options
| author | Jabier Arraiza Cenoz <jabier.arraiza@marker.es> | 2012-12-24 07:05:24 +0000 |
|---|---|---|
| committer | Jabiertxo Arraiza Cenoz <jtx@jtx.marker.es> | 2012-12-24 07:05:24 +0000 |
| commit | d395af6ee332142c63355d008d49b1f4b3487dfe (patch) | |
| tree | 011d1b9bae8fdc121124b35f6ba5e02e84e8d9f9 /src/live_effects | |
| parent | not working, merge from branch (diff) | |
| download | inkscape-d395af6ee332142c63355d008d49b1f4b3487dfe.tar.gz inkscape-d395af6ee332142c63355d008d49b1f4b3487dfe.zip | |
Going to merge
(bzr r11950.1.5)
Diffstat (limited to 'src/live_effects')
| -rw-r--r-- | src/live_effects/lpe-bspline.cpp | 226 | ||||
| -rw-r--r-- | src/live_effects/lpe-bspline.h | 35 |
2 files changed, 261 insertions, 0 deletions
diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp new file mode 100644 index 000000000..e125cc4e0 --- /dev/null +++ b/src/live_effects/lpe-bspline.cpp @@ -0,0 +1,226 @@ +#define INKSCAPE_LPE_BSPLINE_C + +/* + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/lpe-bspline.h" + +#include "display/curve.h" +#include <typeinfo> +#include <2geom/pathvector.h> +#include <2geom/affine.h> +#include <2geom/bezier-curve.h> +#include "helper/geom-curves.h" + +// For handling un-continuous paths: +#include "message-stack.h" +#include "inkscape.h" +#include "desktop.h" + +namespace Inkscape { +namespace LivePathEffect { + +LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) : + Effect(lpeobject) +{ +} + +LPEBSpline::~LPEBSpline() +{ +} +//Crea una nueva curva reseteando la original +SPCurve * +LPEBSpline::reverse_then_reset(SPCurve * orig){ + SPCurve *ret = orig->create_reverse(); + orig->reset(); + return ret; +} + +void +LPEBSpline::doEffect(SPCurve * curve) +{ + using Geom::X; + using Geom::Y; + + // Make copy of old path as it is changed during processing + Geom::PathVector const original_pathv = curve->get_pathvector(); + curve->reset(); + //Sbasis + Geom::D2< Geom::SBasis > SBasisIn; + Geom::D2< Geom::SBasis > SBasisOut; + Geom::D2< Geom::SBasis > SBasisEnd; + Geom::D2< Geom::SBasis > SBasisHelper; + //curves + SPCurve * in = new SPCurve(); + SPCurve * out = new SPCurve(); + SPCurve * end = new SPCurve(); + //Curvas temporales + SPCurve *lineHelper = new SPCurve(); + SPCurve *curveHelper = new SPCurve(); + SPCurve *nCurve = new SPCurve(); + //Puntos a usar. Ponemos todos los posibles para hacer más inteligible el código + Geom::Point startNode(0,0); + Geom::Point previousNode(0,0); + Geom::Point node(0,0); + //Geom::Point previousPointAt3(0,0); + Geom::Point pointAt0(0,0); + Geom::Point pointAt1(0,0); + Geom::Point pointAt2(0,0); + Geom::Point pointAt3(0,0); + //Geom::Point nextPointAt0(0,0); + Geom::Point nextPointAt1(0,0); + Geom::Point nextPointAt2(0,0); + Geom::Point nextPointAt3(0,0); + + //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_end = path_it->end(); // end curve + Geom::Path::const_iterator curve_endit = path_it->end_default(); // this determines when the loop has to stop + //Las lineas rectas forman nodos BSpline + //Las curvas forman nodos CUSP + bool isBSpline = true; + //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 + in->moveto(curve_it1->initialPoint()); + in->lineto(curve_it1->finalPoint()); + out->moveto(curve_it2->initialPoint()); + out->lineto(curve_it2->finalPoint()); + //este no cambia. + end->moveto(curve_end->initialPoint()); + end->lineto(curve_end->finalPoint()); + //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 + if (path_it->closed() && is_straight_curve(*curve_end)) { + //Calculamos el nodo de inicio BSpline + SBasisIn = in->first_segment()->toSBasis(); + SBasisEnd = end->first_segment()->toSBasis(); + lineHelper->moveto(SBasisIn.valueAt(0.3334)); + lineHelper->lineto(SBasisEnd.valueAt(0.6664)); + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + //Guardamos el principio de la curva + startNode = SBasisHelper.valueAt(0.5); + //Definimos el punto de inicio original de la curva resultante + node = startNode; + }else{ + //Guardamos el principio de la curva + startNode = in->first_segment()->initialPoint(); + //Definimos el punto de inicio original de la curva resultante + node = startNode; + } + //Recorremos todos los segmentos menos el último + while ( curve_it2 != curve_endit ) + { + //Damos valor a el objeto SBasis para el path de entrada y el de salida + SBasisIn = in->first_segment()->toSBasis(); + SBasisOut = out->first_segment()->toSBasis(); + //previousPointAt3 = pointAt3; + //Calculamos los puntos que dividirían en tres segmentos iguales el path recto de entrada y de salida + pointAt0 = SBasisIn.valueAt(0); + pointAt1 = SBasisIn.valueAt(0.3334); + pointAt2 = SBasisIn.valueAt(0.6667); + pointAt3 = SBasisIn.valueAt(1); + //Y hacemos lo propio con el path de salida + //nextPointAt0 = curveOut.valueAt(0); + nextPointAt1 = SBasisOut.valueAt(0.3334); + nextPointAt2 = SBasisOut.valueAt(0.6667);; + nextPointAt3 = SBasisOut.valueAt(1); + //La curva BSpline se forma calculando el centro del segmanto de unión + //de el punto situado en las 2/3 partes de el segmento de entrada + //con el punto situado en la posición 1/3 del segmento de salida + //Estos dos puntos ademas estan posicionados en el lugas correspondiente de + //los manejadores de la curva + lineHelper->moveto(pointAt2); + lineHelper->lineto(nextPointAt1); + SBasisHelper = lineHelper->first_segment()->toSBasis(); + lineHelper->reset(); + //almacenamos el punto del anterior bucle -o el de cierre- que nos hara de principio de curva + previousNode = node; + //Y este hará de final de curva + node = SBasisHelper.valueAt(0.5); + //Vemos si el nodo es BSpline o CUSP + //Averiguamos si el path de entrada es recto o tiene manejadores + isBSpline = is_straight_curve(*curve_it1); + //Si no es recto, tenemos que generar la curva con nodo final CUSP + if(!isBSpline ){ + //Definimos como nodo el final del segmento de entrada + node = pointAt3; + } + curveHelper->moveto(previousNode); + curveHelper->curveto(pointAt1, pointAt2, node); + //añadimos la curva generada a la curva pricipal + nCurve->append_continuous(curveHelper, 0.0625); + curveHelper->reset(); + //aumentamos los valores para el siguiente paso en el bucle + ++curve_it1; + ++curve_it2; + in->reset(); + in->moveto(curve_it1->initialPoint()); + in->lineto(curve_it1->finalPoint()); + out->reset(); + if(curve_it1 != curve_end){ + out->moveto(curve_it2->initialPoint()); + out->lineto(curve_it2->finalPoint()); + } + } + //Aberiguamos la ultima parte de la curva correspondiente al último segmento + curveHelper->moveto(node); + //Si está cerrada la curva, la cerramos sobre el valor guardado previamente + //Si no finalizamos en el punto final + if (path_it->closed()) { + curveHelper->curveto(nextPointAt1, nextPointAt2, startNode); + }else{ + curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3); + } + //añadimos este último segmento + nCurve->append_continuous(curveHelper, 0.0625); + //y cerramos la curva + if (path_it->closed()) { + nCurve->closepath_current(); + } + curve->append(nCurve,false); + nCurve->reset(); + //Limpiamos + in->reset(); + out->reset(); + end->reset(); + lineHelper->reset(); + curveHelper->reset(); + } + delete in; + delete out; + delete end; + delete lineHelper; + delete curveHelper; + //Todo: remove? + //delete SBasisIn; + //delete SBasisOut; + //delete SBasisEnd; + //delete SBasisHelper; +} + + + +}; //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-bspline.h b/src/live_effects/lpe-bspline.h new file mode 100644 index 000000000..23ac495df --- /dev/null +++ b/src/live_effects/lpe-bspline.h @@ -0,0 +1,35 @@ +#ifndef INKSCAPE_LPE_BSPLINE_H +#define INKSCAPE_LPE_BSPLINE_H + +/* + * Inkscape::LPEBSpline + * + * Released under GNU GPL, read the file 'COPYING' for more information + */ + +#include "live_effects/effect.h" + + +namespace Inkscape { +namespace LivePathEffect { + +class LPEBSpline : public Effect { +public: + LPEBSpline(LivePathEffectObject *lpeobject); + virtual ~LPEBSpline(); + + virtual LPEPathFlashType pathFlashType() { return SUPPRESS_FLASH; } + + virtual SPCurve *reverse_then_reset(SPCurve * orig); + + virtual void doEffect(SPCurve * curve); + +private: + LPEBSpline(const LPEBSpline&); + LPEBSpline& operator=(const LPEBSpline&); +}; + +}; //namespace LivePathEffect +}; //namespace Inkscape + +#endif |
