added cli

This commit is contained in:
arcadeperfect committed 2020-01-01 16:00:55 -05:00
1 parent b302aa17df
commit 9d3fbb492c
7 files changed
+653059 -156

No files matched your search

+15 -7
View File
@@ -1,6 +1,5 @@
"""G-code emitted at the start of processing the SVG file""" """G-code emitted at the start of processing the SVG file"""
preamble = "(preamble)" preamble = "G90"
#preamble = "G1 X0, Y0, Z100"
"""G-code emitted at the end of processing the SVG file""" """G-code emitted at the end of processing the SVG file"""
@@ -15,21 +14,30 @@ shape_postamble = "(shape postamble)"
#shape_postamble = "Z100)" #shape_postamble = "Z100)"
"""Print bed width in mm""" """Print bed width in mm"""
bed_max_x = 200000 bed_max_x = 200
"""Print bed height in mm""" """Print bed height in mm"""
bed_max_y = 200000 bed_max_y = 280
""" """
Used to control the smoothness/sharpness of the curves. Used to control the smoothness/sharpness of the curves.
Smaller the value greater the sharpness. Make sure the Smaller the value greater the sharpness. Make sure the
value is greater than 0.1 value is greater than 0.1
""" """
smoothness = 10 smoothness = 0.0101
smoothness = 40
""" height that the z axis will use to travel between strokes """
zTravel = 4
zTravel = 100 """ height that the z axis will use to draw """
zDraw = 0 zDraw = 0
""" feed rate """
feed_rate = 80000
""" decimal precision of gcode"""
precision = 2
auto_scale = False
+32
View File
@@ -0,0 +1,32 @@
#!/usr/bin/env python
from svg2gcode import generate_gcode
import sys
# from config import *
if __name__ == "__main__":
if len(sys.argv) < 3:
print("usage: python convert.py source.svg destination.gcode")
sys.exit()
source = sys.argv[1]
target = sys.argv[2]
print("converting!")
print(source, target)
with open(target, 'w+') as output_file:
g = generate_gcode(source)
for i in g:
output_file.write(i + "\n")
print("done!")
+106 -95
View File
@@ -22,81 +22,90 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import simplepath import simplepath
from math import * from math import *
def matprod(mlist):
prod=mlist[0]
for m in mlist[1:]:
a00=prod[0][0]*m[0][0]+prod[0][1]*m[1][0]
a01=prod[0][0]*m[0][1]+prod[0][1]*m[1][1]
a10=prod[1][0]*m[0][0]+prod[1][1]*m[1][0]
a11=prod[1][0]*m[0][1]+prod[1][1]*m[1][1]
prod=[[a00,a01],[a10,a11]]
return prod
def rotmat(teta):
return [[cos(teta),-sin(teta)],[sin(teta),cos(teta)]]
def applymat(mat, pt):
x=mat[0][0]*pt[0]+mat[0][1]*pt[1]
y=mat[1][0]*pt[0]+mat[1][1]*pt[1]
pt[0]=x
pt[1]=y
def norm(pt):
return sqrt(pt[0]*pt[0]+pt[1]*pt[1])
def ArcToPath(p1,params): def matprod(mlist):
A=p1[:] prod = mlist[0]
rx,ry,teta,longflag,sweepflag,x2,y2=params[:] for m in mlist[1:]:
teta = teta*pi/180.0 a00 = prod[0][0] * m[0][0] + prod[0][1] * m[1][0]
B=[x2,y2] a01 = prod[0][0] * m[0][1] + prod[0][1] * m[1][1]
if rx==0 or ry==0: a10 = prod[1][0] * m[0][0] + prod[1][1] * m[1][0]
return([[A,A,A],[B,B,B]]) a11 = prod[1][0] * m[0][1] + prod[1][1] * m[1][1]
mat=matprod((rotmat(teta),[[1/rx,0],[0,1/ry]],rotmat(-teta))) prod = [[a00, a01], [a10, a11]]
return prod
def rotmat(teta):
return [[cos(teta), -sin(teta)], [sin(teta), cos(teta)]]
def applymat(mat, pt):
x = mat[0][0] * pt[0] + mat[0][1] * pt[1]
y = mat[1][0] * pt[0] + mat[1][1] * pt[1]
pt[0] = x
pt[1] = y
def norm(pt):
return sqrt(pt[0] * pt[0] + pt[1] * pt[1])
def ArcToPath(p1, params):
A = p1[:]
rx, ry, teta, longflag, sweepflag, x2, y2 = params[:]
teta = teta * pi / 180.0
B = [x2, y2]
if rx == 0 or ry == 0:
return ([[A, A, A], [B, B, B]])
mat = matprod((rotmat(teta), [[1 / rx, 0], [0, 1 / ry]], rotmat(-teta)))
applymat(mat, A) applymat(mat, A)
applymat(mat, B) applymat(mat, B)
k=[-(B[1]-A[1]),B[0]-A[0]] k = [-(B[1] - A[1]), B[0] - A[0]]
d=k[0]*k[0]+k[1]*k[1] d = k[0] * k[0] + k[1] * k[1]
k[0]/=sqrt(d) k[0] /= sqrt(d)
k[1]/=sqrt(d) k[1] /= sqrt(d)
d=sqrt(max(0,1-d/4)) d = sqrt(max(0, 1 - d / 4))
if longflag==sweepflag: if longflag == sweepflag:
d*=-1 d *= -1
O=[(B[0]+A[0])/2+d*k[0],(B[1]+A[1])/2+d*k[1]] O = [(B[0] + A[0]) / 2 + d * k[0], (B[1] + A[1]) / 2 + d * k[1]]
OA=[A[0]-O[0],A[1]-O[1]] OA = [A[0] - O[0], A[1] - O[1]]
OB=[B[0]-O[0],B[1]-O[1]] OB = [B[0] - O[0], B[1] - O[1]]
start=acos(OA[0]/norm(OA)) start = acos(OA[0] / norm(OA))
if OA[1]<0: if OA[1] < 0:
start*=-1 start *= -1
end=acos(OB[0]/norm(OB)) end = acos(OB[0] / norm(OB))
if OB[1]<0: if OB[1] < 0:
end*=-1 end *= -1
if sweepflag and start>end: if sweepflag and start > end:
end +=2*pi end += 2 * pi
if (not sweepflag) and start<end: if (not sweepflag) and start < end:
end -=2*pi end -= 2 * pi
NbSectors=int(abs(start-end)*2/pi)+1 NbSectors = int(abs(start - end) * 2 / pi) + 1
dTeta=(end-start)/NbSectors dTeta = (end - start) / NbSectors
#v=dTeta*2/pi*0.552 # v=dTeta*2/pi*0.552
#v=dTeta*2/pi*4*(sqrt(2)-1)/3 # v=dTeta*2/pi*4*(sqrt(2)-1)/3
v = 4*tan(dTeta/4)/3 v = 4 * tan(dTeta / 4) / 3
#if not sweepflag: # if not sweepflag:
# v*=-1 # v*=-1
p=[] p = []
for i in range(0,NbSectors+1,1): for i in range(0, NbSectors + 1, 1):
angle=start+i*dTeta angle = start + i * dTeta
v1=[O[0]+cos(angle)-(-v)*sin(angle),O[1]+sin(angle)+(-v)*cos(angle)] v1 = [O[0] + cos(angle) - (-v) * sin(angle), O[1] + sin(angle) + (-v) * cos(angle)]
pt=[O[0]+cos(angle) ,O[1]+sin(angle) ] pt = [O[0] + cos(angle), O[1] + sin(angle)]
v2=[O[0]+cos(angle)- v *sin(angle),O[1]+sin(angle)+ v *cos(angle)] v2 = [O[0] + cos(angle) - v * sin(angle), O[1] + sin(angle) + v * cos(angle)]
p.append([v1,pt,v2]) p.append([v1, pt, v2])
p[ 0][0]=p[ 0][1][:] p[0][0] = p[0][1][:]
p[-1][2]=p[-1][1][:] p[-1][2] = p[-1][1][:]
mat=matprod((rotmat(teta),[[rx,0],[0,ry]],rotmat(-teta))) mat = matprod((rotmat(teta), [[rx, 0], [0, ry]], rotmat(-teta)))
for pts in p: for pts in p:
applymat(mat, pts[0]) applymat(mat, pts[0])
applymat(mat, pts[1]) applymat(mat, pts[1])
applymat(mat, pts[2]) applymat(mat, pts[2])
return(p) return (p)
def CubicSuperPath(simplepath): def CubicSuperPath(simplepath):
csp = [] csp = []
subpath = -1 subpath = -1
@@ -104,66 +113,68 @@ def CubicSuperPath(simplepath):
last = [] last = []
lastctrl = [] lastctrl = []
for s in simplepath: for s in simplepath:
cmd, params = s cmd, params = s
if cmd == 'M': if cmd == 'M':
if last: if last:
csp[subpath].append([lastctrl[:],last[:],last[:]]) csp[subpath].append([lastctrl[:], last[:], last[:]])
subpath += 1 subpath += 1
csp.append([]) csp.append([])
subpathstart = params[:] subpathstart = params[:]
last = params[:] last = params[:]
lastctrl = params[:] lastctrl = params[:]
elif cmd == 'L': elif cmd == 'L':
csp[subpath].append([lastctrl[:],last[:],last[:]]) csp[subpath].append([lastctrl[:], last[:], last[:]])
last = params[:] last = params[:]
lastctrl = params[:] lastctrl = params[:]
elif cmd == 'C': elif cmd == 'C':
csp[subpath].append([lastctrl[:],last[:],params[:2]]) csp[subpath].append([lastctrl[:], last[:], params[:2]])
last = params[-2:] last = params[-2:]
lastctrl = params[2:4] lastctrl = params[2:4]
elif cmd == 'Q': elif cmd == 'Q':
q0=last[:] q0 = last[:]
q1=params[0:2] q1 = params[0:2]
q2=params[2:4] q2 = params[2:4]
x0= q0[0] x0 = q0[0]
x1=1./3*q0[0]+2./3*q1[0] x1 = 1. / 3 * q0[0] + 2. / 3 * q1[0]
x2= 2./3*q1[0]+1./3*q2[0] x2 = 2. / 3 * q1[0] + 1. / 3 * q2[0]
x3= q2[0] x3 = q2[0]
y0= q0[1] y0 = q0[1]
y1=1./3*q0[1]+2./3*q1[1] y1 = 1. / 3 * q0[1] + 2. / 3 * q1[1]
y2= 2./3*q1[1]+1./3*q2[1] y2 = 2. / 3 * q1[1] + 1. / 3 * q2[1]
y3= q2[1] y3 = q2[1]
csp[subpath].append([lastctrl[:],[x0,y0],[x1,y1]]) csp[subpath].append([lastctrl[:], [x0, y0], [x1, y1]])
last = [x3,y3] last = [x3, y3]
lastctrl = [x2,y2] lastctrl = [x2, y2]
elif cmd == 'A': elif cmd == 'A':
arcp=ArcToPath(last[:],params[:]) arcp = ArcToPath(last[:], params[:])
arcp[ 0][0]=lastctrl[:] arcp[0][0] = lastctrl[:]
last=arcp[-1][1] last = arcp[-1][1]
lastctrl = arcp[-1][0] lastctrl = arcp[-1][0]
csp[subpath]+=arcp[:-1] csp[subpath] += arcp[:-1]
elif cmd == 'Z': elif cmd == 'Z':
csp[subpath].append([lastctrl[:],last[:],last[:]]) csp[subpath].append([lastctrl[:], last[:], last[:]])
last = subpathstart[:] last = subpathstart[:]
lastctrl = subpathstart[:] lastctrl = subpathstart[:]
#append final superpoint # append final superpoint
csp[subpath].append([lastctrl[:],last[:],last[:]]) csp[subpath].append([lastctrl[:], last[:], last[:]])
return csp return csp
def unCubicSuperPath(csp): def unCubicSuperPath(csp):
a = [] a = []
for subpath in csp: for subpath in csp:
if subpath: if subpath:
a.append(['M',subpath[0][1][:]]) a.append(['M', subpath[0][1][:]])
for i in range(1,len(subpath)): for i in range(1, len(subpath)):
a.append(['C',subpath[i-1][2][:] + subpath[i][0][:] + subpath[i][1][:]]) a.append(['C', subpath[i - 1][2][:] + subpath[i][0][:] + subpath[i][1][:]])
return a return a
def parsePath(d): def parsePath(d):
return CubicSuperPath(simplepath.parsePath(d)) return CubicSuperPath(simplepath.parsePath(d))
def formatPath(p): def formatPath(p):
return simplepath.formatPath(unCubicSuperPath(p)) return simplepath.formatPath(unCubicSuperPath(p))
# vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99 # vim: expandtab shiftwidth=4 tabstop=8 softtabstop=4 fileencoding=utf-8 textwidth=99
+14
View File
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 22.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 612 792" enable-background="new 0 0 612 792" xml:space="preserve">
<rect x="56.8" y="123.5" fill="#FFFFFF" stroke="#000000" stroke-miterlimit="10" width="150" height="128.1"/>
<path fill="#FFFFFF" stroke="#000000" stroke-miterlimit="10" d="M401,237.5H290.8c-6.6,0-12-5.4-12-12v-83.9c0-6.6,5.4-12,12-12
H401c6.6,0,12,5.4,12,12v83.9C413,232.1,407.6,237.5,401,237.5z"/>
<ellipse fill="#FFFFFF" stroke="#000000" stroke-miterlimit="10" cx="146.3" cy="373.9" rx="71.9" ry="49.6"/>
<circle fill="#FFFFFF" stroke="#000000" stroke-miterlimit="10" cx="325.7" cy="380.1" r="55.7"/>
<polygon fill="#FFFFFF" stroke="#000000" stroke-miterlimit="10" points="193.7,655.9 103.1,658.4 55.8,581.2 98.9,501.6
189.5,499.1 236.8,576.3 "/>
<polygon fill="#FFFFFF" stroke="#000000" stroke-miterlimit="10" points="448.1,649.8 388.3,619.5 329.5,651.6 339.8,585.4
291.1,539.4 357.3,528.8 386,468.2 416.6,527.9 483,536.5 435.7,584 "/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+8
View File
@@ -0,0 +1,8 @@
(Created with svg2gcode_grbl)
(https://github.com/arcadeperfect/svg2gcode_grbl)
(forked from svg2gcode by visphat)
(https://github.com/vishpat/svg2gcode)
+95 -54
View File
@@ -7,7 +7,7 @@ from shapes import point_generator
from config import * from config import *
import re import re
path = "./svg/example.svg" # path = "./svg/example.svg"
# path = "./svg/big_example.svg" # path = "./svg/big_example.svg"
# path = "./svg/medium_example.svg" # path = "./svg/medium_example.svg"
@@ -15,9 +15,11 @@ path = "./svg/example.svg"
# path = "./svg/grid.svg" # path = "./svg/grid.svg"
# path = "./svg/Lorenz_attractor.svg" # path = "./svg/Lorenz_attractor.svg"
# path = "./svg/text.svg" # path = "./svg/text.svg"
# path = "./svg/A.svg"
path = "./example.svg"
output = "./gcode/output2.gcode"
output = "./gcode/output.gcode" output = "temp.gcode"
debug = False debug = False
@@ -29,24 +31,21 @@ debug = False
# todo make interface # todo make interface
def generate_gcode(path): def generate_gcode(path, autoScale = True):
svg_shapes = set(['rect', 'circle', 'ellipse', 'line', 'polyline', 'polygon', 'path']) svg_shapes = set(['rect', 'circle', 'ellipse', 'line', 'polyline', 'polygon', 'path'])
precision = 1
with open("header.txt") as headerFile:
header = headerFile.read()
# preamble = ""
# with open("header.txt") as headerFile:
# for cnt, line in enumerate(headerFile):
# preamble += f"({line})\n"
commands = [] commands = []
tree = ET.parse(path) tree = ET.parse(path)
# tree = ET.parse(sys.stdin)
root = tree.getroot() root = tree.getroot()
# print("\n printing root.iter")
# for i in root.iter():
# print(i.tag)
#
# print("\n printing root with tag and attrib")
# for i in root:
# print(i.tag, i.attrib)
width = root.get('width') width = root.get('width')
height = root.get('height') height = root.get('height')
@@ -59,34 +58,40 @@ def generate_gcode(path):
print("Unable to get width and height for the svg") print("Unable to get width and height for the svg")
sys.exit(1) sys.exit(1)
width = re.sub("[^0-9]", "", width) width = float(re.sub("[^0-9]", "", width))
height = re.sub("[^0-9]", "", height) height = float(re.sub("[^0-9]", "", height))
print("\n width / height") print("\n width / height")
print(width, height) print(width, height)
width = float(width) if autoScale:
height = float(height)
# scale_x = bed_max_x / max(width, height) scale_x = min(bed_max_x / max(width, height),bed_max_y / max(width, height))
# scale_y = bed_max_y / max(width, height) # scale_y = bed_max_y / max(width, height)
# scale_x= min(scale_x, scale_y) # scale_x = min(scale_x, scale_y)
# scale_y = scale_x scale_y = scale_x
#
scale_x = 1
scale_y = 1
print("\npreamble") else:
print(preamble)
commands.append(preamble) scale_x = 1
scale_y = 1
print("scale factor: ", scale_y)
if debug:
print("\n preamble")
print(preamble)
commands.append(header)
commands.append("(begin)") commands.append("(begin)")
for i in [f"{feed_rate}", "G90"]: commands.append(preamble)
commands.append(i)
commands.append(f"F{feed_rate}")
print("\n begin main loop") print("\n begin main loop")
for elem in root.iter(): for elem in root.iter():
if debug: if debug:
print("\nelem") print("\n\n\n***************** elem ******************")
print(elem) print(elem)
try: try:
@@ -98,27 +103,35 @@ def generate_gcode(path):
if tag_suffix in svg_shapes: if tag_suffix in svg_shapes:
if debug: if debug:
print("\ntag_suffix") print("\n tag_suffix")
print(tag_suffix) print(tag_suffix)
for i in ["\n", "({})".format(tag_suffix), ""]: for i in ["\n", "({})".format(tag_suffix), ""]:
commands.append(i) # add tag name ad comment commands.append(i) # add tag name ad comment
shape_class = getattr(shapes_pkg, tag_suffix) shape_class = getattr(shapes_pkg, tag_suffix)
if debug:
print("\n shape_class")
print(shape_class)
shape_obj = shape_class(elem) shape_obj = shape_class(elem)
if debug:
print("\n shape_obj")
#print(shape_obj)
d = shape_obj.d_path() d = shape_obj.d_path()
m = shape_obj.transformation_matrix() # todo work out what d and m are m = shape_obj.transformation_matrix() # todo work out what d and m are
if debug: if debug:
print("\nd", d) print("\n d", d)
print(d) print(d)
print("\nm", m) print("\n m", m)
print(m) print(m)
if d: # begin shape processing if d: # begin shape processing
if debug: if debug:
print("\nshape preamble") print("\n shape preamble")
print(shape_preamble) print(shape_preamble)
commands.append(shape_preamble) commands.append(shape_preamble)
@@ -129,23 +142,20 @@ def generate_gcode(path):
for x, y in p: for x, y in p:
if first: if first:
first = (x, y)
# commands.append("G0 X%0.1f Y%0.1f Z%0.1f" %(scale_x*x, scale_y*y, zTravel)) command = g_string(x * scale_x, (-y+height) * scale_y, zTravel, "G0", precision) #todo why do i need to flip?
command = g_string(x, y, zTravel, "G0", precision)
commands.append(command) commands.append(command)
if debug:
print(command)
first = False first = False
# if x > 0 and x < bed_max_x and y > 0 and y < bed_max_y: # if x > 0 and x < bed_max_x and y > 0 and y < bed_max_y:
# commands.append("G1 X%0.3f Y%0.3f Z%0.3f" % (scale_x*x, scale_y*y, zDraw)) command = g_string(x * scale_x, (-y+height) * scale_y, zDraw, "G1", precision)
command = g_string(x, y, zDraw, "G1", precision)
commands.append(command) commands.append(command)
# else: if debug:
# print("out of bed") print(command)
# count += 1
# commands.append("G0 Z%0.1f" %zTravel)
command = g_string(x, y, zTravel, "G0", precision) command = g_string(x, y, zTravel, "G0", precision)
commands.append(command) commands.append(command)
@@ -166,13 +176,44 @@ def g_string(x, y, z=False, prefix="G1", p=3):
return f"{prefix} X{x:.{p}f} Y{y:.{p}f}" return f"{prefix} X{x:.{p}f} Y{y:.{p}f}"
if __name__ == "__main__": # if __name__ == "__main__":
c = generate_gcode(path) # c = generate_gcode(path)
# for i in c: # # for i in c:
# print(i) # # print(i)
#
# with open(output, 'w+') as output_file:
# for i in c:
# output_file.write(i + "\n")
#
# print("done")
with open(output, 'w+') as output_file:
for i in c:
if __name__ == "__main__":
if len(sys.argv) < 3:
print("usage: python convert.py source.svg destination.gcode")
sys.exit()
source = sys.argv[1]
target = sys.argv[2]
print("converting!")
print(source, target)
with open(target, 'w+') as output_file:
g = generate_gcode(source)
for i in g:
output_file.write(i + "\n") output_file.write(i + "\n")
print("done") print("done!")
+652789
View File
File diff suppressed because it is too large. Load diff