diff options
| author | Jabiertxof <jtx@jtx> | 2016-12-03 22:49:17 +0000 |
|---|---|---|
| committer | Jabiertxof <jtx@jtx> | 2016-12-03 22:49:17 +0000 |
| commit | 4d33b96eb8c47f5aef22f795dd199ba04b734784 (patch) | |
| tree | 2f131732027685db6a7e71fe612832a5d1ff6144 /src | |
| parent | Fix a typo (diff) | |
| download | inkscape-4d33b96eb8c47f5aef22f795dd199ba04b734784.tar.gz inkscape-4d33b96eb8c47f5aef22f795dd199ba04b734784.zip | |
Start coding
(bzr r15295.1.1)
Diffstat (limited to 'src')
| -rw-r--r-- | src/live_effects/lpe-mirror_symmetry.cpp | 201 | ||||
| -rw-r--r-- | src/live_effects/lpe-mirror_symmetry.h | 14 |
2 files changed, 200 insertions, 15 deletions
diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp index 4deb29d8f..e62dbbca9 100644 --- a/src/live_effects/lpe-mirror_symmetry.cpp +++ b/src/live_effects/lpe-mirror_symmetry.cpp @@ -14,12 +14,18 @@ * Released under GNU GPL, read the file 'COPYING' for more information */ #include "live_effects/lpe-mirror_symmetry.h" -#include <display/curve.h> -#include <svg/path-string.h> +#include "display/curve.h" +#include "svg/path-string.h" +#include "svg/svg.h" +#include "sp-defs.h" #include "helper/geom.h" -#include <2geom/path-intersection.h> +#include "2geom/path-intersection.h" +#include "2geom/affine.h" +#include "uri.h" +#include "uri-references.h" #include "knotholder.h" // TODO due to internal breakage in glibmm headers, this must be last: +#include <glibmm/i18n.h> namespace Inkscape { namespace LivePathEffect { @@ -34,6 +40,9 @@ static const Util::EnumData<ModeType> ModeTypeData[MT_END] = { static const Util::EnumDataConverter<ModeType> MTConverter(ModeTypeData, MT_END); +std::vector<Glib::ustring> ms_elements; +SPObject * ms_container; + namespace MS { class KnotHolderEntityCenterMirrorSymmetry : public LPEKnotHolderEntity { @@ -65,6 +74,9 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : discard_orig_path(_("Discard original path?"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false), fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false), oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false), + split(_("Split elements"), _("Split elements, this allow gradients and other paints"), "split", &wr, this, false), + split_sensitive(_("Make split selectable"), _("Allow select splited elements"), "split", &wr, this, false), + split_style(_("Make splits with style"), _("Allow Change colors to split"), "split", &wr, this, false), start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, "Adjust the start of mirroring"), end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, "Adjust end of mirroring") { @@ -73,6 +85,9 @@ LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) : registerParameter( &discard_orig_path); registerParameter( &fuse_paths); registerParameter( &oposite_fuse); + registerParameter( &split); + registerParameter( &split_sensitive); + registerParameter( &split_style); registerParameter( &start_point); registerParameter( &end_point); apply_to_clippath_and_mask = true; @@ -142,8 +157,155 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem) } } previous_center = center_point; + if (split) { + SPLPEItem * splpeitem = const_cast<SPLPEItem *>(lpeitem); + ms_container = dynamic_cast<SPObject *>(splpeitem->parent); + SPDocument * doc = SP_ACTIVE_DOCUMENT; + Inkscape::XML::Node *root = splpeitem->document->getReprRoot(); + Inkscape::XML::Node *root_origin = doc->getReprRoot(); + if (root_origin != root) { + return; + } + Geom::Point point_a(line_separation.initialPoint()); + Geom::Point point_b(line_separation.finalPoint()); + + Geom::Translate m1(point_a[0], point_a[1]); + double hyp = Geom::distance(point_a, point_b); + double cos = 0; + double sin = 0; + if (hyp > 0) { + cos = (point_b[0] - point_a[0]) / hyp; + sin = (point_b[1] - point_a[1]) / hyp; + } + Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0); + Geom::Scale sca(1.0, -1.0); + + Geom::Affine m = m1.inverse() * m2; + m = m * sca; + m = m * m2.inverse(); + m = m * m1; + createPhantom(splpeitem , (Glib::ustring) "origin-clon-", split_style); + createClone(splpeitem , m, (Glib::ustring) "clon-"); + } +} + +void +LPEMirrorSymmetry::createPhantom(SPLPEItem *origin, Glib::ustring id, bool styling) +{ + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + id = id + (Glib::ustring)this->getRepr()->attribute("id"); + Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str()); + Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); + SVGElemRef->attach(SVGElem_uri); + SPObject *elemref = NULL; + Inkscape::XML::Node *phantom = origin->getRepr()->duplicate(xml_doc); + if (elemref = SVGElemRef->getObject()) { + elemref->deleteObject(); + } + if (styling) { + SPCSSAttr *css = sp_repr_css_attr_new(); + sp_repr_css_set_property (css, "fill", NULL); + sp_repr_css_set_property (css, "stroke",NULL); + Glib::ustring css_str; + sp_repr_css_write_string(css,css_str); + sp_repr_css_change_recursive (phantom, css, css_str.c_str()); + } + phantom->setAttribute("id", id); + phantom->setAttribute("inkscape:path-effect", NULL); + SP_OBJECT(desktop->getDocument()->getDefs()->appendChildRepr(phantom)); + Inkscape::GC::release(phantom); + ms_elements.push_back(id); + } +} + +void +LPEMirrorSymmetry::createClone(SPLPEItem *origin, Geom::Affine transform, Glib::ustring id) +{ + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + id = id + (Glib::ustring)this->getRepr()->attribute("id"); + Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str()); + Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); + SVGElemRef->attach(SVGElem_uri); + SPObject *elemref = NULL; + Inkscape::XML::Node *use = NULL; + use = xml_doc->createElement("svg:use"); + use->setAttribute("transform" , sp_svg_transform_write(transform)); + use->setAttribute("xlink:href", ((Glib::ustring)"#origin-" + id).c_str()); + use->setAttribute("width", "100%"); + use->setAttribute("height", "100%"); + use->setAttribute("id", id); + use->setAttribute("x", "0"); + use->setAttribute("y", "0"); + if (split_sensitive) { + use->setAttribute("sodipodi:insensitive" , "false"); + } else { + use->setAttribute("sodipodi:insensitive" , "true"); + } + if (elemref) { + elemref->deleteObject(); + } + elemref = ms_container->appendChildRepr(use); + Inkscape::GC::release(use); + ms_elements.push_back(id); + } +} + + +void +LPEMirrorSymmetry::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) +{ + processObjects(LPE_VISIBILITY); +} + +void +LPEMirrorSymmetry::doOnRemove (SPLPEItem const* /*lpeitem*/) +{ + if (!erase_extra_objects) { + processObjects(LPE_TO_OBJECTS); + ms_elements.clear(); + return; + } + processObjects(LPE_ERASE); } +void +LPEMirrorSymmetry::processObjects(LpeAction lpe_action) +{ + if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) { + for (std::vector<Glib::ustring>::iterator el_it = ms_elements.begin(); + el_it != ms_elements.end();++el_it) { + Glib::ustring id = *el_it; + Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str()); + Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc()); + SVGElemRef->attach(SVGElem_uri); + SPObject *elemref = NULL; + if (elemref = SVGElemRef->getObject()) { + switch (lpe_action){ + case LPE_TO_OBJECTS: + elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL); + break; + case LPE_ERASE: + elemref->deleteObject(); + break; + default: //LPE_VISIBILITY + if (!this->isVisible()) { + elemref->getRepr()->setAttribute("style", "display:none"); + } else { + elemref->getRepr()->setAttribute("style", NULL); + } + break; + } + } + } + if (lpe_action == LPE_ERASE) { + ms_elements.clear(); + } + } +} + + void LPEMirrorSymmetry::transform_multiply(Geom::Affine const& postmul, bool set) { @@ -178,6 +340,9 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem) Geom::PathVector LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) { + if (split && !fuse_paths) { + return path_in; + } Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in); Geom::PathVector path_out; @@ -204,7 +369,7 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) m = m * m2.inverse(); m = m * m1; - if (fuse_paths && !discard_orig_path) { + if (fuse_paths && (!discard_orig_path || split )) { for (Geom::PathVector::const_iterator path_it = original_pathv.begin(); path_it != original_pathv.end(); ++path_it) { @@ -255,11 +420,15 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) } if (position == 1) { Geom::Path mirror = portion.reversed() * m; - mirror.setInitial(portion.finalPoint()); - portion.append(mirror); - if(i!=0) { - portion.setFinal(portion.initialPoint()); + if (split) { portion.close(); + } else { + mirror.setInitial(portion.finalPoint()); + portion.append(mirror); + if(i!=0) { + portion.setFinal(portion.initialPoint()); + portion.close(); + } } tmp_path.push_back(portion); } @@ -277,10 +446,14 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) Geom::Path portion = original.portion(time_start, original.size()); if (!portion.empty()) { portion = portion.reversed(); - Geom::Path mirror = portion.reversed() * m; - mirror.setInitial(portion.finalPoint()); - portion.append(mirror); - portion = portion.reversed(); + if (split) { + + } else { + Geom::Path mirror = portion.reversed() * m; + mirror.setInitial(portion.finalPoint()); + portion.append(mirror); + portion = portion.reversed(); + } if (!original.closed()) { tmp_path.push_back(portion); } else { @@ -304,9 +477,7 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in) path_out.insert(path_out.end(), tmp_path.begin(), tmp_path.end()); tmp_path.clear(); } - } - - if (!fuse_paths || discard_orig_path) { + } else if (!fuse_paths || discard_orig_path) { for (size_t i = 0; i < original_pathv.size(); ++i) { path_out.push_back(original_pathv[i] * m); } diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h index 7ec4029e0..70c82e330 100644 --- a/src/live_effects/lpe-mirror_symmetry.h +++ b/src/live_effects/lpe-mirror_symmetry.h @@ -31,6 +31,12 @@ namespace MS { class KnotHolderEntityCenterMirrorSymmetry; } +enum LpeAction { + LPE_ERASE = 0, + LPE_TO_OBJECTS, + LPE_VISIBILITY +}; + enum ModeType { MT_V, MT_H, @@ -48,8 +54,13 @@ public: virtual void doBeforeEffect (SPLPEItem const* lpeitem); virtual void transform_multiply(Geom::Affine const& postmul, bool set); virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in); + virtual void doOnRemove (SPLPEItem const* /*lpeitem*/); + virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/); + void processObjects(LpeAction lpe_action); /* the knotholder entity classes must be declared friends */ friend class MS::KnotHolderEntityCenterMirrorSymmetry; + void createPhantom(SPLPEItem *origin, Glib::ustring id, bool styling); + void createClone(SPLPEItem *origin, Geom::Affine transform, Glib::ustring id); void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item); protected: @@ -60,6 +71,9 @@ private: BoolParam discard_orig_path; BoolParam fuse_paths; BoolParam oposite_fuse; + BoolParam split; + BoolParam split_sensitive; + BoolParam split_style; PointParam start_point; PointParam end_point; Geom::Line line_separation; |
