1 #!/usr/bin/env python |
1 #!/usr/bin/env python |
2 # -*- coding: utf-8 -*- |
2 # -*- coding: utf-8 -*- |
3 |
3 |
4 import svg, sys |
4 import svg, sys |
|
5 import cairo |
5 from gcode import Gcode |
6 from gcode import Gcode |
6 from optparse import OptionParser |
7 from optparse import OptionParser |
7 from tinycss import CSS21Parser |
8 from tinycss import CSS21Parser |
8 |
9 |
9 from shapely.geometry import box, MultiLineString, Point, Polygon |
10 from shapely.geometry import box, MultiLineString, MultiPolygon, Polygon |
10 from shapely.affinity import rotate |
11 from shapely.affinity import rotate |
11 from shapely import speedups |
12 from shapely import speedups |
12 from math import sqrt |
13 from math import sqrt |
13 |
14 |
14 # enable Shapely speedups, if possible |
15 # enable Shapely speedups, if possible |
60 # Rotate by angle around box centre |
61 # Rotate by angle around box centre |
61 lines = rotate(lines, angle, origin='centroid', use_radians=False) |
62 lines = rotate(lines, angle, origin='centroid', use_radians=False) |
62 # return clipped array |
63 # return clipped array |
63 return rect.intersection(lines) |
64 return rect.intersection(lines) |
64 |
65 |
65 def get_infill(polygon): |
|
66 # create shape from polygon: |
|
67 segments = [] |
|
68 for pnt in polygon: |
|
69 x, y = pnt.coord() |
|
70 segments.append((x, y)) |
|
71 |
|
72 shape = Polygon(segments) |
|
73 if shape.is_valid: |
|
74 return shape.intersection(INFILL) |
|
75 else: |
|
76 return [] |
|
77 |
66 |
78 parser = OptionParser() |
67 parser = OptionParser() |
79 parser.add_option("-f", "--file", dest="filename", default=None, |
68 parser.add_option("-f", "--file", dest="filename", default=None, |
80 help="Load SVG file", metavar="FILE") |
69 help="Load SVG file", metavar="FILE") |
81 parser.add_option("-s", "--scale", |
70 parser.add_option("-s", "--scale", |
143 gcode.engrave(x, y) |
132 gcode.engrave(x, y) |
144 |
133 |
145 if options.outline: |
134 if options.outline: |
146 continue |
135 continue |
147 |
136 |
148 if (isinstance(d, svg.Polygon) or isinstance(d, svg.Path)): |
137 if (isinstance(d, svg.Polygon) or isinstance(d, svg.Path)): |
149 #check if we shoild infill? |
138 #check if we shoild infill? |
150 style = parse_style(d.style) |
139 style = parse_style(d.style) |
151 if not style: |
140 if not style: |
152 continue |
141 continue |
153 if not 'fill' in style.keys(): |
142 if not 'fill' in style.keys(): |
154 continue |
143 continue |
155 if style['fill'] == 'none': |
144 if style['fill'] == 'none': |
156 continue |
145 continue |
157 |
146 |
|
147 poly = None |
|
148 for l in d.segments(1): |
|
149 # create shape from polygon: |
|
150 segments = [] |
|
151 for pnt in l: |
|
152 x, y = pnt.coord() |
|
153 segments.append((x, y)) |
|
154 shape = Polygon(segments) |
|
155 if shape.is_valid: |
|
156 if not poly: |
|
157 poly = shape |
|
158 else: |
|
159 if shape.within(poly): |
|
160 poly = poly.difference(shape) |
|
161 else: |
|
162 poly = poly.union(shape) |
|
163 |
|
164 lines = poly.intersection(INFILL) |
|
165 if lines: |
158 # THE INFILL |
166 # THE INFILL |
159 for line in get_infill(l): |
167 for line in lines: |
160 start = normalize((line.coords[0][0], line.coords[0][1])) |
168 start = normalize((line.coords[0][0], line.coords[0][1])) |
161 end = normalize((line.coords[1][0], line.coords[1][1])) |
169 end = normalize((line.coords[1][0], line.coords[1][1])) |
162 gcode.move(start[0], start[1]) |
170 gcode.move(start[0], start[1]) |
163 gcode.engrave(end[0], end[1]) |
171 gcode.engrave(end[0], end[1]) |
164 |
172 |