From bd1b7508adf4c6b92bd78e38f056255d5bada322 Mon Sep 17 00:00:00 2001 From: daid303 Date: Thu, 16 May 2013 10:55:23 +0200 Subject: [PATCH] Show SD card copy progress. Slightly reduce the memory usage of the GCode loading. --- Cura/gui/sceneView.py | 48 ++++++++++++++++++++----------- Cura/gui/util/openglGui.py | 2 ++ Cura/util/gcodeInterpreter.py | 54 +++++++++++++++++++---------------- 3 files changed, 63 insertions(+), 41 deletions(-) diff --git a/Cura/gui/sceneView.py b/Cura/gui/sceneView.py index 1a009e0f..641187b6 100644 --- a/Cura/gui/sceneView.py +++ b/Cura/gui/sceneView.py @@ -176,12 +176,7 @@ class SceneView(openglGui.glGuiPanel): drive = drives[0] filename = os.path.basename(profile.getPreference('lastFile')) filename = filename[0:filename.rfind('.')] + '.gcode' - try: - shutil.copy(self._gcode.filename, drive[1] + filename) - except: - self.notification.message("Failed to save to SD card") - else: - self.notification.message("Saved as %s" % (drive[1] + filename), lambda : self.notification.message('You can now eject the card.') if removableStorage.ejectDrive(drive[1]) else self.notification.message('Safe remove failed...')) + threading.Thread(target=self._copyFile,args=(self._gcode.filename, drive[1] + filename, drive[1])).start() else: self.showSaveGCode() if button == 3: @@ -204,12 +199,29 @@ class SceneView(openglGui.glGuiPanel): filename = dlg.GetPath() dlg.Destroy() + threading.Thread(target=self._copyFile,args=(self._gcode.filename, filename)).start() + + def _copyFile(self, fileA, fileB, allowEject = False): try: - shutil.copy(self._gcode.filename, filename) + size = float(os.stat(fileA).st_size) + with open(fileA, 'rb') as fsrc: + with open(fileB, 'wb') as fdst: + while 1: + buf = fsrc.read(16*1024) + if not buf: + break + fdst.write(buf) + self.printButton.setProgressBar(float(fsrc.tell()) / size) + self._queueRefresh() except: self.notification.message("Failed to save") else: - self.notification.message("Saved as %s" % (filename)) + if allowEject: + self.notification.message("Saved as %s" % (fileB), lambda : self.notification.message('You can now eject the card.') if removableStorage.ejectDrive(allowEject) else self.notification.message('Safe remove failed...')) + else: + self.notification.message("Saved as %s" % (fileB)) + self.printButton.setProgressBar(None) + def _showSliceLog(self): dlg = wx.TextEntryDialog(self, "The slicing engine reported the following", "Engine log...", '\n'.join(self._slicer.getSliceLog()), wx.TE_MULTILINE | wx.OK | wx.CENTRE) @@ -428,6 +440,8 @@ class SceneView(openglGui.glGuiPanel): def _gcodeLoadCallback(self, progress): if self._gcode is None: return True + if len(self._gcode.layerList) % 5 == 0: + time.sleep(0.1) if self.layerSelect.getValue() == self.layerSelect.getMaxValue(): self.layerSelect.setRange(1, len(self._gcode.layerList) - 1) self.layerSelect.setValue(self.layerSelect.getMaxValue()) @@ -716,7 +730,7 @@ class SceneView(openglGui.glGuiPanel): self._animZoom = None if self.viewMode == 'gcode' and self._gcode is not None: try: - self._viewTarget[2] = self._gcode.layerList[self.layerSelect.getValue()][-1].points[0][2] + self._viewTarget[2] = self._gcode.layerList[self.layerSelect.getValue()][-1]['points'][0][2] except: pass if self._objectShader is None: @@ -1060,8 +1074,8 @@ void main(void) for extrudeType in ['WALL-OUTER', 'WALL-INNER', 'FILL', 'SUPPORT', 'SKIRT']: pointList = numpy.zeros((0,3), numpy.float32) for path in layer: - if path.type == 'extrude' and path.pathType == extrudeType: - a = path.points + if path['type'] == 'extrude' and path['pathType'] == extrudeType: + a = path['points'] a = numpy.concatenate((a[:-1], a[1:]), 1) a = a.reshape((len(a) * 2, 3)) pointList = numpy.concatenate((pointList, a)) @@ -1076,8 +1090,8 @@ void main(void) for extrudeType in ['WALL-OUTER', 'WALL-INNER', 'FILL', 'SUPPORT', 'SKIRT']: pointList = numpy.zeros((0,3), numpy.float32) for path in layer: - if path.type == 'extrude' and path.pathType == extrudeType: - a = path.points + if path['type'] == 'extrude' and path['pathType'] == extrudeType: + a = path['points'] if extrudeType == 'FILL': a[:,2] += 0.01 @@ -1086,8 +1100,8 @@ void main(void) normal[:,0], normal[:,1] = -normal[:,1] / lens, normal[:,0] / lens normal[:,2] /= lens - ePerDist = path.extrusion[1:] / lens - lineWidth = ePerDist * (filamentArea / path.layerThickness / 2) + ePerDist = path['extrusion'][1:] / lens + lineWidth = ePerDist * (filamentArea / path['layerThickness'] / 2) normal[:,0] *= lineWidth normal[:,1] *= lineWidth @@ -1106,8 +1120,8 @@ void main(void) pointList = numpy.zeros((0,3), numpy.float32) for path in layer: - if path.type == 'move' or path.type == 'retract': - a = path.points + if path['type'] == 'move' or path['type'] == 'retract': + a = path['points'] a = numpy.concatenate((a[:-1], a[1:]), 1) a = a.reshape((len(a) * 2, 3)) pointList = numpy.concatenate((pointList, a)) diff --git a/Cura/gui/util/openglGui.py b/Cura/gui/util/openglGui.py index 3eac071c..7c7b3418 100644 --- a/Cura/gui/util/openglGui.py +++ b/Cura/gui/util/openglGui.py @@ -476,6 +476,7 @@ class glButton(glGuiControl): if progress is not None: glColor4ub(255,255,255,192) opengl.glDrawTexturedQuad(pos[0]-bs/2, pos[1]+bs/2, bs, bs / 4, 0) + glColor4ub(255,255,255,255) opengl.glDrawTexturedQuad(pos[0]-bs/2, pos[1]+bs/2, bs * progress, bs / 4, 0) elif len(self._altTooltip) > 0: glPushMatrix() @@ -710,6 +711,7 @@ class glNotification(glFrame): self._label.setLabel(text) self._buttonEject.setHidden(ejectCallback is None) self._ejectCallback = ejectCallback + self._base._queueRefresh() self.updateLayout() def onEject(self, button): diff --git a/Cura/util/gcodeInterpreter.py b/Cura/util/gcodeInterpreter.py index a18ba423..d6b4922b 100644 --- a/Cura/util/gcodeInterpreter.py +++ b/Cura/util/gcodeInterpreter.py @@ -8,13 +8,19 @@ import numpy from Cura.util import profile -class gcodePath(object): - def __init__(self, newType, pathType, layerThickness, startPoint): - self.type = newType - self.pathType = pathType - self.layerThickness = layerThickness - self.points = [startPoint] - self.extrusion = [0] +#class gcodePath(object): +# def __init__(self, newType, pathType, layerThickness, startPoint): +# self.type = newType +# self.pathType = pathType +# self.layerThickness = layerThickness +# self.points = [startPoint] +# self.extrusion = [0.0] +def gcodePath(newType, pathType, layerThickness, startPoint): + return {'type': newType, + 'pathType': pathType, + 'layerThickness': layerThickness, + 'points': [startPoint], + 'extrusion': [0.0]} class gcode(object): def __init__(self): @@ -71,7 +77,7 @@ class gcode(object): pathType = 'CUSTOM'; currentLayer = [] currentPath = gcodePath('move', pathType, layerThickness, pos[:]) - currentPath.extruder = currentExtruder + currentPath['extruder'] = currentExtruder currentLayer.append(currentPath) for line in gcodeFile: @@ -92,11 +98,11 @@ class gcode(object): elif comment == 'skirt': pathType = 'SKIRT' if comment.startswith('LAYER:'): - currentPath = gcodePath(moveType, pathType, layerThickness, currentPath.points[-1]) - currentPath.extruder = currentExtruder + currentPath = gcodePath(moveType, pathType, layerThickness, currentPath['points'][-1]) + currentPath['extruder'] = currentExtruder for path in currentLayer: - path.points = numpy.array(path.points, numpy.float32) - path.extrusion = numpy.array(path.extrusion, numpy.float32) + path['points'] = numpy.array(path['points'], numpy.float32) + path['extrusion'] = numpy.array(path['extrusion'], numpy.float32) self.layerList.append(currentLayer) if self.progressCallback is not None: if self.progressCallback(float(gcodeFile.tell()) / float(self._fileSize)): @@ -122,7 +128,7 @@ class gcode(object): y = getCodeFloat(line, 'Y') z = getCodeFloat(line, 'Z') e = getCodeFloat(line, 'E') - f = getCodeFloat(line, 'F') + #f = getCodeFloat(line, 'F') oldPos = pos[:] if posAbs: if x is not None: @@ -138,8 +144,8 @@ class gcode(object): pos[1] += y * scale if z is not None: pos[2] += z * scale - if f is not None: - feedRate = f + #if f is not None: + # feedRate = f #if x is not None or y is not None or z is not None: # diffX = oldPos[0] - pos[0] # diffY = oldPos[1] - pos[1] @@ -148,9 +154,9 @@ class gcode(object): if e is not None: if absoluteE: e -= currentE - if e > 0: + if e > 0.0: moveType = 'extrude' - if e < 0: + if e < 0.0: moveType = 'retract' totalExtrusion += e currentE += e @@ -162,13 +168,13 @@ class gcode(object): if oldPos[2] > pos[2] and abs(oldPos[2] - pos[2]) > 5.0 and pos[2] < 1.0: oldPos[2] = 0.0 layerThickness = abs(oldPos[2] - pos[2]) - if currentPath.type != moveType or currentPath.pathType != pathType: - currentPath = gcodePath(moveType, pathType, layerThickness, currentPath.points[-1]) - currentPath.extruder = currentExtruder + if currentPath['type'] != moveType or currentPath['pathType'] != pathType: + currentPath = gcodePath(moveType, pathType, layerThickness, currentPath['points'][-1]) + currentPath['extruder'] = currentExtruder currentLayer.append(currentPath) - currentPath.points.append(pos[:]) - currentPath.extrusion.append(e * extrudeAmountMultiply) + currentPath['points'].append(pos[:]) + currentPath['extrusion'].append(e * extrudeAmountMultiply) elif G == 4: #Delay S = getCodeFloat(line, 'S') if S is not None: @@ -264,8 +270,8 @@ class gcode(object): else: print "Unknown M code:" + str(M) for path in currentLayer: - path.points = numpy.array(path.points, numpy.float32) - path.extrusion = numpy.array(path.extrusion, numpy.float32) + path['points'] = numpy.array(path['points'], numpy.float32) + path['extrusion'] = numpy.array(path['extrusion'], numpy.float32) self.layerList.append(currentLayer) if self.progressCallback is not None and self._fileSize > 0: self.progressCallback(float(gcodeFile.tell()) / float(self._fileSize)) -- 2.30.2