From 8c7b156e7e132822cc87c3089a1f09f3e1d90179 Mon Sep 17 00:00:00 2001 From: tatarize Date: Mon, 16 Jul 2018 05:19:38 -0700 Subject: [PATCH] Implicit/Explicit trims before color change. --- pyembroidery/CsvWriter.py | 3 +- pyembroidery/EmbConstant.py | 2 ++ pyembroidery/EmbEncoder.py | 64 +++++++++++++++++++++++++++++------- pyembroidery/EmbPattern.py | 15 ++++----- pyembroidery/PyEmbroidery.py | 22 ++++++++++--- setup.py | 2 +- test.py | 20 ++++------- 7 files changed, 90 insertions(+), 38 deletions(-) diff --git a/pyembroidery/CsvWriter.py b/pyembroidery/CsvWriter.py index 5d45da8b..41dae915 100644 --- a/pyembroidery/CsvWriter.py +++ b/pyembroidery/CsvWriter.py @@ -3,7 +3,6 @@ from .PecGraphics import get_graphic_as_string STRIP_SEQUINS = False -FULL_JUMP = False MAX_JUMP_DISTANCE = 121 MAX_STITCH_DISTANCE = 121 @@ -154,6 +153,8 @@ def get_common_name_dictionary(): OPTION_DISABLE_TIE_OFF: "OPTION_DISABLE_TIE_OFF", OPTION_MAX_STITCH_LENGTH: "OPTION_MAX_STITCH_LENGTH", OPTION_MAX_JUMP_LENGTH: "OPTION_MAX_JUMP_LENGTH", + OPTION_IMPLICIT_TRIM: "OPTION_IMPLICIT_TRIM", + OPTION_EXPLICIT_TRIM: "OPTION_EXPLICIT_TRIM", CONTINGENCY_NONE: "CONTINGENCY_NONE", CONTINGENCY_JUMP_NEEDLE: "CONTINGENCY_JUMP_NEEDLE", CONTINGENCY_SEW_TO: "CONTINGENCY_SEW_TO", diff --git a/pyembroidery/EmbConstant.py b/pyembroidery/EmbConstant.py index 45d9eebe..596e071b 100644 --- a/pyembroidery/EmbConstant.py +++ b/pyembroidery/EmbConstant.py @@ -29,6 +29,8 @@ OPTION_DISABLE_TIE_OFF = 0xD4 OPTION_MAX_STITCH_LENGTH = 0xD5 OPTION_MAX_JUMP_LENGTH = 0xD6 +OPTION_EXPLICIT_TRIM = 0xD7 +OPTION_IMPLICIT_TRIM = 0xD8 CONTINGENCY_NONE = 0xF0 CONTINGENCY_JUMP_NEEDLE = 0xF1 diff --git a/pyembroidery/EmbEncoder.py b/pyembroidery/EmbEncoder.py index 03e62369..304cd743 100644 --- a/pyembroidery/EmbEncoder.py +++ b/pyembroidery/EmbEncoder.py @@ -11,6 +11,7 @@ def __init__(self, settings=None): self.max_jump = settings.get("max_jump", float('inf')) self.full_jump = settings.get("full_jump", False) self.strip_sequins = settings.get("strip_sequins", True) + self.explicit_trim = settings.get("explicit_trim", True) self.has_tie_on = settings.get("tie_on", False) self.has_tie_off = settings.get("tie_off", False) @@ -129,8 +130,7 @@ def transcode_stitches(self): elif flags == SEQUENCE_BREAK: self.tie_off_and_trim_if_needed() elif flags == COLOR_BREAK: - self.tie_off_and_trim_if_needed() - self.color_change_here_if_needed() + self.color_break() elif flags == TIE_OFF: self.tie_off() elif flags == TIE_ON: @@ -153,8 +153,7 @@ def transcode_stitches(self): self.toggle_sequins() self.sequin_at(x, y) elif flags == COLOR_CHANGE: - self.tie_off_and_trim_if_needed() - self.color_change_here() + self.tie_off_trim_color_change() # If we are told to do something we do it. # Even if it's the first command and makes no sense. elif flags == STOP: @@ -178,6 +177,10 @@ def transcode_stitches(self): elif flags == OPTION_MAX_STITCH_LENGTH: x = self.stitch[0] self.max_stitch = x + elif flags == OPTION_EXPLICIT_TRIM: + self.explicit_trim = True + elif flags == OPTION_IMPLICIT_TRIM: + self.explicit_trim = False elif flags == CONTINGENCY_NONE: self.long_stitch_contingency = CONTINGENCY_NONE elif flags == CONTINGENCY_JUMP_NEEDLE: @@ -215,6 +218,52 @@ def add(self, flags, x=None, y=None): y = self.needle_y self.destination_pattern.stitches.append([x, y, flags]) + def lookahead_stitch(self): + """Looks forward from current position and + determines if anymore stitching will occur.""" + source = self.source_pattern.stitches + for pos in range(self.position, len(source)): + stitch = source[pos] + flags = stitch[2] + if flags == STITCH: + return True + elif flags == NEEDLE_AT: + return True + elif flags == SEW_TO: + return True + elif flags == TIE_ON: + return True + elif flags == SEQUIN_EJECT: + return True + elif flags == END: + return False + return False + + def color_break(self): + """Implements color break. Should add color changes add needed only.""" + if self.color_index < 0: + return # We haven't stitched anything, colorbreak happens, before start. Ignore. + if not self.state_trimmed: + if self.has_tie_off: + self.tie_off() + if self.explicit_trim: + self.trim_here() + if not self.lookahead_stitch(): + return # No more stitching will happen, colorchange unneeded. + self.add(COLOR_CHANGE) + self.color_index += 1 + self.state_trimmed = True + + def tie_off_trim_color_change(self): + if not self.state_trimmed: + if self.has_tie_off: + self.tie_off() + if self.explicit_trim: + self.trim_here() + self.add(COLOR_CHANGE) + self.color_index += 1 + self.state_trimmed = True + def tie_off_and_trim_if_needed(self): if not self.state_trimmed: self.tie_off_and_trim() @@ -347,13 +396,6 @@ def end_here(self): self.add(END) self.state_trimmed = True - def color_change_here_if_needed(self): - if self.color_index >= 0: # Have we stitched anything yet? - self.color_change_here() - # We should actually look ahead and ensure - # there are no more objects that will become stitches. - # post-stitch color-changes are pointless. - def color_change_here(self): self.add(COLOR_CHANGE) self.color_index += 1 diff --git a/pyembroidery/EmbPattern.py b/pyembroidery/EmbPattern.py index e5459798..0fd0879c 100644 --- a/pyembroidery/EmbPattern.py +++ b/pyembroidery/EmbPattern.py @@ -206,18 +206,17 @@ def translate(self, dx, dy): stitch[1] += dy def fix_color_count(self): + """Ensure the there are threads for all color blocks.""" thread_index = 0 - starting = True + init_color = True for stitch in self.stitches: data = stitch[2] & COMMAND_MASK - if data == STITCH: - if starting: + if data == STITCH or data == SEW_TO or data == NEEDLE_AT: + if init_color: thread_index += 1 - starting = False - elif data == COLOR_CHANGE: - if starting: - continue - thread_index += 1 + init_color = False + elif data == COLOR_CHANGE or data == COLOR_BREAK: + init_color = True while len(self.threadlist) < thread_index: self.add_thread(self.get_thread_or_filler(len(self.threadlist))) diff --git a/pyembroidery/PyEmbroidery.py b/pyembroidery/PyEmbroidery.py index 4da68cfb..384e26cb 100644 --- a/pyembroidery/PyEmbroidery.py +++ b/pyembroidery/PyEmbroidery.py @@ -32,6 +32,8 @@ import pyembroidery.KsmReader as KsmReader import pyembroidery.TapReader as TapReader import pyembroidery.StxReader as StxReader + + # import pyembroidery.ExyReader as ExyReader # import pyembroidery.FxyReader as FxyReader # import pyembroidery.GtReader as GtReader @@ -345,13 +347,25 @@ def write_embroidery(writer, pattern, stream, settings=None): settings = settings.copy() if settings.get("encode", True): if not ("max_jump" in settings): - settings["max_jump"] = writer.MAX_JUMP_DISTANCE + try: + settings["max_jump"] = writer.MAX_JUMP_DISTANCE + except AttributeError: + pass if not ("max_stitch" in settings): - settings["max_stitch"] = writer.MAX_STITCH_DISTANCE + try: + settings["max_stitch"] = writer.MAX_STITCH_DISTANCE + except AttributeError: + pass if not ("full_jump" in settings): - settings["full_jump"] = writer.FULL_JUMP + try: + settings["full_jump"] = writer.FULL_JUMP + except AttributeError: + pass if not ("strip_sequins" in settings): - settings["strip_sequins"] = writer.STRIP_SEQUINS + try: + settings["strip_sequins"] = writer.STRIP_SEQUINS + except AttributeError: + pass pattern = pattern.get_normalized_pattern(settings) if isinstance(stream, str): diff --git a/setup.py b/setup.py index 113c9e84..1cdb15a9 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="pyembroidery", - version="1.2.12", + version="1.2.13", author="Tatarize", author_email="tatarize@gmail.com", description="Embroidery IO library", diff --git a/test.py b/test.py index b93d73db..b26d0977 100644 --- a/test.py +++ b/test.py @@ -3,27 +3,20 @@ import test_fractals from pyembroidery import * -# -# from pyembroidery.EmbPattern import EmbPattern -# import pyembroidery.PyEmbroidery as pyemb -# from pyembroidery.EmbConstant import * -# import pyembroidery.PecGraphics as pg - # Initial test code. pyembroidery - -# Do not emulate the following pattern, -# using rotates and translates like this is crazy. pattern2 = EmbPattern() -pattern2.color_change() +pattern2.add_command(COLOR_BREAK) pattern2.add_stitch_absolute(SEW_TO, -100, -100) pattern2.add_stitch_absolute(SEW_TO, -100, +100) pattern2.add_stitch_absolute(SEW_TO, +100, +100) +pattern2.add_command(COLOR_BREAK) pattern2.add_stitch_absolute(SEW_TO, +100, -100) pattern2.add_stitch_absolute(SEW_TO, -100, -100) -pattern2.fix_color_count() +pattern2.add_command(COLOR_BREAK) pattern2.add_thread({"color": 0xFF0000}) -write(pattern2, "example.jef") +pattern2.fix_color_count() +write(pattern2, "example.csv", {"explicit_trim": False}) pattern = EmbPattern() @@ -82,7 +75,8 @@ results_file = os.path.join("results", file) + \ '.' + emb_format["extension"] write(pattern, results_file, { - "deltas": True + "deltas": True, + "scale": 2 # "tie_on": True, # "tie_off": True, # "translate": (500, 500)