summaryrefslogtreecommitdiffstats
path: root/src/ui/tool/path-manipulator.cpp
diff options
context:
space:
mode:
authorKrzysztof Kosi??ski <tweenk.pl@gmail.com>2010-01-14 08:42:20 +0000
committerKrzysztof KosiƄski <tweenk.pl@gmail.com>2010-01-14 08:42:20 +0000
commitdd3076a51d8a53223c771a39fa5f976db0c85af5 (patch)
treea77295c5911f20bb9e4dd1f513847ff603ba1cc8 /src/ui/tool/path-manipulator.cpp
parent* Merge from trunk (diff)
downloadinkscape-dd3076a51d8a53223c771a39fa5f976db0c85af5.tar.gz
inkscape-dd3076a51d8a53223c771a39fa5f976db0c85af5.zip
Implement segment weld to make segment join similar to node join
(bzr r8846.2.12)
Diffstat (limited to 'src/ui/tool/path-manipulator.cpp')
-rw-r--r--src/ui/tool/path-manipulator.cpp58
1 files changed, 55 insertions, 3 deletions
diff --git a/src/ui/tool/path-manipulator.cpp b/src/ui/tool/path-manipulator.cpp
index cfa3846f8..9889eb787 100644
--- a/src/ui/tool/path-manipulator.cpp
+++ b/src/ui/tool/path-manipulator.cpp
@@ -317,19 +317,21 @@ void PathManipulator::weldNodes(NodeList::iterator preserve_pos)
}
// Start from unselected node in closed paths, so that we don't start in the middle
- // of a contiguous selection
+ // of a selection
NodeList::iterator sel_beg = sp->begin(), sel_end;
if (sp->closed()) {
while (sel_beg->selected()) ++sel_beg;
}
- // Main loop
+ // Work loop
while (num_selected > 0) {
// Find selected node
while (sel_beg && !sel_beg->selected()) sel_beg = sel_beg.next();
if (!sel_beg) throw std::logic_error("Join nodes: end of open path reached, "
"but there are still nodes to process!");
+ // note: this is initialized to zero, because the loop below counts sel_beg as well
+ // the loop conditions are simpler that way
unsigned num_points = 0;
bool use_pos = false;
Geom::Point back_pos, front_pos;
@@ -373,7 +375,57 @@ void PathManipulator::weldNodes(NodeList::iterator preserve_pos)
/** Remove nodes in the middle of selected segments. */
void PathManipulator::weldSegments()
{
- // TODO
+ if (!_num_selected) return;
+ _dragpoint->setVisible(false);
+
+ for (SubpathList::iterator i = _subpaths.begin(); i != _subpaths.end(); ++i) {
+ SubpathPtr sp = *i;
+ unsigned num_selected = 0, num_unselected = 0;
+ for (NodeList::iterator j = sp->begin(); j != sp->end(); ++j) {
+ if (j->selected()) ++num_selected;
+ else ++num_unselected;
+ }
+ if (num_selected < 3) continue;
+ if (num_unselected == 0 && sp->closed()) {
+ // if all nodes in a closed subpath are selected, the operation doesn't make much sense
+ continue;
+ }
+
+ // Start from unselected node in closed paths, so that we don't start in the middle
+ // of a selection
+ NodeList::iterator sel_beg = sp->begin(), sel_end;
+ if (sp->closed()) {
+ while (sel_beg->selected()) ++sel_beg;
+ }
+
+ // Work loop
+ while (num_selected > 0) {
+ // Find selected node
+ while (sel_beg && !sel_beg->selected()) sel_beg = sel_beg.next();
+ if (!sel_beg) throw std::logic_error("Join nodes: end of open path reached, "
+ "but there are still nodes to process!");
+
+ // note: this is initialized to zero, because the loop below counts sel_beg as well
+ // the loop conditions are simpler that way
+ unsigned num_points = 0;
+
+ // find the end of selected segment
+ for (sel_end = sel_beg; sel_end && sel_end->selected(); sel_end = sel_end.next()) {
+ ++num_points;
+ }
+ if (num_points > 2) {
+ // remove nodes in the middle
+ sel_beg = sel_beg.next();
+ while (sel_beg != sel_end.prev()) {
+ NodeList::iterator next = sel_beg.next();
+ sp->erase(sel_beg);
+ sel_beg = next;
+ }
+ sel_beg = sel_end;
+ }
+ num_selected -= num_points;
+ }
+ }
}
/** Break the subpath at selected nodes. It also works for single node closed paths. */