Skip to content

Commit

Permalink
Merge pull request #63 from EmbroidePy/tatarize-merge_and_builtins
Browse files Browse the repository at this point in the history
Merge patterns and Builtins
  • Loading branch information
tatarize authored Jul 13, 2019
2 parents 2f7ce87 + 17a5f29 commit 1752f0d
Show file tree
Hide file tree
Showing 17 changed files with 292 additions and 22 deletions.
25 changes: 23 additions & 2 deletions pyembroidery/EmbMatrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,29 @@


class EmbMatrix:
def __init__(self):
self.m = self.get_identity()
def __init__(self, m=None):
if m is None:
self.m = self.get_identity()
else:
self.m = m

def __ne__(self, other):
return not self.__eq__(other)

def __eq__(self, other):
return self.m == other.m

def __matmul__(self, other):
return EmbMatrix(EmbMatrix.matrix_multiply(self.m, other.m))

def __rmatmul__(self, other):
return EmbMatrix(EmbMatrix.matrix_multiply(self.m, other.m))

def __imatmul__(self, other):
self.m = EmbMatrix.matrix_multiply(self.m, other.m)

def __str__(self):
return "[%3f, %3f, %3f\n %3f, %3f, %3f\n %3f, %3f, %3f]" % self.m

def get_matrix(self):
return self.m
Expand Down
133 changes: 130 additions & 3 deletions pyembroidery/EmbPattern.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,103 @@ class EmbPattern:
def __init__(self):
self.stitches = [] # type: list
self.threadlist = [] # type: list
self.extras = {}
self.extras = {} # type: dict
# filename, name, category, author, keywords, comments, are typical
self._previousX = 0 # type: float
self._previousY = 0 # type: float

def __ne__(self, other):
return not self.__eq__(other)

def __eq__(self, other):
if not isinstance(other, EmbPattern):
return False
if self.stitches != other.stitches:
return False
if self.threadlist != other.threadlist:
return False
if self.extras != other.extras:
return False
return True

def __str__(self):
if "name" in self.extras:
return "EmbPattern %s (commands: %3d, threads: %3d)" % \
(self.extras["name"], len(self.stitches), len(self.threadlist))
return "EmbPattern (commands: %3d, threads: %3d)" % (len(self.stitches), len(self.threadlist))

def __len__(self):
return len(self.stitches)

def __getitem__(self, item):
if isinstance(item, str):
return self.extras[item]
return self.stitches[item]

def __setitem__(self, key, value):
if isinstance(key, str):
self.extras[key] = value
else:
self.stitches[key] = value

def __copy__(self):
return self.copy()

def __deepcopy__(self):
return self.copy()

def __iadd__(self, other):
if isinstance(other, EmbPattern):
self.add_pattern(other)
elif isinstance(other, EmbThread) or isinstance(other, str):
self.add_thread(other)
for i in range(0, len(self.stitches)):
data = self.stitches[i][2] & COMMAND_MASK
if data == STITCH or data == SEW_TO or data == NEEDLE_AT:
self.color_change()
break # Only add color change if stitching exists.
elif isinstance(other, int):
self.add_command(other)
elif isinstance(other, list) or isinstance(other, tuple): # tuple or list
if len(other) == 0:
return
v = other[0]
if isinstance(v, list) or isinstance(v, tuple): # tuple or list of tuple or lists
for v in other:
x = v[0]
y = v[1]
try:
cmd = v[2]
except IndexError:
cmd = STITCH
self.add_stitch_absolute(cmd, x, y)
elif isinstance(v, complex): # tuple or list of complex
for v in other:
x = v.real
y = v.imag
self.add_stitch_absolute(STITCH, x, y)
elif isinstance(v, int) or isinstance(v, float): # tuple or list of numbers.
i = 0
ie = len(other)
while i < ie:
self.add_stitch_absolute(STITCH, other[i], other[i + 1])
i += 2
elif isinstance(v, str):
self.extras[v] = other[1]
else:
raise ValueError()
return self

def __add__(self, other):
p = self.copy()
p.add_pattern(other)
return p

def __radd__(self, other):
p = other.copy()
p.add_pattern(self)
return p

