Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alternative Black/Gray #3

Merged
merged 9 commits into from
Nov 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
224 changes: 138 additions & 86 deletions MaKe-stitch.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,46 @@
#

import wx
import sys
import pyembroidery

from wx.lib.embeddedimage import PyEmbeddedImage

makestitch_icon = PyEmbeddedImage(
b'iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAAXNSR0IArs4c6QAAAARnQU1B'
b'AACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAASwSURBVGhD1ZlLKLxfGMcf5J5bbNDE'
b'ROR+CVkgkVuSXMJOZGGjJBY2VoqSjYWikJBQLsl9IcREpsYlC5cyKMJC4xaG83+fx/n9/uln'
b'hmHM+/rU5JznnGne73ue5znPOYBJkOHhYQYAzNramnl6elIbPwEBAay5uZnPeovkhGg0Gnpo'
b'tVrNLa88Pz+z9vZ2JpfLabyuro6PvCI5IZ2dnUwmk/He++zv75OYqKgobmHMXDBICicnJzg7'
b'O+O99/Hx8cEFgPX1dSgqKiKbGaqhloQwMzODl5cX+vsROOfi4kKaQuLi4sDW1hbm5ua4RTel'
b'paUgxI/gaBJFeEamUCh4Tzc4x97eXnrB/oe+vj4S8xFarZbmSdK1DAFjycLCAkTPWl1dXSCk'
b'UQpa/Li6ukJhYSEsLS3xGfpZW1sDKysr8WJkdHSUXAI/NTU1bHFxkSmVStbb28syMjL+jtXX'
b'1/NvvE9xcTETUrA4MdLY2EgPiaWIPoaGhpidnR3Nrays5Nb/ubu7o7GTkxPTC7m/v6cfv76+'
b'5paPUalUzNvbm76XmprK5ufnqQLAflVVFc0xuZDa2loWExPDe4Zxfn7OCgoKmBBLzN3dnY2P'
b'j/MRZvqslZycDJGRkdDU1MQtxsHkWQvf20+8O5MLCQoKgt3dXd4zIuhapmRsbIyC1NiIsrPj'
b'xvf4+AiWlpbc8n1E2dnxPNHQ0MB7RoLWxcRg2jT2T4siBEEhAwMDvPd9RBPS2tpq1FURtYzH'
b'oBdKDSgpKeGWV46Pj2FnZwdOT09BKGWgoqKCj+hGVCEzMzOQnp6Oy0J9fPCFhQUSmJKSQpcL'
b'Dw8PkJWVReN6QSFigjVTTk4OW15eZh0dHezw8JDsgiDW09ND7c8g+glxdXUVtra2wNPTE4Rz'
b'CNmE8h6enp7ogPVZRD0hCuU4uZNCoYC8vDyydXd3g7W1tUEiCFoXEcBDE5Yrf8BHwZMhHpK+'
b'giiu1d/fD3K5HGJjY8mtNjY26B4rPz8fjo6OQCaT8Zmfx6RChKMpTE1Nkev4+vpSfNjY2EB8'
b'fDx4eHhAW1sblJeX/81ihmAyIfjWt7e3wcHBAW5ubsDZ2RlCQkL+efsY8NPT0waL+XEhmH0m'
b'Jibo/gnBO6i0tDRaCV2Eh4eTcEMe7UezFvq/ENTUxo3N398fsrOz9YpAVCoVlJWV0cbY0tLC'
b'rfr5kRXBVRAqXHoQbLu4uNBObSibm5sQFhZGbXQ3XEldGF3I3t4elRaYhW5vb+lm3cvLi49+'
b'jebmZqiurgZzc/PXm/d3MKqQyclJyky4CkLpAYmJiXzEOGCyCA4O5r23GEWIUB/R7oxpFUXg'
b'lY+bmxsfNQ3fFjI7OwtXV1ckwM/PD6Kjo/mIafmyEPw/H9ZKeIGAvpuZmUkrIhZfEiKU3KBW'
b'q6mNPhsaGkptMTFIiEajoTSo1WoppaamptIGJwU+LUSpVNLxE10pISGBaiMp8aEQDGKh3KY9'
b'ITAwULRg/gi9Qg4ODuhfYI6OjpCUlESFnlTRKQRjAU9veGYICAjgVunyj5DLy0sYGRmha01c'
b'hd/CGyErKyt05Z+bm0vu9JsgIahlcHCQduaIiAg+9LswE3ZohquAx83fC8B/QI+w8nkB9vAA'
b'AAAASUVORK5CYII=')
# begin wxGlade: dependencies
# end wxGlade

