Merge lp:~inkscape.dev/inkscape/bend_and_pattern_along_path_width_modified_by_knot into lp:~inkscape.dev/inkscape/trunk
- bend_and_pattern_along_path_width_modified_by_knot
- Merge into trunk
Proposed by
Jabiertxof
Status: | Merged |
---|---|
Merged at revision: | 14515 |
Proposed branch: | lp:~inkscape.dev/inkscape/bend_and_pattern_along_path_width_modified_by_knot |
Merge into: | lp:~inkscape.dev/inkscape/trunk |
Diff against target: |
357 lines (+198/-10) 4 files modified
src/live_effects/lpe-bendpath.cpp (+76/-2) src/live_effects/lpe-bendpath.h (+15/-4) src/live_effects/lpe-patternalongpath.cpp (+90/-2) src/live_effects/lpe-patternalongpath.h (+17/-2) |
To merge this branch: | bzr merge lp:~inkscape.dev/inkscape/bend_and_pattern_along_path_width_modified_by_knot |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
su_v (community) | ui | Approve | |
Jabiertxof | Needs Resubmitting | ||
Review via email: mp+266659@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
- 14274. By Jabiertxof <email address hidden>
-
Fix bug on apply effect from pen/pencil toolbar
- 14275. By Jabiertxof <email address hidden>
-
update to trunk
- 14276. By Jabiertxof <email address hidden>
-
update to trunk
- 14277. By Jabiertxof <email address hidden>
-
fix a bug appliening from patheffect list the LPE
Revision history for this message
Jabiertxof (jabiertxof) wrote : | # |
Total rewrite the code, now without this bugs and with the code much more simplest.
review:
Needs Resubmitting
- 14282. By Jabiertxof <email address hidden>
-
minor changes
Revision history for this message
su_v (suv-lp) wrote : | # |
Both earlier reported issues are fixed with the updated branch (tested with r14282 on OS X 10.7.5).
review:
Approve
(ui)
- 14283. By jabiertxof<email address hidden>
-
update to trunk
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/live_effects/lpe-bendpath.cpp' |
2 | --- src/live_effects/lpe-bendpath.cpp 2014-09-29 02:01:20 +0000 |
3 | +++ src/live_effects/lpe-bendpath.cpp 2015-12-08 11:07:10 +0000 |
4 | @@ -20,7 +20,13 @@ |
5 | #include <2geom/d2.h> |
6 | #include <2geom/piecewise.h> |
7 | |
8 | +#include "knot-holder-entity.h" |
9 | +#include "knotholder.h" |
10 | + |
11 | +#include <glibmm/i18n.h> |
12 | + |
13 | #include <algorithm> |
14 | + |
15 | using std::vector; |
16 | |
17 | |
18 | @@ -48,10 +54,21 @@ |
19 | namespace Inkscape { |
20 | namespace LivePathEffect { |
21 | |
22 | +Geom::PathVector bp_helper_path; |
23 | +namespace BeP { |
24 | +class KnotHolderEntityWidthBendPath : public LPEKnotHolderEntity { |
25 | + public: |
26 | + KnotHolderEntityWidthBendPath(LPEBendPath * effect) : LPEKnotHolderEntity(effect) {} |
27 | + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); |
28 | + virtual Geom::Point knot_get() const; |
29 | + }; |
30 | +} // BeP |
31 | + |
32 | LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) : |
33 | Effect(lpeobject), |
34 | bend_path(_("Bend path:"), _("Path along which to bend the original path"), "bendpath", &wr, this, "M0,0 L1,0"), |
35 | - prop_scale(_("_Width:"), _("Width of the path"), "prop_scale", &wr, this, 1), |
36 | + original_height(0.0), |
37 | + prop_scale(_("_Width:"), _("Width of the path"), "prop_scale", &wr, this, 1.0), |
38 | scale_y_rel(_("W_idth in units of length"), _("Scale the width of the path in units of its length"), "scale_y_rel", &wr, this, false), |
39 | vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false) |
40 | { |
41 | @@ -63,6 +80,7 @@ |
42 | prop_scale.param_set_digits(3); |
43 | prop_scale.param_set_increments(0.01, 0.10); |
44 | |
45 | + _provides_knotholder_entities = true; |
46 | concatenate_before_pwd2 = true; |
47 | } |
48 | |
49 | @@ -76,7 +94,9 @@ |
50 | { |
51 | // get the item bounding box |
52 | original_bbox(lpeitem); |
53 | + original_height = boundingbox_Y.max() - boundingbox_Y.min(); |
54 | SPLPEItem * item = const_cast<SPLPEItem*>(lpeitem); |
55 | + |
56 | item->apply_to_clippath(item); |
57 | item->apply_to_mask(item); |
58 | } |
59 | @@ -148,7 +168,61 @@ |
60 | bend_path.set_new_value( path.toPwSb(), true ); |
61 | } |
62 | |
63 | - |
64 | +void |
65 | +LPEBendPath::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec) |
66 | +{ |
67 | + hp_vec.push_back(bp_helper_path); |
68 | +} |
69 | + |
70 | +void |
71 | +LPEBendPath::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) |
72 | +{ |
73 | + KnotHolderEntity *e = new BeP::KnotHolderEntityWidthBendPath(this); |
74 | + e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE); |
75 | + knotholder->add(e); |
76 | +} |
77 | + |
78 | +namespace BeP { |
79 | + |
80 | +void |
81 | +KnotHolderEntityWidthBendPath::knot_set(Geom::Point const &p, Geom::Point const& /*origin*/, guint state) |
82 | +{ |
83 | + LPEBendPath *lpe = dynamic_cast<LPEBendPath *> (_effect); |
84 | + |
85 | + Geom::Point const s = snap_knot_position(p, state); |
86 | + Geom::Path path_in = lpe->bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0)); |
87 | + Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0)); |
88 | + lpe->prop_scale.param_set_value(Geom::distance(s , ptA)/(lpe->original_height/2.0)); |
89 | + |
90 | + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); |
91 | +} |
92 | + |
93 | +Geom::Point |
94 | +KnotHolderEntityWidthBendPath::knot_get() const |
95 | +{ |
96 | + LPEBendPath *lpe = dynamic_cast<LPEBendPath *> (_effect); |
97 | + |
98 | + Geom::Path path_in = lpe->bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0)); |
99 | + Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0)); |
100 | + Geom::Point B = path_in.pointAt(Geom::PathTime(1, 0.0)); |
101 | + Geom::Curve const *first_curve = &path_in.curveAt(Geom::PathTime(0, 0.0)); |
102 | + Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*first_curve); |
103 | + Geom::Ray ray(ptA, B); |
104 | + if (cubic) { |
105 | + ray.setPoints(ptA,(*cubic)[1]); |
106 | + } |
107 | + Geom::Angle first_curve_angle = ray.transformed(Geom::Rotate(Geom::deg_to_rad(90))).angle(); |
108 | + Geom::Point result_point = Geom::Point::polar(first_curve_angle, (lpe->original_height * lpe->prop_scale)/2.0) + ptA; |
109 | + |
110 | + bp_helper_path.clear(); |
111 | + Geom::Path hp(result_point); |
112 | + hp.appendNew<Geom::LineSegment>(ptA); |
113 | + bp_helper_path.push_back(hp); |
114 | + hp.clear(); |
115 | + |
116 | + return result_point; |
117 | +} |
118 | +} // namespace BeP |
119 | } // namespace LivePathEffect |
120 | } /* namespace Inkscape */ |
121 | |
122 | |
123 | === modified file 'src/live_effects/lpe-bendpath.h' |
124 | --- src/live_effects/lpe-bendpath.h 2015-08-05 19:25:52 +0000 |
125 | +++ src/live_effects/lpe-bendpath.h 2015-12-08 11:07:10 +0000 |
126 | @@ -27,6 +27,10 @@ |
127 | namespace Inkscape { |
128 | namespace LivePathEffect { |
129 | |
130 | +namespace BeP { |
131 | +class KnotHolderEntityWidthBendPath; |
132 | +} |
133 | + |
134 | //for Bend path on group : we need information concerning the group Bounding box |
135 | class LPEBendPath : public Effect, GroupBBoxEffect { |
136 | public: |
137 | @@ -39,12 +43,19 @@ |
138 | |
139 | virtual void resetDefaults(SPItem const* item); |
140 | |
141 | - PathParam bend_path; |
142 | + void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec); |
143 | + |
144 | + virtual void addKnotHolderEntities(KnotHolder * knotholder, SPDesktop * desktop, SPItem * item); |
145 | + |
146 | + PathParam bend_path; |
147 | + |
148 | + friend class BeP::KnotHolderEntityWidthBendPath; |
149 | +protected: |
150 | + double original_height; |
151 | + ScalarParam prop_scale; |
152 | private: |
153 | - ScalarParam prop_scale; |
154 | BoolParam scale_y_rel; |
155 | - BoolParam vertical_pattern; |
156 | - |
157 | + BoolParam vertical_pattern; |
158 | Geom::Piecewise<Geom::D2<Geom::SBasis> > uskeleton; |
159 | Geom::Piecewise<Geom::D2<Geom::SBasis> > n; |
160 | |
161 | |
162 | === modified file 'src/live_effects/lpe-patternalongpath.cpp' |
163 | --- src/live_effects/lpe-patternalongpath.cpp 2014-03-27 01:33:44 +0000 |
164 | +++ src/live_effects/lpe-patternalongpath.cpp 2015-12-08 11:07:10 +0000 |
165 | @@ -18,6 +18,9 @@ |
166 | #include <2geom/d2.h> |
167 | #include <2geom/piecewise.h> |
168 | |
169 | +#include "knot-holder-entity.h" |
170 | +#include "knotholder.h" |
171 | + |
172 | #include <algorithm> |
173 | using std::vector; |
174 | |
175 | @@ -45,6 +48,16 @@ |
176 | |
177 | namespace Inkscape { |
178 | namespace LivePathEffect { |
179 | +Geom::PathVector pap_helper_path; |
180 | + |
181 | +namespace WPAP { |
182 | + class KnotHolderEntityWidthPatternAlongPath : public LPEKnotHolderEntity { |
183 | + public: |
184 | + KnotHolderEntityWidthPatternAlongPath(LPEPatternAlongPath * effect) : LPEKnotHolderEntity(effect) {} |
185 | + virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state); |
186 | + virtual Geom::Point knot_get() const; |
187 | + }; |
188 | +} // WPAP |
189 | |
190 | static const Util::EnumData<PAPCopyType> PAPCopyTypeData[PAPCT_END] = { |
191 | {PAPCT_SINGLE, N_("Single"), "single"}, |
192 | @@ -57,9 +70,10 @@ |
193 | LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) : |
194 | Effect(lpeobject), |
195 | pattern(_("Pattern source:"), _("Path to put along the skeleton path"), "pattern", &wr, this, "M0,0 L1,0"), |
196 | + original_height(0), |
197 | + prop_scale(_("_Width:"), _("Width of the pattern"), "prop_scale", &wr, this, 1.0), |
198 | copytype(_("Pattern copies:"), _("How many pattern copies to place along the skeleton path"), |
199 | "copytype", PAPCopyTypeConverter, &wr, this, PAPCT_SINGLE_STRETCHED), |
200 | - prop_scale(_("_Width:"), _("Width of the pattern"), "prop_scale", &wr, this, 1), |
201 | scale_y_rel(_("Wid_th in units of length"), |
202 | _("Scale the width of the pattern in units of its length"), |
203 | "scale_y_rel", &wr, this, false), |
204 | @@ -87,9 +101,11 @@ |
205 | registerParameter( dynamic_cast<Parameter *>(&prop_units) ); |
206 | registerParameter( dynamic_cast<Parameter *>(&vertical_pattern) ); |
207 | registerParameter( dynamic_cast<Parameter *>(&fuse_tolerance) ); |
208 | - |
209 | prop_scale.param_set_digits(3); |
210 | prop_scale.param_set_increments(0.01, 0.10); |
211 | + |
212 | + _provides_knotholder_entities = true; |
213 | + |
214 | } |
215 | |
216 | LPEPatternAlongPath::~LPEPatternAlongPath() |
217 | @@ -97,6 +113,16 @@ |
218 | |
219 | } |
220 | |
221 | +void |
222 | +LPEPatternAlongPath::doBeforeEffect (SPLPEItem const* lpeitem) |
223 | +{ |
224 | + // get the pattern bounding box |
225 | + Geom::OptRect bbox = pattern.get_pathvector().boundsFast(); |
226 | + if (bbox) { |
227 | + original_height = (*bbox)[Geom::Y].max() - (*bbox)[Geom::Y].min(); |
228 | + } |
229 | +} |
230 | + |
231 | Geom::Piecewise<Geom::D2<Geom::SBasis> > |
232 | LPEPatternAlongPath::doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in) |
233 | { |
234 | @@ -238,6 +264,68 @@ |
235 | } |
236 | } |
237 | |
238 | +void |
239 | +LPEPatternAlongPath::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec) |
240 | +{ |
241 | + hp_vec.push_back(pap_helper_path); |
242 | +} |
243 | + |
244 | + |
245 | +void |
246 | +LPEPatternAlongPath::addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item) |
247 | +{ |
248 | + KnotHolderEntity *e = new WPAP::KnotHolderEntityWidthPatternAlongPath(this); |
249 | + e->create(desktop, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE); |
250 | + knotholder->add(e); |
251 | +} |
252 | + |
253 | +namespace WPAP { |
254 | + |
255 | +void |
256 | +KnotHolderEntityWidthPatternAlongPath::knot_set(Geom::Point const &p, Geom::Point const& /*origin*/, guint state) |
257 | +{ |
258 | + LPEPatternAlongPath *lpe = dynamic_cast<LPEPatternAlongPath *> (_effect); |
259 | + |
260 | + Geom::Point const s = snap_knot_position(p, state); |
261 | + SPShape const *sp_shape = dynamic_cast<SPShape const *>(SP_LPE_ITEM(item)); |
262 | + if (sp_shape) { |
263 | + Geom::Path const *path_in = sp_shape->getCurveBeforeLPE()->first_path(); |
264 | + Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); |
265 | + lpe->prop_scale.param_set_value(Geom::distance(s , ptA)/(lpe->original_height/2.0)); |
266 | + } |
267 | + sp_lpe_item_update_patheffect (SP_LPE_ITEM(item), false, true); |
268 | +} |
269 | + |
270 | +Geom::Point |
271 | +KnotHolderEntityWidthPatternAlongPath::knot_get() const |
272 | +{ |
273 | + LPEPatternAlongPath *lpe = dynamic_cast<LPEPatternAlongPath *> (_effect); |
274 | + |
275 | + SPShape const *sp_shape = dynamic_cast<SPShape const *>(SP_LPE_ITEM(item)); |
276 | + if (sp_shape) { |
277 | + Geom::Path const *path_in = sp_shape->getCurveBeforeLPE()->first_path(); |
278 | + Geom::Point ptA = path_in->pointAt(Geom::PathTime(0, 0.0)); |
279 | + Geom::Point B = path_in->pointAt(Geom::PathTime(1, 0.0)); |
280 | + Geom::Curve const *first_curve = &path_in->curveAt(Geom::PathTime(0, 0.0)); |
281 | + Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*first_curve); |
282 | + Geom::Ray ray(ptA, B); |
283 | + if (cubic) { |
284 | + ray.setPoints((*cubic)[1], ptA); |
285 | + } |
286 | + Geom::Angle first_curve_angle = ray.transformed(Geom::Rotate(Geom::deg_to_rad(90))).angle(); |
287 | + Geom::Point result_point = Geom::Point::polar(first_curve_angle, (lpe->original_height * lpe->prop_scale)/2.0) + ptA; |
288 | + |
289 | + pap_helper_path.clear(); |
290 | + Geom::Path hp(result_point); |
291 | + hp.appendNew<Geom::LineSegment>(ptA); |
292 | + pap_helper_path.push_back(hp); |
293 | + hp.clear(); |
294 | + |
295 | + return result_point; |
296 | + } |
297 | + return Geom::Point(); |
298 | +} |
299 | +} // namespace WPAP |
300 | } // namespace LivePathEffect |
301 | } /* namespace Inkscape */ |
302 | |
303 | |
304 | === modified file 'src/live_effects/lpe-patternalongpath.h' |
305 | --- src/live_effects/lpe-patternalongpath.h 2012-02-12 13:43:17 +0000 |
306 | +++ src/live_effects/lpe-patternalongpath.h 2015-12-08 11:07:10 +0000 |
307 | @@ -13,10 +13,15 @@ |
308 | #include "live_effects/effect.h" |
309 | #include "live_effects/parameter/path.h" |
310 | #include "live_effects/parameter/bool.h" |
311 | +#include "live_effects/parameter/point.h" |
312 | |
313 | namespace Inkscape { |
314 | namespace LivePathEffect { |
315 | |
316 | +namespace WPAP { |
317 | +class KnotHolderEntityWidthPatternAlongPath; |
318 | +} |
319 | + |
320 | enum PAPCopyType { |
321 | PAPCT_SINGLE = 0, |
322 | PAPCT_SINGLE_STRETCHED, |
323 | @@ -30,14 +35,25 @@ |
324 | LPEPatternAlongPath(LivePathEffectObject *lpeobject); |
325 | virtual ~LPEPatternAlongPath(); |
326 | |
327 | + virtual void doBeforeEffect (SPLPEItem const* lpeitem); |
328 | + |
329 | virtual Geom::Piecewise<Geom::D2<Geom::SBasis> > doEffect_pwd2 (Geom::Piecewise<Geom::D2<Geom::SBasis> > const & pwd2_in); |
330 | |
331 | virtual void transform_multiply(Geom::Affine const& postmul, bool set); |
332 | |
333 | + void addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec); |
334 | + |
335 | + virtual void addKnotHolderEntities(KnotHolder * knotholder, SPDesktop * desktop, SPItem * item); |
336 | + |
337 | PathParam pattern; |
338 | + |
339 | + friend class WPAP::KnotHolderEntityWidthPatternAlongPath; |
340 | +protected: |
341 | + double original_height; |
342 | + ScalarParam prop_scale; |
343 | + |
344 | private: |
345 | EnumParam<PAPCopyType> copytype; |
346 | - ScalarParam prop_scale; |
347 | BoolParam scale_y_rel; |
348 | ScalarParam spacing; |
349 | ScalarParam normal_offset; |
350 | @@ -45,7 +61,6 @@ |
351 | BoolParam prop_units; |
352 | BoolParam vertical_pattern; |
353 | ScalarParam fuse_tolerance; |
354 | - |
355 | void on_pattern_pasted(); |
356 | |
357 | LPEPatternAlongPath(const LPEPatternAlongPath&); |
Testing r14277 (on OS X):
a) Pattern along path LPE: a path with such an LPE applied cannot be moved without unexpected deformation/changes of the LPE width parameter.
Steps to reproduce:
1) launch branch (new default prefs, new default document)
2) switch to the bezier (pen) tool
3) select shape 'Ellipse'
4) draw a simple (straight) line
5) switch to the select tool
6) grab the path and drag it to a new location
--> the width parameter of the path effect changes unexpectedly.
Steps to reproduce:
1) launch branch (new default prefs, new default document)
2) switch to the bezier (pen) tool
3) select shape 'Ellipse'
4) draw a simple (straight) line
5) switch to the node tool
6) select all nodes of the original path (Ctrl+A)
7) grab one of selected nodes and drag the path to a new location
--> AFAIU the width parameter is not (or incorrectly) adjusted, and the path gets badly mangled or disappears completely. If snapping is enabled while dragging the selected nodes, inkscape produces these console messages:
** (inkscape:69451): WARNING **: encountered non finite point when evaluating snapping callback
Dragging the path by its nodes also fails if snapping is disabled globally.
b) The new width parameter added to the Bend LPE is not modified when dragging the path with the select tool, and doesn't act as erratically when node-editing the bend path (Ctrl+A, drag the bend path by grabbing one of the selected nodes): what is somewhat surprising though in initial tests is that the width parameter does not stay fixed relative to the bend path (it does not seem to be fixed relative to the original position either?) when dragging the bend path by its nodes.