def copy(self):
emb_pattern = EmbPattern()
emb_pattern.stitches = self.stitches[:]
Expand Down Expand Up @@ -238,7 +330,7 @@ def transform(self, matrix):
matrix.apply(stitch)

def fix_color_count(self):
"""Ensure the there are threads for all color blocks."""
"""Ensure that there are threads for all color blocks."""
thread_index = 0
init_color = True
for stitch in self.stitches:
Expand Down Expand Up @@ -321,6 +413,41 @@ def add_stitchblock(self, stitchblock):
except AttributeError:
self.add_stitch_absolute(stitch[2], stitch[0], stitch[1])

def add_pattern(self, pattern):
"""
add_pattern merges the given pattern with the current pattern. It accounts for some edge conditions but
not all of them.
If there is an end command on the current pattern, that is removed.
If the color ending the current pattern is equal to the color starting the next those color blocks are merged.
Any prepended thread change command to the merging pattern is suppressed.
:param pattern: pattern to add to current pattern
:return:
"""
if self.stitches[-1][2] == END:
self.stitches = self.stitches[:-1] # Remove END, if exists

# Add the new thread only if it's different from the last one
self.fix_color_count()

if len(pattern.threadlist) > 0:
if pattern.threadlist[0] == self.threadlist[-1]:
self.threadlist.extend(pattern.threadlist[1:])
else:
self.threadlist.extend(pattern.threadlist)
self.color_change()
join_position = len(self.stitches)
self.stitches.extend(pattern.stitches)

