summaryrefslogtreecommitdiff
path: root/embroider_simulate.py
diff options
context:
space:
mode:
Diffstat (limited to 'embroider_simulate.py')
-rw-r--r--embroider_simulate.py285
1 files changed, 0 insertions, 285 deletions
diff --git a/embroider_simulate.py b/embroider_simulate.py
deleted file mode 100644
index c7c3f6bd..00000000
--- a/embroider_simulate.py
+++ /dev/null
@@ -1,285 +0,0 @@
-import sys
-import os
-import numpy
-import wx
-import inkex
-import simplestyle
-import colorsys
-from itertools import izip
-
-import inkstitch
-from inkstitch.extensions import InkstitchExtension
-from inkstitch import PIXELS_PER_MM
-from inkstitch.stitch_plan import patches_to_stitch_plan
-from inkstitch.svg import color_block_to_point_lists
-
-
-class EmbroiderySimulator(wx.Frame):
- def __init__(self, *args, **kwargs):
- stitch_plan = kwargs.pop('stitch_plan', None)
- self.on_close_hook = kwargs.pop('on_close', None)
- self.frame_period = kwargs.pop('frame_period', 80)
- self.stitches_per_frame = kwargs.pop('stitches_per_frame', 1)
- self.target_duration = kwargs.pop('target_duration', None)
-
- self.margin = 10
-
- screen_rect = wx.Display(0).ClientArea
- self.max_width = kwargs.pop('max_width', screen_rect.GetWidth())
- self.max_height = kwargs.pop('max_height', screen_rect.GetHeight())
- self.scale = 1
-
- wx.Frame.__init__(self, *args, **kwargs)
-
- self.panel = wx.Panel(self, wx.ID_ANY)
- self.panel.SetFocus()
-
- self.load(stitch_plan)
-
- if self.target_duration:
- self.adjust_speed(self.target_duration)
-
- self.buffer = wx.Bitmap(self.width * self.scale + self.margin * 2, self.height * self.scale + self.margin * 2)
- self.dc = wx.MemoryDC()
- self.dc.SelectObject(self.buffer)
- self.canvas = wx.GraphicsContext.Create(self.dc)
-
- self.clear()
-
- self.Bind(wx.EVT_SIZE, self.on_size)
- self.panel.Bind(wx.EVT_PAINT, self.on_paint)
- self.panel.Bind(wx.EVT_KEY_DOWN, self.on_key_down)
-
- self.timer = None
-
- self.last_pos = None
-
- self.Bind(wx.EVT_CLOSE, self.on_close)
-
- def load(self, stitch_plan=None):
- if stitch_plan:
- self.mirror = False
- self.segments = self._stitch_plan_to_segments(stitch_plan)
- else:
- return
-
- self.trim_margins()
- self.calculate_dimensions()
-
- def adjust_speed(self, duration):
- self.frame_period = 1000 * float(duration) / len(self.segments)
- self.stitches_per_frame = 1
-
- while self.frame_period < 1.0:
- self.frame_period *= 2
- self.stitches_per_frame *= 2
-
- def on_key_down(self, event):
- keycode = event.GetKeyCode()
-
- if keycode == ord("+") or keycode == ord("=") or keycode == wx.WXK_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:
- if self.stitches_per_frame == 1:
- self.frame_period *= 2
- else:
- self.stitches_per_frame /= 2
- elif keycode == ord("Q"):
- self.Close()
- elif keycode == ord('P'):
- if self.timer.IsRunning():
- self.timer.Stop()
- else:
- self.timer.Start(self.frame_period)
- elif keycode == ord("R"):
- self.stop()
- self.clear()
- self.go()
-
- self.frame_period = max(1, self.frame_period)
- self.stitches_per_frame = max(self.stitches_per_frame, 1)
-
- if self.timer.IsRunning():
- self.timer.Stop()
- self.timer.Start(self.frame_period)
-
- def _strip_quotes(self, string):
- if string.startswith('"') and string.endswith('"'):
- string = string[1:-1]
-
- return string
-
- def color_to_pen(self, color):
- return wx.Pen(color.visible_on_white.rgb)
-
- def _stitch_plan_to_segments(self, stitch_plan):
- segments = []
-
- for color_block in stitch_plan:
- pen = self.color_to_pen(color_block.color)
-
- for point_list in color_block_to_point_lists(color_block):
- # if there's only one point, there's nothing to do, so skip
- if len(point_list) < 2:
- continue
-
- for start, end in izip(point_list[:-1], point_list[1:]):
- segments.append(((start, end), pen))
-
- return segments
-
- def all_coordinates(self):
- for segment in self.segments:
- start, end = segment[0]
-
- yield start
- yield end
-
- def trim_margins(self):
- """remove any unnecessary whitespace around the design"""
-
- min_x = sys.maxint
- min_y = sys.maxint
-
- for x, y in self.all_coordinates():
- min_x = min(min_x, x)
- min_y = min(min_y, y)
-
- new_segments = []
-
- for segment in self.segments:
- (start, end), color = segment
-
- new_segment = (
- (
- (start[0] - min_x, start[1] - min_y),
- (end[0] - min_x, end[1] - min_y),
- ),
- color
- )
-
- new_segments.append(new_segment)
-
- self.segments = new_segments
-
- def calculate_dimensions(self):
- # 0.01 avoids a division by zero below for designs with no width or
- # height (e.g. a straight vertical or horizontal line)
- width = 0.01
- height = 0.01
-
- for x, y in self.all_coordinates():
- width = max(width, x)
- height = max(height, y)
-
- self.width = width
- self.height = height
- self.scale = min(float(self.max_width) / width, float(self.max_height) / height)
-
- # make room for decorations and the margin
- self.scale *= 0.95
-
- def go(self):
- self.clear()
-
- self.current_stitch = 0
-
- if not self.timer:
- self.timer = wx.PyTimer(self.draw_one_frame)
-
- self.timer.Start(self.frame_period)
-
- def on_close(self, event):
- self.stop()
-
- if self.on_close_hook:
- self.on_close_hook()
-
- # If we keep a reference here, wx crashes when the process exits.
- self.canvas = None
-
- self.Destroy()
-
- def stop(self):
- if self.timer:
- self.timer.Stop()
-
- def clear(self):
- self.dc.SetBackground(wx.Brush('white'))
- self.dc.Clear()
- self.last_pos = None
- self.Refresh()
-
- def on_size(self, e):
- # ensure that the whole canvas is visible
- window_width, window_height = self.GetSize()
- client_width, client_height = self.GetClientSize()
-
- decorations_width = window_width - client_width
- decorations_height = window_height - client_height
-
- self.SetSize((self.width * self.scale + decorations_width + self.margin * 2,
- self.height * self.scale + decorations_height + self.margin * 2))
-
- e.Skip()
-
- def on_paint(self, e):
- dc = wx.PaintDC(self.panel)
- dc.Blit(0, 0, self.buffer.GetWidth(), self.buffer.GetHeight(), self.dc, 0, 0)
-
- if self.last_pos:
- dc.DrawLine(self.last_pos[0] - 10, self.last_pos[1], self.last_pos[0] + 10, self.last_pos[1])
- dc.DrawLine(self.last_pos[0], self.last_pos[1] - 10, self.last_pos[0], self.last_pos[1] + 10)
-
- def draw_one_frame(self):
- for i in xrange(self.stitches_per_frame):
- try:
- ((x1, y1), (x2, y2)), color = self.segments[self.current_stitch]
-
- if self.mirror:
- y1 = self.height - y1
- y2 = self.height - y2
-
- x1 = x1 * self.scale + self.margin
- y1 = y1 * self.scale + self.margin
- x2 = x2 * self.scale + self.margin
- y2 = y2 * self.scale + self.margin
-
- self.canvas.SetPen(color)
- self.canvas.DrawLines(((x1, y1), (x2, y2)))
- self.Refresh()
-
- self.current_stitch += 1
- self.last_pos = (x2, y2)
- except IndexError:
- self.timer.Stop()
-
-class SimulateEffect(InkstitchExtension):
- def __init__(self):
- InkstitchExtension.__init__(self)
- self.OptionParser.add_option("-P", "--path",
- action="store", type="string",
- dest="path", default=".",
- help="Directory in which to store output file")
-
- def effect(self):
- if not self.get_elements():
- return
-
- patches = self.elements_to_patches(self.elements)
- stitch_plan = patches_to_stitch_plan(patches)
- app = wx.App()
- frame = EmbroiderySimulator(None, -1, _("Embroidery Simulation"), wx.DefaultPosition, size=(1000, 1000), stitch_plan=stitch_plan)
- app.SetTopWindow(frame)
- frame.Show()
- wx.CallAfter(frame.go)
- app.MainLoop()
-
-
-if __name__ == "__main__":
- effect = SimulateEffect()
- effect.affect()
- sys.exit(0)