2021-03-12 04:17:19 +00:00
|
|
|
# Authors: see git history
|
|
|
|
#
|
|
|
|
# Copyright (c) 2010 Authors
|
|
|
|
# Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details.
|
|
|
|
|
2020-04-25 12:24:01 +00:00
|
|
|
import os
|
|
|
|
import re
|
|
|
|
import sys
|
|
|
|
|
|
|
|
import inkex
|
2023-01-07 08:32:33 +00:00
|
|
|
|
2022-06-24 15:11:52 +00:00
|
|
|
import pyembroidery
|
2020-04-25 12:24:01 +00:00
|
|
|
|
|
|
|
from ..i18n import _
|
2023-01-07 08:32:33 +00:00
|
|
|
from ..svg.tags import INKSTITCH_ATTRIBS
|
2020-04-25 12:24:01 +00:00
|
|
|
from ..threads import ThreadCatalog
|
|
|
|
from .base import InkstitchExtension
|
|
|
|
|
|
|
|
|
2022-04-24 06:27:42 +00:00
|
|
|
class ApplyThreadlist(InkstitchExtension):
|
|
|
|
'''
|
|
|
|
Applies colors of a thread list to elements
|
|
|
|
Count of colors and elements should fit together
|
|
|
|
Use case: reapply colors to e.g. a dst file
|
|
|
|
'''
|
2020-04-25 12:24:01 +00:00
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
InkstitchExtension.__init__(self, *args, **kwargs)
|
2022-06-24 15:11:52 +00:00
|
|
|
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")
|
2021-03-04 17:40:53 +00:00
|
|
|
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")
|
2020-04-25 12:24:01 +00:00
|
|
|
|
|
|
|
def effect(self):
|
|
|
|
# Remove selection, we want all the elements in the document
|
2022-04-24 06:27:42 +00:00
|
|
|
self.svg.selection.clear()
|
2020-04-25 12:24:01 +00:00
|
|
|
|
|
|
|
if not self.get_elements():
|
|
|
|
return
|
|
|
|
|
|
|
|
path = self.options.filepath
|
2022-06-24 15:11:52 +00:00
|
|
|
self.verify_path(path)
|
2020-04-25 12:24:01 +00:00
|
|
|
|
|
|
|
method = self.options.method
|
2022-06-24 15:11:52 +00:00
|
|
|
|
2023-01-07 08:32:33 +00:00
|
|
|
# colors: [[color, cutwork_needle],[...]]
|
2022-06-24 15:11:52 +00:00
|
|
|
if path.endswith(('col', 'inf', 'edr')):
|
|
|
|
colors = self.parse_color_format(path)
|
|
|
|
elif method == 1:
|
2020-04-25 12:24:01 +00:00
|
|
|
colors = self.parse_inkstitch_threadlist(path)
|
|
|
|
else:
|
|
|
|
colors = self.parse_threadlist_by_catalog_number(path)
|
|
|
|
|
2022-06-24 15:11:52 +00:00
|
|
|
self.verify_colors(colors, method)
|
2020-04-25 12:24:01 +00:00
|
|
|
|
|
|
|
# Iterate through the color blocks to apply colors
|
|
|
|
element_color = ""
|
|
|
|
i = -1
|
|
|
|
for element in self.elements:
|
|
|
|
if element.color != element_color:
|
|
|
|
element_color = element.color
|
|
|
|
i += 1
|
|
|
|
|
|
|
|
# No more colors in the list, stop here
|
|
|
|
if i == len(colors):
|
|
|
|
break
|
|
|
|
|
2023-01-07 08:32:33 +00:00
|
|
|
style = element.node.get('style').replace("%s" % element_color, "%s" % colors[i][0])
|
2020-04-25 12:24:01 +00:00
|
|
|
element.node.set('style', style)
|
|
|
|
|
2023-01-07 08:32:33 +00:00
|
|
|
# apply cutwork
|
|
|
|
if colors[i][1] is not None:
|
|
|
|
element.node.set(INKSTITCH_ATTRIBS['cutwork_needle'], colors[i][1])
|
|
|
|
|
2022-06-24 15:11:52 +00:00
|
|
|
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)
|
|
|
|
|
2020-04-25 12:24:01 +00:00
|
|
|
def parse_inkstitch_threadlist(self, path):
|
|
|
|
colors = []
|
|
|
|
with open(path) as threadlist:
|
|
|
|
for line in threadlist:
|
|
|
|
if line[0].isdigit():
|
|
|
|
m = re.search(r"\((#[0-9A-Fa-f]{6})\)", line)
|
|
|
|
if m:
|
2023-01-07 08:32:33 +00:00
|
|
|
colors.append([m.group(1), None])
|
2020-04-25 12:24:01 +00:00
|
|
|
else:
|
|
|
|
# Color not found
|
2023-01-07 08:32:33 +00:00
|
|
|
colors.append([None, None])
|
2020-04-25 12:24:01 +00:00
|
|
|
return colors
|
|
|
|
|
2022-06-24 15:11:52 +00:00
|
|
|
def parse_color_format(self, path):
|
|
|
|
colors = []
|
|
|
|
threads = pyembroidery.read(path).threadlist
|
|
|
|
for color in threads:
|
2023-03-09 17:57:55 +00:00
|
|
|
if color.description is not None and color.description.startswith("Cut"):
|
2023-01-07 08:32:33 +00:00
|
|
|
# there is a maximum of 4 needles, we can simply take the last element from the description string
|
|
|
|
colors.append([color.hex_color(), color.description[-1]])
|
|
|
|
else:
|
|
|
|
colors.append([color.hex_color(), None])
|
2022-06-24 15:11:52 +00:00
|
|
|
return colors
|
|
|
|
|
2020-04-25 12:24:01 +00:00
|
|
|
def parse_threadlist_by_catalog_number(self, path):
|
|
|
|
palette_name = self.options.palette
|
|
|
|
palette = ThreadCatalog().get_palette_by_name(palette_name)
|
|
|
|
|
|
|
|
colors = []
|
|
|
|
palette_numbers = []
|
|
|
|
palette_colors = []
|
|
|
|
|
|
|
|
for color in palette:
|
|
|
|
palette_numbers.append(color.number)
|
|
|
|
palette_colors.append('#%s' % color.hex_digits.lower())
|
|
|
|
with open(path) as threadlist:
|
|
|
|
for line in threadlist:
|
|
|
|
if line[0].isdigit():
|
2023-01-07 08:32:33 +00:00
|
|
|
# some threadlists may add a # in front of the catalog number
|
2020-04-25 12:24:01 +00:00
|
|
|
# let's remove it from the entire string before splitting it up
|
|
|
|
thread = line.replace('#', '').split()
|
|
|
|
catalog_number = set(thread[1:]).intersection(palette_numbers)
|
|
|
|
if catalog_number:
|
|
|
|
color_index = palette_numbers.index(next(iter(catalog_number)))
|
2023-01-07 08:32:33 +00:00
|
|
|
colors.append([palette_colors[color_index], None])
|
2020-04-25 12:24:01 +00:00
|
|
|
else:
|
|
|
|
# No color found
|
2023-01-07 08:32:33 +00:00
|
|
|
colors.append([None, None])
|
2020-04-25 12:24:01 +00:00
|
|
|
return colors
|