# begin wxGlade: extracode
# end wxGlade

MaKeStitchVersion = "0.2.0"
PMV_SCALE = 2.5
PMV_CURVE = 75


class StitchPanel(wx.Panel):
def __init__(self, *args, **kwds):

Expand All @@ -32,6 +63,7 @@ def __init__(self, *args, **kwds):
self.translate_y = 0
self.buffer = 0.1
self.grid = None
self.text_grid = None
self.clicked_position = None

self.drag_point = None
Expand Down Expand Up @@ -62,9 +94,9 @@ def on_mouse_move(self, event):
if self.drag_point is None:
return
mod_stitch = self.emb_pattern.stitches[self.drag_point]
position = self.get_pattern_point(event.GetPosition())
mod_stitch[0] = position[0]
mod_stitch[1] = position[1]
position = self.scene_location_to_grid_position(event.GetPosition())
mod_stitch[0] = position[0] * PMV_SCALE
mod_stitch[1] = position[1] * PMV_SCALE
self.update_drawing()

def on_mouse_down(self, event):
Expand All @@ -73,7 +105,7 @@ def on_mouse_down(self, event):
return
position = event.GetPosition()
nearest = self.get_nearest_point(position)
if nearest[1] > 25:
if nearest[1] > 100:
event.Skip()
self.drag_point = None
return
Expand All @@ -94,11 +126,11 @@ def on_right_double_click(self, event):
new_stitch = stitch[:]
new_stitch2 = stitch[:]
new_stitch3 = stitch[:]
position = self.get_pattern_point(self.clicked_position)
new_stitch[0] = position[0]
new_stitch[1] = position[1]
new_stitch3[0] = position[0]
new_stitch3[1] = position[1]
position = self.scene_location_to_grid_position(self.clicked_position)
new_stitch[0] = position[0] * PMV_SCALE
new_stitch[1] = position[1] * PMV_SCALE
new_stitch3[0] = position[0] * PMV_SCALE
new_stitch3[1] = position[1] * PMV_SCALE
stitches.insert(self.selected_point + 1, new_stitch)
stitches.insert(self.selected_point + 2, new_stitch2)
stitches.insert(self.selected_point + 3, new_stitch3)
Expand All @@ -110,9 +142,9 @@ def on_left_double_click(self, event):
self.clicked_position = event.GetPosition()
nearest = self.get_nearest_point(self.clicked_position)
if nearest[0] is None: # No nearest node. Must have no nodes.
position = self.get_pattern_point(self.clicked_position)
position = self.scene_location_to_grid_position(self.clicked_position)
stitches = self.emb_pattern.stitches
stitches.append([position[0], position[1], pyembroidery.STITCH])
stitches.append([position[0]*PMV_SCALE, position[1]*PMV_SCALE, pyembroidery.STITCH])
self.selected_point = 0
self.update_affines()
self.update_drawing()
Expand All @@ -123,9 +155,9 @@ def on_left_double_click(self, event):
stitches = self.emb_pattern.stitches
stitch = stitches[self.selected_point]
new_stitch = stitch[:]
position = self.get_pattern_point(self.clicked_position)
new_stitch[0] = position[0]
new_stitch[1] = position[1]
position = self.scene_location_to_grid_position(self.clicked_position)
new_stitch[0] = position[0]*PMV_SCALE
new_stitch[1] = position[1]*PMV_SCALE
stitches.insert(self.selected_point + 1, new_stitch)
self.selected_point += 1
self.update_affines()
Expand Down Expand Up @@ -222,26 +254,38 @@ def update_affine(self, width, height):
max_x = max(extends[2], 100)
max_y = max(extends[3], 35)

embroidery_width = (max_x - min_x) + (width * self.buffer)
embroidery_height = (max_y - min_y) + (height * self.buffer)
embroidery_width = (max_x - min_x) #+ (width * self.buffer)
embroidery_height = (max_y - min_y) #+ (height * self.buffer)
scale_x = float(width) / embroidery_width
scale_y = float(height) / embroidery_height
self.scale = min(scale_x, scale_y)
self.translate_x = -min_x + (width * self.buffer) / 2
self.translate_y = -min_y + (height * self.buffer) / 2
self.scale = min(scale_x, scale_y) * 2
self.translate_x = -min_x + 3
self.translate_y = -(min_y/2)
self.grid = None
self.text_grid = None

