summaryrefslogtreecommitdiffstats
path: root/src/live_effects
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2013-02-23 22:34:58 +0000
committerJabiertxo Arraiza Zenotz <jtx@jtx.marker.es>2013-02-23 22:34:58 +0000
commit9af17a6572db964acebd2b7eeea29c8b722c8221 (patch)
tree20fef1b2c5a2f9d49a841be10238919be7acf72e /src/live_effects
parentMayor refactor (diff)
downloadinkscape-9af17a6572db964acebd2b7eeea29c8b722c8221.tar.gz
inkscape-9af17a6572db964acebd2b7eeea29c8b722c8221.zip
Saved for next refactor
(bzr r11950.1.37)
Diffstat (limited to 'src/live_effects')
-rw-r--r--src/live_effects/lpe-bspline.cpp77
1 files changed, 48 insertions, 29 deletions
diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp
index 8147ae014..8dc840556 100644
--- a/src/live_effects/lpe-bspline.cpp
+++ b/src/live_effects/lpe-bspline.cpp
@@ -32,15 +32,15 @@ LPEBSpline::~LPEBSpline()
void
LPEBSpline::doEffect(SPCurve * curve)
{
- using Geom::X;
- using Geom::Y;
-
if(curve->get_segment_count() < 2)
return;
// 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();
@@ -63,9 +63,9 @@ LPEBSpline::doEffect(SPCurve * curve)
Geom::Point nextPointAt1(0,0);
Geom::Point nextPointAt2(0,0);
Geom::Point nextPointAt3(0,0);
- Geom::CubicBezier const *cubicIn;
- Geom::CubicBezier const *cubicOut;
- Geom::CubicBezier const *cubicEnd;
+
+ Geom::Point endPointAt2(0,0);
+ Geom::CubicBezier const *cubic;
//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...
@@ -75,7 +75,7 @@ LPEBSpline::doEffect(SPCurve * curve)
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_end = path_it->end_open(); // end 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
@@ -92,12 +92,31 @@ LPEBSpline::doEffect(SPCurve * curve)
//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
- cubicEnd = dynamic_cast<Geom::CubicBezier const*>(&*curve_end);
- cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
- if (path_it->closed() && cubicEnd && cubicIn) {
- //Calculamos el nodo de inicio BSpline
- lineHelper->moveto((*cubicIn)[1]);
- lineHelper->lineto((*cubicEnd)[2]);
+
+ 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();
+ }
+ SBasisIn = in->first_segment()->toSBasis();
+ SBasisEnd = end->first_segment()->toSBasis();
+ cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
+ if(cubic){
+ pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment()));
+ }else{
+ pointAt1 = in->first_segment()->initialPoint();
+ }
+ cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_end);
+ if(cubic){
+ endPointAt2 = SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment()));
+ }else{
+ endPointAt2 = end->first_segment()->finalPoint();
+ }
+ lineHelper->moveto(pointAt1);
+ lineHelper->lineto(endPointAt2);
SBasisHelper = lineHelper->first_segment()->toSBasis();
lineHelper->reset();
//Guardamos el principio de la curva
@@ -110,18 +129,18 @@ LPEBSpline::doEffect(SPCurve * curve)
//Definimos el punto de inicio original de la curva resultante
node = startNode;
}
-
//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
- cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
- if(cubicIn){
- pointAt0 = (*cubicIn)[0];
- pointAt1 = (*cubicIn)[1];
- pointAt2 = (*cubicIn)[2];
- pointAt3 = (*cubicIn)[3];
+ cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
+ if(cubic){
+ SBasisIn = in->first_segment()->toSBasis();
+ pointAt0 = (*cubic)[0];
+ pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment()));
+ pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2],*in->first_segment()));
+ pointAt3 = (*cubic)[3];
}else{
pointAt0 = in->first_segment()->initialPoint();
pointAt1 = in->first_segment()->initialPoint();
@@ -130,15 +149,16 @@ LPEBSpline::doEffect(SPCurve * curve)
}
//Y hacemos lo propio con el path de salida
//nextPointAt0 = curveOut.valueAt(0);
- cubicOut = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2);
- if(cubicOut){
- nextPointAt1 = (*cubicOut)[1];
- nextPointAt2 = (*cubicOut)[2];
- nextPointAt3 = (*cubicOut)[3];
+ cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2);
+ if(cubic){
+ SBasisOut = out->first_segment()->toSBasis();
+ nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1],*out->first_segment()));
+ nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[2],*out->first_segment()));;
+ nextPointAt3 = (*cubic)[3];
}else{
- nextPointAt1 = in->first_segment()->initialPoint();
- nextPointAt2 = in->first_segment()->finalPoint();
- nextPointAt3 = in->first_segment()->finalPoint();
+ nextPointAt1 = out->first_segment()->initialPoint();
+ nextPointAt2 = out->first_segment()->finalPoint();
+ nextPointAt3 = out->first_segment()->finalPoint();
}
//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
@@ -203,7 +223,6 @@ LPEBSpline::doEffect(SPCurve * curve)
//Todo: remove?
//delete SBasisHelper;
}
-
}; //namespace LivePathEffect
}; /* namespace Inkscape */