diff --git a/octoprint/util/gcodeInterpreter.py b/octoprint/util/gcodeInterpreter.py index 1621dbf9..b324dfe8 100644 --- a/octoprint/util/gcodeInterpreter.py +++ b/octoprint/util/gcodeInterpreter.py @@ -1,13 +1,14 @@ from __future__ import absolute_import __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License" -import sys import math import os import base64 import zlib import logging +from octoprint.settings import settings + preferences = { "extruder_offset_x1": -22.0, "extruder_offset_y1": 0.0, @@ -26,13 +27,6 @@ def getPreference(key, default=None): class AnalysisAborted(Exception): pass -def gcodePath(newType, pathType, layerThickness, startPoint): - return {'type': newType, - 'pathType': pathType, - 'layerThickness': layerThickness, - 'points': [startPoint], - 'extrusion': [0.0]} - class gcode(object): def __init__(self): self._logger = logging.getLogger(__name__) @@ -49,13 +43,8 @@ class gcode(object): if os.path.isfile(filename): self.filename = filename self._fileSize = os.stat(filename).st_size - gcodeFile = open(filename, 'r') - self._load(gcodeFile) - gcodeFile.close() - - def loadList(self, l): - self.filename = None - self._load(l) + with open(filename, "r") as f: + self._load(f) def abort(self): self._abort = True @@ -64,25 +53,8 @@ class gcode(object): radius = self._filamentDiameter / 2 return (self.extrusionAmount * (math.pi * radius * radius)) / 1000 - def calculateWeight(self): - #Calculates the weight of the filament in kg - volumeM3 = self.calculateVolumeCm3() /(1000*1000) - return volumeM3 * getPreference('filament_physical_density') - - def calculateCost(self): - cost_kg = getPreference('filament_cost_kg') - cost_meter = getPreference('filament_cost_meter') - if cost_kg > 0.0 and cost_meter > 0.0: - return "%.2f / %.2f" % (self.calculateWeight() * cost_kg, self.extrusionAmount / 1000 * cost_meter) - elif cost_kg > 0.0: - return "%.2f" % (self.calculateWeight() * cost_kg) - elif cost_meter > 0.0: - return "%.2f" % (self.extrusionAmount / 1000 * cost_meter) - return None - def _load(self, gcodeFile): filePos = 0 - self.layerList = [] pos = [0.0, 0.0, 0.0] posOffset = [0.0, 0.0, 0.0] currentE = 0.0 @@ -93,21 +65,21 @@ class gcode(object): absoluteE = True scale = 1.0 posAbs = True - feedRate = 3600.0 - unknownGcodes = {} - unknownMcodes = {} + feedRateXY = settings().getFloat(["printerParameters", "movementSpeed", "x"]) for line in gcodeFile: if self._abort: raise AnalysisAborted() - if type(line) is tuple: - line = line[0] filePos += 1 - if self.progressCallback is not None and (filePos % 1000 == 0): - if isinstance(gcodeFile, (file)): - self.progressCallback(float(gcodeFile.tell()) / float(self._fileSize)) - elif isinstance(gcodeFile, (list)): - self.progressCallback(float(filePos) / float(len(gcodeFile))) + + try: + if self.progressCallback is not None and (filePos % 1000 == 0): + if isinstance(gcodeFile, (file)): + self.progressCallback(float(gcodeFile.tell()) / float(self._fileSize)) + elif isinstance(gcodeFile, (list)): + self.progressCallback(float(filePos) / float(len(gcodeFile))) + except: + pass if ';' in line: comment = line[line.find(';')+1:].strip() @@ -157,11 +129,11 @@ class gcode(object): if z is not None: pos[2] += z * scale if f is not None: - feedRate = f + feedRateXY = 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] - totalMoveTimeMinute += math.sqrt(diffX * diffX + diffY * diffY) / feedRate + totalMoveTimeMinute += math.sqrt(diffX * diffX + diffY * diffY) / feedRateXY moveType = 'move' if e is not None: if absoluteE: @@ -194,10 +166,7 @@ class gcode(object): x = getCodeFloat(line, 'X') y = getCodeFloat(line, 'Y') z = getCodeFloat(line, 'Z') - if getPreference('machine_center_is_zero') == 'True': - center = [getPreference('machine_width') / 2, getPreference('machine_depth') / 2,0.0] - else: - center = [0.0,0.0,0.0] + center = [0.0,0.0,0.0] if x is None and y is None and z is None: pos = center else: @@ -225,61 +194,13 @@ class gcode(object): posOffset[1] = pos[1] - y if z is not None: posOffset[2] = pos[2] - z - else: - if G not in unknownGcodes: - self._logger.info("Unknown G code: %r" % G) - unknownGcodes[G] = True else: M = getCodeInt(line, 'M') if M is not None: - if M == 0: #Message with possible wait (ignored) - pass - elif M == 1: #Message with possible wait (ignored) - pass - elif M == 80: #Enable power supply - pass - elif M == 81: #Suicide/disable power supply - pass - elif M == 82: #Absolute E + if M == 82: #Absolute E absoluteE = True elif M == 83: #Relative E absoluteE = False - elif M == 84: #Disable step drivers - pass - elif M == 92: #Set steps per unit - pass - elif M == 101: #Enable extruder - pass - elif M == 103: #Disable extruder - pass - elif M == 104: #Set temperature, no wait - pass - elif M == 105: #Get temperature - pass - elif M == 106: #Enable fan - pass - elif M == 107: #Disable fan - pass - elif M == 108: #Extruder RPM (these should not be in the final GCode, but they are) - pass - elif M == 109: #Set temperature, wait - pass - elif M == 110: #Reset N counter - pass - elif M == 113: #Extruder PWM (these should not be in the final GCode, but they are) - pass - elif M == 117: #LCD message - pass - elif M == 140: #Set bed temperature - pass - elif M == 190: #Set bed temperature & wait - pass - elif M == 221: #Extrude amount multiplier - s = getCodeFloat(line, 'S') - else: - if M not in unknownMcodes: - self._logger.info("Unknown M code: %r" % M) - unknownMcodes[M] = True if self.progressCallback is not None: self.progressCallback(100.0) self.extrusionAmount = maxExtrusion @@ -311,15 +232,3 @@ def getCodeFloat(line, code): return float(line[n:m]) except: return None - -if __name__ == '__main__': - from time import time - t = time() - for filename in sys.argv[1:]: - g = gcode() - g.load(filename) - print g.totalMoveTimeMinute - print g.extrusionAmount - print g.calculateVolumeCm3() - print time() - t -