Merge lp:~inkscape.dev/inkscape/mirror_improvements into lp:~inkscape.dev/inkscape/trunk
- mirror_improvements
- Merge into trunk
Proposed by
Jabiertxof
Status: | Merged |
---|---|
Merged at revision: | 15438 |
Proposed branch: | lp:~inkscape.dev/inkscape/mirror_improvements |
Merge into: | lp:~inkscape.dev/inkscape/trunk |
Diff against target: |
508 lines (+291/-67) 2 files modified
src/live_effects/lpe-mirror_symmetry.cpp (+280/-65) src/live_effects/lpe-mirror_symmetry.h (+11/-2) |
To merge this branch: | bzr merge lp:~inkscape.dev/inkscape/mirror_improvements |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Martin Owens | Approve | ||
Review via email: mp+315307@code.launchpad.net |
Commit message
Description of the change
Add multiple object feature to LPE. Allow add custom style to the mirror
NEEDS ROTATE COPYES MERGED
To post a comment you must log in.
Revision history for this message
Martin Owens (doctormo) wrote : | # |
Look good from here.
review:
Approve
- 15360. By Jabiertxof <jtx@jtx>
-
Bug fixes
- 15361. By Jabiertxof
-
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-mirror_symmetry.cpp' |
2 | --- src/live_effects/lpe-mirror_symmetry.cpp 2016-12-26 12:54:09 +0000 |
3 | +++ src/live_effects/lpe-mirror_symmetry.cpp 2017-01-24 08:45:44 +0000 |
4 | @@ -15,11 +15,22 @@ |
5 | */ |
6 | |
7 | #include <gtkmm.h> |
8 | +#include "live_effects/lpeobject.h" |
9 | +#include "live_effects/lpeobject-reference.h" |
10 | #include "live_effects/lpe-mirror_symmetry.h" |
11 | -#include <display/curve.h> |
12 | -#include <svg/path-string.h> |
13 | -#include "helper/geom.h" |
14 | -#include <2geom/path-intersection.h> |
15 | +#include "display/curve.h" |
16 | +#include "svg/path-string.h" |
17 | +#include "svg/svg.h" |
18 | +#include "sp-defs.h" |
19 | +#include "helper/geom.h" |
20 | +#include "2geom/intersection-graph.h" |
21 | +#include "2geom/path-intersection.h" |
22 | +#include "2geom/affine.h" |
23 | +#include "helper/geom.h" |
24 | +#include "sp-lpe-item.h" |
25 | +#include "path-chemistry.h" |
26 | +#include "style.h" |
27 | +#include "xml/sp-css-attr.h" |
28 | |
29 | // TODO due to internal breakage in glibmm headers, this must be last: |
30 | #include <glibmm/i18n.h> |
31 | @@ -40,73 +51,69 @@ |
32 | LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : |
33 | Effect(lpeobject), |
34 | mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE), |
35 | + split_gap(_("Gap on split"), _("Gap on split"), "split_gap", &wr, this, -0.001), |
36 | discard_orig_path(_("Discard original path"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false), |
37 | fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false), |
38 | oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false), |
39 | + split_items(_("Split elements"), _("Split elements, this allow gradients and other paints."), "split_items", &wr, this, false), |
40 | start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust start of mirroring")), |
41 | end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")), |
42 | - center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")) |
43 | + center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")), |
44 | + id_origin("id origin", "store the id of the first LPEItem", "id_origin", &wr, this,"") |
45 | { |
46 | show_orig_path = true; |
47 | registerParameter(&mode); |
48 | - registerParameter( &discard_orig_path); |
49 | - registerParameter( &fuse_paths); |
50 | - registerParameter( &oposite_fuse); |
51 | - registerParameter( &start_point); |
52 | - registerParameter( &end_point); |
53 | - registerParameter( ¢er_point); |
54 | + registerParameter(&split_gap); |
55 | + registerParameter(&discard_orig_path); |
56 | + registerParameter(&fuse_paths); |
57 | + registerParameter(&oposite_fuse); |
58 | + registerParameter(&split_items); |
59 | + registerParameter(&start_point); |
60 | + registerParameter(&end_point); |
61 | + registerParameter(¢er_point); |
62 | + registerParameter(&id_origin); |
63 | + id_origin.param_hide_canvas_text(); |
64 | + split_gap.param_set_range(-999999.0, 999999.0); |
65 | + split_gap.param_set_increments(0.1, 0.1); |
66 | + split_gap.param_set_digits(5); |
67 | + apply_to_clippath_and_mask = true; |
68 | previous_center = Geom::Point(0,0); |
69 | - apply_to_clippath_and_mask = true; |
70 | } |
71 | |
72 | LPEMirrorSymmetry::~LPEMirrorSymmetry() |
73 | { |
74 | } |
75 | |
76 | -Gtk::Widget * LPEMirrorSymmetry::newWidget() |
77 | +void |
78 | +LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem) |
79 | { |
80 | - // use manage here, because after deletion of Effect object, others might |
81 | - // still be pointing to this widget. |
82 | - Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); |
83 | - |
84 | - vbox->set_border_width(5); |
85 | - vbox->set_homogeneous(false); |
86 | - vbox->set_spacing(2); |
87 | - |
88 | - std::vector<Parameter *>::iterator it = param_vector.begin(); |
89 | - while (it != param_vector.end()) { |
90 | - if ((*it)->widget_is_visible) { |
91 | - Parameter *param = *it; |
92 | - Gtk::Widget *widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget()); |
93 | - Glib::ustring *tip = param->param_getTooltip(); |
94 | - if (widg) { |
95 | - if (param->param_key != "center_point") { |
96 | - vbox->pack_start(*widg, true, true, 2); |
97 | - if (tip) { |
98 | - widg->set_tooltip_text(*tip); |
99 | - } else { |
100 | - widg->set_tooltip_text(""); |
101 | - widg->set_has_tooltip(false); |
102 | - } |
103 | - } |
104 | - } |
105 | + if (split_items && !discard_orig_path) { |
106 | + container = dynamic_cast<SPObject *>(sp_lpe_item->parent); |
107 | + SPDocument * doc = SP_ACTIVE_DOCUMENT; |
108 | + Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot(); |
109 | + Inkscape::XML::Node *root_origin = doc->getReprRoot(); |
110 | + if (root_origin != root) { |
111 | + return; |
112 | } |
113 | - |
114 | - ++it; |
115 | + Geom::Line ls((Geom::Point)start_point, (Geom::Point)end_point); |
116 | + Geom::Affine m = Geom::reflection (ls.vector(), (Geom::Point)start_point); |
117 | + m = m * sp_lpe_item->transform; |
118 | + toMirror(m); |
119 | + } else { |
120 | + processObjects(LPE_ERASE); |
121 | + items.clear(); |
122 | } |
123 | - return dynamic_cast<Gtk::Widget *>(vbox); |
124 | } |
125 | |
126 | - |
127 | void |
128 | LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) |
129 | { |
130 | + |
131 | using namespace Geom; |
132 | original_bbox(lpeitem); |
133 | //center_point->param_set_liveupdate(false); |
134 | Point point_a(boundingbox_X.max(), boundingbox_Y.min()); |
135 | Point point_b(boundingbox_X.max(), boundingbox_Y.max()); |
136 | - Point point_c(boundingbox_X.max(), boundingbox_Y.middle()); |
137 | if (mode == MT_Y) { |
138 | point_a = Geom::Point(boundingbox_X.min(),center_point[Y]); |
139 | point_b = Geom::Point(boundingbox_X.max(),center_point[Y]); |
140 | @@ -173,6 +180,172 @@ |
141 | } |
142 | |
143 | void |
144 | +LPEMirrorSymmetry::cloneD(SPObject *origin, SPObject *dest, bool live, bool root) |
145 | +{ |
146 | + SPDocument * document = SP_ACTIVE_DOCUMENT; |
147 | + Inkscape::XML::Document *xml_doc = document->getReprDoc(); |
148 | + if ( SP_IS_GROUP(origin) && SP_IS_GROUP(dest) && SP_GROUP(origin)->getItemCount() == SP_GROUP(dest)->getItemCount() ) { |
149 | + std::vector< SPObject * > childs = origin->childList(true); |
150 | + size_t index = 0; |
151 | + for (std::vector<SPObject * >::iterator obj_it = childs.begin(); |
152 | + obj_it != childs.end(); ++obj_it) { |
153 | + SPObject *dest_child = dest->nthChild(index); |
154 | + cloneD(*obj_it, dest_child, live, false); |
155 | + index++; |
156 | + } |
157 | + } |
158 | + SPShape * shape = SP_SHAPE(origin); |
159 | + SPPath * path = SP_PATH(dest); |
160 | + if (!path && !SP_IS_GROUP(dest)) { |
161 | + Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0); |
162 | + dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); |
163 | + path = SP_PATH(dest); |
164 | + } |
165 | + if (path && shape) { |
166 | + if ( live) { |
167 | + SPCurve *c = NULL; |
168 | + if (root) { |
169 | + c = new SPCurve(); |
170 | + c->set_pathvector(pathvector_before_effect); |
171 | + } else { |
172 | + c = shape->getCurve(); |
173 | + } |
174 | + if (c) { |
175 | + path->setCurve(c, TRUE); |
176 | + c->unref(); |
177 | + } else { |
178 | + dest->getRepr()->setAttribute("d", NULL); |
179 | + } |
180 | + } else { |
181 | + dest->getRepr()->setAttribute("d", origin->getRepr()->attribute("d")); |
182 | + } |
183 | + } |
184 | +} |
185 | + |
186 | +void |
187 | +LPEMirrorSymmetry::toMirror(Geom::Affine transform) |
188 | +{ |
189 | + SPDocument * document = SP_ACTIVE_DOCUMENT; |
190 | + Inkscape::XML::Document *xml_doc = document->getReprDoc(); |
191 | + const char * id_origin_char = id_origin.param_getSVGValue(); |
192 | + const char * elemref_id = g_strdup(Glib::ustring("mirror-").append(id_origin_char).c_str()); |
193 | + items.clear(); |
194 | + items.push_back(elemref_id); |
195 | + SPObject *elemref= NULL; |
196 | + Inkscape::XML::Node *phantom = NULL; |
197 | + if (elemref = document->getObjectById(elemref_id)) { |
198 | + phantom = elemref->getRepr(); |
199 | + } else { |
200 | + phantom = sp_lpe_item->getRepr()->duplicate(xml_doc); |
201 | + std::vector<const char *> attrs; |
202 | + attrs.push_back("inkscape:path-effect"); |
203 | + attrs.push_back("inkscape:original-d"); |
204 | + attrs.push_back("sodipodi:type"); |
205 | + attrs.push_back("sodipodi:rx"); |
206 | + attrs.push_back("sodipodi:ry"); |
207 | + attrs.push_back("sodipodi:cx"); |
208 | + attrs.push_back("sodipodi:cy"); |
209 | + attrs.push_back("sodipodi:end"); |
210 | + attrs.push_back("sodipodi:start"); |
211 | + attrs.push_back("inkscape:flatsided"); |
212 | + attrs.push_back("inkscape:randomized"); |
213 | + attrs.push_back("inkscape:rounded"); |
214 | + attrs.push_back("sodipodi:arg1"); |
215 | + attrs.push_back("sodipodi:arg2"); |
216 | + attrs.push_back("sodipodi:r1"); |
217 | + attrs.push_back("sodipodi:r2"); |
218 | + attrs.push_back("sodipodi:sides"); |
219 | + attrs.push_back("inkscape:randomized"); |
220 | + attrs.push_back("sodipodi:argument"); |
221 | + attrs.push_back("sodipodi:expansion"); |
222 | + attrs.push_back("sodipodi:radius"); |
223 | + attrs.push_back("sodipodi:revolution"); |
224 | + attrs.push_back("sodipodi:t0"); |
225 | + attrs.push_back("inkscape:randomized"); |
226 | + attrs.push_back("inkscape:randomized"); |
227 | + attrs.push_back("inkscape:randomized"); |
228 | + attrs.push_back("x"); |
229 | + attrs.push_back("y"); |
230 | + attrs.push_back("rx"); |
231 | + attrs.push_back("ry"); |
232 | + attrs.push_back("width"); |
233 | + attrs.push_back("height"); |
234 | + for(const char * attr : attrs) { |
235 | + phantom->setAttribute(attr, NULL); |
236 | + } |
237 | + } |
238 | + phantom->setAttribute("id", elemref_id); |
239 | + if (!elemref) { |
240 | + elemref = container->appendChildRepr(phantom); |
241 | + Inkscape::GC::release(phantom); |
242 | + } |
243 | + cloneD(SP_OBJECT(sp_lpe_item), elemref, true, true); |
244 | + elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform)); |
245 | + if (elemref->parent != container) { |
246 | + Inkscape::XML::Node *copy = phantom->duplicate(xml_doc); |
247 | + copy->setAttribute("id", elemref_id); |
248 | + container->appendChildRepr(copy); |
249 | + Inkscape::GC::release(copy); |
250 | + elemref->deleteObject(); |
251 | + } |
252 | +} |
253 | + |
254 | +Gtk::Widget * |
255 | +LPEMirrorSymmetry::newWidget() |
256 | +{ |
257 | + // use manage here, because after deletion of Effect object, others might |
258 | + // still be pointing to this widget. |
259 | + Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget())); |
260 | + vbox->set_border_width(5); |
261 | + vbox->set_homogeneous(false); |
262 | + vbox->set_spacing(2); |
263 | + |
264 | + std::vector<Parameter *>::iterator it = param_vector.begin(); |
265 | + while (it != param_vector.end()) { |
266 | + if ((*it)->widget_is_visible) { |
267 | + Parameter * param = *it; |
268 | + if (param->param_key == "id_origin" || param->param_key == "center_point") { |
269 | + ++it; |
270 | + continue; |
271 | + } |
272 | + Gtk::Widget * widg = param->param_newWidget(); |
273 | + Glib::ustring * tip = param->param_getTooltip(); |
274 | + if (widg) { |
275 | + vbox->pack_start(*widg, true, true, 2); |
276 | + if (tip) { |
277 | + widg->set_tooltip_text(*tip); |
278 | + } else { |
279 | + widg->set_tooltip_text(""); |
280 | + widg->set_has_tooltip(false); |
281 | + } |
282 | + } |
283 | + } |
284 | + |
285 | + ++it; |
286 | + } |
287 | + this->upd_params = false; |
288 | + return dynamic_cast<Gtk::Widget *>(vbox); |
289 | +} |
290 | + |
291 | +//TODO: Migrate the tree next function to effect.cpp/h to avoid duplication |
292 | +void |
293 | +LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) |
294 | +{ |
295 | + processObjects(LPE_VISIBILITY); |
296 | +} |
297 | + |
298 | +void |
299 | +LPEMirrorSymmetry::doOnRemove (SPLPEItem const* /*lpeitem*/) |
300 | +{ |
301 | + //unset "erase_extra_objects" hook on sp-lpe-item.cpp |
302 | + if (!erase_extra_objects) { |
303 | + processObjects(LPE_TO_OBJECTS); |
304 | + return; |
305 | + } |
306 | + processObjects(LPE_ERASE); |
307 | +} |
308 | + |
309 | +void |
310 | LPEMirrorSymmetry::transform_multiply(Geom::Affine const& postmul, bool set) |
311 | { |
312 | // cycle through all parameters. Most parameters will not need transformation, but path and point params do. |
313 | @@ -193,18 +366,26 @@ |
314 | Point point_a(boundingbox_X.max(), boundingbox_Y.min()); |
315 | Point point_b(boundingbox_X.max(), boundingbox_Y.max()); |
316 | Point point_c(boundingbox_X.max(), boundingbox_Y.middle()); |
317 | - start_point.param_setValue(point_a, true); |
318 | + start_point.param_setValue(point_a); |
319 | start_point.param_update_default(point_a); |
320 | - end_point.param_setValue(point_b, true); |
321 | + end_point.param_setValue(point_b); |
322 | end_point.param_update_default(point_b); |
323 | center_point.param_setValue(point_c, true); |
324 | previous_center = center_point; |
325 | + SPLPEItem * splpeitem = const_cast<SPLPEItem *>(lpeitem); |
326 | + if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet |
327 | + id_origin.param_setValue(lpeitem->getRepr()->attribute("id")); |
328 | + id_origin.write_to_SVG(); |
329 | + } |
330 | } |
331 | |
332 | |
333 | Geom::PathVector |
334 | LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) |
335 | { |
336 | + if (split_items && !fuse_paths) { |
337 | + return path_in; |
338 | + } |
339 | Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in); |
340 | Geom::PathVector path_out; |
341 | |
342 | @@ -214,15 +395,52 @@ |
343 | |
344 | Geom::Line line_separation((Geom::Point)start_point, (Geom::Point)end_point); |
345 | Geom::Affine m = Geom::reflection (line_separation.vector(), (Geom::Point)start_point); |
346 | - |
347 | - if (fuse_paths && !discard_orig_path) { |
348 | + if (split_items && fuse_paths) { |
349 | + Geom::OptRect bbox = sp_lpe_item->geometricBounds(); |
350 | + Geom::Path p(Geom::Point(bbox->left(), bbox->top())); |
351 | + p.appendNew<Geom::LineSegment>(Geom::Point(bbox->right(), bbox->top())); |
352 | + p.appendNew<Geom::LineSegment>(Geom::Point(bbox->right(), bbox->bottom())); |
353 | + p.appendNew<Geom::LineSegment>(Geom::Point(bbox->left(), bbox->bottom())); |
354 | + p.appendNew<Geom::LineSegment>(Geom::Point(bbox->left(), bbox->top())); |
355 | + p.close(); |
356 | + p *= Geom::Translate(bbox->midpoint()).inverse(); |
357 | + p *= Geom::Scale(1.2); |
358 | + p *= Geom::Rotate(line_separation.angle()); |
359 | + p *= Geom::Translate(bbox->midpoint()); |
360 | + bbox = p.boundsFast(); |
361 | + p.clear(); |
362 | + p.start(Geom::Point(bbox->left(), bbox->top())); |
363 | + p.appendNew<Geom::LineSegment>(Geom::Point(bbox->right(), bbox->top())); |
364 | + p.appendNew<Geom::LineSegment>(Geom::Point(bbox->right(), bbox->bottom())); |
365 | + p.appendNew<Geom::LineSegment>(Geom::Point(bbox->left(), bbox->bottom())); |
366 | + p.appendNew<Geom::LineSegment>(Geom::Point(bbox->left(), bbox->top())); |
367 | + p.close(); |
368 | + p *= Geom::Translate(bbox->midpoint()).inverse(); |
369 | + p *= Geom::Rotate(line_separation.angle()); |
370 | + p *= Geom::Translate(bbox->midpoint()); |
371 | + Geom::Point base(p.pointAt(3)); |
372 | + if (oposite_fuse) { |
373 | + base = p.pointAt(0); |
374 | + } |
375 | + p *= Geom::Translate(line_separation.pointAt(line_separation.nearestTime(base)) - base); |
376 | + Geom::PathVector pv_bbox; |
377 | + pv_bbox.push_back(p); |
378 | + Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(pv_bbox, original_pathv); |
379 | + if (pig && !original_pathv.empty() && !pv_bbox.empty()) { |
380 | + path_out = pig->getBminusA(); |
381 | + } |
382 | + Geom::Point dir = rot90(unit_vector((Geom::Point)start_point - (Geom::Point)end_point)); |
383 | + Geom::Point gap = dir * split_gap; |
384 | + m *= Geom::Translate(gap); |
385 | + path_out *= m; |
386 | + } else if (fuse_paths && !discard_orig_path) { |
387 | for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); |
388 | path_it != original_pathv.end(); ++path_it) |
389 | { |
390 | if (path_it->empty()) { |
391 | continue; |
392 | } |
393 | - Geom::PathVector tmp_path; |
394 | + Geom::PathVector tmp_pathvector; |
395 | double time_start = 0.0; |
396 | int position = 0; |
397 | bool end_open = false; |
398 | @@ -268,11 +486,11 @@ |
399 | Geom::Path mirror = portion.reversed() * m; |
400 | mirror.setInitial(portion.finalPoint()); |
401 | portion.append(mirror); |
402 | - if(i!=0) { |
403 | + if(i != 0) { |
404 | portion.setFinal(portion.initialPoint()); |
405 | portion.close(); |
406 | } |
407 | - tmp_path.push_back(portion); |
408 | + tmp_pathvector.push_back(portion); |
409 | } |
410 | portion.clear(); |
411 | } |
412 | @@ -293,36 +511,33 @@ |
413 | portion.append(mirror); |
414 | portion = portion.reversed(); |
415 | if (!original.closed()) { |
416 | - tmp_path.push_back(portion); |
417 | + tmp_pathvector.push_back(portion); |
418 | } else { |
419 | - if (cs.size() > 1 && tmp_path.size() > 0 && tmp_path[0].size() > 0 ) { |
420 | - portion.setFinal(tmp_path[0].initialPoint()); |
421 | - portion.setInitial(tmp_path[0].finalPoint()); |
422 | - tmp_path[0].append(portion); |
423 | + if (cs.size() > 1 && tmp_pathvector.size() > 0 && tmp_pathvector[0].size() > 0 ) { |
424 | + portion.setFinal(tmp_pathvector[0].initialPoint()); |
425 | + portion.setInitial(tmp_pathvector[0].finalPoint()); |
426 | + tmp_pathvector[0].append(portion); |
427 | } else { |
428 | - tmp_path.push_back(portion); |
429 | + tmp_pathvector.push_back(portion); |
430 | } |
431 | - tmp_path[0].close(); |
432 | + tmp_pathvector[0].close(); |
433 | } |
434 | portion.clear(); |
435 | } |
436 | } |
437 | } |
438 | if (cs.size() == 0 && position == 1) { |
439 | - tmp_path.push_back(original); |
440 | - tmp_path.push_back(original * m); |
441 | + tmp_pathvector.push_back(original); |
442 | + tmp_pathvector.push_back(original * m); |
443 | } |
444 | - path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); |
445 | - tmp_path.clear(); |
446 | + path_out.insert(path_out.end(), tmp_pathvector.begin(), tmp_pathvector.end()); |
447 | + tmp_pathvector.clear(); |
448 | } |
449 | - } |
450 | - |
451 | - if (!fuse_paths || discard_orig_path) { |
452 | + } else if (!fuse_paths || discard_orig_path) { |
453 | for (size_t i = 0; i < original_pathv.size(); ++i) { |
454 | path_out.push_back(original_pathv[i] * m); |
455 | } |
456 | } |
457 | - |
458 | return path_out; |
459 | } |
460 | |
461 | |
462 | === modified file 'src/live_effects/lpe-mirror_symmetry.h' |
463 | --- src/live_effects/lpe-mirror_symmetry.h 2016-12-18 23:19:40 +0000 |
464 | +++ src/live_effects/lpe-mirror_symmetry.h 2017-01-24 08:45:44 +0000 |
465 | @@ -18,8 +18,8 @@ |
466 | |
467 | #include "live_effects/effect.h" |
468 | #include "live_effects/parameter/parameter.h" |
469 | +#include "live_effects/parameter/text.h" |
470 | #include "live_effects/parameter/point.h" |
471 | -#include "live_effects/parameter/path.h" |
472 | #include "live_effects/parameter/enum.h" |
473 | #include "live_effects/lpegroupbbox.h" |
474 | |
475 | @@ -41,23 +41,32 @@ |
476 | virtual ~LPEMirrorSymmetry(); |
477 | virtual void doOnApply (SPLPEItem const* lpeitem); |
478 | virtual void doBeforeEffect (SPLPEItem const* lpeitem); |
479 | + virtual void doAfterEffect (SPLPEItem const* lpeitem); |
480 | virtual void transform_multiply(Geom::Affine const& postmul, bool set); |
481 | virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); |
482 | + virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); |
483 | + virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); |
484 | virtual Gtk::Widget * newWidget(); |
485 | + void toMirror(Geom::Affine transform); |
486 | + // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...); |
487 | + void cloneD(SPObject *origin, SPObject *dest, bool live, bool root); |
488 | |
489 | protected: |
490 | virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector<Geom::PathVector> &hp_vec); |
491 | |
492 | private: |
493 | EnumParam<ModeType> mode; |
494 | + ScalarParam split_gap; |
495 | BoolParam discard_orig_path; |
496 | BoolParam fuse_paths; |
497 | BoolParam oposite_fuse; |
498 | + BoolParam split_items; |
499 | PointParam start_point; |
500 | PointParam end_point; |
501 | PointParam center_point; |
502 | + TextParam id_origin; |
503 | Geom::Point previous_center; |
504 | - |
505 | + SPObject * container; |
506 | LPEMirrorSymmetry(const LPEMirrorSymmetry&); |
507 | LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&); |
508 | }; |
Some of this code is the same as the previous code. Which means they won't both merge cleanly.
This should be merged after the previous one or one of them should be the merge request and the other closed.