Updated gcode interperter and GCode preview. Fixed #77
This commit is contained in:
parent
15fe5a60c6
commit
58b4a48162
3 changed files with 104 additions and 80 deletions
|
@ -1,3 +1,7 @@
|
|||
import math
|
||||
|
||||
from util import util3d
|
||||
from util import profile
|
||||
|
||||
try:
|
||||
import OpenGL
|
||||
|
@ -215,3 +219,91 @@ def DrawSTL(mesh):
|
|||
glVertex3f(v3.x, v3.y, v3.z)
|
||||
glVertex3f(v2.x, v2.y, v2.z)
|
||||
glEnd()
|
||||
|
||||
def DrawGCodeLayer(layer):
|
||||
filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
|
||||
filamentArea = math.pi * filamentRadius * filamentRadius
|
||||
lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10
|
||||
|
||||
fillCycle = 0
|
||||
fillColorCycle = [[0.5,0.5,0.0],[0.0,0.5,0.5],[0.5,0.0,0.5]]
|
||||
|
||||
glDisable(GL_CULL_FACE)
|
||||
for path in layer:
|
||||
if path.type == 'move':
|
||||
glColor3f(0,0,1)
|
||||
if path.type == 'extrude':
|
||||
if path.pathType == 'FILL':
|
||||
glColor3fv(fillColorCycle[fillCycle])
|
||||
fillCycle = (fillCycle + 1) % len(fillColorCycle)
|
||||
elif path.pathType == 'WALL-INNER':
|
||||
glColor3fv([0,1,0])
|
||||
elif path.pathType == 'SUPPORT':
|
||||
glColor3fv([0,1,1])
|
||||
elif path.pathType == 'SKIRT':
|
||||
glColor3fv([0,0.5,0.5])
|
||||
else:
|
||||
glColor3fv([1,0,0])
|
||||
if path.type == 'retract':
|
||||
glColor3fv([0,1,1])
|
||||
if path.type == 'extrude':
|
||||
drawLength = 0.0
|
||||
prevNormal = None
|
||||
for i in xrange(0, len(path.list)-1):
|
||||
v0 = path.list[i]
|
||||
v1 = path.list[i+1]
|
||||
|
||||
# Calculate line width from ePerDistance (needs layer thickness and filament diameter)
|
||||
dist = (v0 - v1).vsize()
|
||||
if dist > 0 and path.layerThickness > 0:
|
||||
extrusionMMperDist = (v1.e - v0.e) / dist
|
||||
lineWidth = extrusionMMperDist * filamentArea / path.layerThickness / 2
|
||||
|
||||
drawLength += (v0 - v1).vsize()
|
||||
normal = (v0 - v1).cross(util3d.Vector3(0,0,1))
|
||||
normal.normalize()
|
||||
|
||||
vv2 = v0 + normal * lineWidth
|
||||
vv3 = v1 + normal * lineWidth
|
||||
vv0 = v0 - normal * lineWidth
|
||||
vv1 = v1 - normal * lineWidth
|
||||
|
||||
glBegin(GL_QUADS)
|
||||
glVertex3f(vv0.x, vv0.y, vv0.z - 0.01)
|
||||
glVertex3f(vv1.x, vv1.y, vv1.z - 0.01)
|
||||
glVertex3f(vv3.x, vv3.y, vv3.z - 0.01)
|
||||
glVertex3f(vv2.x, vv2.y, vv2.z - 0.01)
|
||||
glEnd()
|
||||
if prevNormal != None:
|
||||
n = (normal + prevNormal)
|
||||
n.normalize()
|
||||
vv4 = v0 + n * lineWidth
|
||||
vv5 = v0 - n * lineWidth
|
||||
glBegin(GL_QUADS)
|
||||
glVertex3f(vv2.x, vv2.y, vv2.z)
|
||||
glVertex3f(vv4.x, vv4.y, vv4.z)
|
||||
glVertex3f(prevVv3.x, prevVv3.y, prevVv3.z)
|
||||
glVertex3f(v0.x, v0.y, v0.z)
|
||||
|
||||
glVertex3f(vv0.x, vv0.y, vv0.z)
|
||||
glVertex3f(vv5.x, vv5.y, vv5.z)
|
||||
glVertex3f(prevVv1.x, prevVv1.y, prevVv1.z)
|
||||
glVertex3f(v0.x, v0.y, v0.z)
|
||||
glEnd()
|
||||
|
||||
prevNormal = normal
|
||||
prevVv1 = vv1
|
||||
prevVv3 = vv3
|
||||
|
||||
#for v in path.list:
|
||||
# glBegin(GL_TRIANGLE_FAN)
|
||||
# glVertex3f(v.x, v.y, v.z - 0.001)
|
||||
# for i in xrange(0, 16+1):
|
||||
# glVertex3f(v.x + math.cos(math.pi*2/16*i) * lineWidth, v.y + math.sin(math.pi*2/16*i) * lineWidth, v.z - 0.01)
|
||||
# glEnd()
|
||||
else:
|
||||
glBegin(GL_LINE_STRIP)
|
||||
for v in path.list:
|
||||
glVertex3f(v.x, v.y, v.z)
|
||||
glEnd()
|
||||
glEnable(GL_CULL_FACE)
|
||||
|
|
|
@ -446,85 +446,13 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
|
|||
self.gcodeDisplayList = glGenLists(len(self.parent.gcode.layerList));
|
||||
self.gcodeDisplayListCount = len(self.parent.gcode.layerList)
|
||||
self.parent.gcodeDirty = False
|
||||
prevLayerZ = 0.0
|
||||
curLayerZ = 0.0
|
||||
|
||||
layerThickness = 0.0
|
||||
filamentRadius = profile.getProfileSettingFloat('filament_diameter') / 2
|
||||
filamentArea = math.pi * filamentRadius * filamentRadius
|
||||
lineWidth = profile.getProfileSettingFloat('nozzle_size') / 2 / 10
|
||||
|
||||
curLayerNum = 0
|
||||
for layer in self.parent.gcode.layerList:
|
||||
glNewList(self.gcodeDisplayList + curLayerNum, GL_COMPILE)
|
||||
glDisable(GL_CULL_FACE)
|
||||
curLayerZ = layer[0].list[1].z
|
||||
layerThickness = curLayerZ - prevLayerZ
|
||||
prevLayerZ = layer[-1].list[-1].z
|
||||
for path in layer:
|
||||
if path.type == 'move':
|
||||
glColor3f(0,0,1)
|
||||
if path.type == 'extrude':
|
||||
if path.pathType == 'FILL':
|
||||
glColor3f(0.5,0.5,0)
|
||||
elif path.pathType == 'WALL-INNER':
|
||||
glColor3f(0,1,0)
|
||||
elif path.pathType == 'SUPPORT':
|
||||
glColor3f(0,1,1)
|
||||
elif path.pathType == 'SKIRT':
|
||||
glColor3f(0,0.5,0.5)
|
||||
else:
|
||||
glColor3f(1,0,0)
|
||||
if path.type == 'retract':
|
||||
glColor3f(0,1,1)
|
||||
if path.type == 'extrude':
|
||||
for i in xrange(0, len(path.list)-1):
|
||||
v0 = path.list[i]
|
||||
v1 = path.list[i+1]
|
||||
|
||||
# Calculate line width from ePerDistance (needs layer thickness and filament diameter)
|
||||
dist = (v0 - v1).vsize()
|
||||
if dist > 0 and layerThickness > 0:
|
||||
extrusionMMperDist = (v1.e - v0.e) / dist
|
||||
lineWidth = extrusionMMperDist * filamentArea / layerThickness / 2
|
||||
|
||||
normal = (v0 - v1).cross(util3d.Vector3(0,0,1))
|
||||
normal.normalize()
|
||||
v2 = v0 + normal * lineWidth
|
||||
v3 = v1 + normal * lineWidth
|
||||
v0 = v0 - normal * lineWidth
|
||||
v1 = v1 - normal * lineWidth
|
||||
|
||||
glBegin(GL_QUADS)
|
||||
if path.pathType == 'FILL': #Remove depth buffer fighting on infill/wall overlap
|
||||
glVertex3f(v0.x, v0.y, v0.z - 0.02)
|
||||
glVertex3f(v1.x, v1.y, v1.z - 0.02)
|
||||
glVertex3f(v3.x, v3.y, v3.z - 0.02)
|
||||
glVertex3f(v2.x, v2.y, v2.z - 0.02)
|
||||
else:
|
||||
glVertex3f(v0.x, v0.y, v0.z - 0.01)
|
||||
glVertex3f(v1.x, v1.y, v1.z - 0.01)
|
||||
glVertex3f(v3.x, v3.y, v3.z - 0.01)
|
||||
glVertex3f(v2.x, v2.y, v2.z - 0.01)
|
||||
glEnd()
|
||||
|
||||
#for v in path['list']:
|
||||
# glBegin(GL_TRIANGLE_FAN)
|
||||
# glVertex3f(v.x, v.y, v.z - 0.001)
|
||||
# for i in xrange(0, 16+1):
|
||||
# if path['pathType'] == 'FILL': #Remove depth buffer fighting on infill/wall overlap
|
||||
# glVertex3f(v.x + math.cos(math.pi*2/16*i) * lineWidth, v.y + math.sin(math.pi*2/16*i) * lineWidth, v.z - 0.02)
|
||||
# else:
|
||||
# glVertex3f(v.x + math.cos(math.pi*2/16*i) * lineWidth, v.y + math.sin(math.pi*2/16*i) * lineWidth, v.z - 0.01)
|
||||
# glEnd()
|
||||
else:
|
||||
glBegin(GL_LINE_STRIP)
|
||||
for v in path.list:
|
||||
glVertex3f(v.x, v.y, v.z)
|
||||
glEnd()
|
||||
curLayerNum += 1
|
||||
glEnable(GL_CULL_FACE)
|
||||
opengl.DrawGCodeLayer(layer)
|
||||
glEndList()
|
||||
curLayerNum += 1
|
||||
|
||||
if self.parent.gcode != None and (self.viewMode == "GCode" or self.viewMode == "Mixed"):
|
||||
glEnable(GL_COLOR_MATERIAL)
|
||||
|
|
|
@ -10,9 +10,10 @@ from util import util3d
|
|||
from util import profile
|
||||
|
||||
class gcodePath(object):
|
||||
def __init__(self, newType, pathType, startPoint):
|
||||
def __init__(self, newType, pathType, layerThickness, startPoint):
|
||||
self.type = newType
|
||||
self.pathType = pathType
|
||||
self.layerThickness = layerThickness
|
||||
self.list = [startPoint]
|
||||
|
||||
class gcode(object):
|
||||
|
@ -61,10 +62,11 @@ class gcode(object):
|
|||
scale = 1.0
|
||||
posAbs = True
|
||||
feedRate = 3600
|
||||
layerThickness = 0.1
|
||||
pathType = 'CUSTOM';
|
||||
startCodeDone = False
|
||||
currentLayer = []
|
||||
currentPath = gcodePath('move', pathType, pos.copy())
|
||||
currentPath = gcodePath('move', pathType, layerThickness, pos.copy())
|
||||
currentPath.list[0].e = totalExtrusion
|
||||
currentLayer.append(currentPath)
|
||||
for line in gcodeFile:
|
||||
|
@ -88,6 +90,9 @@ class gcode(object):
|
|||
pathType = 'WALL-INNER'
|
||||
elif comment == 'skirt':
|
||||
pathType = 'SKIRT'
|
||||
if comment.startswith('LAYER:'):
|
||||
self.layerList.append(currentLayer)
|
||||
currentLayer = []
|
||||
if pathType != "CUSTOM":
|
||||
startCodeDone = True
|
||||
line = line[0:line.find(';')]
|
||||
|
@ -126,9 +131,8 @@ class gcode(object):
|
|||
else:
|
||||
pos.z += z * scale
|
||||
#Check if we have a new layer.
|
||||
if oldPos.z < pos.z and startCodeDone and len(currentLayer) > 0:
|
||||
self.layerList.append(currentLayer)
|
||||
currentLayer = []
|
||||
if oldPos.z != pos.z:
|
||||
layerThickness = abs(oldPos.z - pos.z)
|
||||
if f is not None:
|
||||
feedRate = f
|
||||
if x is not None or y is not None or z is not None:
|
||||
|
@ -152,7 +156,7 @@ class gcode(object):
|
|||
if totalExtrusion > maxExtrusion:
|
||||
maxExtrusion = totalExtrusion
|
||||
if currentPath.type != moveType or currentPath.pathType != pathType:
|
||||
currentPath = gcodePath(moveType, pathType, currentPath.list[-1])
|
||||
currentPath = gcodePath(moveType, pathType, layerThickness, currentPath.list[-1])
|
||||
currentLayer.append(currentPath)
|
||||
newPos = pos.copy()
|
||||
newPos.e = totalExtrusion
|
||||
|
|
Loading…
Reference in a new issue