b0e8dc8f7106cc0333159a46e3f9339ea7a58120
1 #define INKSCAPE_LPE_EXPRESSION_CPP\r
2 /** \file\r
3 * SVG <skeleton> implementation, used as an example for a base starting class\r
4 * when implementing new LivePathEffects.\r
5 *\r
6 */\r
7 /*\r
8 * Authors:\r
9 * Johan Engelen\r
10 *\r
11 * Copyright (C) Johan Engelen 2007 <j.b.c.engelen@utwente.nl>\r
12 *\r
13 * Released under GNU GPL, read the file 'COPYING' for more information\r
14 */\r
15 \r
16 #include "live_effects/lpe-curvestitch.h"\r
17 #include "display/curve.h"\r
18 #include <libnr/n-art-bpath.h>\r
19 \r
20 #include <2geom/path.h>\r
21 #include <2geom/piecewise.h>\r
22 #include <2geom/sbasis.h>\r
23 #include <2geom/sbasis-geometric.h>\r
24 #include <2geom/bezier-to-sbasis.h>\r
25 #include <2geom/sbasis-to-bezier.h>\r
26 #include <2geom/d2.h>\r
27 #include <2geom/matrix.h>\r
28 \r
29 \r
30 #include "ui/widget/scalar.h"\r
31 #include "libnr/nr-values.h"\r
32 \r
33 namespace Inkscape {\r
34 namespace LivePathEffect {\r
35 \r
36 using namespace Geom;\r
37 \r
38 LPECurveStitch::LPECurveStitch(LivePathEffectObject *lpeobject) :\r
39 Effect(lpeobject),\r
40 strokepath(_("Stroke path"), _("The path that will be stroked, whatever, think of good text here."), "strokepath", &wr, this, "M0,0 L1,0"),\r
41 nrofpaths(_("Nr of paths"), _("The number of paths that will be generated."), "count", &wr, this, 5),\r
42 startpoint_variation(_("Startpoint variation"), _("..."), "startpoint_variation", &wr, this, 0),\r
43 endpoint_variation(_("Endpoint variation"), _("..."), "endpoint_variation", &wr, this, 0)\r
44 {\r
45 registerParameter( dynamic_cast<Parameter *>(&nrofpaths) );\r
46 registerParameter( dynamic_cast<Parameter *>(&startpoint_variation) );\r
47 registerParameter( dynamic_cast<Parameter *>(&endpoint_variation) );\r
48 registerParameter( dynamic_cast<Parameter *>(&strokepath) );\r
49 \r
50 nrofpaths.param_make_integer();\r
51 nrofpaths.param_set_range(2, NR_HUGE);\r
52 \r
53 // startpoint_variation.param_set_range(-NR_HUGE, 1);\r
54 // endpoint_variation.param_set_range(-1, NR_HUGE);\r
55 }\r
56 \r
57 LPECurveStitch::~LPECurveStitch()\r
58 {\r
59 \r
60 }\r
61 \r
62 std::vector<Geom::Path>\r
63 LPECurveStitch::doEffect (std::vector<Geom::Path> & path_in)\r
64 {\r
65 if (path_in.size() >= 2) {\r
66 D2<Piecewise<SBasis> > stroke = make_cuts_independant(strokepath);\r
67 Interval bndsStroke = bounds_exact(stroke[0]);\r
68 gdouble scaling = bndsStroke.max() - bndsStroke.min();\r
69 Interval bndsStrokeY = bounds_exact(stroke[1]);\r
70 Point stroke_origin(bndsStroke.min(), (bndsStrokeY.max()+bndsStrokeY.min())/2);\r
71 \r
72 std::vector<Geom::Path> path_out (nrofpaths);\r
73 \r
74 // do this for all permutations if there are more than 2 paths? realllly cool!\r
75 Piecewise<D2<SBasis> > A = arc_length_parametrization(Piecewise<D2<SBasis> >(path_in[0].toPwSb()),2,.1);\r
76 Piecewise<D2<SBasis> > B = arc_length_parametrization(Piecewise<D2<SBasis> >(path_in[1].toPwSb()),2,.1);\r
77 Interval bndsA = A.domain();\r
78 Interval bndsB = B.domain();\r
79 gdouble incrementA = (bndsA.max()-bndsA.min()) / (nrofpaths-1);\r
80 gdouble incrementB = (bndsB.max()-bndsB.min()) / (nrofpaths-1);\r
81 gdouble tA = bndsA.min();\r
82 gdouble tB = bndsB.min();\r
83 for (int i = 0; i < nrofpaths; i++) {\r
84 Point start = A(tA);\r
85 Point end = B(tB);\r
86 if (startpoint_variation != 0)\r
87 start = start + g_random_double_range(0, startpoint_variation) * (end - start);\r
88 if (endpoint_variation != 0)\r
89 end = end + g_random_double_range(0, endpoint_variation) * (end - start);\r
90 \r
91 Matrix transform;\r
92 transform.setXAxis( (end-start) / scaling );\r
93 transform.setYAxis( rot90(unit_vector(end-start)));\r
94 transform.setTranslation( start );\r
95 Piecewise<D2<SBasis> > pwd2_out = (strokepath-stroke_origin) * transform;\r
96 std::vector<Path> result = Geom::path_from_piecewise(pwd2_out, LPE_CONVERSION_TOLERANCE);\r
97 path_out[i] = result[0];\r
98 tA += incrementA;\r
99 tB += incrementB;\r
100 }\r
101 \r
102 return path_out;\r
103 } else {\r
104 return path_in;\r
105 }\r
106 }\r
107 \r
108 } //namespace LivePathEffect\r
109 } /* namespace Inkscape */\r
110 \r
111 /*\r
112 Local Variables:\r
113 mode:c++\r
114 c-file-style:"stroustrup"\r
115 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
116 indent-tabs-mode:nil\r
117 fill-column:99\r
118 End:\r
119 */\r
120 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r