summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabiertxof <jabier.arraiza@marker.es>2019-05-23 22:02:57 +0000
committerJabiertxof <jabier.arraiza@marker.es>2019-05-23 22:02:57 +0000
commite2b62a335ee1f3e0d17ed5e887d7e999b68f586c (patch)
tree7e390ea2b0180e38d97bddd695d65d37681daca1 /src
parentSpeed improvemets to offset LPE (diff)
downloadinkscape-e2b62a335ee1f3e0d17ed5e887d7e999b68f586c.tar.gz
inkscape-e2b62a335ee1f3e0d17ed5e887d7e999b68f586c.zip
Improvements to Copy Rotate LPE
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/lpe-copy_rotate.cpp159
-rw-r--r--src/live_effects/lpe-copy_rotate.h1
-rw-r--r--src/ui/dialog/livepatheffect-editor.cpp1
3 files changed, 39 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 &divider)
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;
diff --git a/src/ui/dialog/livepatheffect-editor.cpp b/src/ui/dialog/livepatheffect-editor.cpp
index 78b26093a..097078e56 100644
--- a/src/ui/dialog/livepatheffect-editor.cpp
+++ b/src/ui/dialog/livepatheffect-editor.cpp
@@ -520,6 +520,7 @@ LivePathEffectEditor::onRemove()
SPItem *item = sel->singleItem();
SPLPEItem *lpeitem = dynamic_cast<SPLPEItem *>(item);
if ( lpeitem ) {
+ sp_lpe_item_update_patheffect(lpeitem, false, false);
lpeitem->removeCurrentPathEffect(false);
current_lperef = nullptr;
DocumentUndo::done( current_desktop->getDocument(), SP_VERB_DIALOG_LIVE_PATH_EFFECT,