diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/commands.py | 13 | ||||
| -rw-r--r-- | lib/elements/element.py | 15 | ||||
| -rw-r--r-- | lib/extensions/__init__.py | 2 | ||||
| -rw-r--r-- | lib/extensions/cutwork_segmentation.py | 9 | ||||
| -rw-r--r-- | lib/extensions/jump_to_stroke.py | 56 | ||||
| -rw-r--r-- | lib/svg/tags.py | 3 |
6 files changed, 87 insertions, 11 deletions
diff --git a/lib/commands.py b/lib/commands.py index 6280fc0c..f30d6423 100644 --- a/lib/commands.py +++ b/lib/commands.py @@ -407,7 +407,18 @@ def add_commands(element, commands): def add_layer_commands(layer, commands): svg = layer.root - correction_transform = get_correction_transform(layer) + + if not layer.tag_name == 'svg': + correction_transform = get_correction_transform(layer) + else: + # No layer selected while trying to include only layer commands: return a error message and exit + # Since global and layer commands will not be inserted at the same time, we can check the first command only + if commands[0] in LAYER_COMMANDS: + inkex.errormsg(_('Please select a layer to include layer commands.')) + sys.exit(1) + + # global commands do not necesarrily need a layer + correction_transform = '' for i, command in enumerate(commands): ensure_symbol(svg, command) diff --git a/lib/elements/element.py b/lib/elements/element.py index bf87d517..e7eb4dea 100644 --- a/lib/elements/element.py +++ b/lib/elements/element.py @@ -361,7 +361,7 @@ class EmbroideryElement(object): @property @param('trim_after', - _ ('Trim After'), + _('Trim After'), tooltip=_('Add a TRIM command after stitching this object.'), type='boolean', default=False, @@ -371,7 +371,7 @@ class EmbroideryElement(object): @property @param('stop_after', - _ ('Stop After'), + _('Stop After'), tooltip=_('Add a STOP command after stitching this object.'), type='boolean', default=False, @@ -398,7 +398,7 @@ class EmbroideryElement(object): return patches - def fatal(self, message): + def fatal(self, message, point_to_troubleshoot=False): label = self.node.get(INKSCAPE_LABEL) id = self.node.get("id") if label: @@ -407,8 +407,11 @@ class EmbroideryElement(object): name = id # L10N used when showing an error message to the user such as - # "Some Path (path1234): error: satin column: One or more of the rungs doesn't intersect both rails." - error_msg = "%s: %s %s" % (name, _("error:"), message) + # "Failed on PathLabel (path1234): Satin column: One or more of the rungs doesn't intersect both rails." + error_msg = "%s %s: %s" % (_("Failed on "), name, message) + if point_to_troubleshoot: + error_msg += "\n\n%s" % _("Please run Extensions > Ink/Stitch > Troubleshoot > Troubleshoot objects. " + "This will indicate the errorneus position.") inkex.errormsg(error_msg) sys.exit(1) @@ -443,4 +446,4 @@ class EmbroideryElement(object): for error in self.validation_errors(): # note that self.fatal() exits, so this only shows the first error - self.fatal(error.description) + self.fatal(error.description, True) diff --git a/lib/extensions/__init__.py b/lib/extensions/__init__.py index a2261a80..365a47d8 100644 --- a/lib/extensions/__init__.py +++ b/lib/extensions/__init__.py @@ -25,6 +25,7 @@ from .gradient_blocks import GradientBlocks from .input import Input from .install import Install from .install_custom_palette import InstallCustomPalette +from .jump_to_stroke import JumpToStroke from .layer_commands import LayerCommands from .lettering import Lettering from .lettering_custom_font_dir import LetteringCustomFontDir @@ -69,6 +70,7 @@ __all__ = extensions = [StitchPlanPreview, CommandsScaleSymbols, ConvertToSatin, ConvertToStroke, + JumpToStroke, CutSatin, AutoSatin, AutoRun, diff --git a/lib/extensions/cutwork_segmentation.py b/lib/extensions/cutwork_segmentation.py index 672aeade..22b39e4b 100644 --- a/lib/extensions/cutwork_segmentation.py +++ b/lib/extensions/cutwork_segmentation.py @@ -61,9 +61,9 @@ class CutworkSegmentation(InkstitchExtension): self.sectors = {index: sector for index, sector in self.sectors.items() if sector['start'] != sector['end']} self.new_elements = [] + parent = None for element in self.elements: if isinstance(element, Stroke): - # save parent and index to be able to position and insert new elements later on parent = element.node.getparent() index = parent.index(element.node) @@ -73,8 +73,11 @@ class CutworkSegmentation(InkstitchExtension): # fill self.new_elements list with line segments self._prepare_line_sections(element, linestring.coords) - self._insert_elements(parent, element, index) + if parent is None: + inkex.errormsg(_("Please select at least one element with a stroke color.")) + return + self._insert_elements(parent, index) self._remove_originals() def _get_sectors(self, angle): @@ -150,7 +153,7 @@ class CutworkSegmentation(InkstitchExtension): # clear point_list in self.sectors self.sectors[sector['id']].update({'point_list': []}) - def _insert_elements(self, parent, element, index): + def _insert_elements(self, parent, index): self.new_elements.reverse() if self.options.sort_by_color is True: self.new_elements = sorted(self.new_elements, key=lambda x: x[1], reverse=True) diff --git a/lib/extensions/jump_to_stroke.py b/lib/extensions/jump_to_stroke.py new file mode 100644 index 00000000..7cf6ff17 --- /dev/null +++ b/lib/extensions/jump_to_stroke.py @@ -0,0 +1,56 @@ +# Authors: see git history +# +# Copyright (c) 2010 Authors +# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details. + +from inkex import DirectedLineSegment, PathElement, errormsg + +from ..i18n import _ +from ..svg import PIXELS_PER_MM, get_correction_transform +from .base import InkstitchExtension + + +class JumpToStroke(InkstitchExtension): + """Adds a running stitch as a connection between two (or more) selected elements. + The elements must have the same color and a minimum distance (collapse_len).""" + + 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 + + last_stitch_group = None + last_color = None + for element in self.elements: + stitch_group = element.to_stitch_groups(last_stitch_group) + end = stitch_group[-1].stitches[-1] + if last_stitch_group is not None and element.color == last_color: + start = last_stitch_group.stitches[-1] + self.generate_stroke(element, start, end) + + last_stitch_group = stitch_group[-1] + last_color = element.color + + def generate_stroke(self, 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 + line = DirectedLineSegment((start.x, start.y), (end.x, end.y)) + if collapse_len > line.length: + return + + path = f'M {start.x}, {start.y} L {end.x}, {end.y}' + 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)) + parent.insert(index, line) + + +if __name__ == '__main__': + JumpToStroke().run() diff --git a/lib/svg/tags.py b/lib/svg/tags.py index 6ae3b66a..931c82c7 100644 --- a/lib/svg/tags.py +++ b/lib/svg/tags.py @@ -11,6 +11,7 @@ etree.register_namespace("inkstitch", "http://inkstitch.org/namespace") inkex.NSS['inkstitch'] = 'http://inkstitch.org/namespace' SVG_PATH_TAG = inkex.addNS('path', 'svg') +SVG_LINE_TAG = inkex.addNS('line', 'svg') SVG_POLYLINE_TAG = inkex.addNS('polyline', 'svg') SVG_POLYGON_TAG = inkex.addNS('polygon', 'svg') SVG_RECT_TAG = inkex.addNS('rect', 'svg') @@ -42,7 +43,7 @@ SODIPODI_ROLE = inkex.addNS('role', 'sodipodi') INKSTITCH_LETTERING = inkex.addNS('lettering', 'inkstitch') -EMBROIDERABLE_TAGS = (SVG_PATH_TAG, SVG_POLYLINE_TAG, SVG_POLYGON_TAG, +EMBROIDERABLE_TAGS = (SVG_PATH_TAG, SVG_LINE_TAG, SVG_POLYLINE_TAG, SVG_POLYGON_TAG, SVG_RECT_TAG, SVG_ELLIPSE_TAG, SVG_CIRCLE_TAG) NOT_EMBROIDERABLE_TAGS = (SVG_IMAGE_TAG, SVG_TEXT_TAG) SVG_OBJECT_TAGS = (SVG_ELLIPSE_TAG, SVG_CIRCLE_TAG, SVG_RECT_TAG) |
