pull/2/merge
Lex Neva 2016-11-06 19:30:49 -05:00
rodzic 6cdf990c76
commit 50493add9e
5 zmienionych plików z 61 dodań i 48 usunięć

Wyświetl plik

@ -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):

Wyświetl plik

@ -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",

Wyświetl plik

@ -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()

Wyświetl plik

@ -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()

Wyświetl plik

@ -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 = []