diff options
| author | Jabiertxof <jabier.arraiza@marker.es> | 2019-05-23 22:02:57 +0000 |
|---|---|---|
| committer | Jabiertxof <jabier.arraiza@marker.es> | 2019-05-23 22:02:57 +0000 |
| commit | e2b62a335ee1f3e0d17ed5e887d7e999b68f586c (patch) | |
| tree | 7e390ea2b0180e38d97bddd695d65d37681daca1 /src/live_effects | |
| parent | Speed improvemets to offset LPE (diff) | |
| download | inkscape-e2b62a335ee1f3e0d17ed5e887d7e999b68f586c.tar.gz inkscape-e2b62a335ee1f3e0d17ed5e887d7e999b68f586c.zip | |
Improvements to Copy Rotate LPE
Diffstat (limited to 'src/live_effects')
| -rw-r--r-- | src/live_effects/lpe-copy_rotate.cpp | 159 | ||||
| -rw-r--r-- | src/live_effects/lpe-copy_rotate.h | 1 |
2 files changed, 38 insertions, 122 deletions
diff --git a/src/live_effects/lpe-copy_rotate.cpp b/src/live_effects/lpe-copy_rotate.cpp index e4411990c..92296023c 100644 --- a/src/live_effects/lpe-copy_rotate.cpp +++ b/src/live_effects/lpe-copy_rotate.cpp @@ -25,6 +25,7 @@ #include "helper/geom.h" #include "xml/sp-css-attr.h" #include "path-chemistry.h" +#include "object/sp-text.h" #include "object/sp-path.h" #include "object/sp-shape.h" @@ -65,7 +66,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : starting_angle(_("Starting angle"), _("Angle of the first copy"), "starting_angle", &wr, this, 0.0), rotation_angle(_("Rotation angle"), _("Angle between two successive copies"), "rotation_angle", &wr, this, 60.0), num_copies(_("Number of copies"), _("Number of copies of the original path"), "num_copies", &wr, this, 6), - gap(_("Gap"), _("Gap"), "gap", &wr, this, -0.0001), + gap(_("Gap"), _("Gap"), "gap", &wr, this, 0), copies_to_360(_("360º Copies"), _("No rotation angle, fixed to 360º"), "copies_to_360", &wr, this, true), mirror_copies(_("Mirror copies"), _("Mirror between copies"), "mirror_copies", &wr, this, false), split_items(_("Split elements"), _("Split elements, this allow gradients and other paints."), "split_items", &wr, this, false), @@ -101,6 +102,7 @@ LPECopyRotate::LPECopyRotate(LivePathEffectObject *lpeobject) : previous_origin = Geom::Point(0,0); previous_start_point = Geom::Point(0,0); starting_point.param_widget_is_visible(false); + gap_override = gap; reset = false; } @@ -198,6 +200,9 @@ LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bo } Inkscape::XML::Document *xml_doc = document->getReprDoc(); if ( SP_IS_GROUP(orig) && SP_IS_GROUP(dest) && SP_GROUP(orig)->getItemCount() == SP_GROUP(dest)->getItemCount() ) { + if (reset) { + dest->getRepr()->setAttribute("style", orig->getRepr()->attribute("style")); + } std::vector< SPObject * > childs = orig->childList(true); size_t index = 0; for (auto & child : childs) { @@ -207,6 +212,19 @@ LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bo } return; } + + if ( SP_IS_TEXT(orig) && SP_IS_TEXT(dest) && SP_TEXT(orig)->children.size() == SP_TEXT(dest)->children.size()) { + if (reset) { + dest->getRepr()->setAttribute("style", orig->getRepr()->attribute("style")); + } + size_t index = 0; + for (auto & child : SP_TEXT(orig)->children) { + SPObject *dest_child = dest->nthChild(index); + cloneD(&child, dest_child, transform, reset); + index++; + } + } + SPShape * shape = SP_SHAPE(orig); SPPath * path = SP_PATH(dest); if (shape) { @@ -218,10 +236,10 @@ LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bo const char * style = dest->getRepr()->attribute("style"); Inkscape::XML::Document *xml_doc = dest->document->getReprDoc(); Inkscape::XML::Node *dest_node = xml_doc->createElement("svg:path");; - dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); dest_node->setAttribute("id", id); dest_node->setAttribute("inkscape:connector-curvature", "0"); dest_node->setAttribute("style", style); + dest->updateRepr(xml_doc, dest_node, SP_OBJECT_WRITE_ALL); path = SP_PATH(dest); } path->getRepr()->setAttribute("d", str); @@ -230,9 +248,10 @@ LPECopyRotate::cloneD(SPObject *orig, SPObject *dest, Geom::Affine transform, bo } else { path->getRepr()->setAttribute("d", nullptr); } - if (reset) { - dest->getRepr()->setAttribute("style", shape->getRepr()->attribute("style")); - } + + } + if (reset) { + dest->getRepr()->setAttribute("style", orig->getRepr()->attribute("style")); } } @@ -259,6 +278,7 @@ LPECopyRotate::createPathBase(SPObject *elemref) { } Inkscape::XML::Node *resultnode = xml_doc->createElement("svg:path"); resultnode->setAttribute("transform", prev->attribute("transform")); + resultnode->setAttribute("style", prev->attribute("style")); return resultnode; } @@ -366,6 +386,10 @@ LPECopyRotate::doBeforeEffect (SPLPEItem const* lpeitem) { using namespace Geom; original_bbox(lpeitem, false, true); + gap_override = gap; + if (gap <= 0 && gap > -0.5 && method == RM_FUSE && !split_items) { + gap_override = -0.5; + } if (copies_to_360 && num_copies > 2) { rotation_angle.param_set_value(360.0/(double)num_copies); } @@ -474,119 +498,6 @@ LPECopyRotate::split(Geom::PathVector &path_on, Geom::Path const ÷r) path_on = tmp_path; } -//void -//LPECopyRotate::setFusion(Geom::PathVector &path_on, Geom::Path divider, double size_divider) -//{ -// split(path_on,divider); -// Geom::PathVector tmp_path; -// Geom::Affine pre = Geom::Translate(-origin); -// for (Geom::PathVector::const_iterator path_it = path_on.begin(); path_it != path_on.end(); ++path_it) { -// Geom::Path original = *path_it; -// if (path_it->empty()) { -// continue; -// } -// Geom::PathVector tmp_path_helper; -// Geom::Path append_path = original; -// Geom::Point previous = original.finalPoint(); -// for (int i = 0; i < num_copies; ++i) { -// Geom::Rotate rot(-Geom::rad_from_deg(rotation_angle * (i))); -// Geom::Affine m = pre * rot * Geom::Translate(origin); -// if (i%2 != 0 && mirror_copies) { -// Geom::Point point_a = (Geom::Point)origin; -// Geom::Point point_b = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle*i)+starting_angle)) * size_divider; -// Geom::Line ls(point_a, point_b); -// m = Geom::reflection (ls.vector(), point_a); -// append_path *= m; -// } else { -// append_path = original; -// append_path *= m; -// } -// previous = append_path.finalPoint(); -// if (tmp_path_helper.size() > 0) { -// if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(), append_path.finalPoint())) { -// Geom::Path tmp_append = append_path.reversed(); -// tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); -// tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); -// } else if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(), append_path.initialPoint())) { -// Geom::Path tmp_append = append_path; -// tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); -// tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); -// tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); -// } else if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(), append_path.initialPoint())) { -// Geom::Path tmp_append = append_path; -// tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); -// tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); -// } else if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(), append_path.finalPoint())) { -// Geom::Path tmp_append = append_path.reversed(); -// tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1].reversed(); -// tmp_append.setInitial(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); -// tmp_path_helper[tmp_path_helper.size()-1].append(tmp_append); -// } else if (Geom::are_near(tmp_path_helper[0].finalPoint(), append_path.finalPoint())) { -// Geom::Path tmp_append = append_path.reversed(); -// tmp_append.setInitial(tmp_path_helper[0].finalPoint()); -// tmp_path_helper[0].append(tmp_append); -// } else if (Geom::are_near(tmp_path_helper[0].initialPoint(), append_path.initialPoint())) { -// Geom::Path tmp_append = append_path; -// tmp_path_helper[0] = tmp_path_helper[0].reversed(); -// tmp_append.setInitial(tmp_path_helper[0].finalPoint()); -// tmp_path_helper[0].append(tmp_append); -// } else { -// tmp_path_helper.push_back(append_path); -// } -// if ( Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),tmp_path_helper[tmp_path_helper.size()-1].initialPoint())) { -// tmp_path_helper[tmp_path_helper.size()-1].close(); -// } -// } else { -// tmp_path_helper.push_back(append_path); -// } -// } -// if (tmp_path_helper.size() > 0) { -// tmp_path_helper[tmp_path_helper.size()-1] = tmp_path_helper[tmp_path_helper.size()-1]; -// tmp_path_helper[0] = tmp_path_helper[0]; -// if (rotation_angle * num_copies != 360) { -// Geom::Ray base_a(divider.pointAt(1),divider.pointAt(0)); -// double diagonal = Geom::distance(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); -// Geom::Rect bbox(Geom::Point(boundingbox_X.min(),boundingbox_Y.min()),Geom::Point(boundingbox_X.max(),boundingbox_Y.max())); -// double size_divider = Geom::distance(origin,bbox) + (diagonal * 2); -// Geom::Point base_point = origin + dir * Geom::Rotate(-Geom::rad_from_deg((rotation_angle * num_copies) + starting_angle)) * size_divider; -// Geom::Ray base_b(divider.pointAt(1), base_point); -// if (Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && -// Geom::are_near(tmp_path_helper[0].finalPoint(),base_a)) -// { -// tmp_path_helper[0].close(); -// if (tmp_path_helper.size() > 1) { -// tmp_path_helper[tmp_path_helper.size()-1].close(); -// } -// } else if (Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].initialPoint(),base_b) && -// Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_b)) -// { -// tmp_path_helper[0].close(); -// if (tmp_path_helper.size() > 1) { -// tmp_path_helper[tmp_path_helper.size()-1].close(); -// } -// } else if ((Geom::are_near(tmp_path_helper[0].initialPoint(),base_a) && -// Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_b)) || -// (Geom::are_near(tmp_path_helper[0].initialPoint(),base_b) && -// Geom::are_near(tmp_path_helper[tmp_path_helper.size()-1].finalPoint(),base_a))) -// { -// Geom::Path close_path = Geom::Path(tmp_path_helper[tmp_path_helper.size()-1].finalPoint()); -// close_path.appendNew<Geom::LineSegment>((Geom::Point)origin); -// close_path.appendNew<Geom::LineSegment>(tmp_path_helper[0].initialPoint()); -// tmp_path_helper[0].append(close_path); -// } -// } - -// if (Geom::are_near(tmp_path_helper[0].finalPoint(),tmp_path_helper[0].initialPoint())) { -// tmp_path_helper[0].close(); -// } -// } -// tmp_path.insert(tmp_path.end(), tmp_path_helper.begin(), tmp_path_helper.end()); -// tmp_path_helper.clear(); -// } -// path_on = tmp_path; -// tmp_path.clear(); -//} - Geom::PathVector LPECopyRotate::doEffect_path (Geom::PathVector const & path_in) { @@ -599,6 +510,10 @@ LPECopyRotate::doEffect_path (Geom::PathVector const & path_in) divider = Geom::Path(line_start); divider.appendNew<Geom::LineSegment>((Geom::Point)origin); divider.appendNew<Geom::LineSegment>(line_end); + Geom::OptRect trianglebounds = divider.boundsFast(); + if (gap_override <= 0 && method != RM_NORMAL && !split_items) { + divider *= Geom::Translate((*trianglebounds).midpoint()).inverse() * Geom::Scale(1.1) * Geom::Translate((*trianglebounds).midpoint()); + } divider.close(); half_dir = unit_vector(Geom::middle_point(line_start,line_end) - (Geom::Point)origin); if (method != RM_NORMAL) { @@ -616,9 +531,9 @@ LPECopyRotate::doEffect_path (Geom::PathVector const & path_in) if (pig && !path_out.empty() && !triangle.empty()) { path_out = pig->getIntersection(); } - path_out *= Geom::Translate(half_dir * gap); + path_out *= Geom::Translate(half_dir * gap_override); if ( !split_items ) { - path_out *= Geom::Translate(half_dir * gap).inverse(); + path_out *= Geom::Translate(half_dir * gap_override).inverse(); path_out = doEffect_path_post(path_out); } } else { @@ -658,7 +573,7 @@ LPECopyRotate::doEffect_path_post (Geom::PathVector const & path_in) } if (method != RM_NORMAL) { Geom::PathVector join_pv = original_pathv * t; - join_pv *= Geom::Translate(half_dir * rot * gap); + join_pv *= Geom::Translate(half_dir * rot * gap_override); Geom::PathIntersectionGraph *pig = new Geom::PathIntersectionGraph(output_pv, join_pv); if (pig) { if (!output_pv.empty()) { @@ -710,7 +625,7 @@ LPECopyRotate::doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/) } void -LPECopyRotate::doOnRemove (SPLPEItem const* /*lpeitem*/) +LPECopyRotate::doOnRemove (SPLPEItem const* lpeitem) { //set "keep paths" hook on sp-lpe-item.cpp if (keep_paths) { diff --git a/src/live_effects/lpe-copy_rotate.h b/src/live_effects/lpe-copy_rotate.h index 188d79f37..189c18ac8 100644 --- a/src/live_effects/lpe-copy_rotate.h +++ b/src/live_effects/lpe-copy_rotate.h @@ -74,6 +74,7 @@ private: Geom::Point previous_start_point; double dist_angle_handle; double size_divider; + double gap_override; Geom::Path divider; double previous_num_copies; bool reset; |
