Commit 6d09776f authored by Julian Stirling's avatar Julian Stirling 🐧

Added simple way to go from layers to gcode

parent a68fdffc
......@@ -2,8 +2,9 @@ from .swomppy import version
from .swomppy import Params
from .swomppy import tol
from .machinecode import Layer
from .machinecode import PrintSpeeds
from .machinecode import PrintSettings
from .machinecode import PrintPath
from .machinecode import CodeGen
from .machinecode import generateGcode
from .spaths import spath
from .spaths import spathlist
......@@ -65,11 +65,16 @@ class Layer(object):
shell = self.outerShell
for n in range(self.numInset):
shell = shell.insetPath(self.offset)
if len(shell) ==0:
return
for subpath in shell:
self.allShells.append(subpath)
self.allPaths.append(subpath)
#innermostShell is inset of the printed innermost shell to stop fill lines overlapping too far
self.innermostShell= shell.insetPath(.75*self.offset)
if len(self.innermostShell) == 0:
return
#Do hatched fill inside this shell
if self.infillType in [Params.VertInfill,Params.CrossInfill]:
fillLines = self.innermostShell.generateInFill(spacing = self.infillSpacing)
......@@ -227,9 +232,20 @@ class PrintPath():
self.X=self.X+x
self.Y=self.Y+y
class PrintSpeeds():
class PrintSettings():
def __init__(self):
def __init__(self,flavor='Marlin', h0=.125, h=.25):
self.flavor = flavor
self.h0 = h0
self.h = h
assert flavor in CodeGen.acceptedFlavors, 'Unrecognised g-code flavor. Use %s'%str(CodeGen.acceptedFlavors)
if flavor=='UltiGCode':
self.fname_pre = 'sp_UM_'
self.w_ratio=1.4
else:
self.fname_pre = 'sp_Mar_'
self.w_ratio=1.2
self.MSpeed = list(range(PrintPath.N_PTH_TYPES))
self.ESpeed = list(range(PrintPath.N_PTH_TYPES))
......@@ -253,6 +269,25 @@ class PrintSpeeds():
def setMSpeed(self,ptype,speed):
self.MSpeed[ptype] = speed
def generateGcode(layers,name,printsettings=None,prependID=True):
if printsettings is None:
printsettings = PrintSettings()
else:
assert type(printsettings) is PrintSettings, 'printsettings must be a PrintSettings object'
assert type(name) is str, 'Print name must be a string'
if prependID:
fname = printsettings.fname_pre+name+'.gcode'
else:
fname = name+'.gcode'
gfile = CodeGen(fname,flavor=printsettings.flavor)
gfile.writeHeader()
gfile.writeGcode(layers,printsettings)
gfile.writeFooter()
class CodeGen():
acceptedFlavors=['UltiGCode','Marlin']
......@@ -332,10 +367,13 @@ M104 S0
;G-code OVER!'''%self.retract(),LineFeed=False)
self.flush()
def writeGcode(self,layers,w_ratio,h,h0,spd):
def writeGcode(self,layers,printsettings):
N_lay = len(layers)
for n,layer in enumerate(layers):
w=w_ratio*layer.offset
w=printsettings.w_ratio*layer.offset
h=printsettings.h
h0 = printsettings.h0
pth = PrintPath()
if n==0:
linetype = pth.PTH_BOTTOM
......@@ -358,20 +396,20 @@ M104 S0
pth.offset(85,85)
if n==0:
self.writeLayer(pth,w,h0,speed=spd,exFrac=1)
self.writeLayer(pth,w,h0,settings=printsettings,exFrac=1)
elif n==N_lay-2:
self.writeLayer(pth,w,h,speed=spd,exFrac=w/h)
self.writeLayer(pth,w,h,settings=printsettings,exFrac=w/h)
elif n==N_lay-1:
self.writeLayer(pth,w,h,speed=spd,exFrac=1)
self.writeLayer(pth,w,h,settings=printsettings,exFrac=1)
else:
self.writeLayer(pth,w,h,speed=spd,exFrac=.7)
self.writeLayer(pth,w,h,settings=printsettings,exFrac=.7)
def writeLayer(self,pth,w,h,speed=None,exFrac=1):
def writeLayer(self,pth,w,h,settings=None,exFrac=1):
n=self.LayersWritten
#TODO: improve machine/profile specific elements
if speed is None:
speed=PrintSpeeds()
if settings is None:
settings=PrintSpeeds()
self.z+=h
ex_per_d = exFrac*(w-h)*h+np.pi*(h/2)**2
retracted = False
......@@ -386,7 +424,7 @@ M104 S0
retracted=False
D = np.linalg.norm([self.x-x,self.y-y])
self.ex += ex_per_d*D
self.write('G1 F%.0f X%.3f Y%.3f E%.5f'%(speed.ESpeed[ty]*60,x,y,self.ex))
self.write('G1 F%.0f X%.3f Y%.3f E%.5f'%(settings.ESpeed[ty]*60,x,y,self.ex))
else:
......@@ -396,10 +434,10 @@ M104 S0
self.write(self.retract())
retracted=True
if first:
self.write('G0 F%.0f X%.3f Y%.3f Z%.3f'%(speed.MSpeed[ty]*60,x,y,self.z))
self.write('G0 F%.0f X%.3f Y%.3f Z%.3f'%(settings.MSpeed[ty]*60,x,y,self.z))
first = False
else:
self.write('G0 F%.0f X%.3f Y%.3f'%(speed.MSpeed[ty]*60,x,y))
self.write('G0 F%.0f X%.3f Y%.3f'%(settings.MSpeed[ty]*60,x,y))
self.x=x
self.y=y
......
......@@ -93,28 +93,41 @@ class scurve(pyx.normpath.normcurve_pt):
class spath:
#A swomppy path is a list of modified PyX normsubpath items that can be used in a normpath for PyX operations
def __init__(self,points,closed=False):
def __init__(self,inpoints,closed=False):
points = deepcopy(inpoints)
assert len(points)>1, "Must have at least two points"
if type(points) is list:
start = points.pop(0)
lastpoint = point = start
assert len(start)==2, "First item when creating an spath should be a tuple of (x,y) coordinates"
cpath = pyx.path.path(pyx.path.moveto(*start))
for point in points:
if len(point)==2:
#normal point
cpath.append(pyx.path.lineto(*point))
if pdist(lastpoint,point) > .05:
#normal point
cpath.append(pyx.path.lineto(*point))
lastpoint = point
elif len(point)==3 and len(point[0]) == 2:
#Curve to point
cpath.append(pyx.path.curveto(point[0][0],point[0][1],point[1][0],point[1][1],point[2][0],point[2][1]))
if closed:
cpath.append(pyx.path.closepath())
norm = cpath.normpath()
nitems = norm[0].normsubpathitems
#Length can be zero if only two points and they are very close
if len(nitems) == 0:
cpath.append(pyx.path.lineto(*points[0]))
norm = cpath.normpath()
nitems = norm[0].normsubpathitems
elif type(points) is pyx.path.normsubpath:
assert len(points)>0, "Must have at least one item"
nitems = points.normsubpathitems
else:
assert False, "spath should be created from a list of points or a pyx normsubpath"
self.items=[]
for item in nitems:
if type(item) is pyx.normpath.normline_pt:
......@@ -142,7 +155,11 @@ class spath:
return self.nsp
def start(self):
return self[0].start()
try:
return self[0].start()
except:
assert False
def end(self):
return self[-1].end()
......@@ -165,7 +182,6 @@ class spath:
boxbottom = spath([(l,b),(r,b)],False)
#intersection of path with bottom bounding box is lowest point
dists = self.intersectdist(boxbottom)
cprod = 0
n=0
while abs(cprod)<1e-9:
......
......@@ -9,6 +9,7 @@ class Params(object):
VertInfill=0
HorInfill=1
CrossInfill=2
NoInfill=3
def pdist(p1,p2):
return ((p1[0]-p2[0])**2+(p1[1]-p2[1])**2)**.5
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment