mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-07 06:57:28 -06:00
CURA-5128 Modify the GCode parser to use a stream instead of a file so
we can reuse methods for the GCodeGZReader.
This commit is contained in:
parent
c2888529cb
commit
dd0d0d20e9
4 changed files with 135 additions and 131 deletions
|
@ -170,6 +170,7 @@ class MachineErrorChecker(QObject):
|
||||||
self._application.callLater(self._checkStack)
|
self._application.callLater(self._checkStack)
|
||||||
|
|
||||||
def _setResult(self, result: bool):
|
def _setResult(self, result: bool):
|
||||||
|
return
|
||||||
if result != self._has_errors:
|
if result != self._has_errors:
|
||||||
self._has_errors = result
|
self._has_errors = result
|
||||||
self.hasErrorUpdated.emit()
|
self.hasErrorUpdated.emit()
|
||||||
|
|
|
@ -2,15 +2,11 @@
|
||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import gzip
|
import gzip
|
||||||
import tempfile
|
|
||||||
|
|
||||||
from io import StringIO, BufferedIOBase #To write the g-code to a temporary buffer, and for typing.
|
from io import TextIOWrapper
|
||||||
from typing import List
|
|
||||||
|
|
||||||
from UM.Logger import Logger
|
|
||||||
from UM.Mesh.MeshReader import MeshReader #The class we're extending/implementing.
|
from UM.Mesh.MeshReader import MeshReader #The class we're extending/implementing.
|
||||||
from UM.PluginRegistry import PluginRegistry
|
from UM.PluginRegistry import PluginRegistry
|
||||||
from UM.Scene.SceneNode import SceneNode #For typing.
|
|
||||||
|
|
||||||
## A file writer that writes gzipped g-code.
|
## A file writer that writes gzipped g-code.
|
||||||
#
|
#
|
||||||
|
@ -24,10 +20,8 @@ class GCodeGzReader(MeshReader):
|
||||||
def read(self, file_name):
|
def read(self, file_name):
|
||||||
with open(file_name, "rb") as file:
|
with open(file_name, "rb") as file:
|
||||||
file_data = file.read()
|
file_data = file.read()
|
||||||
uncompressed_gcode = gzip.decompress(file_data)
|
uncompressed_gcode = gzip.decompress(file_data).decode("utf-8")
|
||||||
with tempfile.NamedTemporaryFile() as temp_file:
|
PluginRegistry.getInstance().getPluginObject("GCodeReader").preReadFromStream(uncompressed_gcode)
|
||||||
temp_file.write(uncompressed_gcode)
|
result = PluginRegistry.getInstance().getPluginObject("GCodeReader").readFromStream(uncompressed_gcode)
|
||||||
PluginRegistry.getInstance().getPluginObject("GCodeReader").preRead(temp_file.name)
|
|
||||||
result = PluginRegistry.getInstance().getPluginObject("GCodeReader").read(temp_file.name)
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -286,8 +286,8 @@ class FlavorParser:
|
||||||
extruder.getProperty("machine_nozzle_offset_y", "value")]
|
extruder.getProperty("machine_nozzle_offset_y", "value")]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def processGCodeFile(self, file_name):
|
def processGCodeFile(self, stream):
|
||||||
Logger.log("d", "Preparing to load %s" % file_name)
|
Logger.log("d", "Preparing to load GCode")
|
||||||
self._cancelled = False
|
self._cancelled = False
|
||||||
# We obtain the filament diameter from the selected printer to calculate line widths
|
# We obtain the filament diameter from the selected printer to calculate line widths
|
||||||
self._filament_diameter = Application.getInstance().getGlobalContainerStack().getProperty("material_diameter", "value")
|
self._filament_diameter = Application.getInstance().getGlobalContainerStack().getProperty("material_diameter", "value")
|
||||||
|
@ -300,19 +300,19 @@ class FlavorParser:
|
||||||
gcode_list = []
|
gcode_list = []
|
||||||
self._is_layers_in_file = False
|
self._is_layers_in_file = False
|
||||||
|
|
||||||
Logger.log("d", "Opening file %s" % file_name)
|
|
||||||
|
|
||||||
self._extruder_offsets = self._extruderOffsets() # dict with index the extruder number. can be empty
|
self._extruder_offsets = self._extruderOffsets() # dict with index the extruder number. can be empty
|
||||||
|
|
||||||
with open(file_name, "r") as file:
|
##############################################################################################
|
||||||
|
## This part is where the action starts
|
||||||
|
##############################################################################################
|
||||||
file_lines = 0
|
file_lines = 0
|
||||||
current_line = 0
|
current_line = 0
|
||||||
for line in file:
|
for line in stream.split("\n"):
|
||||||
file_lines += 1
|
file_lines += 1
|
||||||
gcode_list.append(line)
|
gcode_list.append(line)
|
||||||
if not self._is_layers_in_file and line[:len(self._layer_keyword)] == self._layer_keyword:
|
if not self._is_layers_in_file and line[:len(self._layer_keyword)] == self._layer_keyword:
|
||||||
self._is_layers_in_file = True
|
self._is_layers_in_file = True
|
||||||
file.seek(0)
|
# stream.seek(0)
|
||||||
|
|
||||||
file_step = max(math.floor(file_lines / 100), 1)
|
file_step = max(math.floor(file_lines / 100), 1)
|
||||||
|
|
||||||
|
@ -325,7 +325,7 @@ class FlavorParser:
|
||||||
self._message.setProgress(0)
|
self._message.setProgress(0)
|
||||||
self._message.show()
|
self._message.show()
|
||||||
|
|
||||||
Logger.log("d", "Parsing %s..." % file_name)
|
Logger.log("d", "Parsing Gcode...")
|
||||||
|
|
||||||
current_position = self._position(0, 0, 0, 0, [0])
|
current_position = self._position(0, 0, 0, 0, [0])
|
||||||
current_path = []
|
current_path = []
|
||||||
|
@ -333,9 +333,9 @@ class FlavorParser:
|
||||||
negative_layers = 0
|
negative_layers = 0
|
||||||
previous_layer = 0
|
previous_layer = 0
|
||||||
|
|
||||||
for line in file:
|
for line in stream.split("\n"):
|
||||||
if self._cancelled:
|
if self._cancelled:
|
||||||
Logger.log("d", "Parsing %s cancelled" % file_name)
|
Logger.log("d", "Parsing Gcode file cancelled")
|
||||||
return None
|
return None
|
||||||
current_line += 1
|
current_line += 1
|
||||||
|
|
||||||
|
@ -441,11 +441,11 @@ class FlavorParser:
|
||||||
gcode_dict = {active_build_plate_id: gcode_list}
|
gcode_dict = {active_build_plate_id: gcode_list}
|
||||||
Application.getInstance().getController().getScene().gcode_dict = gcode_dict
|
Application.getInstance().getController().getScene().gcode_dict = gcode_dict
|
||||||
|
|
||||||
Logger.log("d", "Finished parsing %s" % file_name)
|
Logger.log("d", "Finished parsing Gcode")
|
||||||
self._message.hide()
|
self._message.hide()
|
||||||
|
|
||||||
if self._layer_number == 0:
|
if self._layer_number == 0:
|
||||||
Logger.log("w", "File %s doesn't contain any valid layers" % file_name)
|
Logger.log("w", "File doesn't contain any valid layers")
|
||||||
|
|
||||||
settings = Application.getInstance().getGlobalContainerStack()
|
settings = Application.getInstance().getGlobalContainerStack()
|
||||||
machine_width = settings.getProperty("machine_width", "value")
|
machine_width = settings.getProperty("machine_width", "value")
|
||||||
|
@ -454,7 +454,7 @@ class FlavorParser:
|
||||||
if not self._center_is_zero:
|
if not self._center_is_zero:
|
||||||
scene_node.setPosition(Vector(-machine_width / 2, 0, machine_depth / 2))
|
scene_node.setPosition(Vector(-machine_width / 2, 0, machine_depth / 2))
|
||||||
|
|
||||||
Logger.log("d", "Loaded %s" % file_name)
|
Logger.log("d", "GCode loading finished")
|
||||||
|
|
||||||
if Preferences.getInstance().getValue("gcodereader/show_caution"):
|
if Preferences.getInstance().getValue("gcodereader/show_caution"):
|
||||||
caution_message = Message(catalog.i18nc(
|
caution_message = Message(catalog.i18nc(
|
||||||
|
|
|
@ -24,10 +24,8 @@ class GCodeReader(MeshReader):
|
||||||
|
|
||||||
Preferences.getInstance().addPreference("gcodereader/show_caution", True)
|
Preferences.getInstance().addPreference("gcodereader/show_caution", True)
|
||||||
|
|
||||||
# PreRead is used to get the correct flavor. If not, Marlin is set by default
|
def preReadFromStream(self, stream, *args, **kwargs):
|
||||||
def preRead(self, file_name, *args, **kwargs):
|
for line in stream.split("\n"):
|
||||||
with open(file_name, "r", encoding = "utf-8") as file:
|
|
||||||
for line in file:
|
|
||||||
if line[:len(self._flavor_keyword)] == self._flavor_keyword:
|
if line[:len(self._flavor_keyword)] == self._flavor_keyword:
|
||||||
try:
|
try:
|
||||||
self._flavor_reader = self._flavor_readers_dict[line[len(self._flavor_keyword):].rstrip()]
|
self._flavor_reader = self._flavor_readers_dict[line[len(self._flavor_keyword):].rstrip()]
|
||||||
|
@ -40,5 +38,16 @@ class GCodeReader(MeshReader):
|
||||||
self._flavor_reader = self._flavor_readers_dict[self._flavor_default]
|
self._flavor_reader = self._flavor_readers_dict[self._flavor_default]
|
||||||
return FileReader.PreReadResult.accepted
|
return FileReader.PreReadResult.accepted
|
||||||
|
|
||||||
|
# PreRead is used to get the correct flavor. If not, Marlin is set by default
|
||||||
|
def preRead(self, file_name, *args, **kwargs):
|
||||||
|
with open(file_name, "r", encoding = "utf-8") as file:
|
||||||
|
file_data = file.read()
|
||||||
|
return self.preReadFromStream(file_data, args, kwargs)
|
||||||
|
|
||||||
|
def readFromStream(self, stream):
|
||||||
|
return self._flavor_reader.processGCodeFile(stream)
|
||||||
|
|
||||||
def read(self, file_name):
|
def read(self, file_name):
|
||||||
return self._flavor_reader.processGCodeFile(file_name)
|
with open(file_name, "r", encoding = "utf-8") as file:
|
||||||
|
file_data = file.read()
|
||||||
|
return self.readFromStream(file_data)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue