From fb2e0863df25adc6f17fe0bbbfa65b0b04e7c8e6 Mon Sep 17 00:00:00 2001 From: daid Date: Tue, 9 Jul 2013 10:16:50 +0200 Subject: [PATCH] Show a plane in the 3D window during printing to show the printing process. --- Cura/gui/printWindow.py | 27 +++++++++++++++++++++++---- Cura/gui/sceneView.py | 16 ++++++++++++++-- Cura/gui/util/openglGui.py | 8 +++++++- Cura/util/machineCom.py | 2 +- Cura/util/sliceEngine.py | 5 +++++ 5 files changed, 50 insertions(+), 8 deletions(-) diff --git a/Cura/gui/printWindow.py b/Cura/gui/printWindow.py index 1a4818ba..790562fc 100644 --- a/Cura/gui/printWindow.py +++ b/Cura/gui/printWindow.py @@ -23,12 +23,14 @@ from Cura.util.resources import getPathForImage #The printProcessMonitor is used from the main GUI python process. This monitors the printing python process. # This class also handles starting of the 2nd process for printing and all communications with it. class printProcessMonitor(): - def __init__(self): + def __init__(self, callback = None): self.handle = None self._state = 'CLOSED' self._z = 0.0 + self._callback = callback + self._id = -1 - def loadFile(self, filename): + def loadFile(self, filename, id): if self.handle is None: if platform.system() == "Darwin" and hasattr(sys, 'frozen'): cmdList = [os.path.join(os.path.dirname(sys.executable), 'Cura')] @@ -45,18 +47,22 @@ class printProcessMonitor(): self.thread.start() else: self.handle.stdin.write('LOAD:%s\n' % filename) + self._id = id def Monitor(self): p = self.handle line = p.stdout.readline() while len(line) > 0: + line = line.rstrip() try: if line.startswith('Z:'): self._z = float(line[2:]) + self._callCallback() elif line.startswith('STATE:'): - self._state = float(line[6:]) + self._state = line[6:] + self._callCallback() except: - pass + print sys.exc_info() #print '>' + line.rstrip() line = p.stdout.readline() line = p.stderr.readline() @@ -67,6 +73,19 @@ class printProcessMonitor(): self.handle = None self.thread = None + def getID(self): + return self._id + + def getZ(self): + return self._z + + def getState(self): + return self._state + + def _callCallback(self): + if self._callback is not None: + self._callback() + def startPrintInterface(filename): #startPrintInterface is called from the main script when we want the printer interface to run in a separate process. # It needs to run in a separate process, as any running python code blocks the GCode sender python code (http://wiki.python.org/moin/GlobalInterpreterLock). diff --git a/Cura/gui/sceneView.py b/Cura/gui/sceneView.py index b1f9cc06..6be22ed5 100644 --- a/Cura/gui/sceneView.py +++ b/Cura/gui/sceneView.py @@ -53,7 +53,7 @@ class SceneView(openglGui.glGuiPanel): self._platformMesh = meshLoader.loadMeshes(resources.getPathForMesh('ultimaker_platform.stl'))[0] self._platformMesh._drawOffset = numpy.array([0,0,2.5], numpy.float32) self._isSimpleMode = True - self._usbPrintMonitor = printWindow.printProcessMonitor() + self._usbPrintMonitor = printWindow.printProcessMonitor(lambda : self._queueRefresh()) self._viewport = None self._modelMatrix = None @@ -195,7 +195,7 @@ class SceneView(openglGui.glGuiPanel): def showPrintWindow(self): if self._gcodeFilename is None: return - self._usbPrintMonitor.loadFile(self._gcodeFilename) + self._usbPrintMonitor.loadFile(self._gcodeFilename, self._slicer.getID()) if self._gcodeFilename == self._slicer.getGCodeFilename(): self._slicer.submitSliceInfoOnline() @@ -1028,6 +1028,18 @@ void main(void) self._drawMachine() + if self._usbPrintMonitor.getState() == 'PRINTING' and self._usbPrintMonitor.getID() == self._slicer.getID(): + glEnable(GL_BLEND) + z = self._usbPrintMonitor.getZ() + size = self._machineSize + glColor4ub(255,255,0,128) + glBegin(GL_QUADS) + glVertex3f(-size[0]/2,-size[1]/2, z) + glVertex3f( size[0]/2,-size[1]/2, z) + glVertex3f( size[0]/2, size[1]/2, z) + glVertex3f(-size[0]/2, size[1]/2, z) + glEnd() + if self.viewMode == 'gcode': if self._gcodeLoadThread is not None and self._gcodeLoadThread.isAlive(): glDisable(GL_DEPTH_TEST) diff --git a/Cura/gui/util/openglGui.py b/Cura/gui/util/openglGui.py index 020874b7..ede15b64 100644 --- a/Cura/gui/util/openglGui.py +++ b/Cura/gui/util/openglGui.py @@ -141,6 +141,7 @@ class glGuiPanel(glcanvas.GLCanvas): self._animationList = [] self.glReleaseList = [] self._refreshQueued = False + self._idleCalled = False wx.EVT_PAINT(self, self._OnGuiPaint) wx.EVT_SIZE(self, self._OnSize) @@ -160,6 +161,7 @@ class glGuiPanel(glcanvas.GLCanvas): wx.EVT_IDLE(self, self._OnIdle) def _OnIdle(self, e): + self._idleCalled = True if len(self._animationList) > 0 or self._refreshQueued: self._refreshQueued = False for anim in self._animationList: @@ -197,6 +199,7 @@ class glGuiPanel(glcanvas.GLCanvas): self.OnMouseMotion(e) def _OnGuiPaint(self, e): + self._idleCalled = False h = self.GetSize().GetHeight() w = self.GetSize().GetWidth() oldButtonSize = self._buttonSize @@ -309,7 +312,10 @@ class glGuiPanel(glcanvas.GLCanvas): wx.CallAfter(self._queueRefresh) def _queueRefresh(self): - self._refreshQueued = True + if self._idleCalled: + wx.CallAfter(self.Refresh) + else: + self._refreshQueued = True def add(self, ctrl): if self._container is not None: diff --git a/Cura/util/machineCom.py b/Cura/util/machineCom.py index 64404c0f..bc19cf49 100644 --- a/Cura/util/machineCom.py +++ b/Cura/util/machineCom.py @@ -113,7 +113,7 @@ class VirtualPrinter(): return '' if self.readList is None: return '' - time.sleep(0.001) + time.sleep(0.1) #print "Recv: %s" % (self.readList[0].rstrip()) return self.readList.pop(0) diff --git a/Cura/util/sliceEngine.py b/Cura/util/sliceEngine.py index 86ae0b6a..9a5db78f 100644 --- a/Cura/util/sliceEngine.py +++ b/Cura/util/sliceEngine.py @@ -48,6 +48,7 @@ class Slicer(object): self._printTimeSeconds = None self._filamentMM = None self._modelHash = None + self._id = 0 def cleanup(self): self.abortSlicer() @@ -79,6 +80,9 @@ class Slicer(object): def getSliceLog(self): return self._sliceLog + def getID(self): + return self._id + def getFilamentWeight(self): #Calculates the weight of the filament in kg radius = float(profile.getProfileSetting('filament_diameter')) / 2 @@ -168,6 +172,7 @@ class Slicer(object): if self._process is not None: self._process.terminate() oldThread.join() + self._id += 1 self._callback(-1.0, False) try: self._process = self._runSliceProcess(commandList) -- 2.30.2