# HG changeset patch # User mbayer # Date 1446899843 -3600 # Node ID 234ad2069fddd1368985f5c13199a08a419b800d # Parent a519e3ac38490ea8b7c17f0f4d330afad376873c initial untested svg to gcode script diff -r a519e3ac3849 -r 234ad2069fdd svg2gcode/autobot.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svg2gcode/autobot.svg Sat Nov 07 13:37:23 2015 +0100 @@ -0,0 +1,6 @@ + + + + + + diff -r a519e3ac3849 -r 234ad2069fdd svg2gcode/gcode.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svg2gcode/gcode.py Sat Nov 07 13:37:23 2015 +0100 @@ -0,0 +1,80 @@ +import math + +INCH = 25.4 # mm + +class Gcode(object): + def __init__(self, bbox=None, scale=1.0, travel_speed=20, engrave_speed=20): + self.dpi = 300 + self.e_factor = 0.1 + + self.mm_pixel = round(INCH / self.dpi, 4) + self.steps_pixel = self.mm_pixel * 80 # mine is 80 steps/mm on XY + print "Resolution is %f mm per pixel" % self.mm_pixel + if self.steps_pixel <= 5: + print "Warning: Steps per pixel (needs to be > 5, otherwise marlin joins lines): %f" % self.steps_pixel + + self.lines = [] + self.dist_start = (0, 0) + self.dist = 0.0 + + self.scale = scale + self.travel_speed = travel_speed * 60 + self.engrave_speed = engrave_speed * 60 + + def _dimensions(self, x, y): + x = self.mm_pixel * x + y = self.mm_pixel * y + if self.scale != 1.0: + x = x * self.scale + y = y * self.scale + return (x, y) + + def move(self, x, y): + x, y = self._dimensions(x, y) + if self.e_factor > 0: + self.dist_start = (x, y) + self.dist = 0.0 + self.lines.append("G92 E0") # reset extruder length + self.lines.append( + "G0 X%.4f Y%.4f F%s" % (x, y, self.travel_speed) + ) + + def engrave(self, x, y): + x, y = self._dimensions(x, y) + if self.e_factor > 0: + self.dist += abs(math.hypot(x - self.dist_start[0], y - self.dist_start[1])) + e = "E%.4f" % (self.e_factor * self.dist) + self.dist_start = (x, y) + else: + e = "" + self.lines.append( + "G1 X%.4f Y%.4f %s F%s" % (x, y, e, self.engrave_speed) + ) + + + def write(self, filename): + # write gcode file + fout = open(filename, "w") + + fout.write(""" +; Filename: %s +; GCode generated by bitplotter one-night-quick-hack script (marlin code flavour) + +G21 ; Metric +; We assume Z is in focus height and laser head is focus at bottom left of image! +G92 X0 Y0 E0 ; set zero position - new origin +G90 ; absolute positioning +M82 ; Set extruder (laser) to absolute positioning +M201 X1000 Y1000 E500 ; Set acceleration +M203 X1000 Y1000 Z4 E10 ; Set max feedrate +M209 S0 ; disable firmware retraction, we dont want to burn holes... +M302 ; Allow cold extrudes - doesnt matter because we hack the extruder physically off with the M571 E mod +M571 S1 E1 ; Activate Laser output on extrusion, but block real motor movement! +G0 X0 Y0 F%.1f ; Set moving speed +G1 X0 Y0 F%.1f ; Set engrave speed + +""" % (filename, self.travel_speed, self.engrave_speed)) + + for g in self.lines: + fout.write(g + "\n") + fout.close() diff -r a519e3ac3849 -r 234ad2069fdd svg2gcode/svg2gcode.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/svg2gcode/svg2gcode.py Sat Nov 07 13:37:23 2015 +0100 @@ -0,0 +1,55 @@ +#!/usr/bin/env python +import svg, sys +from gcode import Gcode +from optparse import OptionParser + +parser = OptionParser() +parser.add_option("-f", "--file", dest="filename", default=None, + help="Load SVG file", metavar="FILE") +parser.add_option("-s", "--scale", + dest="scale", type="float", default=1.0, + help="set scale factor (default 1.0)") +parser.add_option("-e", "", + dest="engrave_speed", type="float", default=20, + help="engrave speed mm/sec (default 20)") +parser.add_option("-t", "", + dest="travel_speed", type="float", default=130, + help="travel speed mm/sec (default 130)") + + +(options, args) = parser.parse_args() + + +if not options.filename: + print "no filename given!" + sys.exit(1) + +gcode = Gcode(scale=options.scale, travel_speed=options.travel_speed, engrave_speed=options.engrave_speed) + +im = svg.parse(options.filename) +b1, b2 = im.bbox() +width, height = b2.coord() +print "Original dimension: %.2f x %.2f" % (width, height) +width *= gcode.mm_pixel * options.scale +height *= gcode.mm_pixel * options.scale +print "Print dimension: %.2fmm x %.2fmm" % (width, height) + +def normalize(coord): + x = coord[0] + y = coord[1] + # flip y + y = (b2.coord()[1] - y) + return (x, y) + +data = im.flatten() +for d in data: + if hasattr(d, "segments"): + for l in d.segments(1): + x, y = normalize(l[0].coord()) + gcode.move(x, y) + for pt in l[1:]: + x, y = normalize(pt.coord()) + gcode.engrave(x, y) + +# write gcode file +gcode.write(options.filename + ".g")