summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2014-09-22 19:15:47 +0000
committerJabiertxof <jtx@jtx.marker.es>2014-09-22 19:15:47 +0000
commitfb4d4b30b50b7b4505d63772c0aeca4c05c2c5c6 (patch)
treed92b63382e7b31bb2c02bd3cb5b1f2488d6abbe2 /src
parentCleaned up file, removing unused items in <defs> and unnecessary properties. (diff)
downloadinkscape-fb4d4b30b50b7b4505d63772c0aeca4c05c2c5c6.tar.gz
inkscape-fb4d4b30b50b7b4505d63772c0aeca4c05c2c5c6.zip
Fix for strange gap at shift to cusp in bspline
Now curves with cusp noden in bspline mode looks better, more smooth. Remove some duplicate code from outside for loops Fix a bug continuing shapes in bspline-spiro mode. Style code formating (bzr r13341.1.215)
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/lpe-bspline.cpp360
-rw-r--r--src/ui/tools/freehand-base.cpp8
-rw-r--r--src/ui/tools/pen-tool.cpp232
3 files changed, 216 insertions, 384 deletions
diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp
index 433696aab..1141e87ef 100644
--- a/src/live_effects/lpe-bspline.cpp
+++ b/src/live_effects/lpe-bspline.cpp
@@ -52,6 +52,7 @@ using Inkscape::DocumentUndo;
namespace Inkscape {
namespace LivePathEffect {
+const double handleCubicGap = 0.01;
LPEBSpline::LPEBSpline(LivePathEffectObject *lpeobject) :
Effect(lpeobject),
steps(_("Steps whith CTRL:"), _("Change number of steps whith CTRL pressed"), "steps", &wr, this, 2),
@@ -97,192 +98,136 @@ void LPEBSpline::createAndApply(const char *name, SPDocument *doc, SPItem *item)
void LPEBSpline::doEffect(SPCurve *curve)
{
- if (curve->get_segment_count() < 1)
+ if (curve->get_segment_count() < 1){
return;
- // Make copy of old path as it is changed during processing
+ }
+
Geom::PathVector const original_pathv = curve->get_pathvector();
curve->reset();
- //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_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
- //dichos manejadores
+ Geom::Path::const_iterator curve_it1 = path_it->begin();
+ Geom::Path::const_iterator curve_it2 = ++(path_it->begin());
+ Geom::Path::const_iterator curve_endit = path_it->end_default();
SPCurve *nCurve = new SPCurve();
Geom::Point previousNode(0, 0);
Geom::Point node(0, 0);
Geom::Point pointAt1(0, 0);
Geom::Point pointAt2(0, 0);
Geom::Point nextPointAt1(0, 0);
- Geom::Point nextPointAt2(0, 0);
- Geom::Point nextPointAt3(0, 0);
Geom::D2<Geom::SBasis> SBasisIn;
Geom::D2<Geom::SBasis> SBasisOut;
Geom::D2<Geom::SBasis> SBasisHelper;
Geom::CubicBezier const *cubic = NULL;
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.
+ const Geom::Curve &closingline = path_it->back_closed();
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();
}
}
- //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
nCurve->moveto(curve_it1->initialPoint());
- //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
+ while (curve_it1 != curve_endit) {
SPCurve *in = new SPCurve();
in->moveto(curve_it1->initialPoint());
in->lineto(curve_it1->finalPoint());
cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
if (cubic) {
SBasisIn = in->first_segment()->toSBasis();
- pointAt1 = SBasisIn.valueAt(
- Geom::nearest_point((*cubic)[1], *in->first_segment()));
- pointAt2 = SBasisIn.valueAt(
- Geom::nearest_point((*cubic)[2], *in->first_segment()));
+ if(are_near((*cubic)[1],(*cubic)[0]) && !are_near((*cubic)[2],(*cubic)[3])) {
+ pointAt1 = SBasisIn.valueAt(0.3334);
+ } else {
+ pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1], *in->first_segment()));
+ }
+ if(are_near((*cubic)[2],(*cubic)[3]) && !are_near((*cubic)[1],(*cubic)[0])) {
+ pointAt2 = SBasisIn.valueAt(0.6667);
+ } else {
+ pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2], *in->first_segment()));
+ }
} else {
pointAt1 = in->first_segment()->initialPoint();
pointAt2 = in->first_segment()->finalPoint();
}
in->reset();
delete in;
- //Y hacemos lo propio con el path de salida
- //nextPointAt0 = curveOut.valueAt(0);
- SPCurve *out = new SPCurve();
- out->moveto(curve_it2->initialPoint());
- out->lineto(curve_it2->finalPoint());
- 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 = out->first_segment()->finalPoint();
+ if ( curve_it2 != curve_endit ) {
+ SPCurve *out = new SPCurve();
+ out->moveto(curve_it2->initialPoint());
+ out->lineto(curve_it2->finalPoint());
+ cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it2);
+ if (cubic) {
+ SBasisOut = out->first_segment()->toSBasis();
+ if(are_near((*cubic)[1],(*cubic)[0]) && !are_near((*cubic)[2],(*cubic)[3])) {
+ nextPointAt1 = SBasisIn.valueAt(0.3334);
+ } else {
+ nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1], *out->first_segment()));
+ }
+ } else {
+ nextPointAt1 = out->first_segment()->initialPoint();
+ }
+ out->reset();
+ delete out;
+ }
+ Geom::Point startNode = path_it->begin()->initialPoint();
+ if (path_it->closed() && curve_it2 == curve_endit) {
+ SPCurve *start = new SPCurve();
+ start->moveto(path_it->begin()->initialPoint());
+ start->lineto(path_it->begin()->finalPoint());
+ Geom::D2<Geom::SBasis> SBasisStart = start->first_segment()->toSBasis();
+ SPCurve *lineHelper = new SPCurve();
+ cubic = dynamic_cast<Geom::CubicBezier const *>(&*path_it->begin());
+ if (cubic) {
+ lineHelper->moveto(SBasisStart.valueAt(
+ Geom::nearest_point((*cubic)[1], *start->first_segment())));
+ } else {
+ lineHelper->moveto(start->first_segment()->initialPoint());
+ }
+ start->reset();
+ delete start;
+
+ SPCurve *end = new SPCurve();
+ end->moveto(curve_it1->initialPoint());
+ end->lineto(curve_it1->finalPoint());
+ Geom::D2<Geom::SBasis> SBasisEnd = end->first_segment()->toSBasis();
+ cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
+ if (cubic) {
+ lineHelper->lineto(SBasisEnd.valueAt(
+ Geom::nearest_point((*cubic)[2], *end->first_segment())));
+ } else {
+ lineHelper->lineto(end->first_segment()->finalPoint());
+ }
+ end->reset();
+ delete end;
+ SBasisHelper = lineHelper->first_segment()->toSBasis();
+ lineHelper->reset();
+ delete lineHelper;
+ startNode = SBasisHelper.valueAt(0.5);
+ nCurve->curveto(pointAt1, pointAt2, startNode);
+ nCurve->move_endpoints(startNode, startNode);
+ } else if ( curve_it2 == curve_endit) {
+ nCurve->curveto(pointAt1, pointAt2, curve_it1->finalPoint());
+ nCurve->move_endpoints(path_it->begin()->initialPoint(), curve_it1->finalPoint());
} else {
- nextPointAt1 = out->first_segment()->initialPoint();
- nextPointAt2 = out->first_segment()->finalPoint();
- nextPointAt3 = out->first_segment()->finalPoint();
+ SPCurve *lineHelper = new SPCurve();
+ lineHelper->moveto(pointAt2);
+ lineHelper->lineto(nextPointAt1);
+ SBasisHelper = lineHelper->first_segment()->toSBasis();
+ lineHelper->reset();
+ delete lineHelper;
+ previousNode = node;
+ node = SBasisHelper.valueAt(0.5);
+ Geom::CubicBezier const *cubic2 = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
+ if((cubic && are_near((*cubic)[0],(*cubic)[1])) || (cubic2 && are_near((*cubic2)[2],(*cubic2)[3]))) {
+ node = curve_it1->finalPoint();
+ }
+ nCurve->curveto(pointAt1, pointAt2, node);
}
- out->reset();
- delete out;
- //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
- SPCurve *lineHelper = new SPCurve();
- lineHelper->moveto(pointAt2);
- lineHelper->lineto(nextPointAt1);
- SBasisHelper = lineHelper->first_segment()->toSBasis();
- lineHelper->reset();
- delete lineHelper;
- //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);
- nCurve->curveto(pointAt1, pointAt2, node);
- //aumentamos los valores para el siguiente paso en el bucle
++curve_it1;
++curve_it2;
}
- SPCurve *out = new SPCurve();
- out->moveto(curve_it1->initialPoint());
- out->lineto(curve_it1->finalPoint());
- cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
- 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 = out->first_segment()->finalPoint();
- } else {
- nextPointAt1 = out->first_segment()->initialPoint();
- nextPointAt2 = out->first_segment()->finalPoint();
- nextPointAt3 = out->first_segment()->finalPoint();
- }
- out->reset();
- delete out;
- //Si está cerrada la curva, la cerramos sobre el valor guardado
- //previamente
- //Si no finalizamos en el punto final
- Geom::Point startNode = path_it->begin()->initialPoint();
- if (path_it->closed()) {
- SPCurve *start = new SPCurve();
- start->moveto(path_it->begin()->initialPoint());
- start->lineto(path_it->begin()->finalPoint());
- Geom::D2<Geom::SBasis> SBasisStart = start->first_segment()->toSBasis();
- SPCurve *lineHelper = new SPCurve();
- cubic = dynamic_cast<Geom::CubicBezier const *>(&*path_it->begin());
- if (cubic) {
- lineHelper->moveto(SBasisStart.valueAt(
- Geom::nearest_point((*cubic)[1], *start->first_segment())));
- } else {
- lineHelper->moveto(start->first_segment()->initialPoint());
- }
- start->reset();
- delete start;
-
- SPCurve *end = new SPCurve();
- end->moveto(curve_it1->initialPoint());
- end->lineto(curve_it1->finalPoint());
- Geom::D2<Geom::SBasis> SBasisEnd = end->first_segment()->toSBasis();
-
- cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
- if (cubic) {
- lineHelper->lineto(SBasisEnd.valueAt(
- Geom::nearest_point((*cubic)[2], *end->first_segment())));
- } else {
- lineHelper->lineto(end->first_segment()->finalPoint());
- }
- end->reset();
- delete end;
- SBasisHelper = lineHelper->first_segment()->toSBasis();
- lineHelper->reset();
- delete lineHelper;
- startNode = SBasisHelper.valueAt(0.5);
- nCurve->curveto(nextPointAt1, nextPointAt2, startNode);
- nCurve->move_endpoints(startNode, startNode);
- } else {
- SPCurve *start = new SPCurve();
- start->moveto(path_it->begin()->initialPoint());
- start->lineto(path_it->begin()->finalPoint());
- startNode = start->first_segment()->initialPoint();
- start->reset();
- delete start;
- nCurve->curveto(nextPointAt1, nextPointAt2, nextPointAt3);
- nCurve->move_endpoints(startNode, nextPointAt3);
- }
//y cerramos la curva
if (path_it->closed()) {
nCurve->closepath_current();
@@ -402,7 +347,7 @@ bool LPEBSpline::nodeIsSelected(Geom::Point nodePoint)
for (std::vector<Geom::Point>::iterator i = points.begin();
i != points.end(); ++i) {
Geom::Point p = *i;
- if (Geom::are_near(p, nodePoint, 0.0001)) {
+ if (Geom::are_near(p, nodePoint, handleCubicGap)) {
return true;
} else {
}
@@ -463,10 +408,6 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue)
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);
Geom::D2<Geom::SBasis> SBasisIn;
Geom::D2<Geom::SBasis> SBasisOut;
Geom::CubicBezier const *cubic = NULL;
@@ -490,7 +431,7 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue)
//BSPline
nCurve->moveto(curve_it1->initialPoint());
//Recorremos todos los segmentos menos el último
- while (curve_it2 != curve_endit) {
+ while (curve_it1 != curve_endit) {
//previousPointAt3 = pointAt3;
//Calculamos los puntos que dividirían en tres segmentos iguales el path
//recto de entrada y de salida
@@ -507,7 +448,7 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue)
pointAt1 = SBasisIn.valueAt(weightValue);
if (weightValue != 0.0000) {
pointAt1 =
- Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001);
+ Geom::Point(pointAt1[X] + handleCubicGap, pointAt1[Y] + handleCubicGap);
}
} else {
pointAt1 = in->first_segment()->initialPoint();
@@ -516,7 +457,7 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue)
pointAt2 = SBasisIn.valueAt(1 - weightValue);
if (weightValue != 0.0000) {
pointAt2 =
- Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001);
+ Geom::Point(pointAt2[X] + handleCubicGap, pointAt2[Y] + handleCubicGap);
}
} else {
pointAt2 = in->first_segment()->finalPoint();
@@ -526,12 +467,12 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue)
pointAt1 = SBasisIn.valueAt(weightValue);
if (weightValue != 0.0000) {
pointAt1 =
- Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001);
+ Geom::Point(pointAt1[X] + handleCubicGap, pointAt1[Y] + handleCubicGap);
}
pointAt2 = SBasisIn.valueAt(1 - weightValue);
if (weightValue != 0.0000) {
pointAt2 =
- Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001);
+ Geom::Point(pointAt2[X] + handleCubicGap, pointAt2[Y] + handleCubicGap);
}
} else {
pointAt1 = in->first_segment()->initialPoint();
@@ -545,7 +486,7 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue)
pointAt1 = SBasisIn.valueAt(weightValue);
if (weightValue != 0.0000) {
pointAt1 =
- Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001);
+ Geom::Point(pointAt1[X] + handleCubicGap, pointAt1[Y] + handleCubicGap);
}
} else {
pointAt1 = (*cubic)[1];
@@ -558,7 +499,7 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue)
pointAt2 = SBasisIn.valueAt(1 - weightValue);
if (weightValue != 0.0000) {
pointAt2 =
- Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001);
+ Geom::Point(pointAt2[X] + handleCubicGap, pointAt2[Y] + handleCubicGap);
}
} else {
pointAt2 = (*cubic)[2];
@@ -567,18 +508,18 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue)
pointAt2 = in->first_segment()->finalPoint();
}
} else {
- if (!ignoreCusp && weightValue != 0.000) {
+ if (!ignoreCusp && weightValue != 0.0000) {
if (nodeIsSelected(pointAt0)) {
pointAt1 = SBasisIn.valueAt(weightValue);
pointAt1 =
- Geom::Point(pointAt1[X] + 0.0001, pointAt1[Y] + 0.0001);
+ Geom::Point(pointAt1[X] + handleCubicGap, pointAt1[Y] + handleCubicGap);
} else {
pointAt1 = in->first_segment()->initialPoint();
}
if (nodeIsSelected(pointAt3)) {
pointAt2 = SBasisIn.valueAt(weightValue);
pointAt2 =
- Geom::Point(pointAt2[X] + 0.0001, pointAt2[Y] + 0.0001);
+ Geom::Point(pointAt2[X] + handleCubicGap, pointAt2[Y] + handleCubicGap);
} else {
pointAt2 = in->first_segment()->finalPoint();
}
@@ -601,110 +542,11 @@ void LPEBSpline::doBSplineFromWidget(SPCurve *curve, double weightValue)
++curve_it1;
++curve_it2;
}
- SPCurve *out = new SPCurve();
- out->moveto(curve_it1->initialPoint());
- out->lineto(curve_it1->finalPoint());
- SBasisOut = out->first_segment()->toSBasis();
- nextPointAt0 = out->first_segment()->initialPoint();
- nextPointAt3 = out->first_segment()->finalPoint();
- cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
- if (!onlySelected) {
- if (cubic) {
- if (!ignoreCusp || !Geom::are_near((*cubic)[1], nextPointAt0)) {
- nextPointAt1 = SBasisOut.valueAt(weightValue);
- if (weightValue != 0.0000) {
- nextPointAt1 =
- Geom::Point(nextPointAt1[X] + 0.0001, nextPointAt1[Y] + 0.0001);
- }
- } else {
- nextPointAt1 = out->first_segment()->initialPoint();
- }
- if (!ignoreCusp || !Geom::are_near((*cubic)[2], nextPointAt3)) {
- nextPointAt2 = SBasisOut.valueAt(1 - weightValue);
- if (weightValue != 0.0000) {
- nextPointAt2 =
- Geom::Point(nextPointAt2[X] + 0.0001, nextPointAt2[Y] + 0.0001);
- }
- } else {
- nextPointAt2 = out->first_segment()->finalPoint();
- }
- } else {
- if (!ignoreCusp && weightValue != 0.0000) {
- nextPointAt1 = SBasisOut.valueAt(weightValue);
- nextPointAt1 =
- Geom::Point(nextPointAt1[X] + 0.0001, nextPointAt1[Y] + 0.0001);
- nextPointAt2 = SBasisOut.valueAt(1 - weightValue);
- nextPointAt2 =
- Geom::Point(nextPointAt2[X] + 0.0001, nextPointAt2[Y] + 0.0001);
- } else {
- nextPointAt1 = out->first_segment()->initialPoint();
- nextPointAt2 = out->first_segment()->finalPoint();
- }
- }
- } else {
- if (cubic) {
- if (!ignoreCusp || !Geom::are_near((*cubic)[1], nextPointAt0)) {
- if (nodeIsSelected(nextPointAt0)) {
- nextPointAt1 = SBasisOut.valueAt(weightValue);
- if (weightValue != 0.0000) {
- nextPointAt1 = Geom::Point(nextPointAt1[X] + 0.0001,
- nextPointAt1[Y] + 0.0001);
- }
- } else {
- nextPointAt1 = (*cubic)[1];
- }
- } else {
- nextPointAt1 = out->first_segment()->initialPoint();
- }
- if (!ignoreCusp || !Geom::are_near((*cubic)[2], nextPointAt3)) {
- if (nodeIsSelected(nextPointAt3)) {
- nextPointAt2 = SBasisOut.valueAt(1 - weightValue);
- if (weightValue != 0.0000) {
- nextPointAt2 = Geom::Point(nextPointAt2[X] + 0.0001,
- nextPointAt2[Y] + 0.0001);
- }
- } else {
- nextPointAt2 = (*cubic)[2];
- }
- } else {
- nextPointAt2 = out->first_segment()->finalPoint();
- }
- } else {
- if (!ignoreCusp && weightValue != 0.0000) {
- if (nodeIsSelected(nextPointAt0)) {
- nextPointAt1 = SBasisOut.valueAt(weightValue);
- nextPointAt1 =
- Geom::Point(nextPointAt1[X] + 0.0001, nextPointAt1[Y] + 0.0001);
- } else {
- nextPointAt1 = out->first_segment()->initialPoint();
- }
- if (nodeIsSelected(nextPointAt3)) {
- nextPointAt2 = SBasisOut.valueAt(weightValue);
- nextPointAt2 =
- Geom::Point(nextPointAt2[X] + 0.0001, nextPointAt2[Y] + 0.0001);
- } else {
- nextPointAt2 = out->first_segment()->finalPoint();
- }
- } else {
- nextPointAt1 = out->first_segment()->initialPoint();
- nextPointAt2 = out->first_segment()->finalPoint();
- }
- }
- }
- out->reset();
- delete out;
- //Aberiguamos la ultima parte de la curva correspondiente al último
- //segmento
- //Y hacemos lo propio con el path de salida
- //nextPointAt0 = curveOut.valueAt(0);
if (path_it->closed()) {
- nCurve->curveto(nextPointAt1, nextPointAt2,
- path_it->begin()->initialPoint());
nCurve->move_endpoints(path_it->begin()->initialPoint(),
path_it->begin()->initialPoint());
} else {
- nCurve->curveto(nextPointAt1, nextPointAt2, nextPointAt3);
- nCurve->move_endpoints(path_it->begin()->initialPoint(), nextPointAt3);
+ nCurve->move_endpoints(path_it->begin()->initialPoint(), pointAt3);
}
//y cerramos la curva
if (path_it->closed()) {
diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp
index bab6bc7e3..17f173e47 100644
--- a/src/ui/tools/freehand-base.cpp
+++ b/src/ui/tools/freehand-base.cpp
@@ -609,12 +609,12 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed)
if (dc->sa) {
SPCurve *s = dc->sa->curve;
dc->white_curves = g_slist_remove(dc->white_curves, s);
- if (dc->sa->start) {
- s = reverse_then_unref(s);
- }
if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 ||
prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){
- dc->overwriteCurve = s;
+ s = dc->overwriteCurve;
+ }
+ if (dc->sa->start) {
+ s = reverse_then_unref(s);
}
s->append_continuous(c, 0.0625);
c->unref();
diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp
index b68231e10..a72934ae3 100644
--- a/src/ui/tools/pen-tool.cpp
+++ b/src/ui/tools/pen-tool.cpp
@@ -1827,155 +1827,145 @@ void PenTool::_bspline_spiro_build()
void PenTool::_bspline_doEffect(SPCurve * curve)
{
// commenting the function doEffect in src/live_effects/lpe-bspline.cpp
- Geom::PathVector const original_pathv = curve->get_pathvector();
- if (curve->get_segment_count() < 1)
+ if (curve->get_segment_count() < 1){
return;
+ }
+ // Make copy of old path as it is changed during processing
+ Geom::PathVector const original_pathv = curve->get_pathvector();
curve->reset();
- for(Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) {
+ //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_endit = path_it->end_default(); // this determines when the loop has to stop
+ Geom::Path::const_iterator curve_it1 = path_it->begin();
+ Geom::Path::const_iterator curve_it2 = ++(path_it->begin());
+ Geom::Path::const_iterator curve_endit = path_it->end_default();
SPCurve *nCurve = new SPCurve();
- Geom::Point previousNode(0,0);
- Geom::Point node(0,0);
- Geom::Point pointAt1(0,0);
- Geom::Point pointAt2(0,0);
- Geom::Point nextPointAt1(0,0);
- Geom::Point nextPointAt2(0,0);
- Geom::Point nextPointAt3(0,0);
- Geom::D2< Geom::SBasis > SBasisIn;
- Geom::D2< Geom::SBasis > SBasisOut;
- Geom::D2< Geom::SBasis > SBasisHelper;
+ Geom::Point previousNode(0, 0);
+ Geom::Point node(0, 0);
+ Geom::Point pointAt1(0, 0);
+ Geom::Point pointAt2(0, 0);
+ Geom::Point nextPointAt1(0, 0);
+ Geom::D2<Geom::SBasis> SBasisIn;
+ Geom::D2<Geom::SBasis> SBasisOut;
+ Geom::D2<Geom::SBasis> SBasisHelper;
Geom::CubicBezier const *cubic = NULL;
if (path_it->closed()) {
- const Geom::Curve &closingline = path_it->back_closed(); // the closing line segment is always of type Geom::LineSegment.
+ const Geom::Curve &closingline =
+ path_it->back_closed(); // the closing line segment is always of type
if (are_near(closingline.initialPoint(), closingline.finalPoint())) {
curve_endit = path_it->end_open();
}
}
- while ( curve_it2 != curve_endit )
- {
- SPCurve * in = new SPCurve();
+ nCurve->moveto(curve_it1->initialPoint());
+ while (curve_it1 != curve_endit) {
+ SPCurve *in = new SPCurve();
in->moveto(curve_it1->initialPoint());
in->lineto(curve_it1->finalPoint());
- cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
- if(cubic){
+ cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
+ if (cubic) {
SBasisIn = in->first_segment()->toSBasis();
- pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1],*in->first_segment()));
- pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2],*in->first_segment()));
- }else{
+ if(are_near((*cubic)[1],(*cubic)[0]) && !are_near((*cubic)[2],(*cubic)[3])) {
+ pointAt1 = SBasisIn.valueAt(0.3334);
+ } else {
+ pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[1], *in->first_segment()));
+ }
+ if(are_near((*cubic)[2],(*cubic)[3]) && !are_near((*cubic)[1],(*cubic)[0])) {
+ pointAt2 = SBasisIn.valueAt(0.6667);
+ } else {
+ pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*cubic)[2], *in->first_segment()));
+ }
+ } else {
pointAt1 = in->first_segment()->initialPoint();
pointAt2 = in->first_segment()->finalPoint();
}
in->reset();
delete in;
- SPCurve * out = new SPCurve();
- out->moveto(curve_it2->initialPoint());
- out->lineto(curve_it2->finalPoint());
- 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 = out->first_segment()->initialPoint();
- nextPointAt2 = out->first_segment()->finalPoint();
- nextPointAt3 = out->first_segment()->finalPoint();
+ if ( curve_it2 != curve_endit ) {
+ SPCurve *out = new SPCurve();
+ out->moveto(curve_it2->initialPoint());
+ out->lineto(curve_it2->finalPoint());
+ cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it2);
+ if (cubic) {
+ SBasisOut = out->first_segment()->toSBasis();
+ if(are_near((*cubic)[1],(*cubic)[0]) && !are_near((*cubic)[2],(*cubic)[3])) {
+ nextPointAt1 = SBasisIn.valueAt(0.3334);
+ } else {
+ nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubic)[1], *out->first_segment()));
+ }
+ } else {
+ nextPointAt1 = out->first_segment()->initialPoint();
+ }
+ out->reset();
+ delete out;
+ }
+ Geom::Point startNode = path_it->begin()->initialPoint();
+ if (path_it->closed() && curve_it2 == curve_endit) {
+ SPCurve *start = new SPCurve();
+ start->moveto(path_it->begin()->initialPoint());
+ start->lineto(path_it->begin()->finalPoint());
+ Geom::D2<Geom::SBasis> SBasisStart = start->first_segment()->toSBasis();
+ SPCurve *lineHelper = new SPCurve();
+ cubic = dynamic_cast<Geom::CubicBezier const *>(&*path_it->begin());
+ if (cubic) {
+ lineHelper->moveto(SBasisStart.valueAt(
+ Geom::nearest_point((*cubic)[1], *start->first_segment())));
+ } else {
+ lineHelper->moveto(start->first_segment()->initialPoint());
+ }
+ start->reset();
+ delete start;
+
+ SPCurve *end = new SPCurve();
+ end->moveto(curve_it1->initialPoint());
+ end->lineto(curve_it1->finalPoint());
+ Geom::D2<Geom::SBasis> SBasisEnd = end->first_segment()->toSBasis();
+ cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
+ if (cubic) {
+ lineHelper->lineto(SBasisEnd.valueAt(
+ Geom::nearest_point((*cubic)[2], *end->first_segment())));
+ } else {
+ lineHelper->lineto(end->first_segment()->finalPoint());
+ }
+ end->reset();
+ delete end;
+ SBasisHelper = lineHelper->first_segment()->toSBasis();
+ lineHelper->reset();
+ delete lineHelper;
+ startNode = SBasisHelper.valueAt(0.5);
+ nCurve->curveto(pointAt1, pointAt2, startNode);
+ nCurve->move_endpoints(startNode, startNode);
+ } else if ( curve_it2 == curve_endit) {
+ nCurve->curveto(pointAt1, pointAt2, curve_it1->finalPoint());
+ nCurve->move_endpoints(path_it->begin()->initialPoint(), curve_it1->finalPoint());
+ } else {
+ SPCurve *lineHelper = new SPCurve();
+ lineHelper->moveto(pointAt2);
+ lineHelper->lineto(nextPointAt1);
+ SBasisHelper = lineHelper->first_segment()->toSBasis();
+ lineHelper->reset();
+ delete lineHelper;
+ previousNode = node;
+ node = SBasisHelper.valueAt(0.5);
+ Geom::CubicBezier const *cubic2 = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
+ if((cubic && are_near((*cubic)[0],(*cubic)[1])) || (cubic2 && are_near((*cubic2)[2],(*cubic2)[3]))) {
+ node = curve_it1->finalPoint();
+ }
+ nCurve->curveto(pointAt1, pointAt2, node);
}
- out->reset();
- delete out;
- SPCurve *lineHelper = new SPCurve();
- lineHelper->moveto(pointAt2);
- lineHelper->lineto(nextPointAt1);
- SBasisHelper = lineHelper->first_segment()->toSBasis();
- lineHelper->reset();
- delete lineHelper;
- previousNode = node;
- node = SBasisHelper.valueAt(0.5);
- SPCurve *curveHelper = new SPCurve();
- curveHelper->moveto(previousNode);
- curveHelper->curveto(pointAt1, pointAt2, node);
- nCurve->append_continuous(curveHelper, 0.0625);
- curveHelper->reset();
- delete curveHelper;
++curve_it1;
++curve_it2;
}
- SPCurve *out = new SPCurve();
- out->moveto(curve_it1->initialPoint());
- out->lineto(curve_it1->finalPoint());
- cubic = dynamic_cast<Geom::CubicBezier const *>(&*curve_it1);
- 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 = out->first_segment()->finalPoint();
- } else {
- nextPointAt1 = out->first_segment()->initialPoint();
- nextPointAt2 = out->first_segment()->finalPoint();
- nextPointAt3 = out->first_segment()->finalPoint();
- }
- out->reset();
- delete out;
- SPCurve *curveHelper = new SPCurve();
- curveHelper->moveto(node);
- Geom::Point startNode = path_it->begin()->initialPoint();
- if (path_it->closed()) {
- SPCurve * start = new SPCurve();
- start->moveto(path_it->begin()->initialPoint());
- start->lineto(path_it->begin()->finalPoint());
- Geom::D2< Geom::SBasis > SBasisStart = start->first_segment()->toSBasis();
- SPCurve *lineHelper = new SPCurve();
- cubic = dynamic_cast<Geom::CubicBezier const*>(&*path_it->begin());
- if(cubic){
- lineHelper->moveto(SBasisStart.valueAt(Geom::nearest_point((*cubic)[1],*start->first_segment())));
- }else{
- lineHelper->moveto(start->first_segment()->initialPoint());
- }
- start->reset();
- delete start;
-
- SPCurve * end = new SPCurve();
- end->moveto(curve_it1->initialPoint());
- end->lineto(curve_it1->finalPoint());
- Geom::D2< Geom::SBasis > SBasisEnd = end->first_segment()->toSBasis();
- cubic = dynamic_cast<Geom::CubicBezier const*>(&*curve_it1);
- if(cubic){
- lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*cubic)[2],*end->first_segment())));
- }else{
- lineHelper->lineto(end->first_segment()->finalPoint());
- }
- end->reset();
- delete end;
- SBasisHelper = lineHelper->first_segment()->toSBasis();
- lineHelper->reset();
- delete lineHelper;
- startNode = SBasisHelper.valueAt(0.5);
- curveHelper->curveto(nextPointAt1, nextPointAt2, startNode);
- nCurve->append_continuous(curveHelper, 0.0625);
- nCurve->move_endpoints(startNode,startNode);
- }else{
- SPCurve * start = new SPCurve();
- start->moveto(path_it->begin()->initialPoint());
- start->lineto(path_it->begin()->finalPoint());
- startNode = start->first_segment()->initialPoint();
- start->reset();
- delete start;
- curveHelper->curveto(nextPointAt1, nextPointAt2, nextPointAt3);
- nCurve->append_continuous(curveHelper, 0.0625);
- nCurve->move_endpoints(startNode,nextPointAt3);
- }
- curveHelper->reset();
- delete curveHelper;
if (path_it->closed()) {
nCurve->closepath_current();
}
- curve->append(nCurve,false);
+ curve->append(nCurve, false);
nCurve->reset();
delete nCurve;
}