Force lock stitches option/extension and some typos (#1471)

pull/1509/head
Kaalleen 2021-12-09 15:05:21 +01:00 zatwierdzone przez GitHub
rodzic 41ace3a9e5
commit 36f7610cc0
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
14 zmienionych plików z 161 dodań i 20 usunięć

Wyświetl plik

@ -15,7 +15,7 @@ inx: version locales
messages.po: inx
rm -f messages.po
xgettext inx/*.inx --its=its/inx.its -o messages-inx.po
# There seems to be no propper way to set the charset to utf-8
# There seems to be no proper way to set the charset to utf-8
sed -i 's/charset=CHARSET/charset=UTF-8/g' messages-inx.po
bin/pyembroidery-gettext > pyembroidery-format-descriptions.py
bin/inkstitch-fonts-gettext > inkstitch-fonts-metadata.py

Wyświetl plik

@ -207,6 +207,18 @@ class EmbroideryElement(object):
def ties(self):
return self.get_int_param("ties", 0)
@property
@param('force_lock_stitches',
_('Force lock stitches'),
tooltip=_('Sew lock stitches after sewing this element, '
'even if the distance to the next object is shorter than defined by the collapse length value in the Ink/Stitch preferences.'),
type='boolean',
default=False,
sort_index=5)
@cache
def force_lock_stitches(self):
return self.get_boolean_param('force_lock_stitches', False)
@property
def path(self):
# A CSP is a "cubic superpath".
@ -312,6 +324,7 @@ class EmbroideryElement(object):
for patch in patches:
patch.tie_modus = self.ties
patch.force_lock_stitches = self.force_lock_stitches
if patches:
patches[-1].trim_after = self.has_command("trim") or self.trim_after

Wyświetl plik

@ -24,6 +24,7 @@ from .lettering import Lettering
from .lettering_custom_font_dir import LetteringCustomFontDir
from .lettering_generate_json import LetteringGenerateJson
from .lettering_remove_kerning import LetteringRemoveKerning
from .lettering_force_lock_stitches import LetteringForceLockStitches
from .letters_to_font import LettersToFont
from .object_commands import ObjectCommands
from .output import Output
@ -56,6 +57,7 @@ __all__ = extensions = [StitchPlanPreview,
LetteringGenerateJson,
LetteringRemoveKerning,
LetteringCustomFontDir,
LetteringForceLockStitches,
LettersToFont,
Troubleshoot,
RemoveEmbroiderySettings,

Wyświetl plik

@ -0,0 +1,86 @@
# Authors: see git history
#
# Copyright (c) 2021 Authors
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
import inkex
from shapely.geometry import Point
from ..i18n import _
from ..svg import PIXELS_PER_MM
from ..svg.tags import INKSTITCH_ATTRIBS
from .base import InkstitchExtension
class LetteringForceLockStitches(InkstitchExtension):
'''
This extension helps font creators to add the force lock stitches attribute to the last objects of each glyph
Font creators to add forced lock stitches on glyphs with accents / spaces.
'''
def __init__(self, *args, **kwargs):
InkstitchExtension.__init__(self, *args, **kwargs)
self.arg_parser.add_argument("-a", "--max_distance", type=float, default=3, dest="max_distance")
self.arg_parser.add_argument("-i", "--min_distance", type=float, default=1, dest="min_distance")
self.arg_parser.add_argument("-l", "--last_element", type=inkex.Boolean, dest="last_element")
def effect(self):
if self.options.max_distance < self.options.min_distance:
inkex.errormssg(_("The maximum value is smaller than the minimum value."))
# Set glyph layers to be visible. We don't want them to be ignored by self.elements
self._update_layer_visibility('inline')
# mark last elements of a glyph
xpath = ".//svg:g[@inkscape:groupmode='layer']//svg:path[last()]"
last_elements = self.document.xpath(xpath, namespaces=inkex.NSS)
for last_element in last_elements:
last_element.set('lastglyphelement', str(True))
# find last point of an element
if not self.get_elements():
return
previous_element = None
last_stitch = None
for element in self.elements:
stitch_group = element.to_stitch_groups(None)
# if the distance of the last stitch of the previous object to the first stitch of this objects
# lies within the user defined distance range, set the force_lock_stitches-attribute.
if last_stitch:
first_stitch = stitch_group[0].stitches[0]
first_stitch = Point(first_stitch.x, first_stitch.y)
self._set_force_attribute(first_stitch, last_stitch, previous_element)
# if this is the last element of a glyph, we don't want to compare it to the next element
if element.node.get('lastglyphelement', False):
previous_element = None
last_stitch = None
else:
previous_element = element
last_stitch = stitch_group[-1].stitches[-1]
last_stitch = Point(last_stitch.x, last_stitch.y)
# remove last element attributes again
# set force lock stitches attribute if needed
for last_element in last_elements:
last_element.attrib.pop('lastglyphelement')
if self.options.last_element:
last_element.set(INKSTITCH_ATTRIBS['force_lock_stitches'], True)
# hide glyph layers again
self._update_layer_visibility('none')
def _set_force_attribute(self, first_stitch, last_stitch, previous_element):
distance_mm = first_stitch.distance(last_stitch) / PIXELS_PER_MM
if distance_mm < self.options.max_distance and distance_mm > self.options.min_distance:
previous_element.node.set(INKSTITCH_ATTRIBS['force_lock_stitches'], True)
def _update_layer_visibility(self, display):
xpath = ".//svg:g[@inkscape:groupmode='layer']"
layers = self.document.xpath(xpath, namespaces=inkex.NSS)
for layer in layers:
display_style = 'display:%s' % display
style = inkex.Style(layer.get('style', '')) + inkex.Style(display_style)
layer.set('style', style)

Wyświetl plik

@ -7,7 +7,7 @@ from .base import InkstitchExtension
class Reorder(InkstitchExtension):
# Remove selected objects from the document and readd them in the order they
# Remove selected objects from the document and re-add them in the order they
# were selected.
def effect(self):

Wyświetl plik

@ -41,7 +41,7 @@ class StitchPlanPreview(InkstitchExtension):
# apply options
layer = svg.find(".//*[@id='__inkstitch_stitch_plan__']")
# update layer visibilty 0 = unchanged, 1 = hidden, 2 = lower opacity
# update layer visibility 0 = unchanged, 1 = hidden, 2 = lower opacity
if self.options.layer_visibility == 1:
self.hide_all_layers()
layer.set('style', None)

Wyświetl plik

@ -88,7 +88,7 @@ class Glyph(object):
self.min_x = left
def _process_commands(self):
# Save object ids with commmands in a dictionary: {object_id: [connector_id, symbol_id]}
# Save object ids with commands in a dictionary: {object_id: [connector_id, symbol_id]}
self.commands = {}
for node in self.node.iter(SVG_USE_TAG):

Wyświetl plik

@ -10,7 +10,8 @@ from copy import deepcopy
class Stitch(Point):
"""A stitch is a Point with extra information telling how to sew it."""
def __init__(self, x, y=None, color=None, jump=False, stop=False, trim=False, color_change=False, tie_modus=0, no_ties=False, tags=None):
def __init__(self, x, y=None, color=None, jump=False, stop=False, trim=False, color_change=False,
tie_modus=0, force_lock_stitches=False, no_ties=False, tags=None):
if isinstance(x, Stitch):
# Allow creating a Stitch from another Stitch. Attributes passed as
# arguments will override any existing attributes.
@ -28,6 +29,7 @@ class Stitch(Point):
self.trim = trim
self.stop = stop
self.color_change = color_change
self.force_lock_stitches = force_lock_stitches
self.tie_modus = tie_modus
self.no_ties = no_ties
self.tags = set()
@ -35,15 +37,16 @@ class Stitch(Point):
self.add_tags(tags or [])
def __repr__(self):
return "Stitch(%s, %s, %s, %s, %s, %s, %s, %s, %s)" % (self.x,
self.y,
self.color,
"JUMP" if self.jump else " ",
"TRIM" if self.trim else " ",
"STOP" if self.stop else " ",
"TIE MODUS" if self.tie_modus else " ",
"NO TIES" if self.no_ties else " ",
"COLOR CHANGE" if self.color_change else " ")
return "Stitch(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)" % (self.x,
self.y,
self.color,
"JUMP" if self.jump else " ",
"TRIM" if self.trim else " ",
"STOP" if self.stop else " ",
"TIE MODUS" if self.tie_modus else " ",
"FORCE LOCK STITCHES" if self.force_lock_stitches else " ",
"NO TIES" if self.no_ties else " ",
"COLOR CHANGE" if self.color_change else " ")
def add_tags(self, tags):
for tag in tags:
@ -68,7 +71,8 @@ class Stitch(Point):
return tag in self.tags
def copy(self):
return Stitch(self.x, self.y, self.color, self.jump, self.stop, self.trim, self.color_change, self.tie_modus, self.no_ties, self.tags)
return Stitch(self.x, self.y, self.color, self.jump, self.stop, self.trim, self.color_change,
self.tie_modus, self.force_lock_stitches, self.no_ties, self.tags)
def __json__(self):
attributes = dict(vars(self))

Wyświetl plik

@ -17,11 +17,13 @@ class StitchGroup:
between them by the stitch plan generation code.
"""
def __init__(self, color=None, stitches=None, trim_after=False, stop_after=False, tie_modus=0, stitch_as_is=False, tags=None):
def __init__(self, color=None, stitches=None, trim_after=False, stop_after=False,
tie_modus=0, force_lock_stitches=False, stitch_as_is=False, tags=None):
self.color = color
self.trim_after = trim_after
self.stop_after = stop_after
self.tie_modus = tie_modus
self.force_lock_stitches = force_lock_stitches
self.stitch_as_is = stitch_as_is
self.stitches = []

Wyświetl plik

@ -42,10 +42,13 @@ def stitch_groups_to_stitch_plan(stitch_groups, collapse_len=None, disable_ties=
# always start a color with a JUMP to the first stitch position
color_block.add_stitch(stitch_group.stitches[0], jump=True)
else:
if len(color_block) and (stitch_group.stitches[0] - color_block.stitches[-1]).length() > collapse_len:
if (len(color_block) and
((stitch_group.stitches[0] - color_block.stitches[-1]).length() > collapse_len or
color_block.stitches[-1].force_lock_stitches)):
color_block.add_stitch(stitch_group.stitches[0], jump=True)
color_block.add_stitches(stitches=stitch_group.stitches, tie_modus=stitch_group.tie_modus, no_ties=stitch_group.stitch_as_is)
color_block.add_stitches(stitches=stitch_group.stitches, tie_modus=stitch_group.tie_modus,
force_lock_stitches=stitch_group.force_lock_stitches, no_ties=stitch_group.stitch_as_is)
if stitch_group.trim_after:
color_block.add_stitch(trim=True)

Wyświetl plik

@ -37,7 +37,7 @@ def add_tie(stitches, tie_path):
def add_tie_off(stitches):
# tie_modus: 0 = both | 1 = before | 2 = after | 3 = neither
if stitches[-1].tie_modus not in [1, 3]:
if stitches[-1].tie_modus not in [1, 3] or stitches[-1].force_lock_stitches:
add_tie(stitches, stitches[-1:-3:-1])

Wyświetl plik

@ -49,6 +49,7 @@ SVG_OBJECT_TAGS = (SVG_ELLIPSE_TAG, SVG_CIRCLE_TAG, SVG_RECT_TAG)
INKSTITCH_ATTRIBS = {}
inkstitch_attribs = [
'ties',
'force_lock_stitches',
# clone
'clone',
# polyline

Wyświetl plik

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<inkscape-extension translationdomain="inkstitch" xmlns="http://www.inkscape.org/namespace/inkscape/extension">
<name>Force lock stitches</name>
<id>org.inkstitch.force_lock_stitches</id>
<param name="extension" type="string" gui-hidden="true">lettering_force_lock_stitches</param>
<effect needs-live-preview="false">
<object-type>all</object-type>
<effects-menu>
<submenu name="Ink/Stitch" translatable="no">
<submenu name="Font Management" />
</submenu>
</effects-menu>
</effect>
<param name="force-lock-stitches" type="description" indent="1" >
Small fonts will sometimes unravel if threads are cut after the embroidery machine has finished the work.
Therefore it is important that also diacritics with a smaller distance to the font body than defined by the collapse length value (default: 3mm) have lock stitches.
This can be achieved by adding a forced lock stitch attribute to them.
</param>
<separator />
<param name="extension-description" type="description" indent="1">
This extension has been build to help font authors to define "force lock stitches"-attributes automatically if they are placed in a predefined distance to the next object.
</param>
<param indent="1" name="min_distance" type="float" gui-text="Minimum distance (mm)" min="0" max="3">1</param>
<param indent="1" name="max_distance" type="float" gui-text="Minimum distance (mm)" min="1" max="10">3</param>
<separator />
<param indent="1" name="last_element" type="boolean" gui-text="Add force lock stitches attribute to the last element of each glyph">false</param>
<script>
{{ command_tag | safe }}
</script>
</inkscape-extension>

Wyświetl plik

@ -12,7 +12,7 @@
</effects-menu>
</effect>
<param name="move-to-side" type="boolean" gui-text="Move stitch plan beside the canvas">true</param>
<param name="layer-visibility" type="optiongroup" appearance="combo" gui-text="Design layer visibity">
<param name="layer-visibility" type="optiongroup" appearance="combo" gui-text="Design layer visibility">
<option value="0">Unchanged</option>
<option value="1">Hidden</option>
<option value="2">Lower opacity</option>