kopia lustrzana https://github.com/Reenforcements/PES-Embroidery
253 wiersze
7.1 KiB
Python
253 wiersze
7.1 KiB
Python
from struct import pack
|
|
from svgpathtools import Line
|
|
import math
|
|
|
|
def encodeU8(num):
|
|
return pack("<B", num)
|
|
|
|
def encodeU16(num):
|
|
return pack("<H", num)
|
|
|
|
def encodeU32(num):
|
|
return pack("<I", num)
|
|
|
|
'''
|
|
The EmbroideryDesign class is used to build
|
|
the stitches that will be exported. To actually
|
|
export them, the object is converted to a PES
|
|
object.
|
|
'''
|
|
class EmbroideryDesign:
|
|
|
|
def __init__(self):
|
|
None
|
|
|
|
'''
|
|
The PES object and all the objects that follow it
|
|
are for easy encoding to the PES format.
|
|
'''
|
|
class PES:
|
|
colors = [('Prussian Blue', 26, 10, 148),
|
|
('Blue', 15, 117, 255),
|
|
('Teal Green', 0, 147, 76),
|
|
('Corn Flower Blue', 186, 189, 254),
|
|
('Red', 236, 0, 0),
|
|
('Reddish Brown', 228, 153, 90),
|
|
('Magenta', 204, 72, 171),
|
|
('Light Lilac', 253, 196, 250),
|
|
('Lilac', 221, 132, 205),
|
|
('Mint Green', 107, 211, 138),
|
|
('Deep Gold', 228, 169, 69),
|
|
('Orange', 255, 189, 66),
|
|
('Yellow', 255, 230, 0),
|
|
('Lime Green', 108, 217, 0),
|
|
('Brass', 193, 169, 65),
|
|
('Silver', 181, 173, 151),
|
|
('Russet Brown', 186, 156, 95),
|
|
('Cream Brown', 250, 245, 158),
|
|
('Pewter', 128, 128, 128),
|
|
('Black', 0, 0, 0),
|
|
('Ultramarine', 0, 28, 223),
|
|
('Royal Purple', 223, 0, 184),
|
|
('Dark Gray', 98, 98, 98),
|
|
('Dark Brown', 105, 38, 13),
|
|
('Deep Rose', 255, 0, 96),
|
|
('Light Brown', 191, 130, 0),
|
|
('Salmon Pink', 243, 145, 120),
|
|
('Vermilion', 255, 104, 5),
|
|
('White', 240, 240, 240),
|
|
('Violet', 200, 50, 205),
|
|
('Seacrest', 176, 191, 155),
|
|
('Sky Blue', 101, 191, 235),
|
|
('Pumpkin', 255, 186, 4),
|
|
('Cream Yellow', 255, 240, 108),
|
|
('Khaki', 254, 202, 21),
|
|
('Clay Brown', 243, 129, 1),
|
|
('Leaf Green', 55, 169, 35),
|
|
('Peacock Blue', 35, 70, 95),
|
|
('Gray', 166, 166, 149),
|
|
('Warm Gray', 206, 191, 166),
|
|
('Dark Olive', 150, 170, 2),
|
|
('Linen', 255, 227, 198),
|
|
('Pink', 255, 153, 215),
|
|
('Deep Green', 0, 112, 4),
|
|
('Lavender', 237, 204, 251),
|
|
('Wisteria Violet', 192, 137, 216),
|
|
('Beige', 231, 217, 180),
|
|
('Carmine', 233, 14, 134),
|
|
('Amber Red', 207, 104, 41),
|
|
('Olive Green', 64, 134, 21),
|
|
('Dark Fuchsia', 219, 23, 151),
|
|
('Tangerine', 255, 167, 4),
|
|
('Light Blue', 185, 255, 255),
|
|
('Emerald Green', 34, 137, 39),
|
|
('Purple', 182, 18, 205),
|
|
('Moss Green', 0, 170, 0),
|
|
('Flesh Pink', 254, 169, 220),
|
|
('Harvest Gold', 254, 213, 16),
|
|
('Electric Blue', 0, 151, 223),
|
|
('Lemon Yellow', 255, 255, 132),
|
|
('Fresh Green', 207, 231, 116),
|
|
('Applique Material', 255, 200, 100),
|
|
('Applique Position', 255, 200, 200),
|
|
('Applique', 255, 200, 200)]
|
|
|
|
@classmethod
|
|
def getClosestColor(cls, color):
|
|
# Black by default
|
|
closest = 19
|
|
for cur in cls.colors:
|
|
red = math.pow( cur[1] - color[0], 2)
|
|
green = math.pow(cur[1] - color[0], 2)
|
|
blue = math.pow(cur[1] - color[0], 2)
|
|
dist = math.sqrt( red + green + blue )
|
|
|
|
def __init__(self, stitchCommands=[]):
|
|
self.magic = "#PES"
|
|
self.version = "0001"
|
|
self.sections = []
|
|
self.stitchCommands = []
|
|
|
|
def encode(self):
|
|
b = bytearray()
|
|
b.extend(self.magic)
|
|
b.extend(self.version)
|
|
# Save a spot for the PEC offset that we will
|
|
# change later to the actual offset
|
|
b.extend("0000")
|
|
|
|
# Old code for the PES section
|
|
# that I decided to try excluding.
|
|
# # Assume 100mm x 100mm hoop size
|
|
# b.extend(encodeU16(0))
|
|
# # Use existing design area (don't know what this does.)
|
|
# b.extend(encodeU16(0))
|
|
# # Segment block count
|
|
# b.extend(encodeU16( len(self.sections) ))
|
|
#
|
|
# if len(self.sections) is 0:
|
|
# # No sections follow
|
|
# b.extend("0000")
|
|
# b.extend("0000")
|
|
# else:
|
|
# # Write sections
|
|
# for section in self.sections:
|
|
# section.encode(b)
|
|
|
|
return b
|
|
|
|
class PEC:
|
|
def __init__(self, stitchCommands=[]):
|
|
self.label = "default"
|
|
self.numberOfColors = 1
|
|
self.stitchCommands = stitchCommands
|
|
|
|
|
|
def encode(self, b):
|
|
# The label is always 19 bytes
|
|
# "LA:" + name + spaces to make it 19 bytes total + carriage return
|
|
b.extend("LA:" + self.label[:16].ljust(16))
|
|
b.extend("\r")
|
|
# Lots of values that aren't understood but probably have to be there.
|
|
b.extend([0x20] * 11)
|
|
|
|
b.extend(0xFF)
|
|
|
|
b.extend(0x00)
|
|
b.extend(0xFF)
|
|
|
|
# Thumbnail width and height
|
|
b.extend(6)
|
|
b.extend(38)
|
|
|
|
b.extend([0x20, 0x20, 0x20, 0x20, 0x64, 0x20, 0x00, 0x20, 0x00, 0x20, 0x20, 0x20])
|
|
|
|
# Number of colors - 1
|
|
b.extend((self.numberOfColors - 1) & 0xFF)
|
|
#TEMP, assign color palette indices
|
|
for i in self.numberOfColors:
|
|
b.extend(i & 0xFF)
|
|
# Palette section padding?
|
|
b.extend([0x20] * (462 - self.numberOfColors))
|
|
|
|
# Second section of PEC header
|
|
|
|
b.extend([0x00, 0x00])
|
|
|
|
# Offset to image thumbnail relative to the beginning of the second section
|
|
# Set to zero for now because we don't know how many stitches we have yet.
|
|
b.extend([0x00, 0x00])
|
|
|
|
b.extend([0x31, 0x00])
|
|
b.extend([0xF0, 0xFF])
|
|
|
|
# Width and height
|
|
# TEMP values
|
|
b.extend([0x0A, 0x0A])
|
|
b.extend([0x0A, 0x0A])
|
|
|
|
b.extend([0x01, 0xE0])
|
|
b.extend([0x01, 0xB0])
|
|
|
|
b.extend([0x00] * 4)
|
|
|
|
for stitch in self.stitchCommands:
|
|
stitch.encode(b)
|
|
|
|
# End of stitch list
|
|
b.extend(0xFF)
|
|
|
|
|
|
|
|
|
|
|
|
class CEmbOne:
|
|
def __init__(self):
|
|
None
|
|
|
|
def encode(self, b):
|
|
b.extend(encodeU16(7))
|
|
b.extend("CEmbOne")
|
|
b.extend()
|
|
|
|
|
|
class BlockGeometry:
|
|
def __init__(self):
|
|
None
|
|
def encode(self, b):
|
|
None
|
|
|
|
|
|
class CSewSeg:
|
|
def __init__(self):
|
|
None
|
|
|
|
class Stitch:
|
|
TYPE_ERROR = 0
|
|
TYPE_LONG = 0x8000
|
|
TYPE_JUMP = 0x9000
|
|
TYPE_TRIM = 0xA000
|
|
TYPE_COLOR_CHANGE = 0xFEB0
|
|
|
|
# Initialize a new stitch from the previous location
|
|
# to the new location.
|
|
def __init__(self, line):
|
|
assert(type(line) is Line)
|
|
|
|
self.line = line
|
|
|
|
self.type = Stitch.TYPE_LONG
|
|
|
|
self.previous = line.start
|
|
self.new = line.end
|
|
|
|
def encode(self, b):
|
|
None
|
|
|
|
def length(self):
|
|
return self.line.length()
|
|
|
|
# Flips the start and end points of a stitch
|
|
def reverse(self):
|
|
self.line = Line(start=self.line.end, end=self.line.start)
|