summaryrefslogtreecommitdiffstats
path: root/src/live_effects
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2012-12-24 07:05:24 +0000
committerJabiertxo Arraiza Cenoz <jtx@jtx.marker.es>2012-12-24 07:05:24 +0000
commitd395af6ee332142c63355d008d49b1f4b3487dfe (patch)
tree011d1b9bae8fdc121124b35f6ba5e02e84e8d9f9 /src/live_effects
parentnot working, merge from branch (diff)
downloadinkscape-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.cpp226
-rw-r--r--src/live_effects/lpe-bspline.h35
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