Code

fix Bug #191909 crash on lpe stitch sub-paths, also fix crash for bend path lpe
authorjohanengelen <johanengelen@users.sourceforge.net>
Wed, 20 Feb 2008 08:58:35 +0000 (08:58 +0000)
committerjohanengelen <johanengelen@users.sourceforge.net>
Wed, 20 Feb 2008 08:58:35 +0000 (08:58 +0000)
src/live_effects/lpe-curvestitch.cpp
src/live_effects/lpe-pathalongpath.cpp
src/live_effects/parameter/path.cpp
src/live_effects/parameter/path.h

index 98814eab0ef09d0853b31d5aa32e4d63362aa8ff..8dbd9feb153335edcc6e8651c1da8e334b8da671 100644 (file)
@@ -85,52 +85,61 @@ LPECurveStitch::doEffect_path (std::vector<Geom::Path> & path_in)
         Interval bndsStrokeY = bounds_exact(stroke[1]);
         Point stroke_origin(bndsStroke.min(), (bndsStrokeY.max()+bndsStrokeY.min())/2);
 
-        std::vector<Geom::Path> path_out (nrofpaths);
-
-        // do this for all permutations if there are more than 2 paths? realllly cool!
-        Piecewise<D2<SBasis> > A = arc_length_parametrization(Piecewise<D2<SBasis> >(path_in[0].toPwSb()),2,.1);
-        Piecewise<D2<SBasis> > B = arc_length_parametrization(Piecewise<D2<SBasis> >(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<Geom::Path> 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<D2<SBasis> > A = arc_length_parametrization(Piecewise<D2<SBasis> >(path_in[ii].toPwSb()),2,.1);
+            Piecewise<D2<SBasis> > B = arc_length_parametrization(Piecewise<D2<SBasis> >(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<D2<SBasis> > pwd2_out = (strokepath-stroke_origin) * transform;
+
+                    // add stuff to one big pw<d2<sbasis> > 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<Geom::Path> 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<D2<SBasis> > pwd2_out = (strokepath-stroke_origin) * transform;
-            // add stuff to one big pw<d2<sbasis> > and then outside the loop convert to path?
-            std::vector<Geom::Path> 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<Geom::LineSegment>( end );
-    strokepath.param_set_and_write_new_value( path.toPwSb() );
+    if ( !Geom::are_near(start,end) ) {
+        Geom::Path path;
+        path.start( start );
+        path.appendNew<Geom::LineSegment>( 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
index ba09402b7fbb545121db4a23ec88a3d046281928..750d7834675402dd4ee1c1149435262ae387c55d 100644 (file)
@@ -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<Geom::LineSegment>( end );
index 7d7679496ba489b39174095ca3656cfa535ad7af..09b0ff5d40cc4216c382cdad10d86bbc2f86d2ea 100644 (file)
@@ -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)
 {
index f02974bc7b9793de318ec7c910cef4e8a12ad4c1..8ee7950a3a860ef94e3c1756f92794a151116778 100644 (file)
@@ -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<Geom::D2<Geom::SBasis> > newpath);
 
     void param_editOncanvas(SPItem * item, SPDesktop * dt);