def get_pattern_point(self, position):
def scene_location_to_grid_position(self, position):
px = position[0]
py = position[1]
px /= self.scale
py /= self.scale
px -= self.translate_x
py -= self.translate_y
px = round(px / 2.5) * 2.5
py = round(py / 2.5) * 2.5
px -= py * py / PMV_CURVE
px = round(px)
py = round(py)
return px, py

def grid_position_to_scene_location(self, grid_x, grid_y):
x = grid_x
y = grid_y
x += grid_y * grid_y / PMV_CURVE
x += self.translate_x
y += self.translate_y
x *= self.scale
y *= self.scale
return x, y

@staticmethod
def distance_sq(p0, p1):
dx = p0[0] - p1[0]
Expand All @@ -251,18 +295,12 @@ def distance_sq(p0, p1):
return dx + dy

def get_nearest_point(self, position):
scene_x = position[0]
scene_y = position[1]
scene_x /= self.scale
scene_y /= self.scale
scene_x -= self.translate_x
scene_y -= self.translate_y
click_point = (scene_x, scene_y)
best_point = None
best_index = None
best_distance = sys.maxint
best_distance = float('-inf')
for i, stitch in enumerate(self.emb_pattern.stitches):
distance = self.distance_sq(click_point, stitch)
s_x, s_y = self.grid_position_to_scene_location(stitch[0]/PMV_SCALE, stitch[1]/PMV_SCALE)
distance = self.distance_sq(position, (s_x, s_y))
if best_point is None or distance < best_distance or (
distance == best_distance and self.selected_point == i):
best_point = stitch
Expand All @@ -284,47 +322,56 @@ def __do_layout(self):
def perform_draw_grid(self, dc):
if self.grid is None:
self.build_grid()
dc.SetPen(wx.Pen(self.grid[0]))
dc.DrawLineList(self.grid[1])
for g in self.grid:
dc.SetPen(wx.Pen(g[0]))
dc.DrawLineList(g[1])
for t in self.text_grid:
font = wx.Font(10, wx.SWISS, wx.NORMAL, wx.BOLD)
dc.SetFont(font)
w, h = dc.GetTextExtent(t[0])
if t[3] == 0:
dc.DrawText(t[0], wx.Point(t[1] - w, t[2]-h/2))
elif t[3] == 1:
dc.DrawText(t[0], wx.Point(t[1] - w / 2, t[2]-h))
else:
dc.DrawText(t[0], wx.Point(t[1] - w / 2, t[2]))

def build_grid(self):
scale = self.scale
tran_x = self.translate_x
tran_y = self.translate_y
lines = []
text = []
black_lines = []
grey_lines = []
magenta_lines = []
black = False
for j in range(-14, 14 + 1):
x0 = 0 * 2.5
y0 = j * 2.5
x1 = 100 * 2.5
y1 = j * 2.5

x0 += tran_x
y0 += tran_y
x1 += tran_x
y1 += tran_y

x0 *= scale
y0 *= scale
x1 *= scale
y1 *= scale
lines.append([x0, y0, x1, y1])
for k in range(0, 100):
x0 = k * 2.5
y0 = -14 * 2.5
x1 = k * 2.5
y1 = +14 * 2.5

x0 += tran_x
y0 += tran_y
x1 += tran_x
y1 += tran_y

x0 *= scale
y0 *= scale
x1 *= scale
y1 *= scale
lines.append([x0, y0, x1, y1])
self.grid = ((0xFF, 0, 0), lines)
black = not black
x0, y0 = self.grid_position_to_scene_location(0, j)
x1, y1 = self.grid_position_to_scene_location(100,j)
text.append((str(j), x0, y0, 0))
if j == 0:
magenta_lines.append([x0, y0, x1, y1])
else:
if black:
black_lines.append([x0, y0, x1, y1])
else:
grey_lines.append([x0, y0, x1, y1])
black = False
for j in range(-14, 14):
for k in range(0, 100):
black = not black
x0, y0 = self.grid_position_to_scene_location(k, j)
x1, y1 = self.grid_position_to_scene_location(k, j+1)
if k % 5 == 0 and j == -14:
text.append((str(k), x0, y0, 1))
if k % 5 == 0 and j == 13:
text.append((str(k), x1, y1, -1))
if black:
black_lines.append([x0, y0, x1, y1])
else:
grey_lines.append([x0, y0, x1, y1])
self.grid = [((0xFF, 0, 0xFF), magenta_lines),
((0x80, 0x80, 0x80), grey_lines),
((0, 0, 0), black_lines)]
self.text_grid = text

