From ab8c87928b39e7874c09a75b2f9badd3a46719b2 Mon Sep 17 00:00:00 2001
From: Kaalleen <36401965+kaalleen@users.noreply.github.com>
Date: Fri, 24 Jun 2022 17:11:52 +0200
Subject: [PATCH] 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
---
lib/extensions/apply_threadlist.py | 47 +++++++++++++------
lib/extensions/input.py | 8 ++++
lib/extensions/zip.py | 4 +-
lib/inx/extensions.py | 2 +-
lib/inx/inputs.py | 2 +-
lib/inx/outputs.py | 8 +++-
lib/output.py | 18 ++++---
pyembroidery | 2 +-
templates/apply_threadlist.xml | 36 ++++++++++----
...params_txt.xml => output_params_gcode.xml} | 0
templates/zip.xml | 4 +-
11 files changed, 93 insertions(+), 38 deletions(-)
rename templates/{output_params_txt.xml => output_params_gcode.xml} (100%)
diff --git a/lib/extensions/apply_threadlist.py b/lib/extensions/apply_threadlist.py
index 318615132..2779a9012 100644
--- a/lib/extensions/apply_threadlist.py
+++ b/lib/extensions/apply_threadlist.py
@@ -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)
diff --git a/lib/extensions/input.py b/lib/extensions/input.py
index 066b90033..4240be0ef 100644
--- a/lib/extensions/input.py
+++ b/lib/extensions/input.py
@@ -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'))
diff --git a/lib/extensions/zip.py b/lib/extensions/zip.py
index 280c2a140..e80bc34c5 100644
--- a/lib/extensions/zip.py
+++ b/lib/extensions/zip.py
@@ -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)
diff --git a/lib/inx/extensions.py b/lib/inx/extensions.py
index 9a197c5df..0ff3e8896 100755
--- a/lib/inx/extensions.py
+++ b/lib/inx/extensions.py
@@ -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']
diff --git a/lib/inx/inputs.py b/lib/inx/inputs.py
index 2cf84df9f..716e17087 100755
--- a/lib/inx/inputs.py
+++ b/lib/inx/inputs.py
@@ -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']
diff --git a/lib/inx/outputs.py b/lib/inx/outputs.py
index 1ac1daf88..3a4ac9d0f 100644
--- a/lib/inx/outputs.py
+++ b/lib/inx/outputs.py
@@ -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']
diff --git a/lib/output.py b/lib/output.py
index e330354d4..65e6f64d1 100644
--- a/lib/output.py
+++ b/lib/output.py
@@ -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)
diff --git a/pyembroidery b/pyembroidery
index 2ab0085cc..4817386d2 160000
--- a/pyembroidery
+++ b/pyembroidery
@@ -1 +1 @@
-Subproject commit 2ab0085cc997762ece7b9f96aef86457a205ca82
+Subproject commit 4817386d269a2724bf0c9a87d91a5103c6dffc78
diff --git a/templates/apply_threadlist.xml b/templates/apply_threadlist.xml
index 58776cb58..303cb793d 100644
--- a/templates/apply_threadlist.xml
+++ b/templates/apply_threadlist.xml
@@ -3,15 +3,33 @@
Apply Threadlist
org.inkstitch.apply_threadlist
apply_threadlist
-
-
-
-
-
-
- {%- for item in threadcatalog %}
- - {{ item }}
- {%- endfor %}
+
+
+
+
+
+
+
+
+ {%- for item in threadcatalog %}
+ - {{ item }}
+ {%- endfor %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
all
diff --git a/templates/output_params_txt.xml b/templates/output_params_gcode.xml
similarity index 100%
rename from templates/output_params_txt.xml
rename to templates/output_params_gcode.xml
diff --git a/templates/zip.xml b/templates/zip.xml
index 55366afdf..0018cb195 100644
--- a/templates/zip.xml
+++ b/templates/zip.xml
@@ -10,12 +10,12 @@
true
{%- for format, description, mimetype, category in formats %}
- {%- if category == "embroidery" %}
+ {%- if category != "vector" and category != "debug" %}
false
{%- endif %}
{%- endfor %}
+ false
false
- false
zip