Skip to content

Commit

Permalink
Merge pull request #64 from EmbroidePy/tatarize-140
Browse files Browse the repository at this point in the history
1.4.0 update
  • Loading branch information
tatarize authored Jul 16, 2019
2 parents 1752f0d + 8752c81 commit 9576a22
Show file tree
Hide file tree
Showing 26 changed files with 696 additions and 172 deletions.
130 changes: 73 additions & 57 deletions README.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions __init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
name = "pyembroidery"
13 changes: 9 additions & 4 deletions pyembroidery/CsvWriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,16 +221,21 @@ def write_stitches(pattern, f):


def write(pattern, f, settings=None):
deltas = settings is not None and "deltas" in settings
displacement = settings is not None and "displacement" in settings
version = "default"
if settings is not None:
if "deltas" in settings:
version = "delta"
elif "displacement" in settings:
version = "full"
version = settings.get("version", version)
write_data(pattern, f)
write_metadata(pattern, f)
write_threads(pattern, f)

if len(pattern.stitches) > 0:
if displacement:
if version == "full":
write_stitches_displacement(pattern, f)
elif deltas:
elif version == "delta":
write_stitches_deltas(pattern, f)
else:
write_stitches(pattern, f)
18 changes: 15 additions & 3 deletions pyembroidery/DstReader.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def dst_read_header(f, out):
process_header_info(out, line[0:2].strip(), line[3:].strip())


def dst_read_stitches(f, out):
def dst_read_stitches(f, out, settings=None):
sequin_mode = False
while True:
byte = bytearray(f.read(3))
Expand All @@ -67,7 +67,7 @@ def dst_read_stitches(f, out):
dx = decode_dx(byte[0], byte[1], byte[2])
dy = decode_dy(byte[0], byte[1], byte[2])
if byte[2] & 0b11110011 == 0b11110011:
out.end(dx, dy)
break
elif byte[2] & 0b11000011 == 0b11000011:
out.color_change(dx, dy)
elif byte[2] & 0b01000011 == 0b01000011:
Expand All @@ -80,8 +80,20 @@ def dst_read_stitches(f, out):
out.move(dx, dy)
else:
out.stitch(dx, dy)
out.end()

count_max = 3
clipping = True
trim_distance = None
if settings is not None:
count_max = settings.get('trim_at', count_max)
trim_distance = settings.get("trim_distance", trim_distance)
clipping = settings.get('clipping', clipping)
if trim_distance is not None:
trim_distance *= 10 # Pixels per mm. Native units are 1/10 mm.
out.interpolate_trims(count_max, trim_distance, clipping)


def read(f, out, settings=None):
dst_read_header(f, out)
dst_read_stitches(f, out)
dst_read_stitches(f, out, settings)
17 changes: 12 additions & 5 deletions pyembroidery/DstWriter.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,9 +102,13 @@ def encode_record(x, y, flags):

def write(pattern, f, settings=None):
extended_header = False
trim_at = 3
if settings is not None:
extended_header = settings.get("extended header", extended_header)

extended_header = settings.get("extended header", extended_header) # deprecated, use version="extended"
version = settings.get("version", "default")
if version == "extended":
extended_header = True
trim_at = settings.get("trim_at", trim_at)
bounds = pattern.bounds()

name = pattern.get_metadata("name", "Untitled")
Expand Down Expand Up @@ -164,8 +168,11 @@ def write(pattern, f, settings=None):
xx += dx
yy += dy
if data == TRIM:
f.write(encode_record(2, 2, JUMP))
f.write(encode_record(-4, -4, JUMP))
f.write(encode_record(2, 2, JUMP))
delta = -4
f.write(encode_record(-delta/2, -delta/2, JUMP))
for p in range(1,trim_at-1):
f.write(encode_record(delta, delta, JUMP))
delta = -delta
f.write(encode_record(delta/2, delta/2, JUMP))
else:
f.write(encode_record(dx, dy, data))
151 changes: 129 additions & 22 deletions pyembroidery/EmbPattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,50 +120,83 @@ def clear(self):
self._previousX = 0
self._previousY = 0

def move(self, dx=0, dy=0):
def move(self, dx=0, dy=0, position=None):
"""Move dx, dy"""
self.add_stitch_relative(JUMP, dx, dy)
if position is None:
self.add_stitch_relative(JUMP, dx, dy)
else:
self.insert_stitch_relative(position, JUMP, dx, dy)

def move_abs(self, x, y):
def move_abs(self, x, y, position=None):
"""Move absolute x, y"""
self.add_stitch_absolute(JUMP, x, y)
if position is None:
self.add_stitch_absolute(JUMP, x, y)
else:
self.insert(position, JUMP, x, y)

def stitch(self, dx=0, dy=0):
def stitch(self, dx=0, dy=0, position=None):
"""Stitch dx, dy"""
self.add_stitch_relative(STITCH, dx, dy)
if position is None:
self.add_stitch_relative(STITCH, dx, dy)
else:
self.insert_stitch_relative(position, STITCH, dx, dy)

def stitch_abs(self, x, y):
def stitch_abs(self, x, y, position=None):
"""Stitch absolute x, y"""
self.add_stitch_absolute(STITCH, x, y)
if position is None:
self.add_stitch_absolute(STITCH, x, y)
else:
self.insert(position, STITCH, x, y)

def stop(self, dx=0, dy=0):
def stop(self, dx=0, dy=0, position=None):
"""Stop dx, dy"""
self.add_stitch_relative(STOP, dx, dy)
if position is None:
self.add_stitch_relative(STOP, dx, dy)
else:
self.insert_stitch_relative(position, STOP, dx, dy)

