Merge lp:~inkscape.dev/inkscape/mirror_improvements into lp:~inkscape.dev/inkscape/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
Reviewer Review Type Date Requested Status
Martin Owens Approve
Review via email: mp+315307@code.launchpad.net

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 :

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.

review: Needs Fixing
15358. By Jabiertxof <jtx@jtx>

Remove some code and make dependant of rotate copies

15359. By Jabiertxof <jtx@jtx>

Fixes some compiling bug

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
=== modified file 'src/live_effects/lpe-mirror_symmetry.cpp'
--- src/live_effects/lpe-mirror_symmetry.cpp 2016-12-26 12:54:09 +0000
+++ src/live_effects/lpe-mirror_symmetry.cpp 2017-01-24 08:45:44 +0000
@@ -15,11 +15,22 @@
15 */15 */
1616
17#include <gtkmm.h>17#include <gtkmm.h>
18#include "live_effects/lpeobject.h"
19#include "live_effects/lpeobject-reference.h"
18#include "live_effects/lpe-mirror_symmetry.h"20#include "live_effects/lpe-mirror_symmetry.h"
19#include <display/curve.h>21#include "display/curve.h"
20#include <svg/path-string.h>22#include "svg/path-string.h"
21#include "helper/geom.h"23#include "svg/svg.h"
22#include <2geom/path-intersection.h>24#include "sp-defs.h"
25#include "helper/geom.h"
26#include "2geom/intersection-graph.h"
27#include "2geom/path-intersection.h"
28#include "2geom/affine.h"
29#include "helper/geom.h"
30#include "sp-lpe-item.h"
31#include "path-chemistry.h"
32#include "style.h"
33#include "xml/sp-css-attr.h"
2334
24// TODO due to internal breakage in glibmm headers, this must be last:35// TODO due to internal breakage in glibmm headers, this must be last:
25#include <glibmm/i18n.h>36#include <glibmm/i18n.h>
@@ -40,73 +51,69 @@
40LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) :51LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) :
41 Effect(lpeobject),52 Effect(lpeobject),
42 mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE),53 mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE),
54 split_gap(_("Gap on split"), _("Gap on split"), "split_gap", &wr, this, -0.001),
43 discard_orig_path(_("Discard original path"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false),55 discard_orig_path(_("Discard original path"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false),
44 fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false),56 fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false),
45 oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false),57 oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false),
58 split_items(_("Split elements"), _("Split elements, this allow gradients and other paints."), "split_items", &wr, this, false),
46 start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust start of mirroring")),59 start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, _("Adjust start of mirroring")),
47 end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")),60 end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, _("Adjust end of mirroring")),
48 center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring"))61 center_point(_("Center mirror line"), _("Center mirror line"), "center_point", &wr, this, _("Adjust center of mirroring")),
62 id_origin("id origin", "store the id of the first LPEItem", "id_origin", &wr, this,"")
49{63{
50 show_orig_path = true;64 show_orig_path = true;
51 registerParameter(&mode);65 registerParameter(&mode);
52 registerParameter( &discard_orig_path);66 registerParameter(&split_gap);
53 registerParameter( &fuse_paths);67 registerParameter(&discard_orig_path);
54 registerParameter( &oposite_fuse);68 registerParameter(&fuse_paths);
55 registerParameter( &start_point);69 registerParameter(&oposite_fuse);
56 registerParameter( &end_point);70 registerParameter(&split_items);
57 registerParameter( &center_point);71 registerParameter(&start_point);
72 registerParameter(&end_point);
73 registerParameter(&center_point);
74 registerParameter(&id_origin);
75 id_origin.param_hide_canvas_text();
76 split_gap.param_set_range(-999999.0, 999999.0);
77 split_gap.param_set_increments(0.1, 0.1);
78 split_gap.param_set_digits(5);
79 apply_to_clippath_and_mask = true;
58 previous_center = Geom::Point(0,0);80 previous_center = Geom::Point(0,0);
59 apply_to_clippath_and_mask = true;
60}81}
6182
62LPEMirrorSymmetry::~LPEMirrorSymmetry()83LPEMirrorSymmetry::~LPEMirrorSymmetry()
63{84{
64}85}
6586
66Gtk::Widget * LPEMirrorSymmetry::newWidget()87void
88LPEMirrorSymmetry::doAfterEffect (SPLPEItem const* lpeitem)
67{89{
68 // use manage here, because after deletion of Effect object, others might90 if (split_items && !discard_orig_path) {
69 // still be pointing to this widget.91 container = dynamic_cast<SPObject *>(sp_lpe_item->parent);
70 Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget()));92 SPDocument * doc = SP_ACTIVE_DOCUMENT;
7193 Inkscape::XML::Node *root = sp_lpe_item->document->getReprRoot();
72 vbox->set_border_width(5);94 Inkscape::XML::Node *root_origin = doc->getReprRoot();
73 vbox->set_homogeneous(false);95 if (root_origin != root) {
74 vbox->set_spacing(2);96 return;
75
76 std::vector<Parameter *>::iterator it = param_vector.begin();
77 while (it != param_vector.end()) {
78 if ((*it)->widget_is_visible) {
79 Parameter *param = *it;
80 Gtk::Widget *widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget());
81 Glib::ustring *tip = param->param_getTooltip();
82 if (widg) {
83 if (param->param_key != "center_point") {
84 vbox->pack_start(*widg, true, true, 2);
85 if (tip) {
86 widg->set_tooltip_text(*tip);
87 } else {
88 widg->set_tooltip_text("");
89 widg->set_has_tooltip(false);
90 }
91 }
92 }
93 }97 }
9498 Geom::Line ls((Geom::Point)start_point, (Geom::Point)end_point);
95 ++it;99 Geom::Affine m = Geom::reflection (ls.vector(), (Geom::Point)start_point);
100 m = m * sp_lpe_item->transform;
101 toMirror(m);
102 } else {
103 processObjects(LPE_ERASE);
104 items.clear();
96 }105 }
97 return dynamic_cast<Gtk::Widget *>(vbox);
98}106}
99107
100
101void108void
102LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem)109LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem)
103{110{
111
104 using namespace Geom;112 using namespace Geom;
105 original_bbox(lpeitem);113 original_bbox(lpeitem);
106 //center_point->param_set_liveupdate(false);114 //center_point->param_set_liveupdate(false);
107 Point point_a(boundingbox_X.max(), boundingbox_Y.min());115 Point point_a(boundingbox_X.max(), boundingbox_Y.min());
108 Point point_b(boundingbox_X.max(), boundingbox_Y.max());116 Point point_b(boundingbox_X.max(), boundingbox_Y.max());
109 Point point_c(boundingbox_X.max(), boundingbox_Y.middle());
110 if (mode == MT_Y) {117 if (mode == MT_Y) {
111 point_a = Geom::Point(boundingbox_X.min(),center_point[Y]);118 point_a = Geom::Point(boundingbox_X.min(),center_point[Y]);
112 point_b = Geom::Point(boundingbox_X.max(),center_point[Y]);119 point_b = Geom::Point(boundingbox_X.max(),center_point[Y]);
@@ -173,6 +180,172 @@
173}180}
174181
175void182void
183LPEMirrorSymmetry::cloneD(SPObject *origin, SPObject *dest, bool live, bool root)
184{
185 SPDocument * document = SP_ACTIVE_DOCUMENT;
186 Inkscape::XML::Document *xml_doc = document->getReprDoc();
187 if ( SP_IS_GROUP(origin) && SP_IS_GROUP(dest) && SP_GROUP(origin)->getItemCount() == SP_GROUP(dest)->getItemCount() ) {
188 std::vector< SPObject * > childs = origin->childList(true);
189 size_t index = 0;
190 for (std::vector<SPObject * >::iterator obj_it = childs.begin();
191 obj_it != childs.end(); ++obj_it) {
192 SPObject *dest_child = dest->nthChild(index);
193 cloneD(*obj_it, dest_child, live, false);
194 index++;
195 }
196 }
197 SPShape * shape = SP_SHAPE(origin);
198 SPPath * path = SP_PATH(dest);
199 if (!path && !SP_IS_GROUP(dest)) {
200 Inkscape::XML::Node *dest_node = sp_selected_item_to_curved_repr(SP_ITEM(dest), 0);
201 dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL);
202 path = SP_PATH(dest);
203 }
204 if (path && shape) {
205 if ( live) {
206 SPCurve *c = NULL;
207 if (root) {
208 c = new SPCurve();
209 c->set_pathvector(pathvector_before_effect);
210 } else {
211 c = shape->getCurve();
212 }
213 if (c) {
214 path->setCurve(c, TRUE);
215 c->unref();
216 } else {
217 dest->getRepr()->setAttribute("d", NULL);
218 }
219 } else {
220 dest->getRepr()->setAttribute("d", origin->getRepr()->attribute("d"));
221 }
222 }
223}
224
225void
226LPEMirrorSymmetry::toMirror(Geom::Affine transform)
227{
228 SPDocument * document = SP_ACTIVE_DOCUMENT;
229 Inkscape::XML::Document *xml_doc = document->getReprDoc();
230 const char * id_origin_char = id_origin.param_getSVGValue();
231 const char * elemref_id = g_strdup(Glib::ustring("mirror-").append(id_origin_char).c_str());
232 items.clear();
233 items.push_back(elemref_id);
234 SPObject *elemref= NULL;
235 Inkscape::XML::Node *phantom = NULL;
236 if (elemref = document->getObjectById(elemref_id)) {
237 phantom = elemref->getRepr();
238 } else {
239 phantom = sp_lpe_item->getRepr()->duplicate(xml_doc);
240 std::vector<const char *> attrs;
241 attrs.push_back("inkscape:path-effect");
242 attrs.push_back("inkscape:original-d");
243 attrs.push_back("sodipodi:type");
244 attrs.push_back("sodipodi:rx");
245 attrs.push_back("sodipodi:ry");
246 attrs.push_back("sodipodi:cx");
247 attrs.push_back("sodipodi:cy");
248 attrs.push_back("sodipodi:end");
249 attrs.push_back("sodipodi:start");
250 attrs.push_back("inkscape:flatsided");
251 attrs.push_back("inkscape:randomized");
252 attrs.push_back("inkscape:rounded");
253 attrs.push_back("sodipodi:arg1");
254 attrs.push_back("sodipodi:arg2");
255 attrs.push_back("sodipodi:r1");
256 attrs.push_back("sodipodi:r2");
257 attrs.push_back("sodipodi:sides");
258 attrs.push_back("inkscape:randomized");
259 attrs.push_back("sodipodi:argument");
260 attrs.push_back("sodipodi:expansion");
261 attrs.push_back("sodipodi:radius");
262 attrs.push_back("sodipodi:revolution");
263 attrs.push_back("sodipodi:t0");
264 attrs.push_back("inkscape:randomized");
265 attrs.push_back("inkscape:randomized");
266 attrs.push_back("inkscape:randomized");
267 attrs.push_back("x");
268 attrs.push_back("y");
269 attrs.push_back("rx");
270 attrs.push_back("ry");
271 attrs.push_back("width");
272 attrs.push_back("height");
273 for(const char * attr : attrs) {
274 phantom->setAttribute(attr, NULL);
275 }
276 }
277 phantom->setAttribute("id", elemref_id);
278 if (!elemref) {
279 elemref = container->appendChildRepr(phantom);
280 Inkscape::GC::release(phantom);
281 }
282 cloneD(SP_OBJECT(sp_lpe_item), elemref, true, true);
283 elemref->getRepr()->setAttribute("transform" , sp_svg_transform_write(transform));
284 if (elemref->parent != container) {
285 Inkscape::XML::Node *copy = phantom->duplicate(xml_doc);
286 copy->setAttribute("id", elemref_id);
287 container->appendChildRepr(copy);
288 Inkscape::GC::release(copy);
289 elemref->deleteObject();
290 }
291}
292
293Gtk::Widget *
294LPEMirrorSymmetry::newWidget()
295{
296 // use manage here, because after deletion of Effect object, others might
297 // still be pointing to this widget.
298 Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget()));
299 vbox->set_border_width(5);
300 vbox->set_homogeneous(false);
301 vbox->set_spacing(2);
302
303 std::vector<Parameter *>::iterator it = param_vector.begin();
304 while (it != param_vector.end()) {
305 if ((*it)->widget_is_visible) {
306 Parameter * param = *it;
307 if (param->param_key == "id_origin" || param->param_key == "center_point") {
308 ++it;
309 continue;
310 }
311 Gtk::Widget * widg = param->param_newWidget();
312 Glib::ustring * tip = param->param_getTooltip();
313 if (widg) {
314 vbox->pack_start(*widg, true, true, 2);
315 if (tip) {
316 widg->set_tooltip_text(*tip);
317 } else {
318 widg->set_tooltip_text("");
319 widg->set_has_tooltip(false);
320 }
321 }
322 }
323
324 ++it;
325 }
326 this->upd_params = false;
327 return dynamic_cast<Gtk::Widget *>(vbox);
328}
329
330//TODO: Migrate the tree next function to effect.cpp/h to avoid duplication
331void
332LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/)
333{
334 processObjects(LPE_VISIBILITY);
335}
336
337void
338LPEMirrorSymmetry::doOnRemove (SPLPEItem const* /*lpeitem*/)
339{
340 //unset "erase_extra_objects" hook on sp-lpe-item.cpp
341 if (!erase_extra_objects) {
342 processObjects(LPE_TO_OBJECTS);
343 return;
344 }
345 processObjects(LPE_ERASE);
346}
347
348void
176LPEMirrorSymmetry::transform_multiply(Geom::Affine const& postmul, bool set)349LPEMirrorSymmetry::transform_multiply(Geom::Affine const& postmul, bool set)
177{350{
178 // cycle through all parameters. Most parameters will not need transformation, but path and point params do.351 // cycle through all parameters. Most parameters will not need transformation, but path and point params do.
@@ -193,18 +366,26 @@
193 Point point_a(boundingbox_X.max(), boundingbox_Y.min());366 Point point_a(boundingbox_X.max(), boundingbox_Y.min());
194 Point point_b(boundingbox_X.max(), boundingbox_Y.max());367 Point point_b(boundingbox_X.max(), boundingbox_Y.max());
195 Point point_c(boundingbox_X.max(), boundingbox_Y.middle());368 Point point_c(boundingbox_X.max(), boundingbox_Y.middle());
196 start_point.param_setValue(point_a, true);369 start_point.param_setValue(point_a);
197 start_point.param_update_default(point_a);370 start_point.param_update_default(point_a);
198 end_point.param_setValue(point_b, true);371 end_point.param_setValue(point_b);
199 end_point.param_update_default(point_b);372 end_point.param_update_default(point_b);
200 center_point.param_setValue(point_c, true);373 center_point.param_setValue(point_c, true);
201 previous_center = center_point;374 previous_center = center_point;
375 SPLPEItem * splpeitem = const_cast<SPLPEItem *>(lpeitem);
376 if (!lpeitem->hasPathEffectOfType(this->effectType(), false) ){ //first applied not ready yet
377 id_origin.param_setValue(lpeitem->getRepr()->attribute("id"));
378 id_origin.write_to_SVG();
379 }
202}380}
203381
204382
205Geom::PathVector383Geom::PathVector
206LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in)384LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in)
207{385{
386 if (split_items && !fuse_paths) {
387 return path_in;
388 }
208 Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in);389 Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in);
209 Geom::PathVector path_out;390 Geom::PathVector path_out;
210 391
@@ -214,15 +395,52 @@
214395
215 Geom::Line line_separation((Geom::Point)start_point, (Geom::Point)end_point);396 Geom::Line line_separation((Geom::Point)start_point, (Geom::Point)end_point);
216 Geom::Affine m = Geom::reflection (line_separation.vector(), (Geom::Point)start_point);397 Geom::Affine m = Geom::reflection (line_separation.vector(), (Geom::Point)start_point);
217398 if (split_items && fuse_paths) {
218 if (fuse_paths && !discard_orig_path) {399 Geom::OptRect bbox = sp_lpe_item->geometricBounds();
400 Geom::Path p(Geom::Point(bbox->left(), bbox->top()));
401 p.appendNew<Geom::LineSegment>(Geom::Point(bbox->right(), bbox->top()));
402 p.appendNew<Geom::LineSegment>(Geom::Point(bbox->right(), bbox->bottom()));
403 p.appendNew<Geom::LineSegment>(Geom::Point(bbox->left(), bbox->bottom()));
404 p.appendNew<Geom::LineSegment>(Geom::Point(bbox->left(), bbox->top()));
405 p.close();
406 p *= Geom::Translate(bbox->midpoint()).inverse();
407 p *= Geom::Scale(1.2);
408 p *= Geom::Rotate(line_separation.angle());
409 p *= Geom::Translate(bbox->midpoint());
410 bbox = p.boundsFast();
411 p.clear();
412 p.start(Geom::Point(bbox->left(), bbox->top()));
413 p.appendNew<Geom::LineSegment>(Geom::Point(bbox->right(), bbox->top()));
414 p.appendNew<Geom::LineSegment>(Geom::Point(bbox->right(), bbox->bottom()));
415 p.appendNew<Geom::LineSegment>(Geom::Point(bbox->left(), bbox->bottom()));
416 p.appendNew<Geom::LineSegment>(Geom::Point(bbox->left(), bbox->top()));
417 p.close();
418 p *= Geom::Translate(bbox->midpoint()).inverse();
419 p *= Geom::Rotate(line_separation.angle());
420 p *= Geom::Translate(bbox->midpoint());
421 Geom::Point base(p.pointAt(3));
422 if (oposite_fuse) {
423 base = p.pointAt(0);
424 }
425 p *= Geom::Translate(line_separation.pointAt(line_separation.nearestTime(base)) - base);
426 Geom::PathVector pv_bbox;
427 pv_bbox.push_back(p);
428 Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(pv_bbox, original_pathv);
429 if (pig && !original_pathv.empty() && !pv_bbox.empty()) {
430 path_out = pig->getBminusA();
431 }
432 Geom::Point dir = rot90(unit_vector((Geom::Point)start_point - (Geom::Point)end_point));
433 Geom::Point gap = dir * split_gap;
434 m *= Geom::Translate(gap);
435 path_out *= m;
436 } else if (fuse_paths && !discard_orig_path) {
219 for (Geom::PathVector::const_iterator path_it = original_pathv.begin();437 for (Geom::PathVector::const_iterator path_it = original_pathv.begin();
220 path_it != original_pathv.end(); ++path_it) 438 path_it != original_pathv.end(); ++path_it)
221 {439 {
222 if (path_it->empty()) {440 if (path_it->empty()) {
223 continue;441 continue;
224 }442 }
225 Geom::PathVector tmp_path;443 Geom::PathVector tmp_pathvector;
226 double time_start = 0.0;444 double time_start = 0.0;
227 int position = 0;445 int position = 0;
228 bool end_open = false;446 bool end_open = false;
@@ -268,11 +486,11 @@
268 Geom::Path mirror = portion.reversed() * m;486 Geom::Path mirror = portion.reversed() * m;
269 mirror.setInitial(portion.finalPoint());487 mirror.setInitial(portion.finalPoint());
270 portion.append(mirror);488 portion.append(mirror);
271 if(i!=0) {489 if(i != 0) {
272 portion.setFinal(portion.initialPoint());490 portion.setFinal(portion.initialPoint());
273 portion.close();491 portion.close();
274 }492 }
275 tmp_path.push_back(portion);493 tmp_pathvector.push_back(portion);
276 }494 }
277 portion.clear();495 portion.clear();
278 }496 }
@@ -293,36 +511,33 @@
293 portion.append(mirror);511 portion.append(mirror);
294 portion = portion.reversed();512 portion = portion.reversed();
295 if (!original.closed()) {513 if (!original.closed()) {
296 tmp_path.push_back(portion);514 tmp_pathvector.push_back(portion);
297 } else {515 } else {
298 if (cs.size() > 1 && tmp_path.size() > 0 && tmp_path[0].size() > 0 ) {516 if (cs.size() > 1 && tmp_pathvector.size() > 0 && tmp_pathvector[0].size() > 0 ) {
299 portion.setFinal(tmp_path[0].initialPoint());517 portion.setFinal(tmp_pathvector[0].initialPoint());
300 portion.setInitial(tmp_path[0].finalPoint());518 portion.setInitial(tmp_pathvector[0].finalPoint());
301 tmp_path[0].append(portion);519 tmp_pathvector[0].append(portion);
302 } else {520 } else {
303 tmp_path.push_back(portion);521 tmp_pathvector.push_back(portion);
304 }522 }
305 tmp_path[0].close();523 tmp_pathvector[0].close();
306 }524 }
307 portion.clear();525 portion.clear();
308 }526 }
309 }527 }
310 }528 }
311 if (cs.size() == 0 && position == 1) {529 if (cs.size() == 0 && position == 1) {
312 tmp_path.push_back(original);530 tmp_pathvector.push_back(original);
313 tmp_path.push_back(original * m);531 tmp_pathvector.push_back(original * m);
314 }532 }
315 path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end());533 path_out.insert(path_out.end(), tmp_pathvector.begin(), tmp_pathvector.end());
316 tmp_path.clear();534 tmp_pathvector.clear();
317 }535 }
318 }536 } else if (!fuse_paths || discard_orig_path) {
319
320 if (!fuse_paths || discard_orig_path) {
321 for (size_t i = 0; i < original_pathv.size(); ++i) {537 for (size_t i = 0; i < original_pathv.size(); ++i) {
322 path_out.push_back(original_pathv[i] * m);538 path_out.push_back(original_pathv[i] * m);
323 }539 }
324 }540 }
325
326 return path_out;541 return path_out;
327}542}
328543
329544
=== modified file 'src/live_effects/lpe-mirror_symmetry.h'
--- src/live_effects/lpe-mirror_symmetry.h 2016-12-18 23:19:40 +0000
+++ src/live_effects/lpe-mirror_symmetry.h 2017-01-24 08:45:44 +0000
@@ -18,8 +18,8 @@
1818
19#include "live_effects/effect.h"19#include "live_effects/effect.h"
20#include "live_effects/parameter/parameter.h"20#include "live_effects/parameter/parameter.h"
21#include "live_effects/parameter/text.h"
21#include "live_effects/parameter/point.h"22#include "live_effects/parameter/point.h"
22#include "live_effects/parameter/path.h"
23#include "live_effects/parameter/enum.h"23#include "live_effects/parameter/enum.h"
24#include "live_effects/lpegroupbbox.h"24#include "live_effects/lpegroupbbox.h"
2525
@@ -41,23 +41,32 @@
41 virtual ~LPEMirrorSymmetry();41 virtual ~LPEMirrorSymmetry();
42 virtual void doOnApply (SPLPEItem const* lpeitem);42 virtual void doOnApply (SPLPEItem const* lpeitem);
43 virtual void doBeforeEffect (SPLPEItem const* lpeitem);43 virtual void doBeforeEffect (SPLPEItem const* lpeitem);
44 virtual void doAfterEffect (SPLPEItem const* lpeitem);
44 virtual void transform_multiply(Geom::Affine const& postmul, bool set);45 virtual void transform_multiply(Geom::Affine const& postmul, bool set);
45 virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in);46 virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in);
47 virtual void doOnRemove (SPLPEItem const* /*lpeitem*/);
48 virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/);
46 virtual Gtk::Widget * newWidget();49 virtual Gtk::Widget * newWidget();
50 void toMirror(Geom::Affine transform);
51 // void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, const char * first_attribute, ...);
52 void cloneD(SPObject *origin, SPObject *dest, bool live, bool root);
4753
48protected:54protected:
49 virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector<Geom::PathVector> &hp_vec);55 virtual void addCanvasIndicators(SPLPEItem const *lpeitem, std::vector<Geom::PathVector> &hp_vec);
5056
51private:57private:
52 EnumParam<ModeType> mode;58 EnumParam<ModeType> mode;
59 ScalarParam split_gap;
53 BoolParam discard_orig_path;60 BoolParam discard_orig_path;
54 BoolParam fuse_paths;61 BoolParam fuse_paths;
55 BoolParam oposite_fuse;62 BoolParam oposite_fuse;
63 BoolParam split_items;
56 PointParam start_point;64 PointParam start_point;
57 PointParam end_point;65 PointParam end_point;
58 PointParam center_point;66 PointParam center_point;
67 TextParam id_origin;
59 Geom::Point previous_center;68 Geom::Point previous_center;
6069 SPObject * container;
61 LPEMirrorSymmetry(const LPEMirrorSymmetry&);70 LPEMirrorSymmetry(const LPEMirrorSymmetry&);
62 LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&);71 LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&);
63};72};