From: daid Date: Mon, 7 May 2012 11:24:26 +0000 (+0200) Subject: Updated gcode interperter and GCode preview. Fixed #77 X-Git-Tag: RC3~12^2~8 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=58b4a4816253f75483074b0001d398042b6ca351;p=cura.git Updated gcode interperter and GCode preview. Fixed #77 --- diff --git a/Cura/gui/opengl.py b/Cura/gui/opengl.py index 92ffcdea..0507f566 100644 --- a/Cura/gui/opengl.py +++ b/Cura/gui/opengl.py @@ -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) diff --git a/Cura/gui/preview3d.py b/Cura/gui/preview3d.py index 52665936..71a2638b 100644 --- a/Cura/gui/preview3d.py +++ b/Cura/gui/preview3d.py @@ -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) diff --git a/Cura/util/gcodeInterpreter.py b/Cura/util/gcodeInterpreter.py index 5714972c..08586178 100644 --- a/Cura/util/gcodeInterpreter.py +++ b/Cura/util/gcodeInterpreter.py @@ -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