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
+653056 -153

No files matched your search

+15 -7
View File
@@ -1,6 +1,5 @@
"""G-code emitted at the start of processing the SVG file"""
preamble = "(preamble)"
#preamble = "G1 X0, Y0, Z100"
preamble = "G90"
"""G-code emitted at the end of processing the SVG file"""
@@ -15,21 +14,30 @@ shape_postamble = "(shape postamble)"
#shape_postamble = "Z100)"
"""Print bed width in mm"""
bed_max_x = 200000
bed_max_x = 200
"""Print bed height in mm"""
bed_max_y = 200000
bed_max_y = 280
"""
Used to control the smoothness/sharpness of the curves.
Smaller the value greater the sharpness. Make sure the
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
""" 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!")
+103 -92
View File
@@ -22,80 +22,89 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
import simplepath
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):
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)))
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):
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, B)
k=[-(B[1]-A[1]),B[0]-A[0]]
d=k[0]*k[0]+k[1]*k[1]
k[0]/=sqrt(d)
k[1]/=sqrt(d)
d=sqrt(max(0,1-d/4))
if longflag==sweepflag:
d*=-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]]
OB=[B[0]-O[0],B[1]-O[1]]
start=acos(OA[0]/norm(OA))
if OA[1]<0:
start*=-1
end=acos(OB[0]/norm(OB))
if OB[1]<0:
end*=-1
k = [-(B[1] - A[1]), B[0] - A[0]]
d = k[0] * k[0] + k[1] * k[1]
k[0] /= sqrt(d)
k[1] /= sqrt(d)
d = sqrt(max(0, 1 - d / 4))
if longflag == sweepflag:
d *= -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]]
OB = [B[0] - O[0], B[1] - O[1]]
start = acos(OA[0] / norm(OA))
if OA[1] < 0:
start *= -1
end = acos(OB[0] / norm(OB))
if OB[1] < 0:
end *= -1
if sweepflag and start>end:
end +=2*pi
if (not sweepflag) and start<end:
end -=2*pi
if sweepflag and start > end:
end += 2 * pi
if (not sweepflag) and start < end:
end -= 2 * pi
NbSectors=int(abs(start-end)*2/pi)+1
dTeta=(end-start)/NbSectors
#v=dTeta*2/pi*0.552
#v=dTeta*2/pi*4*(sqrt(2)-1)/3
v = 4*tan(dTeta/4)/3
#if not sweepflag:
NbSectors = int(abs(start - end) * 2 / pi) + 1
dTeta = (end - start) / NbSectors
# v=dTeta*2/pi*0.552
# v=dTeta*2/pi*4*(sqrt(2)-1)/3
v = 4 * tan(dTeta / 4) / 3
# if not sweepflag:
# v*=-1
p=[]
for i in range(0,NbSectors+1,1):
angle=start+i*dTeta
v1=[O[0]+cos(angle)-(-v)*sin(angle),O[1]+sin(angle)+(-v)*cos(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)]
p.append([v1,pt,v2])
p[ 0][0]=p[ 0][1][:]
p[-1][2]=p[-1][1][:]
p = []
for i in range(0, NbSectors + 1, 1):
angle = start + i * dTeta
v1 = [O[0] + cos(angle) - (-v) * sin(angle), O[1] + sin(angle) + (-v) * cos(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)]
p.append([v1, pt, v2])
p[0][0] = p[0][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:
applymat(mat, pts[0])
applymat(mat, pts[1])
applymat(mat, pts[2])
return(p)
return (p)
def CubicSuperPath(simplepath):
csp = []
@@ -107,63 +116,65 @@ def CubicSuperPath(simplepath):
cmd, params = s
if cmd == 'M':
if last:
csp[subpath].append([lastctrl[:],last[:],last[:]])
csp[subpath].append([lastctrl[:], last[:], last[:]])
subpath += 1
csp.append([])
subpathstart = params[:]
subpathstart = params[:]
last = params[:]
lastctrl = params[:]
elif cmd == 'L':
csp[subpath].append([lastctrl[:],last[:],last[:]])
csp[subpath].append([lastctrl[:], last[:], last[:]])
last = params[:]
lastctrl = params[:]
elif cmd == 'C':
csp[subpath].append([lastctrl[:],last[:],params[:2]])
csp[subpath].append([lastctrl[:], last[:], params[:2]])
last = params[-2:]
lastctrl = params[2:4]
elif cmd == 'Q':
q0=last[:]
q1=params[0:2]
q2=params[2:4]
x0= q0[0]
x1=1./3*q0[0]+2./3*q1[0]
x2= 2./3*q1[0]+1./3*q2[0]
x3= q2[0]
y0= q0[1]
y1=1./3*q0[1]+2./3*q1[1]
y2= 2./3*q1[1]+1./3*q2[1]
y3= q2[1]
csp[subpath].append([lastctrl[:],[x0,y0],[x1,y1]])
last = [x3,y3]
lastctrl = [x2,y2]
q0 = last[:]
q1 = params[0:2]
q2 = params[2:4]
x0 = q0[0]
x1 = 1. / 3 * q0[0] + 2. / 3 * q1[0]
x2 = 2. / 3 * q1[0] + 1. / 3 * q2[0]
x3 = q2[0]
y0 = q0[1]
y1 = 1. / 3 * q0[1] + 2. / 3 * q1[1]
y2 = 2. / 3 * q1[1] + 1. / 3 * q2[1]
y3 = q2[1]
csp[subpath].append([lastctrl[:], [x0, y0], [x1, y1]])
last = [x3, y3]
lastctrl = [x2, y2]
elif cmd == 'A':
arcp=ArcToPath(last[:],params[:])
arcp[ 0][0]=lastctrl[:]
last=arcp[-1][1]
arcp = ArcToPath(last[:], params[:])
arcp[0][0] = lastctrl[:]
last = arcp[-1][1]
lastctrl = arcp[-1][0]
csp[subpath]+=arcp[:-1]
csp[subpath] += arcp[:-1]
elif cmd == 'Z':
csp[subpath].append([lastctrl[:],last[:],last[:]])
csp[subpath].append([lastctrl[:], last[:], last[:]])
last = subpathstart[:]
lastctrl = subpathstart[:]
#append final superpoint
csp[subpath].append([lastctrl[:],last[:],last[:]])
# append final superpoint
csp[subpath].append([lastctrl[:], last[:], last[:]])
return csp
def unCubicSuperPath(csp):
a = []
for subpath in csp:
if subpath:
a.append(['M',subpath[0][1][:]])
for i in range(1,len(subpath)):
a.append(['C',subpath[i-1][2][:] + subpath[i][0][:] + subpath[i][1][:]])
a.append(['M', subpath[0][1][:]])
for i in range(1, len(subpath)):
a.append(['C', subpath[i - 1][2][:] + subpath[i][0][:] + subpath[i][1][:]])
return a
def parsePath(d):
return CubicSuperPath(simplepath.parsePath(d))
def formatPath(p):
return simplepath.formatPath(unCubicSuperPath(p))
# 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 *
import re
path = "./svg/example.svg"
# path = "./svg/example.svg"
# path = "./svg/big_example.svg"
# path = "./svg/medium_example.svg"
@@ -15,9 +15,11 @@ path = "./svg/example.svg"
# path = "./svg/grid.svg"
# path = "./svg/Lorenz_attractor.svg"
# path = "./svg/text.svg"
# path = "./svg/A.svg"
path = "./example.svg"
output = "./gcode/output.gcode"
output = "./gcode/output2.gcode"
output = "temp.gcode"
debug = False
@@ -29,24 +31,21 @@ debug = False
# todo make interface
def generate_gcode(path):
def generate_gcode(path, autoScale = True):
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 = []
tree = ET.parse(path)
# tree = ET.parse(sys.stdin)
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')
height = root.get('height')
@@ -59,34 +58,40 @@ def generate_gcode(path):
print("Unable to get width and height for the svg")
sys.exit(1)
width = re.sub("[^0-9]", "", width)
height = re.sub("[^0-9]", "", height)
width = float(re.sub("[^0-9]", "", width))
height = float(re.sub("[^0-9]", "", height))
print("\n width / height")
print(width, height)
width = float(width)
height = float(height)
if autoScale:
# scale_x = bed_max_x / max(width, height)
# scale_y = bed_max_y / max(width, height)
# scale_x= min(scale_x, scale_y)
# scale_y = scale_x
#
scale_x = 1
scale_y = 1
scale_x = min(bed_max_x / max(width, height),bed_max_y / max(width, height))
# scale_y = bed_max_y / max(width, height)
# scale_x = min(scale_x, scale_y)
scale_y = scale_x
print("\npreamble")
print(preamble)
commands.append(preamble)
else:
scale_x = 1
scale_y = 1
print("scale factor: ", scale_y)
if debug:
print("\n preamble")
print(preamble)
commands.append(header)
commands.append("(begin)")
for i in [f"{feed_rate}", "G90"]:
commands.append(i)
commands.append(preamble)
commands.append(f"F{feed_rate}")
print("\n begin main loop")
for elem in root.iter():
if debug:
print("\nelem")
print("\n\n\n***************** elem ******************")
print(elem)
try:
@@ -98,27 +103,35 @@ def generate_gcode(path):
if tag_suffix in svg_shapes:
if debug:
print("\ntag_suffix")
print("\n tag_suffix")
print(tag_suffix)
for i in ["\n", "({})".format(tag_suffix), ""]:
commands.append(i) # add tag name ad comment
shape_class = getattr(shapes_pkg, tag_suffix)
if debug:
print("\n shape_class")
print(shape_class)
shape_obj = shape_class(elem)
if debug:
print("\n shape_obj")
#print(shape_obj)
d = shape_obj.d_path()
m = shape_obj.transformation_matrix() # todo work out what d and m are
if debug:
print("\nd", d)
print("\n d", d)
print(d)
print("\nm", m)
print("\n m", m)
print(m)
if d: # begin shape processing
if debug:
print("\nshape preamble")
print("\n shape preamble")
print(shape_preamble)
commands.append(shape_preamble)
@@ -129,23 +142,20 @@ def generate_gcode(path):
for x, y in p:
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, y, zTravel, "G0", precision)
command = g_string(x * scale_x, (-y+height) * scale_y, zTravel, "G0", precision) #todo why do i need to flip?
commands.append(command)
if debug:
print(command)
first = False
# 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, y, zDraw, "G1", precision)
command = g_string(x * scale_x, (-y+height) * scale_y, zDraw, "G1", precision)
commands.append(command)
# else:
# print("out of bed")
if debug:
print(command)
# count += 1
# commands.append("G0 Z%0.1f" %zTravel)
command = g_string(x, y, zTravel, "G0", precision)
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}"
if __name__ == "__main__":
c = generate_gcode(path)
# for i in c:
# print(i)
# if __name__ == "__main__":
# c = generate_gcode(path)
# # for i in c:
# # 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")
print("done")
print("done!")
+652789
View File
File diff suppressed because it is too large. Load diff