2018-09-02 00:11:44 +00:00
|
|
|
import sys
|
2018-07-16 00:15:35 +00:00
|
|
|
import pyembroidery
|
2018-05-02 01:21:07 +00:00
|
|
|
import simpletransform
|
|
|
|
|
2018-09-02 00:11:44 +00:00
|
|
|
from .i18n import _
|
2018-05-02 01:21:07 +00:00
|
|
|
from .utils import Point
|
|
|
|
from .svg import PIXELS_PER_MM, get_doc_size, get_viewbox_transform
|
2018-08-23 02:48:40 +00:00
|
|
|
from .commands import global_command
|
2018-05-02 01:21:07 +00:00
|
|
|
|
|
|
|
|
2018-07-16 00:15:35 +00:00
|
|
|
def get_command(stitch):
|
2018-05-02 01:21:07 +00:00
|
|
|
if stitch.jump:
|
2018-07-16 00:15:35 +00:00
|
|
|
return pyembroidery.JUMP
|
|
|
|
elif stitch.trim:
|
|
|
|
return pyembroidery.TRIM
|
|
|
|
elif stitch.color_change:
|
|
|
|
return pyembroidery.COLOR_CHANGE
|
|
|
|
elif stitch.stop:
|
|
|
|
return pyembroidery.STOP
|
|
|
|
else:
|
|
|
|
return pyembroidery.NEEDLE_AT
|
2018-05-02 01:21:07 +00:00
|
|
|
|
2018-08-22 00:32:50 +00:00
|
|
|
|
2018-05-02 01:21:07 +00:00
|
|
|
def _string_to_floats(string):
|
|
|
|
floats = string.split(',')
|
|
|
|
return [float(num) for num in floats]
|
|
|
|
|
|
|
|
|
|
|
|
def get_origin(svg):
|
2018-08-23 02:48:40 +00:00
|
|
|
origin_command = global_command(svg, "origin")
|
2018-05-02 01:21:07 +00:00
|
|
|
|
2018-08-23 02:48:40 +00:00
|
|
|
if origin_command:
|
|
|
|
return origin_command.point
|
2018-08-23 02:13:51 +00:00
|
|
|
else:
|
|
|
|
# default: center of the canvas
|
2018-05-02 01:21:07 +00:00
|
|
|
|
2018-08-23 02:13:51 +00:00
|
|
|
doc_size = list(get_doc_size(svg))
|
2018-05-02 01:21:07 +00:00
|
|
|
|
2018-08-23 02:13:51 +00:00
|
|
|
# convert the size from viewbox-relative to real-world pixels
|
|
|
|
viewbox_transform = get_viewbox_transform(svg)
|
|
|
|
simpletransform.applyTransformToPoint(simpletransform.invertTransform(viewbox_transform), doc_size)
|
2018-05-02 01:21:07 +00:00
|
|
|
|
2018-08-23 02:13:51 +00:00
|
|
|
default = [doc_size[0] / 2.0, doc_size[1] / 2.0]
|
|
|
|
simpletransform.applyTransformToPoint(viewbox_transform, default)
|
|
|
|
default = Point(*default)
|
2018-05-02 01:21:07 +00:00
|
|
|
|
|
|
|
return default
|
|
|
|
|
|
|
|
|
2018-08-23 02:48:40 +00:00
|
|
|
def jump_to_stop_point(pattern, svg):
|
|
|
|
stop_position = global_command(svg, "stop_position")
|
|
|
|
if stop_position:
|
|
|
|
pattern.add_stitch_absolute(pyembroidery.JUMP, stop_position.point.x, stop_position.point.y)
|
|
|
|
|
|
|
|
|
2018-05-02 01:21:07 +00:00
|
|
|
def write_embroidery_file(file_path, stitch_plan, svg):
|
|
|
|
origin = get_origin(svg)
|
|
|
|
|
2018-07-16 00:15:35 +00:00
|
|
|
pattern = pyembroidery.EmbPattern()
|
2018-05-02 01:21:07 +00:00
|
|
|
|
|
|
|
for color_block in stitch_plan:
|
2018-07-16 00:15:35 +00:00
|
|
|
pattern.add_thread(color_block.color.pyembroidery_thread)
|
2018-05-02 01:21:07 +00:00
|
|
|
|
|
|
|
for stitch in color_block:
|
2018-08-23 02:48:40 +00:00
|
|
|
if stitch.stop:
|
|
|
|
jump_to_stop_point(pattern, svg)
|
2018-07-16 00:15:35 +00:00
|
|
|
command = get_command(stitch)
|
|
|
|
pattern.add_stitch_absolute(command, stitch.x, stitch.y)
|
2018-05-02 01:21:07 +00:00
|
|
|
|
2018-07-16 00:15:35 +00:00
|
|
|
pattern.add_stitch_absolute(pyembroidery.END, stitch.x, stitch.y)
|
2018-05-02 01:21:07 +00:00
|
|
|
|
|
|
|
# convert from pixels to millimeters
|
2018-07-16 00:15:35 +00:00
|
|
|
# also multiply by 10 to get tenths of a millimeter as required by pyembroidery
|
|
|
|
scale = 10 / PIXELS_PER_MM
|
|
|
|
|
2018-08-22 00:32:50 +00:00
|
|
|
settings = {
|
|
|
|
# correct for the origin
|
|
|
|
"translate": -origin,
|
2018-05-02 01:21:07 +00:00
|
|
|
|
2018-08-22 00:32:50 +00:00
|
|
|
# convert from pixels to millimeters
|
|
|
|
# also multiply by 10 to get tenths of a millimeter as required by pyembroidery
|
|
|
|
"scale": (scale, scale),
|
2018-07-16 02:53:18 +00:00
|
|
|
|
2018-08-22 00:32:50 +00:00
|
|
|
# This forces a jump at the start of the design and after each trim,
|
|
|
|
# even if we're close enough not to need one.
|
|
|
|
"full_jump": True,
|
|
|
|
}
|
2018-05-02 01:21:07 +00:00
|
|
|
|
2018-08-27 19:36:54 +00:00
|
|
|
if file_path.endswith('.csv'):
|
|
|
|
# Special treatment for CSV: instruct pyembroidery not to do any post-
|
|
|
|
# processing. This will allow the user to match up stitch numbers seen
|
|
|
|
# in the simulator with commands in the CSV.
|
|
|
|
settings['max_stitch'] = float('inf')
|
|
|
|
settings['max_jump'] = float('inf')
|
|
|
|
settings['explicit_trim'] = False
|
|
|
|
|
2018-08-25 01:44:42 +00:00
|
|
|
try:
|
|
|
|
pyembroidery.write(pattern, file_path, settings)
|
|
|
|
except IOError as e:
|
|
|
|
# L10N low-level file error. %(error)s is (hopefully?) translated by
|
|
|
|
# the user's system automatically.
|
|
|
|
print >> sys.stderr, _("Error writing to %(path)s: %(error)s") % dict(path=file_path, error=e.message)
|
|
|
|
sys.exit(1)
|