summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2013-02-18 10:23:51 +0000
committerJabiertxo Arraiza Zenotz <jtx@jtx.marker.es>2013-02-18 10:23:51 +0000
commit4a0858ff965d54fc08f721fbbc2503f9ab3d9d3c (patch)
tree7719939529093ed6ed64f4d3873bc28d6c18a1cf /src
parentMerge from lp:~jabiertxof/inkscape/SpiroLive+BSpline@BPower for fix diverged (diff)
downloadinkscape-4a0858ff965d54fc08f721fbbc2503f9ab3d9d3c.tar.gz
inkscape-4a0858ff965d54fc08f721fbbc2503f9ab3d9d3c.zip
refactor
(bzr r11950.1.35)
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/lpe-bspline.cpp46
-rw-r--r--src/pen-context.cpp88
-rw-r--r--src/ui/tool/node.cpp26
-rw-r--r--src/ui/tool/path-manipulator.cpp102
-rw-r--r--src/ui/tool/path-manipulator.h6
5 files changed, 196 insertions, 72 deletions
diff --git a/src/live_effects/lpe-bspline.cpp b/src/live_effects/lpe-bspline.cpp
index 0ce18dcea..858a09159 100644
--- a/src/live_effects/lpe-bspline.cpp
+++ b/src/live_effects/lpe-bspline.cpp
@@ -45,14 +45,14 @@ LPEBSpline::doEffect(SPCurve * curve)
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);
@@ -66,9 +66,7 @@ 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::BezierCurve const *bezier;
//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...
@@ -80,6 +78,7 @@ LPEBSpline::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
@@ -91,19 +90,18 @@ LPEBSpline::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() && cubicEnd && (*cubicEnd)[3] != (*cubicEnd)[2]){
+ bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_end);
+ if (path_it->closed() && bezier && (*bezier)[2] != (*bezier)[3]) {
//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())));
+ bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_it1);
+ lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*bezier)[1],*in->first_segment())));
+ bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_end);
+ lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*bezier)[2],*end->first_segment())));
SBasisHelper = lineHelper->first_segment()->toSBasis();
lineHelper->reset();
//Guardamos el principio de la curva
@@ -111,9 +109,12 @@ LPEBSpline::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 )
{
@@ -121,10 +122,11 @@ LPEBSpline::doEffect(SPCurve * curve)
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
- if(cubicIn){
+ bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_it1);
+ if(bezier){
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()));
+ pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*bezier)[1],*in->first_segment()));
+ pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*bezier)[2],*in->first_segment()));
pointAt3 = SBasisIn.valueAt(1);
}else{
pointAt0 = SBasisIn.valueAt(0);
@@ -134,9 +136,10 @@ LPEBSpline::doEffect(SPCurve * curve)
}
//Y hacemos lo propio con el path de salida
//nextPointAt0 = curveOut.valueAt(0);
- if(cubicOut){
- nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[1],*out->first_segment()));
- nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[2],*out->first_segment()));
+ bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_it2);
+ if(bezier){
+ nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*bezier)[1],*out->first_segment()));
+ nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*bezier)[2],*out->first_segment()));
nextPointAt3 = SBasisOut.valueAt(1);
}else{
nextPointAt1 = SBasisOut.valueAt(0);
@@ -178,10 +181,7 @@ LPEBSpline::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);
diff --git a/src/pen-context.cpp b/src/pen-context.cpp
index 9577ecbf9..26eb77b06 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;
@@ -1951,14 +1989,14 @@ static void bspline_doEffect(SPCurve * curve)
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);
@@ -1972,9 +2010,7 @@ static void bspline_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::BezierCurve const *bezier;
//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...
@@ -1986,6 +2022,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 +2034,18 @@ 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()){
+ bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_end);
+ if (path_it->closed() && bezier && (*bezier)[2] != (*bezier)[3]) {
//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())));
+ bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_it1);
+ lineHelper->moveto(SBasisIn.valueAt(Geom::nearest_point((*bezier)[1],*in->first_segment())));
+ bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_end);
+ lineHelper->lineto(SBasisEnd.valueAt(Geom::nearest_point((*bezier)[2],*end->first_segment())));
SBasisHelper = lineHelper->first_segment()->toSBasis();
lineHelper->reset();
//Guardamos el principio de la curva
@@ -2017,9 +2053,12 @@ 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 )
{
@@ -2027,10 +2066,11 @@ static void bspline_doEffect(SPCurve * curve)
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
- if(cubicIn){
+ bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_it1);
+ if(bezier){
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()));
+ pointAt1 = SBasisIn.valueAt(Geom::nearest_point((*bezier)[1],*in->first_segment()));
+ pointAt2 = SBasisIn.valueAt(Geom::nearest_point((*bezier)[2],*in->first_segment()));
pointAt3 = SBasisIn.valueAt(1);
}else{
pointAt0 = SBasisIn.valueAt(0);
@@ -2040,9 +2080,10 @@ static void bspline_doEffect(SPCurve * curve)
}
//Y hacemos lo propio con el path de salida
//nextPointAt0 = curveOut.valueAt(0);
- if(cubicOut){
- nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[1],*out->first_segment()));
- nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*cubicOut)[2],*out->first_segment()));
+ bezier = dynamic_cast<Geom::BezierCurve const*>(&*curve_it2);
+ if(bezier){
+ nextPointAt1 = SBasisOut.valueAt(Geom::nearest_point((*bezier)[1],*out->first_segment()));
+ nextPointAt2 = SBasisOut.valueAt(Geom::nearest_point((*bezier)[2],*out->first_segment()));
nextPointAt3 = SBasisOut.valueAt(1);
}else{
nextPointAt1 = SBasisOut.valueAt(0);
@@ -2084,10 +2125,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);
diff --git a/src/ui/tool/node.cpp b/src/ui/tool/node.cpp
index dc6e0fbae..dff8d3dd9 100644
--- a/src/ui/tool/node.cpp
+++ b/src/ui/tool/node.cpp
@@ -13,7 +13,6 @@
#include <glib/gi18n.h>
#include <2geom/bezier-utils.h>
#include <2geom/transforms.h>
-
#include "display/sp-ctrlline.h"
#include "display/sp-canvas.h"
#include "display/sp-canvas-util.h"
@@ -196,8 +195,13 @@ void Handle::move(Geom::Point const &new_pos)
break;
default: break;
}
-
- setPosition(new_pos);
+ //BSpline
+ if(_pm().isBSpline()){
+ Handle *h = this;
+ setPosition(_pm().BSplineHandleReposition(h));
+ }else
+ setPosition(new_pos);
+ //BSpline End
}
void Handle::setPosition(Geom::Point const &p)
@@ -550,10 +554,24 @@ void Node::move(Geom::Point const &new_pos)
// move handles when the node moves.
Geom::Point old_pos = position();
Geom::Point delta = new_pos - position();
+ //BSpline
+ float pos = 0;
+ if(_pm().isBSpline()){
+ Node *n = this;
+ pos = _pm().BSplineMaxPosition(n);
+ }
+ //BSpline End
setPosition(new_pos);
_front.setPosition(_front.position() + delta);
_back.setPosition(_back.position() + delta);
-
+ //BSpline
+ if(_pm().isBSpline()){
+ Handle* front = &_front;
+ Handle* back = &_back;
+ _front.setPosition(_pm().BSplineHandleRepositionFixed(front,pos));
+ _back.setPosition(_pm().BSplineHandleRepositionFixed(back,pos));
+ }
+ //BSpline End
// if the node has a smooth handle after a line segment, it should be kept colinear
// with the segment
_fixNeighbors(old_pos, new_pos);
diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp
index f1b2e12be..b650987bc 100644
--- a/src/ui/tool/path-manipulator.cpp
+++ b/src/ui/tool/path-manipulator.cpp
@@ -1102,7 +1102,6 @@ void PathManipulator::_createControlPointsFromGeometry()
Geom::Curve const &cseg = pit->back_closed();
bool fuse_ends = pit->closed()
&& Geom::are_near(cseg.initialPoint(), cseg.finalPoint());
-
for (Geom::Path::const_iterator cit = pit->begin(); cit != pit->end_open(); ++cit) {
Geom::Point pos = cit->finalPoint();
Node *current_node;
@@ -1169,6 +1168,75 @@ void PathManipulator::_createControlPointsFromGeometry()
}
}
+
+bool PathManipulator::isBSpline(){
+ LivePathEffect::LPEBSpline *lpe_bsp = NULL;
+ if (SP_IS_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))) {
+ PathEffectList effect_list = sp_lpe_item_get_effect_list(SP_LPE_ITEM(_path));
+ lpe_bsp = dynamic_cast<LivePathEffect::LPEBSpline*>( effect_list.front()->lpeobject->get_lpe());
+ }else{
+ lpe_bsp = NULL;
+ }
+ if(lpe_bsp){
+ return true;
+ }
+ return false;
+}
+double PathManipulator::BSplineMaxPosition(Node *n){
+ double nearestPointAt = 0;
+ Geom::D2< Geom::SBasis > SBasisInsideNodes;
+ SPCurve *lineInsideNodes = new SPCurve();
+ Node * frontNode = n->nodeToward(n->front());
+ if(frontNode){
+ lineInsideNodes->moveto(n->position());
+ lineInsideNodes->lineto(frontNode->position());
+ SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis();
+ nearestPointAt = Geom::nearest_point(n->front()->position(),*lineInsideNodes->first_segment());
+ }
+ Node * backNode = n->nodeToward(n->back());
+ if(backNode){
+ lineInsideNodes->reset();
+ lineInsideNodes->moveto(n->position());
+ lineInsideNodes->lineto(backNode->position());
+ SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis();
+ using std::max;
+ nearestPointAt = max(nearestPointAt,1-Geom::nearest_point(n->back()->position(),*lineInsideNodes->first_segment()));
+ }
+ return nearestPointAt;
+}
+
+Geom::Point PathManipulator::BSplineHandleReposition(Handle *h){
+ double nearestPointAt = 0;
+ Node *n = h->parent();
+ Geom::D2< Geom::SBasis > SBasisInsideNodes;
+ SPCurve *lineInsideNodes = new SPCurve();
+ Node * nextNode = n->nodeToward(h);
+ if(nextNode){
+ lineInsideNodes->moveto(n->position());
+ lineInsideNodes->lineto(nextNode->position());
+ SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis();
+ nearestPointAt = Geom::nearest_point(n->front()->position(),*lineInsideNodes->first_segment());
+ }
+ return SBasisInsideNodes.valueAt(nearestPointAt);
+}
+
+Geom::Point PathManipulator::BSplineHandleRepositionFixed(Handle *h,double pos){
+ Node *n = h->parent();
+ if(n->back()->position() == h->position())
+ pos = 1-pos;
+ Geom::D2< Geom::SBasis > SBasisInsideNodes;
+ SPCurve *lineInsideNodes = new SPCurve();
+ Node * nextNode = n->nodeToward(h);
+ if(nextNode){
+ lineInsideNodes->moveto(n->position());
+ lineInsideNodes->lineto(nextNode->position());
+ SBasisInsideNodes = lineInsideNodes->first_segment()->toSBasis();
+ }else{
+ return n->position();
+ }
+ return SBasisInsideNodes.valueAt(pos);
+}
+
/** Construct the geometric representation of nodes and handles, update the outline
* and display
* \param alert_LPE if true, first the LPE is warned what the new path is going to be before updating it
@@ -1184,14 +1252,25 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE)
}
NodeList::iterator prev = subpath->begin();
builder.moveTo(prev->position());
-
for (NodeList::iterator i = ++subpath->begin(); i != subpath->end(); ++i) {
+ if (this->isBSpline()) {
+ float pos = BSplineMaxPosition(i.ptr());
+ i.ptr()->front()->setPosition(BSplineHandleRepositionFixed(i.ptr()->front(),pos));
+ i.ptr()->back()->setPosition(BSplineHandleRepositionFixed(i.ptr()->back(),pos));
+ }
+ //BSplie End
build_segment(builder, prev.ptr(), i.ptr());
prev = i;
}
if (subpath->closed()) {
// Here we link the last and first node if the path is closed.
// If the last segment is Bezier, we add it.
+ if (this->isBSpline()) {
+ float pos = BSplineMaxPosition(prev.ptr());
+ subpath->begin().ptr()->front()->setPosition(BSplineHandleRepositionFixed(subpath->begin().ptr()->front(),pos));
+ prev.ptr()->back()->setPosition(BSplineHandleRepositionFixed(prev.ptr()->back(),pos));
+
+ }
if (!prev->front()->isDegenerate() || !subpath->begin()->back()->isDegenerate()) {
build_segment(builder, prev.ptr(), subpath->begin().ptr());
}
@@ -1200,6 +1279,7 @@ void PathManipulator::_createGeometryFromControlPoints(bool alert_LPE)
}
++spi;
}
+
builder.finish();
Geom::PathVector pathv = builder.peek() * (_edit_transform * _i2d_transform).inverse();
_spcurve->set_pathvector(pathv);
@@ -1261,24 +1341,6 @@ void PathManipulator::_updateOutline()
}
Geom::PathVector pv = _spcurve->get_pathvector();
pv *= (_edit_transform * _i2d_transform);
- //BSpline
- if (SP_IS_LPE_ITEM(_path) && sp_lpe_item_has_path_effect(SP_LPE_ITEM(_path))) {
- PathEffectList effect_list = sp_lpe_item_get_effect_list(SP_LPE_ITEM(_path));
- LivePathEffect::LPEBSpline *lpe_bsp = dynamic_cast<LivePathEffect::LPEBSpline*>( effect_list.front()->lpeobject->get_lpe());
- if (lpe_bsp) {
- Geom::PathVector pv2;
- for (Geom::PathVector::iterator i = pv.begin(); i != pv.end(); ++i) {
- Geom::Path &path = *i;
- for (Geom::Path::const_iterator j = path.begin(); j != path.end_default(); ++j) {
- Geom::Path pv2j(j->pointAt(0));
- pv2j.appendNew<Geom::LineSegment>(j->pointAt(1));
- pv2.push_back(pv2j);
- }
- }
- pv = pv2;
- }
- }
- //BSpline End
// This SPCurve thing has to be killed with extreme prejudice
SPCurve *_hc = new SPCurve();
if (_show_path_direction) {
diff --git a/src/ui/tool/path-manipulator.h b/src/ui/tool/path-manipulator.h
index a51b8c410..72d84a241 100644
--- a/src/ui/tool/path-manipulator.h
+++ b/src/ui/tool/path-manipulator.h
@@ -104,6 +104,12 @@ private:
typedef boost::shared_ptr<NodeList> SubpathPtr;
void _createControlPointsFromGeometry();
+ //BSpline
+ bool isBSpline();
+ double BSplineMaxPosition(Node *n);
+ Geom::Point BSplineHandleReposition(Handle *h);
+ Geom::Point BSplineHandleRepositionFixed(Handle *h,double pos);
+ //BSpline End
void _createGeometryFromControlPoints(bool alert_LPE = false);
unsigned _deleteStretch(NodeList::iterator first, NodeList::iterator last, bool keep_shape);
std::string _createTypeString();