diff options
| author | jtx <javier.arraiza@marker.es> | 2013-02-19 16:48:44 +0000 |
|---|---|---|
| committer | jtx <javier.arraiza@marker.es> | 2013-02-19 16:48:44 +0000 |
| commit | e77f8af15850e964f5d69c84b0f45a66ae229d94 (patch) | |
| tree | 66eeb27d793d6874bc51e7e2601b1b41fa6aae81 /src/pen-context.cpp | |
| parent | Fix cusp continuous? path close broken (diff) | |
| parent | Mayor refactor (diff) | |
| download | inkscape-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.cpp | 128 |
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) |
