Merge commit '19fcc1186a1173b594a16fcd2a88a3616415b291'

This commit is contained in:
Lawrence Johnston 2012-03-18 14:32:48 -07:00
commit 20349fc834
4 changed files with 78 additions and 51 deletions

View file

@ -188,9 +188,19 @@ class UltimakerCheckupPage(InfoPage):
self.comm.close() self.comm.close()
return return
if self.DoCommCommandWithTimeout("M104 S0") == False:
wx.CallAfter(self.AddProgressText, "Failed to set temperature")
self.comm.close()
return
wx.MessageBox('Please move the printer head to the center of the machine\nalso move the platform so it is not at the highest or lowest position,\nand make sure the machine is powered on.', 'Machine check', wx.OK | wx.ICON_INFORMATION) wx.MessageBox('Please move the printer head to the center of the machine\nalso move the platform so it is not at the highest or lowest position,\nand make sure the machine is powered on.', 'Machine check', wx.OK | wx.ICON_INFORMATION)
idleTemp = self.readTemp() idleTemp = self.readTemp()
if idleTemp > 40:
wx.CallAfter(self.AddProgressText, "Waiting for head to cool down before temperature test...")
while idleTemp > 40:
idleTemp = self.readTemp()
time.sleep(1)
wx.CallAfter(self.AddProgressText, "Checking heater and temperature sensor...") wx.CallAfter(self.AddProgressText, "Checking heater and temperature sensor...")
wx.CallAfter(self.AddProgressText, "(This takes about 30 seconds)") wx.CallAfter(self.AddProgressText, "(This takes about 30 seconds)")
@ -267,6 +277,7 @@ class UltimakerCheckupPage(InfoPage):
return True return True
if ret == False: if ret == False:
return False return False
time.sleep(1)
def DoCommCommandWithTimeout(self, cmd = None, replyStart = 'ok'): def DoCommCommandWithTimeout(self, cmd = None, replyStart = 'ok'):
if cmd != None: if cmd != None:

View file

@ -2,11 +2,13 @@ import sys
import math import math
import threading import threading
import re import re
import os
from newui import util3d from newui import util3d
class gcode(): class gcode():
def __init__(self, filename): def __init__(self, filename):
print os.stat(filename).st_size
f = open(filename, 'r') f = open(filename, 'r')
pos = util3d.Vector3() pos = util3d.Vector3()
posOffset = util3d.Vector3() posOffset = util3d.Vector3()
@ -21,7 +23,9 @@ class gcode():
pathType = 'CUSTOM'; pathType = 'CUSTOM';
layerNr = 0; #Note layer 0 will be the start code. layerNr = 0; #Note layer 0 will be the start code.
startCodeDone = False startCodeDone = False
self.stepsPerE = 865.888
currentPath = {'type': 'move', 'pathType': pathType, 'list': [pos.copy()], 'layerNr': layerNr} currentPath = {'type': 'move', 'pathType': pathType, 'list': [pos.copy()], 'layerNr': layerNr}
currentPath['list'][-1].e = totalExtrusion
for line in f: for line in f:
if line.startswith(';TYPE:'): if line.startswith(';TYPE:'):
pathType = line[6:].strip() pathType = line[6:].strip()
@ -79,6 +83,7 @@ class gcode():
pathList.append(currentPath) pathList.append(currentPath)
currentPath = {'type': moveType, 'pathType': pathType, 'list': [currentPath['list'][-1]], 'layerNr': layerNr} currentPath = {'type': moveType, 'pathType': pathType, 'list': [currentPath['list'][-1]], 'layerNr': layerNr}
currentPath['list'].append(pos.copy()) currentPath['list'].append(pos.copy())
currentPath['list'][-1].e = totalExtrusion
elif G == 20: #Units are inches elif G == 20: #Units are inches
scale = 25.4 scale = 25.4
elif G == 21: #Units are mm elif G == 21: #Units are mm
@ -123,6 +128,9 @@ class gcode():
elif M == 84: #Disable step drivers elif M == 84: #Disable step drivers
pass pass
elif M == 92: #Set steps per unit elif M == 92: #Set steps per unit
e = self.getCodeFloat(line, 'E')
if e is not None:
self.stepsPerE = e
pass pass
elif M == 104: #Set temperature, no wait elif M == 104: #Set temperature, no wait
pass pass

View file

