From 7c8501338990ae740eae8c53c4cdbd7fd6205222 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gina=20H=C3=A4u=C3=9Fge?= Date: Tue, 18 Jun 2013 21:28:05 +0200 Subject: [PATCH] Added filament diameter retrieval from gcode generated by Cura, fixed Slic3r version --- octoprint/gcodefiles.py | 2 +- octoprint/util/gcodeInterpreter.py | 38 +++++++++++++++++++++--------- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/octoprint/gcodefiles.py b/octoprint/gcodefiles.py index 7dd8329..6f64284 100644 --- a/octoprint/gcodefiles.py +++ b/octoprint/gcodefiles.py @@ -64,7 +64,7 @@ class GcodeManager: if gcode.extrusionAmount: analysisResult["filament"] = "%.2fm" % (gcode.extrusionAmount / 1000) if gcode.extrusionVolume: - analysisResult["filament"] += " / %.2fcc" % gcode.extrusionVolume + analysisResult["filament"] += " / %.2fcm³" % gcode.extrusionVolume dirty = True if dirty: diff --git a/octoprint/util/gcodeInterpreter.py b/octoprint/util/gcodeInterpreter.py index 00ada5e..eebdd55 100644 --- a/octoprint/util/gcodeInterpreter.py +++ b/octoprint/util/gcodeInterpreter.py @@ -4,6 +4,9 @@ import sys import math import re import os +import base64 +import zlib +import logging from octoprint.util import util3d @@ -34,10 +37,12 @@ class gcodePath(object): class gcode(object): def __init__(self): + self._logger = logging.getLogger(__name__) + self.regMatch = {} self.layerList = [] self.extrusionAmount = 0 - self.extrusionVolume = 0 + self.extrusionVolume = None self.totalMoveTimeMinute = 0 self.progressCallback = None self._abort = False @@ -62,17 +67,16 @@ class gcode(object): currentE = 0.0 totalExtrusion = 0.0 maxExtrusion = 0.0 - extrusionDiameter = 0 currentExtruder = 0 extrudeAmountMultiply = 1.0 totalMoveTimeMinute = 0.0 + filamentDiameter = 0.0 scale = 1.0 posAbs = True posAbsExtruder = True; feedRate = 3600 layerThickness = 0.1 pathType = 'CUSTOM'; - startCodeDone = False currentLayer = [] unknownGcodes={} unknownMcodes={} @@ -99,7 +103,7 @@ class gcode(object): startCodeDone = True if ';' in line: - #Slic3r GCode comment parser + # Slic3r GCode comment parser comment = line[line.find(';')+1:].strip() if comment == 'fill': pathType = 'FILL' @@ -107,13 +111,21 @@ class gcode(object): pathType = 'WALL-INNER' elif comment == 'skirt': pathType = 'SKIRT' - elif comment.startswith('filament_diameter = '): - filamentDiameter = int(line[line.find('=')+1:]) + elif comment.startswith("filament_diameter"): + filamentDiameter = float(line.split("=", 1)[1].strip()) + + # Cura Gcode comment parser if comment.startswith('LAYER:'): self.layerList.append(currentLayer) currentLayer = [] - if pathType != "CUSTOM": - startCodeDone = True + elif comment.startswith("CURA_PROFILE_STRING"): + curaOptions = self._parseCuraProfileString(comment) + + if "filament_diameter" in curaOptions.keys(): + try: + filamentDiameter = float(curaOptions["filament_diameter"]) + except: + filamentDiameter = 0.0 line = line[0:line.find(';')] T = self.getCodeInt(line, 'T') if T is not None: @@ -227,7 +239,7 @@ class gcode(object): posOffset.z = pos.z - z else: if G not in unknownGcodes: - print "Unknown G code:" + str(G) + self._logger.info("Unknown G code: %r" % G) unknownGcodes[G] = True else: M = self.getCodeInt(line, 'M') @@ -276,11 +288,12 @@ class gcode(object): extrudeAmountMultiply = s / 100.0 else: if M not in unknownMcodes: - print "Unknown M code:" + str(M) + self._logger.info("Unknown M code: %r" % M) unknownMcodes[M] = True self.layerList.append(currentLayer) self.extrusionAmount = maxExtrusion - self.extrusionVolume = math.pi * math.pow(filamentDiameter / 2.0, 2) * maxExtrusion / 1000.0 + if filamentDiameter is not None and filamentDiameter > 0: + self.extrusionVolume = math.pi * math.pow(filamentDiameter / 2.0, 2) * maxExtrusion / 1000.0 self.totalMoveTimeMinute = totalMoveTimeMinute def getCodeInt(self, line, code): @@ -305,6 +318,9 @@ class gcode(object): except: return None + def _parseCuraProfileString(self, comment): + return {key: value for (key, value) in map(lambda x: x.split("=", 1), zlib.decompress(base64.b64decode(comment[len("CURA_PROFILE_STRING:"):])).split("\b"))} + if __name__ == '__main__': for filename in sys.argv[1:]: gcode().load(filename)