kopia lustrzana https://github.com/inkstitch/inkstitch
pep8
rodzic
6cdf990c76
commit
50493add9e
1
PyEmb.py
1
PyEmb.py
|
@ -66,6 +66,7 @@ class Point:
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
return 2
|
return 2
|
||||||
|
|
||||||
|
|
||||||
class Stitch(Point):
|
class Stitch(Point):
|
||||||
|
|
||||||
def __init__(self, x, y, color=None, jump_stitch=False):
|
def __init__(self, x, y, color=None, jump_stitch=False):
|
||||||
|
|
76
embroider.py
76
embroider.py
|
@ -48,7 +48,9 @@ SVG_PATH_TAG = inkex.addNS('path', 'svg')
|
||||||
SVG_DEFS_TAG = inkex.addNS('defs', 'svg')
|
SVG_DEFS_TAG = inkex.addNS('defs', 'svg')
|
||||||
SVG_GROUP_TAG = inkex.addNS('g', 'svg')
|
SVG_GROUP_TAG = inkex.addNS('g', 'svg')
|
||||||
|
|
||||||
|
|
||||||
class EmbroideryElement(object):
|
class EmbroideryElement(object):
|
||||||
|
|
||||||
def __init__(self, node, options):
|
def __init__(self, node, options):
|
||||||
self.node = node
|
self.node = node
|
||||||
self.options = options
|
self.options = options
|
||||||
|
@ -60,28 +62,27 @@ class EmbroideryElement(object):
|
||||||
value = getattr(self.options, param, None)
|
value = getattr(self.options, param, None)
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def get_boolean_param(self, param, default=None):
|
def get_boolean_param(self, param, default=None):
|
||||||
value = self.get_param(param, default)
|
value = self.get_param(param, default)
|
||||||
|
|
||||||
if isinstance(value, bool):
|
if isinstance(value, bool):
|
||||||
return value
|
return value
|
||||||
else:
|
else:
|
||||||
return value and (value.lower() in ('yes', 'y', 'true', 't', '1'))
|
return value and (value.lower() in ('yes', 'y', 'true', 't', '1'))
|
||||||
|
|
||||||
def get_float_param(self, param, default=None):
|
def get_float_param(self, param, default=None):
|
||||||
try:
|
try:
|
||||||
value = float(self.get_param(param, default))
|
value = float(self.get_param(param, default))
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
return default
|
return default
|
||||||
|
|
||||||
if param.endswith('_mm'):
|
if param.endswith('_mm'):
|
||||||
#print >> dbg, "get_float_param", param, value, "*", self.options.pixels_per_mm
|
# print >> dbg, "get_float_param", param, value, "*", self.options.pixels_per_mm
|
||||||
value = value * self.options.pixels_per_mm
|
value = value * self.options.pixels_per_mm
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
def get_int_param(self, param, default=None):
|
def get_int_param(self, param, default=None):
|
||||||
try:
|
try:
|
||||||
value = int(self.get_param(param, default))
|
value = int(self.get_param(param, default))
|
||||||
|
@ -92,7 +93,7 @@ class EmbroideryElement(object):
|
||||||
value = int(value * self.options.pixels_per_mm)
|
value = int(value * self.options.pixels_per_mm)
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def get_style(self, style_name):
|
def get_style(self, style_name):
|
||||||
style = simplestyle.parseStyle(self.node.get("style"))
|
style = simplestyle.parseStyle(self.node.get("style"))
|
||||||
if (style_name not in style):
|
if (style_name not in style):
|
||||||
|
@ -101,15 +102,15 @@ class EmbroideryElement(object):
|
||||||
if value == 'none':
|
if value == 'none':
|
||||||
return None
|
return None
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def has_style(self, style_name):
|
def has_style(self, style_name):
|
||||||
style = simplestyle.parseStyle(self.node.get("style"))
|
style = simplestyle.parseStyle(self.node.get("style"))
|
||||||
return style_name in style
|
return style_name in style
|
||||||
|
|
||||||
def parse_path(self):
|
def parse_path(self):
|
||||||
# A CSP is a "cubic superpath".
|
# A CSP is a "cubic superpath".
|
||||||
#
|
#
|
||||||
# A "path" is a sequence of strung-together bezier curves.
|
# A "path" is a sequence of strung-together bezier curves.
|
||||||
#
|
#
|
||||||
# A "superpath" is a collection of paths that are all in one object.
|
# A "superpath" is a collection of paths that are all in one object.
|
||||||
#
|
#
|
||||||
|
@ -135,35 +136,35 @@ class EmbroideryElement(object):
|
||||||
# Tuples all the way down. Hasn't anyone heard of using classes?
|
# Tuples all the way down. Hasn't anyone heard of using classes?
|
||||||
|
|
||||||
path = cubicsuperpath.parsePath(self.node.get("d"))
|
path = cubicsuperpath.parsePath(self.node.get("d"))
|
||||||
|
|
||||||
# print >> sys.stderr, pformat(path)
|
# print >> sys.stderr, pformat(path)
|
||||||
|
|
||||||
# start with the identity transform
|
# start with the identity transform
|
||||||
transform = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
|
transform = [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0]]
|
||||||
|
|
||||||
# combine this node's transform with all parent groups' transforms
|
# combine this node's transform with all parent groups' transforms
|
||||||
transform = simpletransform.composeParents(self.node, transform)
|
transform = simpletransform.composeParents(self.node, transform)
|
||||||
|
|
||||||
# apply the combined transform to this node's path
|
# apply the combined transform to this node's path
|
||||||
simpletransform.applyTransformToPath(transform, path)
|
simpletransform.applyTransformToPath(transform, path)
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
|
||||||
def flatten(self, path):
|
def flatten(self, path):
|
||||||
"""approximate a path containing beziers with a series of points"""
|
"""approximate a path containing beziers with a series of points"""
|
||||||
|
|
||||||
path = deepcopy(path)
|
path = deepcopy(path)
|
||||||
|
|
||||||
cspsubdiv(path, self.options.flat)
|
cspsubdiv(path, self.options.flat)
|
||||||
|
|
||||||
flattened = []
|
flattened = []
|
||||||
|
|
||||||
for comp in path:
|
for comp in path:
|
||||||
vertices = []
|
vertices = []
|
||||||
for ctl in comp:
|
for ctl in comp:
|
||||||
vertices.append((ctl[1][0], ctl[1][1]))
|
vertices.append((ctl[1][0], ctl[1][1]))
|
||||||
flattened.append(vertices)
|
flattened.append(vertices)
|
||||||
|
|
||||||
return flattened
|
return flattened
|
||||||
|
|
||||||
def to_patches(self, last_patch):
|
def to_patches(self, last_patch):
|
||||||
|
@ -175,6 +176,7 @@ class EmbroideryElement(object):
|
||||||
|
|
||||||
|
|
||||||
class Fill(EmbroideryElement):
|
class Fill(EmbroideryElement):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(Fill, self).__init__(*args, **kwargs)
|
super(Fill, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@ -231,7 +233,7 @@ class Fill(EmbroideryElement):
|
||||||
# biggest path.
|
# biggest path.
|
||||||
# TODO: actually figure out which things are holes and which are shells
|
# TODO: actually figure out which things are holes and which are shells
|
||||||
poly_ary.sort(key=lambda point_list: shgeo.Polygon(point_list).area, reverse=True)
|
poly_ary.sort(key=lambda point_list: shgeo.Polygon(point_list).area, reverse=True)
|
||||||
|
|
||||||
polygon = shgeo.MultiPolygon([(poly_ary[0], poly_ary[1:])])
|
polygon = shgeo.MultiPolygon([(poly_ary[0], poly_ary[1:])])
|
||||||
# print >> sys.stderr, "polygon valid:", polygon.is_valid
|
# print >> sys.stderr, "polygon valid:", polygon.is_valid
|
||||||
return polygon
|
return polygon
|
||||||
|
@ -463,6 +465,7 @@ class Fill(EmbroideryElement):
|
||||||
|
|
||||||
|
|
||||||
class AutoFill(Fill):
|
class AutoFill(Fill):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(AutoFill, self).__init__(*args, **kwargs)
|
super(AutoFill, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@ -536,9 +539,9 @@ class AutoFill(Fill):
|
||||||
stitch = self.running_stitch_length * direction
|
stitch = self.running_stitch_length * direction
|
||||||
|
|
||||||
for i in xrange(stitches):
|
for i in xrange(stitches):
|
||||||
pos = (pos + stitch) % self.outline_length
|
pos = (pos + stitch) % self.outline_length
|
||||||
|
|
||||||
patch.add_stitch(PyEmb.Point(*self.outline.interpolate(pos).coords[0]))
|
patch.add_stitch(PyEmb.Point(*self.outline.interpolate(pos).coords[0]))
|
||||||
|
|
||||||
return patch
|
return patch
|
||||||
|
|
||||||
|
@ -551,7 +554,7 @@ class AutoFill(Fill):
|
||||||
|
|
||||||
def find_nearest_section(self, sections, point):
|
def find_nearest_section(self, sections, point):
|
||||||
sections_with_nearest_corner = [(i, self.nearest_corner(section, point))
|
sections_with_nearest_corner = [(i, self.nearest_corner(section, point))
|
||||||
for i, section in enumerate(sections)]
|
for i, section in enumerate(sections)]
|
||||||
return min(sections_with_nearest_corner,
|
return min(sections_with_nearest_corner,
|
||||||
key=lambda(section, corner): abs(self.perimeter_distance(point, corner)))
|
key=lambda(section, corner): abs(self.perimeter_distance(point, corner)))
|
||||||
|
|
||||||
|
@ -598,7 +601,9 @@ class AutoFill(Fill):
|
||||||
|
|
||||||
return patches
|
return patches
|
||||||
|
|
||||||
|
|
||||||
class Stroke(EmbroideryElement):
|
class Stroke(EmbroideryElement):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def color(self):
|
def color(self):
|
||||||
return self.get_style("stroke")
|
return self.get_style("stroke")
|
||||||
|
@ -659,7 +664,7 @@ class Stroke(EmbroideryElement):
|
||||||
|
|
||||||
# vector pointing along segment
|
# vector pointing along segment
|
||||||
along = (p1 - p0).unit()
|
along = (p1 - p0).unit()
|
||||||
|
|
||||||
# vector pointing to edge of stroke width
|
# vector pointing to edge of stroke width
|
||||||
perp = along.rotate_left().mul(stroke_width * 0.5)
|
perp = along.rotate_left().mul(stroke_width * 0.5)
|
||||||
|
|
||||||
|
@ -693,7 +698,7 @@ class Stroke(EmbroideryElement):
|
||||||
if self.is_running_stitch():
|
if self.is_running_stitch():
|
||||||
patch = self.stroke_points(path, self.running_stitch_length, stroke_width=0.0)
|
patch = self.stroke_points(path, self.running_stitch_length, stroke_width=0.0)
|
||||||
else:
|
else:
|
||||||
patch = self.stroke_points(path, self.zigzag_spacing/2.0, stroke_width=self.width)
|
patch = self.stroke_points(path, self.zigzag_spacing / 2.0, stroke_width=self.width)
|
||||||
|
|
||||||
patches.append(patch)
|
patches.append(patch)
|
||||||
|
|
||||||
|
@ -701,6 +706,7 @@ class Stroke(EmbroideryElement):
|
||||||
|
|
||||||
|
|
||||||
class SatinColumn(EmbroideryElement):
|
class SatinColumn(EmbroideryElement):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(SatinColumn, self).__init__(*args, **kwargs)
|
super(SatinColumn, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
@ -842,7 +848,7 @@ class SatinColumn(EmbroideryElement):
|
||||||
# we're currently on. <start_pos> is where along that line
|
# we're currently on. <start_pos> is where along that line
|
||||||
# segment we are. Return a new position and index.
|
# segment we are. Return a new position and index.
|
||||||
|
|
||||||
#print >> dbg, "walk", start_pos, start_index, distance
|
# print >> dbg, "walk", start_pos, start_index, distance
|
||||||
|
|
||||||
pos = start_pos
|
pos = start_pos
|
||||||
index = start_index
|
index = start_index
|
||||||
|
@ -939,12 +945,12 @@ class SatinColumn(EmbroideryElement):
|
||||||
|
|
||||||
end1 = remainder_path1[-1]
|
end1 = remainder_path1[-1]
|
||||||
end2 = remainder_path2[-1]
|
end2 = remainder_path2[-1]
|
||||||
|
|
||||||
if (end1 - pos1).length() > 0.3 * spacing:
|
if (end1 - pos1).length() > 0.3 * spacing:
|
||||||
add_pair(pos1, pos2)
|
add_pair(pos1, pos2)
|
||||||
|
|
||||||
add_pair(end1, end2)
|
add_pair(end1, end2)
|
||||||
|
|
||||||
return points
|
return points
|
||||||
|
|
||||||
def do_contour_underlay(self):
|
def do_contour_underlay(self):
|
||||||
|
@ -1039,6 +1045,7 @@ class SatinColumn(EmbroideryElement):
|
||||||
|
|
||||||
|
|
||||||
class Patch:
|
class Patch:
|
||||||
|
|
||||||
def __init__(self, color=None, stitches=None):
|
def __init__(self, color=None, stitches=None):
|
||||||
self.color = color
|
self.color = color
|
||||||
self.stitches = stitches or []
|
self.stitches = stitches or []
|
||||||
|
@ -1123,6 +1130,7 @@ def emit_inkscape(parent, stitches):
|
||||||
|
|
||||||
|
|
||||||
class Embroider(inkex.Effect):
|
class Embroider(inkex.Effect):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
inkex.Effect.__init__(self)
|
inkex.Effect.__init__(self)
|
||||||
self.OptionParser.add_option("-r", "--row_spacing_mm",
|
self.OptionParser.add_option("-r", "--row_spacing_mm",
|
||||||
|
|
|
@ -12,6 +12,7 @@ import inkex
|
||||||
|
|
||||||
|
|
||||||
class EmbroiderParams(inkex.Effect):
|
class EmbroiderParams(inkex.Effect):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
inkex.Effect.__init__(self)
|
inkex.Effect.__init__(self)
|
||||||
|
|
||||||
|
@ -36,12 +37,12 @@ class EmbroiderParams(inkex.Effect):
|
||||||
"fill_underlay_angle",
|
"fill_underlay_angle",
|
||||||
"fill_underlay_row_spacing_mm",
|
"fill_underlay_row_spacing_mm",
|
||||||
"fill_underlay_max_stitch_length_mm",
|
"fill_underlay_max_stitch_length_mm",
|
||||||
]
|
]
|
||||||
|
|
||||||
for param in self.params:
|
for param in self.params:
|
||||||
self.OptionParser.add_option("--%s" % param, default="")
|
self.OptionParser.add_option("--%s" % param, default="")
|
||||||
|
|
||||||
def effect(self):
|
def effect(self):
|
||||||
for node in self.selected.itervalues():
|
for node in self.selected.itervalues():
|
||||||
for param in self.params:
|
for param in self.params:
|
||||||
value = getattr(self.options, param).strip()
|
value = getattr(self.options, param).strip()
|
||||||
|
|
|
@ -11,22 +11,24 @@ import simplestyle
|
||||||
|
|
||||||
PIXELS_PER_MM = 10
|
PIXELS_PER_MM = 10
|
||||||
|
|
||||||
|
|
||||||
class EmbroiderParams(inkex.Effect):
|
class EmbroiderParams(inkex.Effect):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
inkex.Effect.__init__(self)
|
inkex.Effect.__init__(self)
|
||||||
|
|
||||||
self.mapping = { "zigzag_spacing": "zigzag_spacing_mm",
|
self.mapping = {"zigzag_spacing": "zigzag_spacing_mm",
|
||||||
"row_spacing": "row_spacing_mm",
|
"row_spacing": "row_spacing_mm",
|
||||||
"pull_compensation": "pull_compensation_mm",
|
"pull_compensation": "pull_compensation_mm",
|
||||||
"max_stitch_length": "max_stitch_length_mm",
|
"max_stitch_length": "max_stitch_length_mm",
|
||||||
"satin_underlay": "contour_underlay",
|
"satin_underlay": "contour_underlay",
|
||||||
"satin_underlay_inset": "contour_underlay_inset_mm",
|
"satin_underlay_inset": "contour_underlay_inset_mm",
|
||||||
"satin_zigzag_underlay_spacing": "zigzag_underlay_spacing_mm",
|
"satin_zigzag_underlay_spacing": "zigzag_underlay_spacing_mm",
|
||||||
"satin_center_walk": "center_walk_underlay",
|
"satin_center_walk": "center_walk_underlay",
|
||||||
"stitch_length": "running_stitch_length_mm",
|
"stitch_length": "running_stitch_length_mm",
|
||||||
}
|
}
|
||||||
|
|
||||||
def effect(self):
|
def effect(self):
|
||||||
for node in self.document.getroot().iter():
|
for node in self.document.getroot().iter():
|
||||||
for old, new in self.mapping.iteritems():
|
for old, new in self.mapping.iteritems():
|
||||||
old = "embroider_%s" % old
|
old = "embroider_%s" % old
|
||||||
|
@ -46,7 +48,7 @@ class EmbroiderParams(inkex.Effect):
|
||||||
|
|
||||||
if style.get('fill', 'none') != 'none' and \
|
if style.get('fill', 'none') != 'none' and \
|
||||||
'embroider_auto_fill' not in node.attrib:
|
'embroider_auto_fill' not in node.attrib:
|
||||||
node.set('embroider_auto_fill', 'no')
|
node.set('embroider_auto_fill', 'no')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
e = EmbroiderParams()
|
e = EmbroiderParams()
|
||||||
|
|
|
@ -10,6 +10,7 @@ import inkex
|
||||||
|
|
||||||
|
|
||||||
class Reorder(inkex.Effect):
|
class Reorder(inkex.Effect):
|
||||||
|
|
||||||
def get_selected_in_order(self):
|
def get_selected_in_order(self):
|
||||||
selected = []
|
selected = []
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue