Update pyembroidery (#1683)

Embroidery formats (read)
.hus: Husqvarna Embroidery Format
.zhs: Zeng Hsing Embroidery Format

Color formats (read & write)
.col : Color format.
.edr : Color format.
.inf : Color format.

Stitch formats (read & write)
.pmv : Brother Stitch Format.

Image (write)
.png : Portable Network Graphic (line art)

G-Code
The export file format is not .txt anymore but .gcode

Bug fixes
pull/1718/head
Kaalleen 2022-06-24 17:11:52 +02:00 zatwierdzone przez GitHub
rodzic 3985b5ac71
commit ab8c87928b
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
11 zmienionych plików z 93 dodań i 38 usunięć

Wyświetl plik

@ -8,6 +8,7 @@ import re
import sys
import inkex
import pyembroidery
from ..i18n import _
from ..threads import ThreadCatalog
@ -22,6 +23,8 @@ class ApplyThreadlist(InkstitchExtension):
'''
def __init__(self, *args, **kwargs):
InkstitchExtension.__init__(self, *args, **kwargs)
self.arg_parser.add_argument("-o", "--options", type=str, default=None, dest="page_1")
self.arg_parser.add_argument("-i", "--info", type=str, default=None, dest="page_2")
self.arg_parser.add_argument("-f", "--filepath", type=str, default="", dest="filepath")
self.arg_parser.add_argument("-m", "--method", type=int, default=1, dest="method")
self.arg_parser.add_argument("-t", "--palette", type=str, default=None, dest="palette")
@ -34,26 +37,18 @@ class ApplyThreadlist(InkstitchExtension):
return
path = self.options.filepath
if not os.path.exists(path):
inkex.errormsg(_("File not found."))
sys.exit(1)
if os.path.isdir(path):
inkex.errormsg(_("The filepath specified is not a file but a dictionary.\nPlease choose a threadlist file to import."))
sys.exit(1)
self.verify_path(path)
method = self.options.method
if method == 1:
if path.endswith(('col', 'inf', 'edr')):
colors = self.parse_color_format(path)
elif method == 1:
colors = self.parse_inkstitch_threadlist(path)
else:
colors = self.parse_threadlist_by_catalog_number(path)
if all(c is None for c in colors):
inkex.errormsg(_("Couldn't find any matching colors in the file."))
if method == 1:
inkex.errormsg(_('Please try to import as "other threadlist" and specify a color palette below.'))
else:
inkex.errormsg(_("Please chose an other color palette for your design."))
sys.exit(1)
self.verify_colors(colors, method)
# Iterate through the color blocks to apply colors
element_color = ""
@ -70,6 +65,23 @@ class ApplyThreadlist(InkstitchExtension):
style = element.node.get('style').replace("%s" % element_color, "%s" % colors[i])
element.node.set('style', style)
def verify_path(self, path):
if not os.path.exists(path):
inkex.errormsg(_("File not found."))
sys.exit(1)
if os.path.isdir(path):
inkex.errormsg(_("The filepath specified is not a file but a dictionary.\nPlease choose a threadlist file to import."))
sys.exit(1)
def verify_colors(self, colors, method):
if all(c is None for c in colors):
inkex.errormsg(_("Couldn't find any matching colors in the file."))
if method == 1:
inkex.errormsg(_('Please try to import as "other threadlist" and specify a color palette below.'))
else:
inkex.errormsg(_("Please chose an other color palette for your design."))
sys.exit(1)
def parse_inkstitch_threadlist(self, path):
colors = []
with open(path) as threadlist:
@ -83,6 +95,13 @@ class ApplyThreadlist(InkstitchExtension):
colors.append(None)
return colors
def parse_color_format(self, path):
colors = []
threads = pyembroidery.read(path).threadlist
for color in threads:
colors.append(color.hex_color())
return colors
def parse_threadlist_by_catalog_number(self, path):
palette_name = self.options.palette
palette = ThreadCatalog().get_palette_by_name(palette_name)

Wyświetl plik

@ -5,11 +5,19 @@
from lxml import etree
from inkex import errormsg
from ..i18n import _
from ..stitch_plan import generate_stitch_plan
class Input(object):
def run(self, args):
embroidery_file = args[0]
if args[0].endswith(('edr', 'col', 'inf')):
msg = _("Ink/Stitch cannot import color formats directly. But you can open the embroidery file and apply the color with "
"Extensions > Ink/Stitch > Thread Color Management > Apply Threadlist")
errormsg(msg)
exit(0)
stitch_plan = generate_stitch_plan(embroidery_file)
print(etree.tostring(stitch_plan).decode('utf-8'))

Wyświetl plik

@ -9,10 +9,10 @@ import tempfile
from copy import deepcopy
from zipfile import ZipFile
from inkex import Boolean
from lxml import etree
import pyembroidery
from inkex import Boolean
from ..i18n import _
from ..output import write_embroidery_file
@ -28,7 +28,7 @@ class Zip(InkstitchExtension):
# it's kind of obnoxious that I have to do this...
self.formats = []
for format in pyembroidery.supported_formats():
if 'writer' in format and format['category'] == 'embroidery':
if 'writer' in format and format['category'] in ['embroidery', 'color', 'image', 'stitch']:
extension = format['extension']
self.arg_parser.add_argument('--format-%s' % extension, type=Boolean, dest=extension)
self.formats.append(extension)

Wyświetl plik

@ -30,7 +30,7 @@ def object_commands():
def pyembroidery_debug_formats():
for format in pyembroidery.supported_formats():
if 'writer' in format and format['category'] != 'embroidery':
if 'writer' in format and format['category'] not in ['embroidery', 'image', 'color', 'stitch']:
yield format['extension'], format['description']

Wyświetl plik

@ -10,7 +10,7 @@ from .utils import build_environment, write_inx_file
def pyembroidery_input_formats():
for format in pyembroidery.supported_formats():
if 'reader' in format and format['category'] == 'embroidery':
if 'reader' in format and format['category'] in ['embroidery', 'color', 'stitch']:
yield format['extension'], format['description']

Wyświetl plik

@ -12,7 +12,13 @@ def pyembroidery_output_formats():
for format in pyembroidery.supported_formats():
if 'writer' in format:
description = format['description']
if format['category'] != "embroidery":
if format['category'] == "color":
description = "%s [COLOR]" % description
elif format['category'] == "image":
description = "%s [IMAGE]" % description
elif format['category'] == "stitch":
description = "%s [STITCH]" % description
elif format['category'] != "embroidery":
description = "%s [DEBUG]" % description
yield format['extension'], description, format['mimetype'], format['category']

Wyświetl plik

@ -4,8 +4,8 @@
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
import sys
import inkex
import inkex
import pyembroidery
from .commands import global_command
@ -33,8 +33,8 @@ def _string_to_floats(string):
return [float(num) for num in floats]
def get_origin(svg, xxx_todo_changeme):
(minx, miny, maxx, maxy) = xxx_todo_changeme
def get_origin(svg, bounding_box):
(minx, miny, maxx, maxy) = bounding_box
origin_command = global_command(svg, "origin")
if origin_command:
@ -52,7 +52,12 @@ def jump_to_stop_point(pattern, svg):
def write_embroidery_file(file_path, stitch_plan, svg, settings={}):
# convert from pixels to millimeters
# also multiply by 10 to get tenths of a millimeter as required by pyembroidery
scale = 10 / PIXELS_PER_MM
origin = get_origin(svg, stitch_plan.bounding_box)
origin = origin * scale
pattern = pyembroidery.EmbPattern()
stitch = Stitch(0, 0)
@ -68,10 +73,6 @@ def write_embroidery_file(file_path, stitch_plan, svg, settings={}):
pattern.add_stitch_absolute(pyembroidery.END, stitch.x, stitch.y)
# convert from pixels to millimeters
# also multiply by 10 to get tenths of a millimeter as required by pyembroidery
scale = 10 / PIXELS_PER_MM
settings.update({
# correct for the origin
"translate": -origin,
@ -92,6 +93,9 @@ def write_embroidery_file(file_path, stitch_plan, svg, settings={}):
settings['max_stitch'] = float('inf')
settings['max_jump'] = float('inf')
settings['explicit_trim'] = False
elif file_path.endswith('.png'):
settings['linewidth'] = 1
settings['background'] = 'white'
try:
pyembroidery.write(pattern, file_path, settings)

@ -1 +1 @@
Subproject commit 2ab0085cc997762ece7b9f96aef86457a205ca82
Subproject commit 4817386d269a2724bf0c9a87d91a5103c6dffc78

Wyświetl plik

@ -3,15 +3,33 @@
<name>Apply Threadlist</name>
<id>org.inkstitch.apply_threadlist</id>
<param name="extension" type="string" gui-hidden="true">apply_threadlist</param>
<param name="filepath" type="path" gui-text="Choose file" mode="file" filetypes="txt"/>
<param name="method" type="optiongroup" gui-text="Choose method">
<option value="1">Apply Ink/Stitch threadlist</option>
<option value="2">Apply other threadlist*</option>
</param>
<param name="palette" type="enum" gui-text="*Choose color palette">
{%- for item in threadcatalog %}
<item value="{{ item }}">{{ item }}</item>
{%- endfor %}
<param name="options" type="notebook">
<page name="options" gui-text="Options">
<param name="filepath" type="path" gui-text="Choose file" mode="file" filetypes="txt,edr,col,inf"/>
<param name="method" type="optiongroup" gui-text="Choose method">
<option value="1">Apply Ink/Stitch threadlist</option>
<option value="2">Apply other threadlist*</option>
</param>
<param name="palette" type="enum" gui-text="*Choose color palette">
{%- for item in threadcatalog %}
<item value="{{ item }}">{{ item }}</item>
{%- endfor %}
</param>
</page>
<page name="info" gui-text="Help">
<label appearance="header">This extension applies colors from a color file to the objects in this document.</label>
<label>COL, INF, EDR</label>
<label indent="2">Select the file and apply. The chosen method is not important for these file types.</label>
<spacer />
<label>TXT</label>
<label indent="2">Import an Ink/Stitch threadlist file (created through the zip export option).</label>
<spacer />
<label indent="2">Import any other Threadlist file in txt format. Ink/Stitch will try to match the colors to the selected thread palette.
The objects in this document will be colored accordingly if color matching has been successful.</label>
<spacer />
<label>Get more information on our website</label>
<label appearance="url">https://inkstitch.org/docs/thread-color/#apply-threadlist</label>
</page>
</param>
<effect>
<object-type>all</object-type>

Wyświetl plik

@ -10,12 +10,12 @@
<dataloss>true</dataloss>
</output>
{%- for format, description, mimetype, category in formats %}
{%- if category == "embroidery" %}
{%- if category != "vector" and category != "debug" %}
<param name="format-{{ format }}" type="boolean" _gui-text=".{{ format | upper }}: {{ description }}">false</param>
{%- endif %}
{%- endfor %}
<param name="format-threadlist" type="boolean" gui-text=".TXT: Threadlist [COLOR]">false</param>
<param name="format-svg" type="boolean" gui-text=".SVG: Scalable Vector Graphic">false</param>
<param name="format-threadlist" type="boolean" gui-text=".TXT: Threadlist">false</param>
<param name="extension" type="string" gui-hidden="true">zip</param>
<script>
{{ command_tag | safe }}