From 9bddaf7172a6bb788ccae3ba5a30599d63acf424 Mon Sep 17 00:00:00 2001 From: johanengelen Date: Wed, 20 Feb 2008 08:58:35 +0000 Subject: [PATCH] fix Bug #191909 crash on lpe stitch sub-paths, also fix crash for bend path lpe --- src/live_effects/lpe-curvestitch.cpp | 112 ++++++++++++++----------- src/live_effects/lpe-pathalongpath.cpp | 3 + src/live_effects/parameter/path.cpp | 6 ++ src/live_effects/parameter/path.h | 2 +- 4 files changed, 73 insertions(+), 50 deletions(-) diff --git a/src/live_effects/lpe-curvestitch.cpp b/src/live_effects/lpe-curvestitch.cpp index 98814eab0..8dbd9feb1 100644 --- a/src/live_effects/lpe-curvestitch.cpp +++ b/src/live_effects/lpe-curvestitch.cpp @@ -85,52 +85,61 @@ LPECurveStitch::doEffect_path (std::vector & path_in) Interval bndsStrokeY = bounds_exact(stroke[1]); Point stroke_origin(bndsStroke.min(), (bndsStrokeY.max()+bndsStrokeY.min())/2); - std::vector path_out (nrofpaths); - - // do this for all permutations if there are more than 2 paths? realllly cool! - Piecewise > A = arc_length_parametrization(Piecewise >(path_in[0].toPwSb()),2,.1); - Piecewise > B = arc_length_parametrization(Piecewise >(path_in[1].toPwSb()),2,.1); - Interval bndsA = A.domain(); - Interval bndsB = B.domain(); - gdouble incrementA = (bndsA.max()-bndsA.min()) / (nrofpaths-1); - gdouble incrementB = (bndsB.max()-bndsB.min()) / (nrofpaths-1); - gdouble tA = bndsA.min(); - gdouble tB = bndsB.min(); - gdouble tAclean = tA; // the tA without spacing_variation - gdouble tBclean = tB; // the tB without spacing_variation - for (int i = 0; i < nrofpaths; i++) { - Point start = A(tA); - Point end = B(tB); - if (startpoint_edge_variation.get_value() != 0) - start = start + (startpoint_edge_variation - startpoint_edge_variation.get_value()/2) * (end - start); - if (endpoint_edge_variation.get_value() != 0) - end = end + (endpoint_edge_variation - endpoint_edge_variation.get_value()/2)* (end - start); - - gdouble scaling_y = 1.0; - if (scale_y_rel.get_value()) { - scaling_y = (L2(end-start)/scaling)*prop_scale; - } else { - scaling_y = prop_scale; + std::vector path_out; + + // do this for all permutations (ii,jj) if there are more than 2 paths? realllly cool! + for (int ii = 0 ; ii < path_in.size() - 1; ii++) + for (int jj = ii+1; jj < path_in.size(); jj++) + { + Piecewise > A = arc_length_parametrization(Piecewise >(path_in[ii].toPwSb()),2,.1); + Piecewise > B = arc_length_parametrization(Piecewise >(path_in[jj].toPwSb()),2,.1); + Interval bndsA = A.domain(); + Interval bndsB = B.domain(); + gdouble incrementA = (bndsA.max()-bndsA.min()) / (nrofpaths-1); + gdouble incrementB = (bndsB.max()-bndsB.min()) / (nrofpaths-1); + gdouble tA = bndsA.min(); + gdouble tB = bndsB.min(); + gdouble tAclean = tA; // the tA without spacing_variation + gdouble tBclean = tB; // the tB without spacing_variation + + for (int i = 0; i < nrofpaths; i++) { + Point start = A(tA); + Point end = B(tB); + if (startpoint_edge_variation.get_value() != 0) + start = start + (startpoint_edge_variation - startpoint_edge_variation.get_value()/2) * (end - start); + if (endpoint_edge_variation.get_value() != 0) + end = end + (endpoint_edge_variation - endpoint_edge_variation.get_value()/2)* (end - start); + + if (!Geom::are_near(start,end)) { + gdouble scaling_y = 1.0; + if (scale_y_rel.get_value()) { + scaling_y = (L2(end-start)/scaling)*prop_scale; + } else { + scaling_y = prop_scale; + } + + Matrix transform; + transform.setXAxis( (end-start) / scaling ); + transform.setYAxis( rot90(unit_vector(end-start)) * scaling_y); + transform.setTranslation( start ); + Piecewise > pwd2_out = (strokepath-stroke_origin) * transform; + + // add stuff to one big pw > and then outside the loop convert to path? + // No: this way, the separate result paths are kept separate which might come in handy some time! + std::vector result = Geom::path_from_piecewise(pwd2_out, LPE_CONVERSION_TOLERANCE); + path_out.push_back(result[0]); + } + gdouble svA = startpoint_spacing_variation - startpoint_spacing_variation.get_value()/2; + gdouble svB = endpoint_spacing_variation - endpoint_spacing_variation.get_value()/2; + tAclean += incrementA; + tBclean += incrementB; + tA = tAclean + incrementA * svA; + tB = tBclean + incrementB * svB; + if (tA > bndsA.max()) + tA = bndsA.max(); + if (tB > bndsB.max()) + tB = bndsB.max(); } - - Matrix transform; - transform.setXAxis( (end-start) / scaling ); - transform.setYAxis( rot90(unit_vector(end-start)) * scaling_y); - transform.setTranslation( start ); - Piecewise > pwd2_out = (strokepath-stroke_origin) * transform; - // add stuff to one big pw > and then outside the loop convert to path? - std::vector result = Geom::path_from_piecewise(pwd2_out, LPE_CONVERSION_TOLERANCE); - path_out[i] = result[0]; - gdouble svA = startpoint_spacing_variation - startpoint_spacing_variation.get_value()/2; - gdouble svB = endpoint_spacing_variation - endpoint_spacing_variation.get_value()/2; - tAclean += incrementA; - tBclean += incrementB; - tA = tAclean + incrementA * svA; - tB = tBclean + incrementB * svB; - if (tA > bndsA.max()) - tA = bndsA.max(); - if (tB > bndsB.max()) - tB = bndsB.max(); } return path_out; @@ -159,10 +168,15 @@ LPECurveStitch::resetDefaults(SPItem * item) Point start(bndsX.min(), (bndsY.max()+bndsY.min())/2); Point end(bndsX.max(), (bndsY.max()+bndsY.min())/2); - Geom::Path path; - path.start( start ); - path.appendNew( end ); - strokepath.param_set_and_write_new_value( path.toPwSb() ); + if ( !Geom::are_near(start,end) ) { + Geom::Path path; + path.start( start ); + path.appendNew( end ); + strokepath.param_set_and_write_new_value( path.toPwSb() ); + } else { + // bounding box is too small to make decent path. set to default default. :-) + strokepath.param_set_and_write_default(); + } } void diff --git a/src/live_effects/lpe-pathalongpath.cpp b/src/live_effects/lpe-pathalongpath.cpp index ba09402b7..750d78346 100644 --- a/src/live_effects/lpe-pathalongpath.cpp +++ b/src/live_effects/lpe-pathalongpath.cpp @@ -130,6 +130,9 @@ LPEPathAlongPath::resetDefaults(SPItem * item) Point start(bndsX.min(), (bndsY.max()+bndsY.min())/2); Point end(bndsX.max(), (bndsY.max()+bndsY.min())/2); + if ( Geom::are_near(start,end) ) { + end += Point(1.,0.); + } Geom::Path path; path.start( start ); path.appendNew( end ); diff --git a/src/live_effects/parameter/path.cpp b/src/live_effects/parameter/path.cpp index 7d7679496..09b0ff5d4 100644 --- a/src/live_effects/parameter/path.cpp +++ b/src/live_effects/parameter/path.cpp @@ -58,6 +58,12 @@ PathParam::param_set_default() param_readSVGValue(defvalue); } +void +PathParam::param_set_and_write_default() +{ + param_write_to_repr(defvalue); +} + bool PathParam::param_readSVGValue(const gchar * strvalue) { diff --git a/src/live_effects/parameter/path.h b/src/live_effects/parameter/path.h index f02974bc7..8ee7950a3 100644 --- a/src/live_effects/parameter/path.h +++ b/src/live_effects/parameter/path.h @@ -39,7 +39,7 @@ public: gchar * param_writeSVGValue() const; void param_set_default(); - + void param_set_and_write_default(); void param_set_and_write_new_value (Geom::Piecewise > newpath); void param_editOncanvas(SPItem * item, SPDesktop * dt); -- 2.30.2