for i in range(join_position, len(self.stitches)):
data = self.stitches[i][2] & COMMAND_MASK
if data == STITCH or data == SEW_TO or data == NEEDLE_AT:
break
elif data == COLOR_CHANGE or data == COLOR_BREAK or data == NEEDLE_SET:
self.stitches[i][2] = NO_COMMAND
self.extras.update(pattern.extras)

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 All @@ -337,7 +464,7 @@ def get_pattern_interpolate_trim(self, jumps_to_require_trim):
command = stitch[2] & COMMAND_MASK
if command == STITCH or command == SEQUIN_EJECT:
trimmed = False
elif command == COLOR_CHANGE or command == TRIM:
elif command == COLOR_CHANGE or command == NEEDLE_SET or command == TRIM:
trimmed = True
if trimmed or stitch[2] != JUMP:
new_pattern.add_stitch_absolute(stitch[2],
Expand Down
35 changes: 34 additions & 1 deletion pyembroidery/EmbThread.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def color_distance_red_mean(

class EmbThread:

def __init__(self):
def __init__(self, thread=None):
self.color = 0xFF000000
self.description = None # type: str
self.catalog_number = None # type: str
Expand All @@ -64,6 +64,39 @@ def __init__(self):
self.chart = None # type: str
self.weight = None # type: str
# description, catalog_number, details, brand, chart, weight
if thread is not None:
self.set(thread)

def __ne__(self, other):
return not self.__eq__(other)

def __eq__(self, other):
if other is None:
return False
if isinstance(other, int):
return (0xFF000000 | self.color) == (0xFF000000 | other)
if isinstance(other, str):
return (0xFF000000 | self.color) == (0xFF000000 | EmbThread.parse_string_color(other))
if not isinstance(other, EmbThread):
return False
if (0xFF000000 | self.color) != (0xFF000000 | other.color):
return False
if self.description != other.description:
return False
if self.catalog_number != other.description:
return False
if self.details != other.details:
return False
if self.brand != other.brand:
return False
if self.chart != other.chart:
return False
if self.weight != other.weight:
return False
return True

def __hash__(self):
return self.color & 0xFFFFFF

def set_color(self, r, g, b):
self.color = color_rgb(r, g, b)
Expand Down
2 changes: 0 additions & 2 deletions pyembroidery/InbReader.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@


def read_inb_stitches(f, out):
count = 0
while True:
Expand Down
1 change: 0 additions & 1 deletion pyembroidery/MitReader.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

MIT_SIZE_CONVERSION_RATIO = 2.0 / 1.0


Expand Down
2 changes: 1 addition & 1 deletion pyembroidery/PcdReader.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .ReadHelper import read_int_8, read_int_24be, read_int_24le, read_int_16le, signed24
from .EmbThread import EmbThread
from .ReadHelper import read_int_8, read_int_24be, read_int_24le, read_int_16le, signed24

PC_SIZE_CONVERSION_RATIO = 5.0 / 3.0

Expand Down
2 changes: 1 addition & 1 deletion pyembroidery/PcqReader.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .ReadHelper import read_int_8, read_int_24be, read_int_24le, read_int_16le, signed24
from .EmbThread import EmbThread
from .ReadHelper import read_int_8, read_int_24be, read_int_24le, read_int_16le, signed24

PC_SIZE_CONVERSION_RATIO = 5.0 / 3.0

Expand Down
2 changes: 1 addition & 1 deletion pyembroidery/PcsReader.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .ReadHelper import read_int_8, read_int_24be, read_int_24le, read_int_16le, signed24
from .EmbThread import EmbThread
from .ReadHelper import read_int_8, read_int_24be, read_int_24le, read_int_16le, signed24

PC_SIZE_CONVERSION_RATIO = 5.0 / 3.0

Expand Down
4 changes: 2 additions & 2 deletions pyembroidery/PesWriter.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
from .PecWriter import write_pec
from .EmbConstant import *
from .EmbThreadPec import get_thread_set
from .PecWriter import write_pec
from .WriteHelper import write_string_utf8, write_int_32le, write_int_24le, write_int_16le, write_int_8, \
write_float_32le
from .EmbConstant import *

SEQUIN_CONTINGENCY = CONTINGENCY_SEQUIN_JUMP
FULL_JUMP = True
Expand Down
2 changes: 1 addition & 1 deletion pyembroidery/PhbReader.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .PecReader import read_pec_stitches
from .EmbThreadPec import get_thread_set
from .PecReader import read_pec_stitches
from .ReadHelper import read_int_8, read_int_32le, read_int_16le


Expand Down
2 changes: 1 addition & 1 deletion pyembroidery/PhcReader.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ def read(f, out, settings=None):
bytes_in_section2 = read_int_32le(f) # Sectional bounds.
f.seek(bytes_in_section2 + 10, 1)
color_count2 = read_int_8(f)
f.seek(color_count2 + 0x1D, 1) #1D toto back
f.seek(color_count2 + 0x1D, 1) # 1D toto back
read_pec_stitches(f, out)
5 changes: 3 additions & 2 deletions pyembroidery/ShvReader.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import math

from .EmbConstant import *
from .EmbThreadShv import get_thread_set
from .ReadHelper import read_int_16be, read_int_32be, \
read_int_8, read_string_8, signed16, signed8
from .EmbThreadShv import get_thread_set
from .EmbConstant import *


def read(f, out, settings=None):
Expand Down
2 changes: 1 addition & 1 deletion pyembroidery/StxReader.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .ReadHelper import read_int_32le
from .ExpReader import read_exp_stitches
from .ReadHelper import read_int_32le


def read(f, out, settings=None):
Expand Down
2 changes: 1 addition & 1 deletion pyembroidery/TbfReader.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from .ReadHelper import signed8, read_int_8, read_int_24be
from .EmbThread import EmbThread
from .ReadHelper import signed8, read_int_8, read_int_24be


def read(f, out, settings=None):
Expand Down
2 changes: 1 addition & 1 deletion pyembroidery/ZxyReader.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from .ReadHelper import signed8, read_int_32le, read_int_16be
from .ReadHelper import read_int_16be


def read_zxy_stitches(f, out):
Expand Down
3 changes: 2 additions & 1 deletion pyembroidery/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from .EmbFunctions import *
from .EmbPattern import EmbPattern
from .EmbMatrix import EmbMatrix
from .EmbThread import EmbThread

# items available in a sub-heirarchy (e.g. pyembroidery.PecGraphics.get_graphic_as_string)
from .PecGraphics import get_graphic_as_string
from .PecGraphics import get_graphic_as_string
Loading

0 comments on commit 1752f0d

Please sign in to comment.