Sat, 07 Nov 2015 20:50:55 +0100
finished refactoring
svg2gcode/svg2gcode.py | file | annotate | diff | comparison | revisions |
--- a/svg2gcode/svg2gcode.py Sat Nov 07 20:31:30 2015 +0100 +++ b/svg2gcode/svg2gcode.py Sat Nov 07 20:50:55 2015 +0100 @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -import svg, sys +import svg, sys, math from gcode import Gcode from optparse import OptionParser from tinycss import CSS21Parser @@ -65,16 +65,23 @@ return rect.intersection(lines) def parse_style(stylestr): + """ + Parse the given string containing CSS2.1 syntax + Returns a dict with the keys/values + """ if stylestr.strip() == '': return None parser = CSS21Parser() style = parser.parse_style_attr(stylestr) - kv = {} + data = {} for obj in style[0]: - kv[obj.name] = obj.value[0].value - return kv + data[obj.name] = obj.value[0].value + return data class Image(object): + """ + SVG Image handler class + """ def __init__(self, filename, options, gcoder): self.gcoder = gcoder self.options = options @@ -87,9 +94,13 @@ self._generate_infill() def _check_dimensions(self): + """ + Output image dimensions/scaling to console and gcode + """ msg = "Original dimension: %.2f x %.2f" % (self.width, self.height) print msg self.gcoder.comment(msg) + self.gcoder.comment("Scale: %.2f" % (self.options.scale)) width = self.width * self.gcoder.mm_pixel * self.options.scale height = self.height * self.gcoder.mm_pixel * self.options.scale msg = "Print dimension: %.2fmm x %.2fmm" % (width, height) @@ -97,6 +108,9 @@ self.gcoder.comment(msg) def _generate_infill(self): + """ + Generates infill pattern image for later use + """ b1x, b1y = self.bb1.coord() b2x, b2y = self.bb2.coord() page = box(b1x, b1y, b2x, b2y) @@ -105,6 +119,10 @@ self.infill = hatchbox(page, 0, 2) def normalize(self, coord): + """ + Normalize X / Y Axis of coordinates + At the moment only Y gets flipped to match Reprap coordinate system (0,0 is bottom left instead top left on SVG) + """ c_x = coord[0] c_y = coord[1] # flip y @@ -165,12 +183,23 @@ lines = poly.intersection(image.infill) if lines: # THE INFILL + prev_end = None for line in lines: - # TODO: swap start/end to nearest move! - start = image.normalize((line.coords[0][0], line.coords[0][1])) - end = image.normalize((line.coords[1][0], line.coords[1][1])) - gcoder.move(start[0], start[1]) - gcoder.engrave(end[0], end[1]) + coords = [ + image.normalize((line.coords[0][0], line.coords[0][1])), + image.normalize((line.coords[1][0], line.coords[1][1])) + ] + if prev_end: + # calculate distances to previous end, swap if current end is nearest + dist = [ + abs(math.hypot(coords[0][0] - prev_end[0], coords[0][1] - prev_end[1])), + abs(math.hypot(coords[1][0] - prev_end[0], coords[1][1] - prev_end[1])) + ] + if dist[0] > dist[1]: + coords = list(reversed(coords)) + prev_end = coords[1] + gcoder.move(coords[0][0], coords[0][1]) + gcoder.engrave(coords[1][0], coords[1][1]) def init_options(): parser = OptionParser()