diff options
| author | Kaalleen <36401965+kaalleen@users.noreply.github.com> | 2024-02-23 16:54:39 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-23 16:54:39 +0100 |
| commit | 0816635d7ef1b93c93824da156b17a93f19becef (patch) | |
| tree | 003ea6cd9ceb719c777bc06c6246c0f26d83cde8 /lib/extensions | |
| parent | c61473f02ff2b56a8e72db3eff46010af2784894 (diff) | |
Jump to stroke options (#2733)
* Min width
* Max width
* Connect only within groups or layers
* Do not connect after trim, stop or forced lock stitches
* Merge new strokes with previous/next stroke
Diffstat (limited to 'lib/extensions')
| -rw-r--r-- | lib/extensions/jump_to_stroke.py | 94 |
1 files changed, 79 insertions, 15 deletions
diff --git a/lib/extensions/jump_to_stroke.py b/lib/extensions/jump_to_stroke.py index 9c9d099f..1487de4d 100644 --- a/lib/extensions/jump_to_stroke.py +++ b/lib/extensions/jump_to_stroke.py @@ -3,11 +3,13 @@ # Copyright (c) 2023 Authors # Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details. -from inkex import DirectedLineSegment, PathElement, errormsg +from inkex import (Boolean, DirectedLineSegment, Path, PathElement, Transform, + errormsg) +from ..elements import Stroke from ..i18n import _ from ..svg import PIXELS_PER_MM, get_correction_transform -from ..svg.tags import INKSTITCH_ATTRIBS +from ..svg.tags import INKSTITCH_ATTRIBS, SVG_GROUP_TAG from .base import InkstitchExtension @@ -17,6 +19,16 @@ class JumpToStroke(InkstitchExtension): def __init__(self, *args, **kwargs): InkstitchExtension.__init__(self, *args, **kwargs) + self.arg_parser.add_argument("--tab") + + self.arg_parser.add_argument("-i", "--minimum-jump-length", type=float, default=3.0, dest="min_jump") + self.arg_parser.add_argument("-a", "--maximum-jump-length", type=float, default=0, dest="max_jump") + self.arg_parser.add_argument("--connect", type=str, default="all", dest="connect") + self.arg_parser.add_argument("--exclude-trim", type=Boolean, default=True, dest="exclude_trim") + self.arg_parser.add_argument("--exclude-stop", type=Boolean, default=True, dest="exclude_stop") + 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("-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") @@ -25,36 +37,88 @@ class JumpToStroke(InkstitchExtension): errormsg(_("Please select at least two elements to convert the jump stitch to a running stitch.")) return + last_group = None + last_layer = None + last_element = None last_stitch_group = None - last_color = 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 + (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 + (self.options.exclude_stop and (last_element.has_command("stop") or last_element.stop_after)) or + (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 + continue + + start = last_stitch_group.stitches[-1] end = stitch_group[-1].stitches[0] - if last_stitch_group is not None and element.color == last_color: - start = last_stitch_group.stitches[-1] - self.generate_stroke(element, start, end) + self.generate_stroke(last_element, element, start, end) + last_group = group + last_layer = layer last_stitch_group = stitch_group[-1] - last_color = element.color + last_element = element - def generate_stroke(self, element, start, end): + def generate_stroke(self, last_element, element, start, end): node = element.node parent = node.getparent() index = parent.index(node) - # do not add a running stitch if the distance is smaller than the collapse setting - self.metadata = self.get_inkstitch_metadata() - collapse_len = self.metadata['collapse_len_mm'] or 3.0 - collapse_len *= PIXELS_PER_MM + # do not add a running stitch if the distance is smaller than min_jump setting line = DirectedLineSegment((start.x, start.y), (end.x, end.y)) - if collapse_len > line.length: + if line.length < self.options.min_jump * PIXELS_PER_MM: + return + # do not add a running stitch if the distance is longer than max_jump setting + if self.options.max_jump > 0 and line.length > self.options.max_jump * PIXELS_PER_MM: + return + + 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": + 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": + path.transform(Transform(get_correction_transform(node)), True) + path = path + node.get_path()[1:] + node.set('d', str(path)) + if merged: + # remove last element (since it is merged) + last_parent = last_element.node.getparent() + last_parent.remove(last_element.node) + # remove parent group if empty + if len(last_parent) == 0: + last_parent.getparent().remove(last_parent) + return + + if merged: return - path = f'M {start.x}, {start.y} L {end.x}, {end.y}' + # add simple stroke to connect elements + path.transform(Transform(get_correction_transform(node)), True) color = element.color style = f'stroke:{color};stroke-width:1px;stroke-dasharray:3, 1;fill:none;' - line = PathElement(d=path, style=style, transform=get_correction_transform(node)) + line = PathElement(d=str(path), style=style) line.set(INKSTITCH_ATTRIBS['running_stitch_length_mm'], self.options.running_stitch_length_mm) line.set(INKSTITCH_ATTRIBS['running_stitch_tolerance_mm'], self.options.running_stitch_tolerance_mm) parent.insert(index, line) |
