summaryrefslogtreecommitdiff
path: root/lib/extensions/jump_to_stroke.py
diff options
context:
space:
mode:
authorKaalleen <36401965+kaalleen@users.noreply.github.com>2024-03-07 17:57:51 +0100
committerGitHub <noreply@github.com>2024-03-07 17:57:51 +0100
commitd43f2e2ff91b1f9b0210399acd04a062f4795c9a (patch)
tree52973936482bf534000b65b45ea988afdc78d997 /lib/extensions/jump_to_stroke.py
parent0573772b60de05b1ad6bd7000125b973a848dd8f (diff)
Jump to strokes connect subpaths (#2750)
Diffstat (limited to 'lib/extensions/jump_to_stroke.py')
-rw-r--r--lib/extensions/jump_to_stroke.py116
1 files changed, 89 insertions, 27 deletions
diff --git a/lib/extensions/jump_to_stroke.py b/lib/extensions/jump_to_stroke.py
index 1487de4d..121af885 100644
--- a/lib/extensions/jump_to_stroke.py
+++ b/lib/extensions/jump_to_stroke.py
@@ -3,12 +3,10 @@
# Copyright (c) 2023 Authors
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
-from inkex import (Boolean, DirectedLineSegment, Path, PathElement, Transform,
- errormsg)
+from inkex import Boolean, DirectedLineSegment, Path, PathElement, Transform
from ..elements import Stroke
-from ..i18n import _
-from ..svg import PIXELS_PER_MM, get_correction_transform
+from ..svg import PIXELS_PER_MM, generate_unique_id, get_correction_transform
from ..svg.tags import INKSTITCH_ATTRIBS, SVG_GROUP_TAG
from .base import InkstitchExtension
@@ -29,32 +27,32 @@ class JumpToStroke(InkstitchExtension):
self.arg_parser.add_argument("--exclude-force-lock-stitch", type=Boolean, default=True, dest="exclude_forced_lock")
self.arg_parser.add_argument("-m", "--merge", type=Boolean, default=False, dest="merge")
+ self.arg_parser.add_argument("--merge_subpaths", type=Boolean, default=False, dest="merge_subpaths")
self.arg_parser.add_argument("-l", "--stitch-length", type=float, default=2.5, dest="running_stitch_length_mm")
self.arg_parser.add_argument("-t", "--tolerance", type=float, default=2.0, dest="running_stitch_tolerance_mm")
def effect(self):
- if not self.svg.selection or not self.get_elements() or len(self.elements) < 2:
- errormsg(_("Please select at least two elements to convert the jump stitch to a running stitch."))
- return
+ self._set_selection()
+ self.get_elements()
+
+ if self.options.merge_subpaths:
+ # when we merge stroke elements we are going to replace original path elements
+ # which would be bad in the case that the element has more subpaths
+ self._split_stroke_elements_with_subpaths()
last_group = None
last_layer = None
last_element = None
last_stitch_group = None
for element in self.elements:
- group = None
- layer = None
- for ancestor in element.node.iterancestors(SVG_GROUP_TAG):
- if group is None:
- group = ancestor
- if ancestor.groupmode == "layer":
- layer = ancestor
- break
-
- stitch_group = element.to_stitch_groups(last_stitch_group)
-
- if (last_stitch_group is None or
- element.color != last_element.color or
+ layer, group = self._get_element_layer_and_group(element)
+ stitch_groups = element.to_stitch_groups(last_stitch_group)
+
+ if not self.options.merge_subpaths and stitch_groups:
+ stitch_groups = [stitch_groups[-1]]
+
+ if (not stitch_groups or
+ last_element is None or
(self.options.connect == "layer" and last_layer != layer) or
(self.options.connect == "group" and last_group != group) or
(self.options.exclude_trim and (last_element.has_command("trim") or last_element.trim_after)) or
@@ -62,19 +60,83 @@ class JumpToStroke(InkstitchExtension):
(self.options.exclude_forced_lock and last_element.force_lock_stitches)):
last_layer = layer
last_group = group
- last_stitch_group = stitch_group[-1]
last_element = element
+ if stitch_groups:
+ last_stitch_group = stitch_groups[-1]
continue
- start = last_stitch_group.stitches[-1]
- end = stitch_group[-1].stitches[0]
- self.generate_stroke(last_element, element, start, end)
+ for stitch_group in stitch_groups:
+ if last_stitch_group is None or stitch_group.color != last_stitch_group.color:
+ last_layer = layer
+ last_group = group
+ last_stitch_group = stitch_group
+ continue
+
+ start = last_stitch_group.stitches[-1]
+ end = stitch_group.stitches[0]
+ self.generate_stroke(last_element, element, start, end)
+ last_stitch_group = stitch_group
last_group = group
last_layer = layer
- last_stitch_group = stitch_group[-1]
last_element = element
+ def _set_selection(self):
+ if not self.svg.selection:
+ self.svg.selection.clear()
+
+ def _get_element_layer_and_group(self, element):
+ layer = None
+ group = None
+ for ancestor in element.node.iterancestors(SVG_GROUP_TAG):
+ if group is None:
+ group = ancestor
+ if ancestor.groupmode == "layer":
+ layer = ancestor
+ break
+ return layer, group
+
+ def _split_stroke_elements_with_subpaths(self):
+ elements = []
+ for element in self.elements:
+ if isinstance(element, Stroke) and len(element.paths) > 1:
+ if element.get_param('stroke_method', None) in ['ripple_stitch']:
+ elements.append(element)
+ continue
+ node = element.node
+ parent = node.getparent()
+ index = parent.index(node)
+ paths = node.get_path().break_apart()
+ paths.reverse()
+
+ block_ids = []
+ for path in paths:
+ subpath_element = node.copy()
+ subpath_id = generate_unique_id(node, f'{node.get_id()}_', block_ids)
+ subpath_element.set('id', subpath_id)
+ subpath_element.set('d', str(path))
+ block_ids.append(subpath_id)
+ parent.insert(index, subpath_element)
+ elements.append(Stroke(subpath_element))
+ parent.remove(node)
+ else:
+ elements.append(element)
+ self.elements = elements
+
+ def _is_mergable(self, element1, element2):
+ if not (isinstance(element1, Stroke)):
+ return False
+ if (self.options.merge_subpaths and
+ element1.node.get_id() not in self.svg.selection.ids and
+ element2.node.get_id() not in self.svg.selection.ids):
+ return True
+ if (self.options.merge and
+ element1.node.TAG == "path" and
+ element1.get_param('stroke_method', None) == element2.get_param('stroke_method', None) and
+ not element1.get_param('stroke_method', '') == 'ripple_stitch'):
+ return True
+ return False
+
def generate_stroke(self, last_element, element, start, end):
node = element.node
parent = node.getparent()
@@ -91,13 +153,13 @@ class JumpToStroke(InkstitchExtension):
path = Path([(start.x, start.y), (end.x, end.y)])
# option: merge line with paths
merged = False
- if self.options.merge and isinstance(last_element, Stroke) and last_element.node.TAG == "path":
+ if self._is_mergable(last_element, element):
path.transform(Transform(get_correction_transform(last_element.node)), True)
path = last_element.node.get_path() + path[1:]
last_element.node.set('d', str(path))
path.transform(-Transform(get_correction_transform(last_element.node)), True)
merged = True
- if self.options.merge and isinstance(element, Stroke) and node.TAG == "path":
+ if self._is_mergable(element, last_element):
path.transform(Transform(get_correction_transform(node)), True)
path = path + node.get_path()[1:]
node.set('d', str(path))