inkstitch/lib/stitch_plan/stop.py

89 wiersze
3.2 KiB
Python

from copy import copy
from ..svg import PIXELS_PER_MM
def process_stop(stitch_plan):
"""Handle the "stop after" checkbox.
The user wants the machine to pause after this patch. This can
be useful for applique and similar on multi-needle machines that
normally would not stop between colors.
In most machine embroidery file formats, there's no such thing as
an actual "STOP" instruction. All that exists is a "color change"
command.
On multi-needle machines, the user assigns needles to the colors in
the design before starting stitching. C01, C02, etc are the normal
needles, but C00 is special. For a block of stitches assigned
to C00, the machine will continue sewing with the last color it
had and pause after it completes the C00 block. Machines that don't
call it C00 still have a similar concept.
We'll add a STOP instruction at the end of this color block.
Unfortunately, we have a bit of a catch-22: the user needs to set
C00 (or equivalent) for the _start_ of this block to get the
machine to stop at the end of this block. That means it will use
the previous color, which isn't the right color at all!
For the first STOP in a given thread color, we'll need to
introduce an extra color change. The user can then set the correct
color for the first section and C00 for the second, resulting in
a stop where we want it.
We'll try to find a logical place to split the color block, like
a TRIM or a really long stitch. Failing that, we'll just split
it in half.
"""
color_block = stitch_plan.last_color_block
if not color_block or len(color_block) < 2:
return
last_stitch = color_block.last_stitch
color_block.add_stitch(stop=True)
if len(stitch_plan) > 1:
# if this isn't the first stop in this color, then we're done
if stitch_plan.color_blocks[-2].stop_after and \
stitch_plan.color_blocks[-2].color == color_block.color:
return
# We need to split this color block. Pick the last TRIM or
# the last long stitch (probably between distant patches).
for i in xrange(len(color_block) - 2, -1, -1):
stitch = color_block.stitches[i]
if stitch.trim:
# ignore the trim right before the stop we just added
if i < len(color_block) - 2:
# split after the trim
i = i + 1
break
if i > 0:
next_stitch = color_block.stitches[i + 1]
if (stitch - next_stitch).length() > 20 * PIXELS_PER_MM:
break
if i == 0:
# Darn, we didn't find a TRIM or long stitch. Just chop the
# block in half.
i = len(color_block) / 2
new_color_block = color_block.split_at(i)
# If we're splitting in the middle of a run of stitches, we don't
# want a gap to appear in the preview and the PDF printout, so
# add an extra stitch to bridge the gap. Technically this will
# result in a double needle penetration but it's no big deal.
if not color_block.last_stitch.trim:
color_block.add_stitch(copy(new_color_block.stitches[0]))
color_block.add_stitch(color_change=True, fake_color_change=True)
stitch_plan.add_color_block(new_color_block)