diff -r 92835c3f171a -r e7feabe18234 svg2gcode/svg2gcode.py --- a/svg2gcode/svg2gcode.py Sat Nov 07 20:50:55 2015 +0100 +++ b/svg2gcode/svg2gcode.py Sun Nov 08 04:18:58 2015 +0100 @@ -2,17 +2,21 @@ # -*- coding: utf-8 -*- import svg, sys, math +from pprint import pprint from gcode import Gcode from optparse import OptionParser from tinycss import CSS21Parser + from shapely.geometry import box, MultiLineString, Polygon from shapely.affinity import rotate from shapely import speedups from math import sqrt +from functools import cmp_to_key # enable Shapely speedups, if possible if speedups.available: + print "shapely speedups available and enabled!" speedups.enable() def hatchbox(rect, angle, spacing): @@ -139,6 +143,59 @@ data.append(dwg) return data +def cmp_smallest_distance(line1, line2, coords1=None, coords2=None): + if not coords1: + coords1 = list(line1.coords) + if not coords2: + coords2 = list(line2.coords) + + dist = [ + abs(math.hypot(coords1[0][0] - coords2[0][0], coords1[0][1] - coords2[0][1])), + abs(math.hypot(coords1[0][0] - coords2[1][0], coords1[0][1] - coords2[1][1])), + abs(math.hypot(coords1[1][0] - coords2[0][0], coords1[1][1] - coords2[0][1])), + abs(math.hypot(coords1[1][0] - coords2[1][0], coords1[1][1] - coords2[1][1])) + ] + + # return the smallest distance between the two lines + # check both start and endpoints to each other + return sorted(dist)[0] + +def slow_sort_lines_by_distance(multilines): + lines = [] + coords = [] + for line in multilines: + lines.append(line) + # coords list for brutal speedup! + # without this it would be terrible_slow_sort_lines_by_distance() + coords.append(list(line.coords)) + + data = [lines.pop(0)] + last = coords.pop(0) + + def pop_nearest(line, last): + idx = -1 + dist = 99999999 + for test in lines: + idx += 1 + tmp = cmp_smallest_distance(line, test, last, coords[idx]) + if tmp < dist: + dist = tmp + dist_idx = idx + # nearest item found + return (lines.pop(dist_idx), coords.pop(dist_idx)) + + print "Optimizing infill movement, please wait..." + while len(lines) > 0: + tmp = len(lines) + if not (tmp % 10): + sys.stdout.write("\r%d " % tmp) + sys.stdout.flush() + tmp = pop_nearest(data[-1], last) + data.append(tmp[0]) + last = tmp[1] + print "\rdone" + return data + def svg2gcode(options, gcoder): image = Image(options.filename, options, gcoder) @@ -182,9 +239,24 @@ lines = poly.intersection(image.infill) if lines: + #pprint (dir(lines)) # THE INFILL prev_end = None - for line in lines: + # sort lines by nearest + lines_ordered = slow_sort_lines_by_distance(lines) + + + #lines_distances = [] + #prev_line = lines[0] + #for line in lines: + # lines_distances.append(cmp_smallest_distance(line, prev_line)) + # prev_line = line + ##lines_ordered = sorted(lines, key=cmp_to_key(cmp_smallest_distance)) + ## decorate, sort, undecorate: + #lines_distances, lines = zip(*sorted(zip(lines_distances, lines))) + + + for line in lines_ordered: coords = [ image.normalize((line.coords[0][0], line.coords[0][1])), image.normalize((line.coords[1][0], line.coords[1][1]))