def perform_draw(self, dc):
dc.SetBackground(wx.Brush("White"))
Expand All @@ -333,22 +380,17 @@ def perform_draw(self, dc):
if self.emb_pattern is None:
return

scale = self.scale
tran_x = self.translate_x
tran_y = self.translate_y
draw_data = []
for color in self.emb_pattern.get_as_colorblocks():
lines = []
last_x = None
last_y = None
for i, stitch in enumerate(color[0]):
current_x = stitch[0] + tran_x
current_y = stitch[1] + tran_y
current_x, current_y = self.grid_position_to_scene_location(stitch[0]/PMV_SCALE, stitch[1]/PMV_SCALE)
if last_x is not None:
lines.append([last_x * scale, last_y * scale, current_x * scale, current_y * scale])
lines.append([last_x, last_y, current_x, current_y])
last_x = current_x
last_y = current_y
thread = color[1]
draw_data.append(((0, 0, 0), lines))

current_stitch = self.current_stitch
Expand Down Expand Up @@ -380,17 +422,24 @@ def perform_draw(self, dc):
dc.SetBrush(wx.Brush("Blue"))
dc.GetPen().SetWidth(1)
for stitch in self.emb_pattern.stitches:
dc.DrawCircle((tran_x + stitch[0]) * scale, (tran_y + stitch[1]) * scale, scale * 3)
current_x, current_y = self.grid_position_to_scene_location(stitch[0]/PMV_SCALE, stitch[1]/PMV_SCALE)
dc.DrawCircle(current_x, current_y, 10)

if self.selected_point is not None:
font = wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD)
dc.SetFont(font)
mod_stitch = self.emb_pattern.stitches[self.selected_point]
name = self.name_dict[mod_stitch[2]] + " " + str(self.selected_point)
dc.DrawText(name, 25, 25)
name = "%s %d (%g, %g)" % (self.name_dict[mod_stitch[2]],
int(self.selected_point),
float(mod_stitch[0]) / PMV_SCALE,
float(mod_stitch[1]) / PMV_SCALE)
dc.DrawText(name, 0, 0)
dc.SetBrush(wx.Brush("Green"))
dc.DrawCircle((tran_x + mod_stitch[0]) * scale, (tran_y + mod_stitch[1]) * scale, scale * 3)
m_x, m_y = self.grid_position_to_scene_location(mod_stitch[0]/PMV_SCALE, mod_stitch[1]/PMV_SCALE)
dc.DrawCircle(m_x, m_y, 10)

def on_paint(self, event):
dc = wx.BufferedPaintDC(self, self._Buffer)
wx.BufferedPaintDC(self, self._Buffer)

def on_size(self, event):
# The Buffer init is done here, to make sure the buffer is always
Expand Down Expand Up @@ -458,7 +507,10 @@ def __init__(self, *args, **kwds):

def __set_properties(self):
# begin wxGlade: Stitcher.__set_properties
self.SetTitle("MK Stitch")
self.SetTitle("MK Stitch v%s" % MaKeStitchVersion)
_icon = wx.NullIcon
_icon.CopyFromBitmap(makestitch_icon.GetBitmap())
self.SetIcon(_icon)
# end wxGlade

def __do_layout(self):
Expand All @@ -473,7 +525,7 @@ def on_menu_import(self, event):
files = ""
for format in pyembroidery.supported_formats():
try:
if format["reader"] is not None and format["category"] is "stitch":
if format["reader"] is not None and format["category"] == "stitch":
files += "*." + format["extension"] + ";"
except KeyError:
pass
Expand All @@ -489,7 +541,7 @@ def on_menu_export(self, event):
files = ""
for format in pyembroidery.supported_formats():
try:
if format["writer"] is not None and format["category"] is "stitch":
if format["writer"] is not None and format["category"] == "stitch":
files += format["description"] + "(*." + format["extension"] + ")|*." + format[
"extension"] + "|"
except KeyError:
Expand Down
Loading