fix for Cura Gcode changes in Version 4.7.1

This commit is contained in:
2020-11-22 15:19:04 +01:00
parent abb0e1c67e
commit d61b4aa218

View File

@@ -10,8 +10,8 @@ logging.basicConfig(level=logging.DEBUG,
FLOAT_OR_INT = r'-?\d+(\.\d*)?' FLOAT_OR_INT = r'-?\d+(\.\d*)?'
RE_ENGINE_VERSION = re.compile(r'SteamEngine (\d+\.\d+\.\d+)')
RE_LAYER_COUNT = re.compile(r';LAYER_COUNT:(\d+)', re.MULTILINE) RE_LAYER_COUNT = re.compile(r';LAYER_COUNT:(\d+)', re.MULTILINE)
RE_LAYER = re.compile(r'(;LAYER:\d+)', re.MULTILINE)
RE_LAYER_NUMBER = re.compile(r';LAYER:(\d+)') RE_LAYER_NUMBER = re.compile(r';LAYER:(\d+)')
RE_FOOTER_START = re.compile(r'(;TIME_ELAPSED:\d+\.\d+)\n[^;]', re.MULTILINE) RE_FOOTER_START = re.compile(r'(;TIME_ELAPSED:\d+\.\d+)\n[^;]', re.MULTILINE)
RE_FAN_SPEED = re.compile(r'(M106 .+)\n', re.MULTILINE) RE_FAN_SPEED = re.compile(r'(M106 .+)\n', re.MULTILINE)
@@ -19,6 +19,9 @@ RE_LAYER_ZHEIGHT = re.compile(r'G0 .*Z({})'.format(FLOAT_OR_INT))
RE_EXTRUSION = re.compile(r'G1 .*E({})'.format(FLOAT_OR_INT)) RE_EXTRUSION = re.compile(r'G1 .*E({})'.format(FLOAT_OR_INT))
RE_MILLIMETERS = re.compile(r'({})mm'.format(FLOAT_OR_INT)) RE_MILLIMETERS = re.compile(r'({})mm'.format(FLOAT_OR_INT))
RE_LAYER_V3 = re.compile(r'(;LAYER:\d+)', re.MULTILINE)
RE_LAYER_V4 = re.compile(r'^G0.* Z\d+\.?\d*$|^;LAYER:0$', re.MULTILINE)
class GcodeFileAnalyzer: class GcodeFileAnalyzer:
@classmethod @classmethod
@@ -38,6 +41,7 @@ class GcodeFileAnalyzer:
f.write('\n'.join(lines)) f.write('\n'.join(lines))
def __init__(self, lines): def __init__(self, lines):
self.curaVersion: tuple(int) = None
self.lines: list(str) = lines self.lines: list(str) = lines
self.header: list(str) = [] self.header: list(str) = []
self.footer: list(str) = [] self.footer: list(str) = []
@@ -50,23 +54,15 @@ class GcodeFileAnalyzer:
logging.info('Analyzing GCode') logging.info('Analyzing GCode')
fullCode = '\n'.join(self.lines) fullCode = '\n'.join(self.lines)
versionMatch = RE_ENGINE_VERSION.search(fullCode)
self.curaVersion = tuple(int(v) for v in versionMatch.group(1).split('.'))
# Find footer # Find footer
footerStartMatch = RE_FOOTER_START.search(fullCode) footerStartMatch = RE_FOOTER_START.search(fullCode)
startOfFooterIndex = self.lines.index(footerStartMatch.group(1)) + 1 startOfFooterIndex = self.lines.index(footerStartMatch.group(1)) + 1
self.footer = self.lines[startOfFooterIndex:] self.footer = self.lines[startOfFooterIndex:]
# Find layers layersIndices = self.__FindLayers(fullCode, startOfFooterIndex)
layerCountMatch = RE_LAYER_COUNT.search(fullCode)
self.layerCount = int(layerCountMatch.group(1))
layersList = RE_LAYER.findall(fullCode)
if len(layersList) != self.layerCount:
logging.warning('Gcode states wrong layer count {}. But found {} layers.'
.format(layerCountMatch.group(0), len(layersList)))
self.layerCount = len(layersList)
layersIndices = [self.lines.index(layer) for layer in layersList] + [startOfFooterIndex]
self.layers = [Layer(self.lines[i:j]) for i, j in zip(layersIndices[:-1], layersIndices[1:])]
# Find header # Find header
self.header = self.lines[:layersIndices[0]] self.header = self.lines[:layersIndices[0]]
@@ -76,6 +72,31 @@ class GcodeFileAnalyzer:
if fanSpeedMatch: if fanSpeedMatch:
self.fanSpeedCode = fanSpeedMatch.group(1) self.fanSpeedCode = fanSpeedMatch.group(1)
def __FindLayers(self, fullCode, startOfFooterIndex):
# Find layers
layerCountMatch = RE_LAYER_COUNT.search(fullCode)
self.layerCount = int(layerCountMatch.group(1))
if self.curaVersion < (4, 0, 0):
# Layers start at line ;LAYER:<layer_no>
layersList = RE_LAYER_V3.findall(fullCode)
else: # Version > 4.0.0
# Layers start already before line ;LAYER:<layer_no>
# (except for ;LAYER:0)
# Look for actual Z-position changes
layersList = RE_LAYER_V4.findall(fullCode)
layersList.remove(layersList[1]) # drop Z-change for layer 0, because it happens after the ;LAYER:0 line
if len(layersList) != self.layerCount:
logging.warning('Gcode states wrong layer count {}. But found {} layers.'
.format(layerCountMatch.group(0), len(layersList)))
self.layerCount = len(layersList)
layersIndices = [self.lines.index(layer) for layer in layersList] + [startOfFooterIndex]
self.layers = [Layer(self.lines[i:j]) for i, j in zip(layersIndices[:-1], layersIndices[1:])]
return layersIndices
def ExportSplitted(self, splitBeforeLayers: list) -> list: def ExportSplitted(self, splitBeforeLayers: list) -> list:
splitBeforeLayers = self._FindLayerIndices(splitBeforeLayers) splitBeforeLayers = self._FindLayerIndices(splitBeforeLayers)
assert all(l in range(1, self.layerCount) for l in splitBeforeLayers) assert all(l in range(1, self.layerCount) for l in splitBeforeLayers)
@@ -165,9 +186,9 @@ class Layer:
self.startExtrusion: float = 0 self.startExtrusion: float = 0
self.endExtrusion: float = 0 self.endExtrusion: float = 0
self.number: int = 0 self.number: int = 0
self.__AnalyzeGcode() self.__AnalyzeLayerGcode()
def __AnalyzeGcode(self): def __AnalyzeLayerGcode(self):
""" Analyze layer GCode to find its Z height and extrusion position """ Analyze layer GCode to find its Z height and extrusion position
""" """
# Find Layer number # Find Layer number
@@ -211,5 +232,13 @@ if __name__ == '__main__':
# GcodeFileAnalyzer.SplitFileAtLayers('test/BigL.gcode', ['2.8001mm', 300]) # GcodeFileAnalyzer.SplitFileAtLayers('test/BigL.gcode', ['2.8001mm', 300])
# GcodeFileAnalyzer.SplitFileAtLayers(r"Q:\DIY\3Dprint\Models\Thingiverse\Murmelbahnen\The_Cyclone_triple_lift_triple_track_marble_machine\files\gcode\Marble_machine.gcode", # GcodeFileAnalyzer.SplitFileAtLayers(r"Q:\DIY\3Dprint\Models\Thingiverse\Murmelbahnen\The_Cyclone_triple_lift_triple_track_marble_machine\files\gcode\Marble_machine.gcode",
# ['97.3mm', 405, 480]) # ['97.3mm', 405, 480])
GcodeFileAnalyzer.SplitFileAtLayers(r"Q:\DIY\3Dprint\Models\Thingiverse\Shuttle\Shuttle100.gcode", # GcodeFileAnalyzer.SplitFileAtLayers(r"Q:\DIY\3Dprint\Models\Thingiverse\Shuttle\Shuttle100.gcode",
['87.60mm']) # ['87.60mm'])
# GcodeFileAnalyzer.SplitFileAtLayers(r"Q:\DIY\3Dprint\Models\Geschenke\Nudossi\NudossiDeckel_Yakup.gcode",
# [124])
# GcodeFileAnalyzer.SplitFileAtLayers(r"Q:\DIY\3Dprint\Models\Geschenke\Nudossi\NudossiDeckel_Harun.gcode",
# [124])
# GcodeFileAnalyzer.SplitFileAtLayers(r"Q:\DIY\3Dprint\Models\Thingiverse\MoonLamp\gcode\moon5inches.gcode",
# [100, 200, 400, 600, 700])
GcodeFileAnalyzer.SplitFileAtLayers(r"Q:\DIY\3Dprint\Models\Pi\PiJukebox\bottom_2020-11-22\bottom.gcode",
[87])