diff options
Diffstat (limited to 'lib/stitch_plan/stitch_plan.py')
| -rw-r--r-- | lib/stitch_plan/stitch_plan.py | 176 |
1 files changed, 18 insertions, 158 deletions
diff --git a/lib/stitch_plan/stitch_plan.py b/lib/stitch_plan/stitch_plan.py index fc0d3760..7e7621c1 100644 --- a/lib/stitch_plan/stitch_plan.py +++ b/lib/stitch_plan/stitch_plan.py @@ -3,56 +3,54 @@ # Copyright (c) 2010 Authors # Licensed under the GNU GPL version 3.0 or later. See the file LICENSE for details. -from ..svg import PIXELS_PER_MM -from ..threads import ThreadColor -from ..utils.geometry import Point -from .stitch import Stitch from .ties import add_ties +from .color_block import ColorBlock +from ..svg import PIXELS_PER_MM -def patches_to_stitch_plan(patches, collapse_len=None, disable_ties=False): # noqa: C901 +def stitch_groups_to_stitch_plan(stitch_groups, collapse_len=None, disable_ties=False): # noqa: C901 - """Convert a collection of inkstitch.element.Patch objects to a StitchPlan. + """Convert a collection of StitchGroups to a StitchPlan. - * applies instructions embedded in the Patch such as trim_after and stop_after + * applies instructions embedded in the StitchGroup such as trim_after and stop_after * adds tie-ins and tie-offs - * adds jump-stitches between patches if necessary + * adds jump-stitches between stitch_group if necessary """ if collapse_len is None: collapse_len = 3.0 collapse_len = collapse_len * PIXELS_PER_MM stitch_plan = StitchPlan() - color_block = stitch_plan.new_color_block(color=patches[0].color) + color_block = stitch_plan.new_color_block(color=stitch_groups[0].color) - for patch in patches: - if not patch.stitches: + for stitch_group in stitch_groups: + if not stitch_group.stitches: continue - if color_block.color != patch.color: + if color_block.color != stitch_group.color: if len(color_block) == 0: # We just processed a stop, which created a new color block. # We'll just claim this new block as ours: - color_block.color = patch.color + color_block.color = stitch_group.color else: # end the previous block with a color change color_block.add_stitch(color_change=True) # make a new block of our color - color_block = stitch_plan.new_color_block(color=patch.color) + color_block = stitch_plan.new_color_block(color=stitch_group.color) # always start a color with a JUMP to the first stitch position - color_block.add_stitch(patch.stitches[0], jump=True) + color_block.add_stitch(stitch_group.stitches[0], jump=True) else: - if len(color_block) and (patch.stitches[0] - color_block.stitches[-1]).length() > collapse_len: - color_block.add_stitch(patch.stitches[0], jump=True) + if len(color_block) and (stitch_group.stitches[0] - color_block.stitches[-1]).length() > collapse_len: + color_block.add_stitch(stitch_group.stitches[0], jump=True) - color_block.add_stitches(stitches=patch.stitches, tie_modus=patch.tie_modus, no_ties=patch.stitch_as_is) + color_block.add_stitches(stitches=stitch_group.stitches, tie_modus=stitch_group.tie_modus, no_ties=stitch_group.stitch_as_is) - if patch.trim_after: + if stitch_group.trim_after: color_block.add_stitch(trim=True) - if patch.stop_after: + if stitch_group.stop_after: color_block.add_stitch(stop=True) color_block = stitch_plan.new_color_block(color_block.color) @@ -168,141 +166,3 @@ class StitchPlan(object): return self.color_blocks[-1] else: return None - - -class ColorBlock(object): - """Holds a set of stitches, all with the same thread color.""" - - def __init__(self, color=None, stitches=None): - self.color = color - self.stitches = stitches or [] - - def __iter__(self): - return iter(self.stitches) - - def __len__(self): - return len(self.stitches) - - def __repr__(self): - return "ColorBlock(%s, %s)" % (self.color, self.stitches) - - def __getitem__(self, item): - return self.stitches[item] - - def __delitem__(self, item): - del self.stitches[item] - - def __json__(self): - return dict(color=self.color, stitches=self.stitches) - - def has_color(self): - return self._color is not None - - @property - def color(self): - return self._color - - @color.setter - def color(self, value): - if isinstance(value, ThreadColor): - self._color = value - elif value is None: - self._color = None - else: - self._color = ThreadColor(value) - - @property - def last_stitch(self): - if self.stitches: - return self.stitches[-1] - else: - return None - - @property - def num_stitches(self): - """Number of stitches in this color block.""" - return len(self.stitches) - - @property - def num_trims(self): - """Number of trims in this color block.""" - - return sum(1 for stitch in self if stitch.trim) - - @property - def stop_after(self): - if self.last_stitch is not None: - return self.last_stitch.stop - else: - return False - - @property - def trim_after(self): - # If there's a STOP, it will be at the end. We still want to return - # True. - for stitch in reversed(self.stitches): - if stitch.stop or stitch.jump: - continue - elif stitch.trim: - return True - else: - break - - return False - - def filter_duplicate_stitches(self): - if not self.stitches: - return - - stitches = [self.stitches[0]] - - for stitch in self.stitches[1:]: - if stitches[-1].jump or stitch.stop or stitch.trim or stitch.color_change: - # Don't consider jumps, stops, color changes, or trims as candidates for filtering - pass - else: - length = (stitch - stitches[-1]).length() - if length <= 0.1 * PIXELS_PER_MM: - # duplicate stitch, skip this one - continue - - stitches.append(stitch) - - self.stitches = stitches - - def add_stitch(self, *args, **kwargs): - if not args: - # They're adding a command, e.g. `color_block.add_stitch(stop=True)``. - # Use the position from the last stitch. - if self.last_stitch: - args = (self.last_stitch.x, self.last_stitch.y) - else: - raise ValueError("internal error: can't add a command to an empty stitch block") - - if isinstance(args[0], Stitch): - self.stitches.append(args[0]) - elif isinstance(args[0], Point): - self.stitches.append(Stitch(args[0].x, args[0].y, *args[1:], **kwargs)) - else: - if not args and self.last_stitch: - args = (self.last_stitch.x, self.last_stitch.y) - self.stitches.append(Stitch(*args, **kwargs)) - - def add_stitches(self, stitches, *args, **kwargs): - for stitch in stitches: - if isinstance(stitch, (Stitch, Point)): - self.add_stitch(stitch, *args, **kwargs) - else: - self.add_stitch(*(list(stitch) + args), **kwargs) - - def replace_stitches(self, stitches): - self.stitches = stitches - - @property - def bounding_box(self): - minx = min(stitch.x for stitch in self) - miny = min(stitch.y for stitch in self) - maxx = max(stitch.x for stitch in self) - maxy = max(stitch.y for stitch in self) - - return minx, miny, maxx, maxy |
