Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved vp3 file trim handling #73

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions .idea/inkpyembroidery.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pyembroidery/EmbConstant.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
COLOR_CHANGE = 5
SEQUIN_MODE = 6
SEQUIN_EJECT = 7
NEEDLE_SET = 9
SLOW = 0xB
FAST = 0xC

Expand Down
7 changes: 7 additions & 0 deletions pyembroidery/EmbPattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,13 @@ def get_as_command_blocks(self):
last_pos = pos
yield self.stitches[last_pos:]

def last_command_was_trim(self, command):
if command == TRIM:
bol_last_command_was_trim = True
else:
bol_last_command_was_trim = False
return bol_last_command_was_trim

def get_as_colorblocks(self):
thread_index = 0
last_pos = 0
Expand Down
16 changes: 10 additions & 6 deletions pyembroidery/Vp3Reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,13 @@ def read(f, out, settings=None):
skip_vp3_string(f) # "Produced by Software Ltd"
count_colors = read_int_16be(f)
for i in range(0, count_colors):
vp3_read_colorblock(f, out, center_x, center_y)
vp3_read_colorblock(f, out, center_x, center_y, i >= (count_colors - 1))


def vp3_read_colorblock(f, read_object, center_x, center_y):
def vp3_read_colorblock(f, read_object, center_x, center_y, is_last_color_block=False):
bytescheck = f.read(3) # \x00\x05\x00
distance_to_next_block_050 = read_int_32be(f)
block_end_position = distance_to_next_block_050 + f.tell()

start_position_x = (signed32(read_int_32be(f)) / 100)
start_position_y = -(signed32(read_int_32be(f)) / 100)
abs_x = start_position_x + center_x
Expand All @@ -87,19 +86,24 @@ def vp3_read_colorblock(f, read_object, center_x, center_y):
y = signed16(stitch_bytes[i], stitch_bytes[i + 1])
i += 2
if abs(x) > 255 or abs(y) > 255:
read_object.trim()
read_object.move(x, y)
read_object.trim()
else:
read_object.stitch(x, y)
elif y == 0x02:
pass # ends long stitch mode.
elif y == 0x03:
read_object.end(0, 0)
return
# TODO correlate this with end in writer. If an end command may have a changed address, I need to
# both write it and read it. If not, I must avoid to write it if I do not read it
# Do not return if this is a colour change inside the colorblock.
# if it is, it actually means it is a trim command
# return
else:
read_object.stitch(x, y)
read_object.trim()
read_object.color_change()
if not is_last_color_block:
read_object.color_change()


def vp3_read_thread(f):
Expand Down
57 changes: 43 additions & 14 deletions pyembroidery/Vp3Writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,41 +222,70 @@ def write_stitches_block(f, stitches, first_pos_x, first_pos_y):
f.write(b'\x0A\xF6\x00')
last_x = first_pos_x
last_y = first_pos_y
last_flag = None

for stitch in stitches:
x = stitch[0]
y = stitch[1]
flags = stitch[2]
if flags == END:
f.write(b'\x80\x03')
break
f.write(b'\x80\x03') # if END command, write END, all places in file
last_flag = END
# TODO likely just like for input, we should not break on END, but should we add an END ourselves?
# check for end of colorblock
continue
elif flags == COLOR_CHANGE:
last_flag = COLOR_CHANGE
continue
elif flags == TRIM:
# dx, dy, last_x, last_y = track_distance_change(last_x, last_y, x, y)
# last_flag = output_one_stitch(dx, dy, f, last_flag)
if last_flag != TRIM:
f.write(b'\x80\x03') # If Trim command, write TRIM
last_flag = TRIM
continue
elif flags == SEQUIN_MODE:
last_flag = SEQUIN_MODE
continue
elif flags == SEQUIN_EJECT:
last_flag = SEQUIN_EJECT
continue
elif flags == STOP:
# Not sure what to do here.
# f.write(b'\x80\x04')
last_flag = STOP
continue
elif flags == JUMP:
# f.write(b'\x80\x01') # If Jump command, write JUMP
# last_flag = JUMP
# There is an automatic cut of jump stitches, but not triggered if not called jump stitches
# Since VP3.Jump == VP3.Stitch, we combine jumps.
continue
dx = int(x - last_x)
dy = int(y - last_y)
last_x += dx
last_y += dy
dx, dy, last_x, last_y = track_distance_change(last_x, last_y, x, y)
if flags == STITCH:
if -127 <= dx <= 127 and -127 <= dy <= 127:
write_int_8(f, dx)
write_int_8(f, dy)
else:
f.write(b'\x80\x01')
write_int_16be(f, dx)
write_int_16be(f, dy)
f.write(b'\x80\x02')
last_flag = output_one_stitch(dx, dy, f, last_flag)
# VSM gave ending stitches as 80 03 35 A5, so, 80 03 isn't strictly end.
vp3_patch_byte_offset(f, placeholder_distance_to_end_of_stitches_block_010)


def output_one_stitch(dx, dy, f, last_flag):
if -127 <= dx <= 127 and -127 <= dy <= 127:
write_int_8(f, dx)
write_int_8(f, dy)
last_flag = STITCH
else:
if last_flag != JUMP:
f.write(b'\x80\x01')
write_int_16be(f, dx)
write_int_16be(f, dy)
f.write(b'\x80\x02')
last_flag = TRIM
return last_flag


def track_distance_change(last_x, last_y, x, y):
dx = int(x - last_x)
dy = int(y - last_y)
last_x += dx
last_y += dy
return dx, dy, last_x, last_y