def trim(self, dx=0, dy=0):
def trim(self, dx=0, dy=0, position=None):
"""Trim dx, dy"""
self.add_stitch_relative(TRIM, dx, dy)
if position is None:
self.add_stitch_relative(TRIM, dx, dy)
else:
self.insert_stitch_relative(position, TRIM, dx, dy)

def color_change(self, dx=0, dy=0):
def color_change(self, dx=0, dy=0, position=None):
"""Color Change dx, dy"""
self.add_stitch_relative(COLOR_CHANGE, dx, dy)
if position is None:
self.add_stitch_relative(COLOR_CHANGE, dx, dy)
else:
self.insert_stitch_relative(position, COLOR_CHANGE, dx, dy)

def needle_change(self, needle=0, dx=0, dy=0):
def needle_change(self, needle=0, dx=0, dy=0, position=None):
"""Needle change, needle, dx, dy"""
cmd = encode_thread_change(NEEDLE_SET, None, needle)
self.add_stitch_relative(cmd, dx, dy)
if position is None:
self.add_stitch_relative(cmd, dx, dy)
else:
self.insert_stitch_relative(position, cmd, dx, dy)

def sequin_eject(self, dx=0, dy=0):
def sequin_eject(self, dx=0, dy=0, position=None):
"""Eject Sequin dx, dy"""
self.add_stitch_relative(SEQUIN_EJECT, dx, dy)
if position is None:
self.add_stitch_relative(SEQUIN_EJECT, dx, dy)
else:
self.insert_stitch_relative(position, SEQUIN_EJECT, dx, dy)

def sequin_mode(self, dx=0, dy=0):
def sequin_mode(self, dx=0, dy=0, position=None):
"""Eject Sequin dx, dy"""
self.add_stitch_relative(SEQUIN_MODE, dx, dy)
if position is None:
self.add_stitch_relative(SEQUIN_MODE, dx, dy)
else:
self.insert_stitch_relative(position, SEQUIN_MODE, dx, dy)

def end(self, dx=0, dy=0):
def end(self, dx=0, dy=0, position=None):
"""End Design dx, dy"""
self.add_stitch_relative(END, dx, dy)
if position is None:
self.add_stitch_relative(END, dx, dy)
else:
self.insert_stitch_relative(position, END, dx, dy)

def add_thread(self, thread):
"""Adds thread to design.
Expand Down Expand Up @@ -356,6 +389,26 @@ def add_stitch_relative(self, cmd, dx=0, dy=0):
y = self._previousY + dy
self.add_stitch_absolute(cmd, x, y)

def insert_stitch_relative(self, position, cmd, dx=0, dy=0):
"""Insert a relative stitch into the pattern. The stitch is relative to the stitch before it.
If inserting at position 0, it's relative to 0,0. If appending, add is called, updating the positioning.
"""
if position < 0:
position += len(self.stitches) # I need positive positions.
if position == 0:
self.stitches.insert(0, [dx, dy, TRIM]) # started (0,0)
elif position == len(self.stitches) or position is None: # This is properly just an add.
self.add_stitch_relative(cmd, dx, dy)
elif 0 < position < len(self.stitches):
p = self.stitches[position - 1]
x = p[0] + dx
y = p[1] + dy
self.stitches.insert(position, [x, y, TRIM])

def insert(self, position, cmd, x=0, y=0):
"""Insert a stitch or command"""
self.stitches.insert(position, [x, y, cmd])

def prepend_command(self, cmd, x=0, y=0):
"""Prepend a command, without treating parameters as locations"""
self.stitches.insert(0, [x, y, cmd])
Expand Down Expand Up @@ -448,6 +501,60 @@ def add_pattern(self, pattern):
self.stitches[i][2] = NO_COMMAND
self.extras.update(pattern.extras)

def interpolate_trims(self, jumps_to_require_trim=None, distance_to_require_trim=None, clipping=True):
"""Processes a pattern adding trims according to the given criteria."""
i = -1
ie = len(self.stitches) - 1

x = 0
y = 0
jump_count = 0
jump_start = 0
jump_dx = 0
jump_dy = 0
jumping = False
trimmed = True
while i < ie:
i += 1
stitch = self.stitches[i]
dx = stitch[0] - x
dy = stitch[1] - y
x = stitch[0]
y = stitch[1]
command = stitch[2] & COMMAND_MASK
if command == STITCH or command == SEQUIN_EJECT:
trimmed = False
jumping = False
elif command == COLOR_CHANGE or command == NEEDLE_SET or command == TRIM:
trimmed = True
jumping = False
if command == JUMP:
if not jumping:
jump_dx = 0
jump_dy = 0
jump_count = 0
jump_start = i
jumping = True
jump_count += 1
jump_dx += dx
jump_dy += dy
if not trimmed:
if jump_count == jumps_to_require_trim or\
distance_to_require_trim is not None and\
(
abs(jump_dy) > distance_to_require_trim or\
abs(jump_dx) > distance_to_require_trim
):
self.trim(position=jump_start)
jump_start += 1 # We inserted a position, start jump has moved.
i += 1
ie += 1
trimmed = True
if clipping and jump_dx == 0 and jump_dy == 0: # jump displacement is 0, clip trim command.
del self.stitches[jump_start:i+1]
i = jump_start - 1
ie = len(self.stitches) - 1

def get_pattern_interpolate_trim(self, jumps_to_require_trim):
"""Gets a processed pattern with untrimmed jumps merged
and trims added if merged jumps are beyond the given value.
Expand Down
Loading

0 comments on commit 9576a22

Please sign in to comment.