a0a473fe7fdcbdcc6fecabf24685d34a5235d789
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 scale_y(_("Scale stroke y"), _("Scale the height of the stroke path with its length"), "scale_stroke_y", &wr, this, false)\r
45 {\r
46 registerParameter( dynamic_cast<Parameter *>(&nrofpaths) );\r
47 registerParameter( dynamic_cast<Parameter *>(&startpoint_variation) );\r
48 registerParameter( dynamic_cast<Parameter *>(&endpoint_variation) );\r
49 registerParameter( dynamic_cast<Parameter *>(&strokepath) );\r
50 registerParameter( dynamic_cast<Parameter *>(&scale_y) );\r
51 \r
52 nrofpaths.param_make_integer();\r
53 nrofpaths.param_set_range(2, NR_HUGE);\r
54 \r
55 // startpoint_variation.param_set_range(-NR_HUGE, 1);\r
56 // endpoint_variation.param_set_range(-1, NR_HUGE);\r
57 }\r
58 \r
59 LPECurveStitch::~LPECurveStitch()\r
60 {\r
61 \r
62 }\r
63 \r
64 std::vector<Geom::Path>\r
65 LPECurveStitch::doEffect (std::vector<Geom::Path> & path_in)\r
66 {\r
67 if (path_in.size() >= 2) {\r
68 startpoint_variation.resetRandomizer();\r
69 endpoint_variation.resetRandomizer();\r
70 \r
71 D2<Piecewise<SBasis> > stroke = make_cuts_independant(strokepath);\r
72 Interval bndsStroke = bounds_exact(stroke[0]);\r
73 gdouble scaling = bndsStroke.max() - bndsStroke.min();\r
74 Interval bndsStrokeY = bounds_exact(stroke[1]);\r
75 Point stroke_origin(bndsStroke.min(), (bndsStrokeY.max()+bndsStrokeY.min())/2);\r
76 \r
77 std::vector<Geom::Path> path_out (nrofpaths);\r
78 \r
79 // do this for all permutations if there are more than 2 paths? realllly cool!\r
80 Piecewise<D2<SBasis> > A = arc_length_parametrization(Piecewise<D2<SBasis> >(path_in[0].toPwSb()),2,.1);\r
81 Piecewise<D2<SBasis> > B = arc_length_parametrization(Piecewise<D2<SBasis> >(path_in[1].toPwSb()),2,.1);\r
82 Interval bndsA = A.domain();\r
83 Interval bndsB = B.domain();\r
84 gdouble incrementA = (bndsA.max()-bndsA.min()) / (nrofpaths-1);\r
85 gdouble incrementB = (bndsB.max()-bndsB.min()) / (nrofpaths-1);\r
86 gdouble tA = bndsA.min();\r
87 gdouble tB = bndsB.min();\r
88 for (int i = 0; i < nrofpaths; i++) {\r
89 Point start = A(tA);\r
90 Point end = B(tB);\r
91 if (startpoint_variation.get_value() != 0)\r
92 start = start + startpoint_variation * (end - start);\r
93 if (endpoint_variation.get_value() != 0)\r
94 end = end + endpoint_variation * (end - start);\r
95 \r
96 Matrix transform;\r
97 transform.setXAxis( (end-start) / scaling );\r
98 gdouble scaling_y = scale_y.get_value() ? L2(end-start)/scaling : 1.0;\r
99 transform.setYAxis( rot90(unit_vector(end-start)) * scaling_y);\r
100 transform.setTranslation( start );\r
101 Piecewise<D2<SBasis> > pwd2_out = (strokepath-stroke_origin) * transform;\r
102 // add stuff to one big pw<d2<sbasis> > and then outside the loop convert to path?\r
103 std::vector<Path> result = Geom::path_from_piecewise(pwd2_out, LPE_CONVERSION_TOLERANCE);\r
104 path_out[i] = result[0];\r
105 tA += incrementA;\r
106 tB += incrementB;\r
107 }\r
108 \r
109 return path_out;\r
110 } else {\r
111 return path_in;\r
112 }\r
113 }\r
114 \r
115 } //namespace LivePathEffect\r
116 } /* namespace Inkscape */\r
117 \r
118 /*\r
119 Local Variables:\r
120 mode:c++\r
121 c-file-style:"stroustrup"\r
122 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
123 indent-tabs-mode:nil\r
124 fill-column:99\r
125 End:\r
126 */\r
127 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r