From cdb8fdb1339476e36ad2e294283eec33d13b2d3d Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Fri, 27 Jul 2018 20:26:18 -0400 Subject: add bean stitch option --- lib/elements/stroke.py | 21 ++++++++++++++++----- lib/stitches/running_stitch.py | 29 +++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 5 deletions(-) (limited to 'lib') diff --git a/lib/elements/stroke.py b/lib/elements/stroke.py index e8eb4783..e086ccd9 100644 --- a/lib/elements/stroke.py +++ b/lib/elements/stroke.py @@ -4,7 +4,7 @@ import shapely.geometry from .element import param, EmbroideryElement, Patch from ..i18n import _ from ..utils import cache, Point -from ..stitches import running_stitch +from ..stitches import running_stitch, bean_stitch from ..svg import parse_length_with_units warned_about_legacy_running_stitch = False @@ -27,18 +27,28 @@ class Stroke(EmbroideryElement): return self.get_style("stroke-dasharray") is not None @property - @param('running_stitch_length_mm', _('Running stitch length'), unit='mm', type='float', default=1.5) + @param('running_stitch_length_mm', _('Running stitch length'), unit='mm', type='float', default=1.5, sort_index=3) def running_stitch_length(self): return max(self.get_float_param("running_stitch_length_mm", 1.5), 0.01) @property - @param('zigzag_spacing_mm', _('Zig-zag spacing (peak-to-peak)'), unit='mm', type='float', default=0.4) + @param('bean_stitch_repeats', + _('Bean stitch number of repeats'), + tooltip=_('Backtrack each stitch this many times. A value of 1 would triple each stitch (forward, back, forward). A value of 2 would quintuple each stitch, etc. Only applies to running stitch.'), + type='int', + default=0, + sort_index=2) + def bean_stitch_repeats(self): + return self.get_int_param("bean_stitch_repeats", 0) + + @property + @param('zigzag_spacing_mm', _('Zig-zag spacing (peak-to-peak)'), unit='mm', type='float', default=0.4, sort_index=3) @cache def zigzag_spacing(self): return max(self.get_float_param("zigzag_spacing_mm", 0.4), 0.01) @property - @param('repeats', _('Repeats'), type='int', default="1") + @param('repeats', _('Repeats'), type='int', default="1", sort_index=1) def repeats(self): return self.get_int_param("repeats", 1) @@ -58,7 +68,7 @@ class Stroke(EmbroideryElement): return shapely.geometry.MultiLineString(line_strings) @property - @param('manual_stitch', _('Manual stitch placement'), tooltip=_("Stitch every node in the path. Stitch length and zig-zag spacing are ignored."), type='boolean', default=False) + @param('manual_stitch', _('Manual stitch placement'), tooltip=_("Stitch every node in the path. Stitch length and zig-zag spacing are ignored."), type='boolean', default=False, sort_index=0) def manual_stitch_mode(self): return self.get_boolean_param('manual_stitch') @@ -139,6 +149,7 @@ class Stroke(EmbroideryElement): repeated_path.extend(this_path) stitches = running_stitch(repeated_path, stitch_length) + stitches = bean_stitch(stitches, self.bean_stitch_repeats) return Patch(self.color, stitches) diff --git a/lib/stitches/running_stitch.py b/lib/stitches/running_stitch.py index 96075e7a..5f8ed21e 100644 --- a/lib/stitches/running_stitch.py +++ b/lib/stitches/running_stitch.py @@ -1,3 +1,6 @@ +from copy import copy + + """ Utility functions to produce running stitches. """ @@ -64,3 +67,29 @@ def running_stitch(points, stitch_length): output.append(segment_start) return output + + +def bean_stitch(stitches, repeats): + """Generate bean stitch from a set of stitches. + + "Bean" stitch is made by backtracking each stitch to make it heaver. A + simple bean stitch would be two stitches forward, one stitch back, two + stitches forward, etc. This would result in each stitch being tripled. + + We'll say that the above counts as 1 repeat. Backtracking each stitch + repeatedly will result in a heavier bean stitch. There will always be + an odd number of threads piled up for each stitch. + """ + + if len(stitches) < 2: + return stitches + + new_stitches = [stitches[0]] + + for stitch in stitches: + new_stitches.append(stitch) + + for i in xrange(repeats): + new_stitches.extend(copy(new_stitches[-2:])) + + return new_stitches -- cgit v1.2.3 From 0ab7223980d849dd732cb9572644339d5c2a6228 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Fri, 27 Jul 2018 21:10:02 -0400 Subject: add E stitch for satin columns --- lib/elements/satin_column.py | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/elements/satin_column.py b/lib/elements/satin_column.py index 2ceb38de..78275745 100644 --- a/lib/elements/satin_column.py +++ b/lib/elements/satin_column.py @@ -17,6 +17,12 @@ class SatinColumn(EmbroideryElement): def satin_column(self): return self.get_boolean_param("satin_column") + # I18N: "E" stitch is so named because it looks like the letter E. + @property + @param('e_stitch', _('"E" stitch'), type='boolean', default='false') + def e_stitch(self): + return self.get_boolean_param("e_stitch") + @property def color(self): return self.get_style("stroke") @@ -28,7 +34,7 @@ class SatinColumn(EmbroideryElement): return max(self.get_float_param("zigzag_spacing_mm", 0.4), 0.01) @property - @param('pull_compensation_mm', _('Pull compensation'), unit='mm', type='float') + @param('pull_compensation_mm', _('Pull compensation'), unit='mm', type='float', default=0) def pull_compensation(self): # In satin stitch, the stitches have a tendency to pull together and # narrow the entire column. We can compensate for this by stitching @@ -76,7 +82,7 @@ class SatinColumn(EmbroideryElement): return max(self.get_float_param("zigzag_underlay_spacing_mm", 3), 0.01) @property - @param('zigzag_underlay_inset_mm', _('Inset amount (default: half of contour underlay inset)'), unit='mm', group=_('Zig-zag Underlay'), type='float') + @param('zigzag_underlay_inset_mm', _('Inset amount (default: half of contour underlay inset)'), unit='mm', group=_('Zig-zag Underlay'), type='float', default="") def zigzag_underlay_inset(self): # how far in from the edge of the satin the points in the zigzags # should be @@ -388,6 +394,28 @@ class SatinColumn(EmbroideryElement): return patch + def do_e_stitch(self): + # e stitch: do a pattern that looks like the letter "E". It looks like + # this: + # + # _|_|_|_|_|_|_|_|_|_|_|_| + + # print >> dbg, "satin", self.zigzag_spacing, self.pull_compensation + + patch = Patch(color=self.color) + + sides = self.walk_paths(self.zigzag_spacing, self.pull_compensation) + + # "left" and "right" here are kind of arbitrary designations meaning + # a point from the first and second rail repectively + for left, right in izip(*sides): + patch.add_stitch(left) + patch.add_stitch(right) + patch.add_stitch(left) + + return patch + + def to_patches(self, last_patch): # Stitch a variable-width satin column, zig-zagging between two paths. @@ -411,6 +439,9 @@ class SatinColumn(EmbroideryElement): # zigzags sit on the contour walk underlay like rail ties on rails. patches.append(self.do_zigzag_underlay()) - patches.append(self.do_satin()) + if self.e_stitch: + patches.append(self.do_e_stitch()) + else: + patches.append(self.do_satin()) return patches -- cgit v1.2.3 From f8f108367abf71e2e8a2eb7718a2759568337c53 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Sat, 28 Jul 2018 20:10:27 -0400 Subject: fix simple satin --- lib/elements/stroke.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/elements/stroke.py b/lib/elements/stroke.py index e086ccd9..bc2ee54c 100644 --- a/lib/elements/stroke.py +++ b/lib/elements/stroke.py @@ -149,7 +149,6 @@ class Stroke(EmbroideryElement): repeated_path.extend(this_path) stitches = running_stitch(repeated_path, stitch_length) - stitches = bean_stitch(stitches, self.bean_stitch_repeats) return Patch(self.color, stitches) @@ -163,6 +162,10 @@ class Stroke(EmbroideryElement): patch = Patch(color=self.color, stitches=path, stitch_as_is=True) elif self.is_running_stitch(): patch = self.running_stitch(path, self.running_stitch_length) + + if self.bean_stitch_repeats > 0: + patch.stitches = bean_stitch(patch.stitches, self.bean_stitch_repeats) + else: patch = self.simple_satin(path, self.zigzag_spacing, self.stroke_width) -- cgit v1.2.3 From eb98e851cdfdcc52f2ed7bcb1785d8ceb0b6bae8 Mon Sep 17 00:00:00 2001 From: Kaalleen <36401965+kaalleen@users.noreply.github.com> Date: Wed, 1 Aug 2018 16:58:48 +0200 Subject: Add simulator controls (#246) --- lib/simulator.py | 49 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 39 insertions(+), 10 deletions(-) (limited to 'lib') diff --git a/lib/simulator.py b/lib/simulator.py index c7e74353..2d2d3e08 100644 --- a/lib/simulator.py +++ b/lib/simulator.py @@ -27,6 +27,26 @@ class EmbroiderySimulator(wx.Frame): self.panel = wx.Panel(self, wx.ID_ANY) self.panel.SetFocus() + self.sizer = wx.BoxSizer(wx.VERTICAL) + self.button_sizer = wx.BoxSizer(wx.HORIZONTAL) + + self.button_label = ( + [_("Speed up"),_('Press + or arrow up to speed up')], + [_("Slow down"),_('Press - or arrow down to slow down')], + [_("Pause"),_("Press P to pause the animation")], + [_("Restart"),_("Press R to restart the animation")], + [_("Quit"),_("Press Q to close the simulation window")]) + self.buttons = [] + for i in range(0, len(self.button_label)): + self.buttons.append(wx.Button(self, -1, self.button_label[i][0])) + self.button_sizer.Add(self.buttons[i], 1, wx.EXPAND) + self.buttons[i].Bind(wx.EVT_BUTTON, self.on_key_down) + self.buttons[i].SetToolTip(self.button_label[i][1]) + + self.sizer.Add(self.panel, 1, wx.EXPAND) + self.sizer.Add(self.button_sizer, 0, wx.EXPAND) + self.SetSizer(self.sizer) + self.load(stitch_plan) if self.target_duration: @@ -68,26 +88,30 @@ class EmbroiderySimulator(wx.Frame): self.stitches_per_frame *= 2 def on_key_down(self, event): - keycode = event.GetKeyCode() + if hasattr(event, 'GetKeyCode'): + keycode = event.GetKeyCode() + else: + keycode = event.GetEventObject().GetLabelText() + self.panel.SetFocus() - if keycode == ord("+") or keycode == ord("=") or keycode == wx.WXK_UP: + if keycode == ord("+") or keycode == ord("=") or keycode == wx.WXK_UP or keycode == "Speed up": if self.frame_period == 1: self.stitches_per_frame *= 2 else: self.frame_period = self.frame_period / 2 - elif keycode == ord("-") or keycode == ord("_") or keycode == wx.WXK_DOWN: + elif keycode == ord("-") or keycode == ord("_") or keycode == wx.WXK_DOWN or keycode == "Slow down": if self.stitches_per_frame == 1: self.frame_period *= 2 else: self.stitches_per_frame /= 2 - elif keycode == ord("Q"): + elif keycode == ord("Q") or keycode == "Quit": self.Close() - elif keycode == ord('P'): + elif keycode == ord("P") or keycode == "Pause": if self.timer.IsRunning(): self.timer.Stop() else: self.timer.Start(self.frame_period) - elif keycode == ord("R"): + elif keycode == ord("R") or keycode == "Restart": self.stop() self.clear() self.go() @@ -170,7 +194,7 @@ class EmbroiderySimulator(wx.Frame): self.width = width self.height = height - self.scale = min(float(self.max_width) / width, float(self.max_height) / height) + self.scale = min(float(self.max_width) / width, float(self.max_height - 60) / height) # make room for decorations and the margin self.scale *= 0.95 @@ -212,10 +236,15 @@ class EmbroiderySimulator(wx.Frame): client_width, client_height = self.GetClientSize() decorations_width = window_width - client_width - decorations_height = window_height - client_height + decorations_height = window_height - client_height + 40 + + setsize_window_width = self.width * self.scale + decorations_width + self.margin * 2 + setsize_window_height = (self.height) * self.scale + decorations_height + self.margin * 2 + + if setsize_window_width < 600: + setsize_window_width = 600 - self.SetSize((self.width * self.scale + decorations_width + self.margin * 2, - self.height * self.scale + decorations_height + self.margin * 2)) + self.SetSize(( setsize_window_width, setsize_window_height)) e.Skip() -- cgit v1.2.3 From b8dc82570641eb5117d46980186c207b30e44223 Mon Sep 17 00:00:00 2001 From: Lex Neva Date: Wed, 1 Aug 2018 20:43:31 -0400 Subject: try using GetScreenRect() instead --- lib/extensions/params.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/extensions/params.py b/lib/extensions/params.py index 58fedd6b..1b8f2589 100644 --- a/lib/extensions/params.py +++ b/lib/extensions/params.py @@ -424,7 +424,7 @@ class SettingsFrame(wx.Frame): self.simulate_window.stop() self.simulate_window.load(stitch_plan=stitch_plan) else: - my_rect = self.GetRect() + my_rect = self.GetScreenRect() simulator_pos = my_rect.GetTopRight() simulator_pos.x += 5 -- cgit v1.2.3