@ -3,6 +3,7 @@ import math
import threading import threading
import re import re
import time import time
import os
from wx import glcanvas from wx import glcanvas
import wx import wx
@ -47,13 +48,11 @@ class previewPanel(wx.Panel):
self.toolbar.AddControl(button) self.toolbar.AddControl(button)
self.Bind(wx.EVT_BUTTON, self.OnTopClick, button) self.Bind(wx.EVT_BUTTON, self.OnTopClick, button)
self.transparentButton = wx.Button(self.toolbar, -1, "T", size=(21,21)) self.viewSelect = wx.ComboBox(self.toolbar, -1, 'Model - Normal', choices=['Model - Normal', 'Model - Transparent', 'Model - X-Ray', 'GCode', 'Mixed'], style=wx.CB_DROPDOWN|wx.CB_READONLY)
self.toolbar.AddControl(self.transparentButton) self.toolbar.AddControl(self.viewSelect)
self.Bind(wx.EVT_BUTTON, self.OnTransparentClick, self.transparentButton) self.viewSelect.Bind(wx.EVT_TEXT, self.OnViewChange)
self.XRayButton = wx.Button(self.toolbar, -1, "X-RAY", size=(21*2,21)) self.glCanvas.viewMode = self.viewSelect.GetValue()
self.toolbar.AddControl(self.XRayButton)
self.Bind(wx.EVT_BUTTON, self.OnXRayClick, self.XRayButton)
self.layerSpin = wx.SpinCtrl(self.toolbar, -1, '', size=(21*4,21), style=wx.SP_ARROW_KEYS) self.layerSpin = wx.SpinCtrl(self.toolbar, -1, '', size=(21*4,21), style=wx.SP_ARROW_KEYS)
self.toolbar.AddControl(self.layerSpin) self.toolbar.AddControl(self.layerSpin)
self.Bind(wx.EVT_SPINCTRL, self.OnLayerNrChange, self.layerSpin) self.Bind(wx.EVT_SPINCTRL, self.OnLayerNrChange, self.layerSpin)
@ -80,7 +79,7 @@ class previewPanel(wx.Panel):
self.glCanvas.Refresh() self.glCanvas.Refresh()
def OnLayerNrChange(self, e): def OnLayerNrChange(self, e):
self.modelDirty = True self.gcodeDirty = True
self.glCanvas.Refresh() self.glCanvas.Refresh()
def updateCenterX(self, x): def updateCenterX(self, x):
@ -103,6 +102,7 @@ class previewPanel(wx.Panel):
def loadModelFile(self, filename): def loadModelFile(self, filename):
self.modelFilename = filename self.modelFilename = filename
self.gcodeFilename = filename[: filename.rfind('.')] + "_export.gcode"
#Do the STL file loading in a background thread so we don't block the UI. #Do the STL file loading in a background thread so we don't block the UI.
thread = threading.Thread(target=self.DoModelLoad) thread = threading.Thread(target=self.DoModelLoad)
thread.start() thread.start()
@ -121,38 +121,29 @@ class previewPanel(wx.Panel):
triangleMesh.origonalVertexes[i] = triangleMesh.origonalVertexes[i].copy() triangleMesh.origonalVertexes[i] = triangleMesh.origonalVertexes[i].copy()
triangleMesh.getMinimumZ() triangleMesh.getMinimumZ()
self.triangleMesh = triangleMesh self.triangleMesh = triangleMesh
self.gcode = None
self.updateModelTransform() self.updateModelTransform()
wx.CallAfter(self.updateToolbar) wx.CallAfter(self.updateToolbar)
wx.CallAfter(self.glCanvas.Refresh) wx.CallAfter(self.glCanvas.Refresh)
if os.path.isfile(self.gcodeFilename):
self.DoGCodeLoad()
def DoGCodeLoad(self): def DoGCodeLoad(self):
gcode = gcodeInterpreter.gcode(self.gcodeFilename) gcode = gcodeInterpreter.gcode(self.gcodeFilename)
self.modelDirty = False self.gcodeDirty = False
self.gcode = gcode self.gcode = gcode
self.triangleMesh = None self.gcodeDirty = True
self.modelDirty = True
wx.CallAfter(self.updateToolbar) wx.CallAfter(self.updateToolbar)
wx.CallAfter(self.glCanvas.Refresh) wx.CallAfter(self.glCanvas.Refresh)
def updateToolbar(self): def updateToolbar(self):
self.transparentButton.Show(self.triangleMesh != None)
self.XRayButton.Show(self.triangleMesh != None)
self.layerSpin.Show(self.gcode != None) self.layerSpin.Show(self.gcode != None)
if self.gcode != None: if self.gcode != None:
self.layerSpin.SetRange(1, self.gcode.layerCount) self.layerSpin.SetRange(1, self.gcode.layerCount)
self.toolbar.Realize() self.toolbar.Realize()
def OnTransparentClick(self, e): def OnViewChange(self, e):
self.glCanvas.renderTransparent = not self.glCanvas.renderTransparent self.glCanvas.viewMode = self.viewSelect.GetValue()
if self.glCanvas.renderTransparent:
self.glCanvas.renderXRay = False
self.glCanvas.Refresh()
def OnXRayClick(self, e):
self.glCanvas.renderXRay = not self.glCanvas.renderXRay
if self.glCanvas.renderXRay:
self.glCanvas.renderTransparent = False
self.glCanvas.Refresh() self.glCanvas.Refresh()
def updateModelTransform(self, f=0): def updateModelTransform(self, f=0):
@ -228,9 +219,8 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
self.lineWidth = 0.4 self.lineWidth = 0.4
self.fillLineWidth = 0.4 self.fillLineWidth = 0.4
self.view3D = True self.view3D = True
self.renderTransparent = False
self.renderXRay = False
self.modelDisplayList = None self.modelDisplayList = None
self.gcodeDisplayList = None
def OnMouseMotion(self,e): def OnMouseMotion(self,e):
if e.Dragging() and e.LeftIsDown(): if e.Dragging() and e.LeftIsDown():
@ -260,6 +250,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
self.Refresh() self.Refresh()
def OnEraseBackground(self,event): def OnEraseBackground(self,event):
#Workaround for windows background redraw flicker.
pass pass
def OnSize(self,event): def OnSize(self,event):
@ -319,11 +310,11 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
glEnd() glEnd()
if self.parent.gcode != None: if self.parent.gcode != None:
if self.modelDisplayList == None: if self.gcodeDisplayList == None:
self.modelDisplayList = glGenLists(1); self.gcodeDisplayList = glGenLists(1);
if self.parent.modelDirty: if self.parent.gcodeDirty:
self.parent.modelDirty = False self.parent.gcodeDirty = False
glNewList(self.modelDisplayList, GL_COMPILE) glNewList(self.gcodeDisplayList, GL_COMPILE)
for path in self.parent.gcode.pathList: for path in self.parent.gcode.pathList:
c = 1.0 c = 1.0
if path['layerNr'] != self.parent.layerSpin.GetValue(): if path['layerNr'] != self.parent.layerSpin.GetValue():
@ -352,6 +343,10 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
for i in xrange(0, len(path['list'])-1): for i in xrange(0, len(path['list'])-1):
v0 = path['list'][i] v0 = path['list'][i]
v1 = path['list'][i+1] v1 = path['list'][i+1]
dist = (v0 - v1).vsize()
if dist > 0:
extrusionMMperDist = (v1.e - v0.e) / (v0 - v1).vsize() / self.parent.gcode.stepsPerE
#TODO: Calculate line width from ePerDistance (needs layer thickness, steps_per_E and filament diameter)
normal = (v0 - v1).cross(util3d.Vector3(0,0,1)) normal = (v0 - v1).cross(util3d.Vector3(0,0,1))
normal.normalize() normal.normalize()
v2 = v0 + normal * lineWidth v2 = v0 + normal * lineWidth
@ -360,16 +355,25 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
v1 = v1 - normal * lineWidth v1 = v1 - normal * lineWidth
glBegin(GL_QUADS) glBegin(GL_QUADS)
glVertex3f(v0.x, v0.y, v0.z - 0.001) if path['pathType'] == 'FILL': #Remove depth buffer fighting on infill/wall overlap
glVertex3f(v1.x, v1.y, v1.z - 0.001) glVertex3f(v0.x, v0.y, v0.z - 0.02)
glVertex3f(v3.x, v3.y, v3.z - 0.001) glVertex3f(v1.x, v1.y, v1.z - 0.02)
glVertex3f(v2.x, v2.y, v2.z - 0.001) 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() glEnd()
for v in path['list']: for v in path['list']:
glBegin(GL_TRIANGLE_FAN) glBegin(GL_TRIANGLE_FAN)
glVertex3f(v.x, v.y, v.z - 0.001) glVertex3f(v.x, v.y, v.z - 0.001)
for i in xrange(0, 16+1): 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.001) 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() glEnd()
else: else:
glBegin(GL_LINE_STRIP) glBegin(GL_LINE_STRIP)
@ -377,7 +381,8 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
glVertex3f(v.x, v.y, v.z) glVertex3f(v.x, v.y, v.z)
glEnd() glEnd()
glEndList() glEndList()
glCallList(self.modelDisplayList) if self.viewMode == "GCode" or self.viewMode == "Mixed":
glCallList(self.gcodeDisplayList)
if self.parent.triangleMesh != None: if self.parent.triangleMesh != None:
if self.modelDisplayList == None: if self.modelDisplayList == None:
@ -411,13 +416,14 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
glPopMatrix() glPopMatrix()
glPopMatrix() glPopMatrix()
glEndList() glEndList()
if self.renderTransparent: if self.viewMode == "Model - Transparent" or self.viewMode == "Mixed":
#If we want transparent, then first render a solid black model to remove the printer size lines. #If we want transparent, then first render a solid black model to remove the printer size lines.
glDisable(GL_BLEND) if self.viewMode != "Mixed":
glDisable(GL_LIGHTING) glDisable(GL_BLEND)
glColor3f(0,0,0) glDisable(GL_LIGHTING)
glCallList(self.modelDisplayList) glColor3f(0,0,0)
glColor3f(1,1,1) glCallList(self.modelDisplayList)
glColor3f(1,1,1)
#After the black model is rendered, render the model again but now with lighting and no depth testing. #After the black model is rendered, render the model again but now with lighting and no depth testing.
glDisable(GL_DEPTH_TEST) glDisable(GL_DEPTH_TEST)
glEnable(GL_LIGHTING) glEnable(GL_LIGHTING)
@ -425,7 +431,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
glBlendFunc(GL_ONE, GL_ONE) glBlendFunc(GL_ONE, GL_ONE)
glEnable(GL_LIGHTING) glEnable(GL_LIGHTING)
glCallList(self.modelDisplayList) glCallList(self.modelDisplayList)
elif self.renderXRay: elif self.viewMode == "Model - X-Ray":
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE) glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE)
glDisable(GL_DEPTH_TEST) glDisable(GL_DEPTH_TEST)
glEnable(GL_STENCIL_TEST); glEnable(GL_STENCIL_TEST);
@ -436,7 +442,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE)
glStencilFunc(GL_EQUAL, 0, 1); glStencilFunc(GL_EQUAL, 0, 1);
glColor(0, 1, 0) glColor(1, 1, 1)
glCallList(self.modelDisplayList) glCallList(self.modelDisplayList)
glStencilFunc(GL_EQUAL, 1, 1); glStencilFunc(GL_EQUAL, 1, 1);
glColor(1, 0, 0) glColor(1, 0, 0)
@ -444,16 +450,16 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
glPushMatrix() glPushMatrix()
glLoadIdentity() glLoadIdentity()
for i in xrange(2, 20, 2): for i in xrange(2, 15, 2):
glStencilFunc(GL_EQUAL, i, 0xFF); glStencilFunc(GL_EQUAL, i, 0xFF);
glColor(0, float(i)/10, 0) glColor(float(i)/10, float(i)/10, float(i)/5)
glBegin(GL_QUADS) glBegin(GL_QUADS)
glVertex3f(-1000,-1000,-1) glVertex3f(-1000,-1000,-1)
glVertex3f( 1000,-1000,-1) glVertex3f( 1000,-1000,-1)
glVertex3f( 1000, 1000,-1) glVertex3f( 1000, 1000,-1)
glVertex3f(-1000, 1000,-1) glVertex3f(-1000, 1000,-1)
glEnd() glEnd()
for i in xrange(1, 20, 2): for i in xrange(1, 15, 2):
glStencilFunc(GL_EQUAL, i, 0xFF); glStencilFunc(GL_EQUAL, i, 0xFF);
glColor(float(i)/10, 0, 0) glColor(float(i)/10, 0, 0)
glBegin(GL_QUADS) glBegin(GL_QUADS)
@ -466,7 +472,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
glEnable(GL_DEPTH_TEST) glEnable(GL_DEPTH_TEST)
else: elif self.viewMode == "Model - Normal":
glEnable(GL_LIGHTING) glEnable(GL_LIGHTING)
glCallList(self.modelDisplayList) glCallList(self.modelDisplayList)
glFlush() glFlush()
@ -478,7 +484,7 @@ class PreviewGLCanvas(glcanvas.GLCanvas):
size = self.GetSize() size = self.GetSize()
glViewport(0,0, size.GetWidth(), size.GetHeight()) glViewport(0,0, size.GetWidth(), size.GetHeight())
if self.renderTransparent: if self.viewMode == "Model - Transparent" or self.viewMode == "Mixed":
glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.5, 0.4, 0.3, 1.0]) glLightfv(GL_LIGHT0, GL_DIFFUSE, [0.5, 0.4, 0.3, 1.0])
glLightfv(GL_LIGHT0, GL_AMBIENT, [0.1, 0.1, 0.1, 0.0]) glLightfv(GL_LIGHT0, GL_AMBIENT, [0.1, 0.1, 0.1, 0.0])
else: else:

View file

@ -66,7 +66,9 @@ class sliceProgessPanel(wx.Panel):
self.abort = True self.abort = True
def OnShowGCode(self, e): def OnShowGCode(self, e):
self.mainWindow.preview3d.loadGCodeFile(self.filename[: self.filename.rfind('.')] + "_export.gcode") self.mainWindow.preview3d.loadModelFile(self.filename)
self.mainWindow.preview3d.viewSelect.SetValue("GCode")
self.mainWindow.preview3d.OnViewChange(None)
def OnShowLog(self, e): def OnShowLog(self, e):
LogWindow('\n'.join(self.progressLog)) LogWindow('\n'.join(self.progressLog))