summaryrefslogtreecommitdiffstats
path: root/src/pen-context.cpp
diff options
context:
space:
mode:
authorjtx <javier.arraiza@marker.es>2013-02-19 16:48:44 +0000
committerjtx <javier.arraiza@marker.es>2013-02-19 16:48:44 +0000
commite77f8af15850e964f5d69c84b0f45a66ae229d94 (patch)
tree66eeb27d793d6874bc51e7e2601b1b41fa6aae81 /src/pen-context.cpp
parentFix cusp continuous? path close broken (diff)
parentMayor refactor (diff)
downloadinkscape-e77f8af15850e964f5d69c84b0f45a66ae229d94.tar.gz
inkscape-e77f8af15850e964f5d69c84b0f45a66ae229d94.zip
Refactor problem cusp nodes
(bzr r11950.3.2)
Diffstat (limited to 'src/pen-context.cpp')
-rw-r--r--src/pen-context.cpp128
1 files changed, 77 insertions, 51 deletions
diff --git a/src/pen-context.cpp b/src/pen-context.cpp
index 9577ecbf9..e393a706b 100644
--- a/src/pen-context.cpp
+++ b/src/pen-context.cpp
@@ -1844,7 +1844,45 @@ static void bspline(SPPenContext *const pc, bool Shift)
lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]);
previousCurve->backspace();
previousCurve->append_continuous(lastSeg, 0.0625);
- pc->sa = previousCurve;
+ pc->sa->curve = previousCurve;
+ }
+ }
+ }
+ if(pc->anchor_statusbar && !pc->red_curve->is_empty()){
+ // Step B - both start and end anchored to same curve
+ if ( pc->sa && pc->ea
+ && ( pc->sa->curve == pc->ea->curve )
+ && ( ( pc->sa != pc->ea )
+ || pc->sa->curve->is_closed() ) )
+ {
+ SPCurve * same = pc->sa->curve->copy();
+ if (pc->sa->start) {
+ same = same->create_reverse();
+ }
+ cubic = dynamic_cast<Geom::CubicBezier const*>(&*same->last_segment());
+ if(cubic){
+ SPCurve *lastSeg = new SPCurve();
+ lastSeg->moveto((*cubic)[0]);
+ lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]);
+ same->backspace();
+ same->append_continuous(lastSeg, 0.0625);
+ same = same->create_reverse();
+ pc->sa->curve = same;
+ }
+ }
+ // Step A - test, whether we ended on green anchor
+ if ( pc->green_anchor && pc->green_anchor->active ) {
+ // We hit green anchor, closing Green-Blue-Red
+ SPCurve * green = pc->green_curve->copy()->create_reverse();
+ cubic = dynamic_cast<Geom::CubicBezier const*>(&*green->last_segment());
+ if(cubic){
+ SPCurve *lastSeg = new SPCurve();
+ lastSeg->moveto((*cubic)[0]);
+ lastSeg->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]);
+ green->backspace();
+ green->append_continuous(lastSeg, 0.0625);
+ green = green->create_reverse();
+ pc->green_curve = green;
}
}
}
@@ -1936,7 +1974,7 @@ static void bspline_build(SPPenContext *const pc)
}
}
-static void bspline_doEffect(SPCurve * curve)
+static void __attribute__((optimize(0))) bspline_doEffect(SPCurve * curve)
{
using Geom::X;
using Geom::Y;
@@ -1947,18 +1985,15 @@ static void bspline_doEffect(SPCurve * curve)
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;
- //Curvas temporales
- SPCurve *lineHelper = new SPCurve();
- SPCurve *curveHelper = new SPCurve();
- SPCurve *nCurve = new SPCurve();
//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);
@@ -1986,6 +2021,7 @@ static void bspline_doEffect(SPCurve * 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
+
//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
@@ -1997,19 +2033,15 @@ static void bspline_doEffect(SPCurve * curve)
//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
- cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
- cubicOut = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2);
cubicEnd = dynamic_cast<Geom::CubicBezier const*>(&*curve_end);
- if (path_it->closed()){
+ cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
+ if (path_it->closed() && cubicEnd && cubicIn) {
//Calculamos el nodo de inicio BSpline
- SBasisIn = in->first_segment()->toSBasis();
- SBasisEnd = end->first_segment()->toSBasis();
- lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*cubicIn)[1],*in->first_segment())));
- lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubicEnd)[2],*end->first_segment())));
+ lineHelper->moveto((*cubicIn)[1]);
+ lineHelper->lineto((*cubicEnd)[2]);
SBasisHelper = lineHelper->first_segment()->toSBasis();
lineHelper->reset();
//Guardamos el principio de la curva
@@ -2017,57 +2049,54 @@ static void bspline_doEffect(SPCurve * curve)
//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 )
{
- 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
+ cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
if(cubicIn){
- pointAt0 = SBasisIn.valueAt(0);
- pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubicIn)[1],*in->first_segment()));
- pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubicIn)[2],*in->first_segment()));
- pointAt3 = SBasisIn.valueAt(1);
+ pointAt0 = (*cubicIn)[0];
+ pointAt1 = (*cubicIn)[1];
+ pointAt2 = (*cubicIn)[2];
+ pointAt3 = (*cubicIn)[3];
}else{
- pointAt0 = SBasisIn.valueAt(0);
- pointAt1 = SBasisIn.valueAt(0);
- pointAt2 = SBasisIn.valueAt(1);
- pointAt3 = SBasisIn.valueAt(1);
+ pointAt0 = in->first_segment()->initialPoint();
+ pointAt1 = in->first_segment()->initialPoint();
+ pointAt2 = in->first_segment()->finalPoint();
+ pointAt3 = in->first_segment()->finalPoint();
}
//Y hacemos lo propio con el path de salida
//nextPointAt0 = curveOut.valueAt(0);
+ cubicOut = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2);
if(cubicOut){
- nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[1],*out->first_segment()));
- nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[2],*out->first_segment()));
- nextPointAt3 = SBasisOut.valueAt(1);
+ nextPointAt1 = (*cubicOut)[1];
+ nextPointAt2 = (*cubicOut)[2];
+ nextPointAt3 = (*cubicOut)[3];
}else{
- nextPointAt1 = SBasisOut.valueAt(0);
- nextPointAt2 = SBasisOut.valueAt(1);
- nextPointAt3 = SBasisOut.valueAt(1);
+ nextPointAt1 = in->first_segment()->initialPoint();
+ nextPointAt2 = in->first_segment()->finalPoint();
+ nextPointAt3 = in->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
//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
- if(nextPointAt1 != pointAt2){
- 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);
- }else{
- previousNode = node;
- //Y este hará de final de curva
- node = nextPointAt1;
- }
+ 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);
curveHelper->moveto(previousNode);
curveHelper->curveto(pointAt1, pointAt2, node);
//añadimos la curva generada a la curva pricipal
@@ -2084,10 +2113,7 @@ static void bspline_doEffect(SPCurve * curve)
if(curve_it1 != curve_end){
out->moveto(curve_it2->initialPoint());
out->lineto(curve_it2->finalPoint());
- cubicOut = dynamic_cast<Geom::CubicBezier const*>(&*curve_it2);
}
- cubicIn = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
-
}
//Aberiguamos la ultima parte de la curva correspondiente al último segmento
curveHelper->moveto(node);
@@ -2121,7 +2147,7 @@ static void bspline_doEffect(SPCurve * curve)
//Todo: remove?
//delete SBasisHelper;
}
-
+
//BSpline end
static void spdc_pen_set_subsequent_point(SPPenContext *const pc, Geom::Point const p, bool statusbar, guint status)