mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-15 01:55:57 +08:00
Merge branch 'master' of https://github.com/Ultimaker/Cura
This commit is contained in:
commit
8871ac9955
@ -2,6 +2,7 @@
|
|||||||
# Cura is released under the terms of the LGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv3 or higher.
|
||||||
|
|
||||||
import copy
|
import copy
|
||||||
|
import uuid
|
||||||
|
|
||||||
from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
|
from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
|
||||||
from UM.Signal import Signal, signalemitter
|
from UM.Signal import Signal, signalemitter
|
||||||
@ -34,7 +35,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
|||||||
super().__init__()
|
super().__init__()
|
||||||
self._stack = PerObjectContainerStack(container_id = "per_object_stack_" + str(id(self)))
|
self._stack = PerObjectContainerStack(container_id = "per_object_stack_" + str(id(self)))
|
||||||
self._stack.setDirty(False) # This stack does not need to be saved.
|
self._stack.setDirty(False) # This stack does not need to be saved.
|
||||||
user_container = InstanceContainer(container_id = "SettingOverrideInstanceContainer")
|
user_container = InstanceContainer(container_id = self._generateUniqueName())
|
||||||
user_container.addMetaDataEntry("type", "user")
|
user_container.addMetaDataEntry("type", "user")
|
||||||
self._stack.userChanges = user_container
|
self._stack.userChanges = user_container
|
||||||
self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0).getId()
|
self._extruder_stack = ExtruderManager.getInstance().getExtruderStack(0).getId()
|
||||||
@ -49,12 +50,19 @@ class SettingOverrideDecorator(SceneNodeDecorator):
|
|||||||
self.activeExtruderChanged.connect(self._updateNextStack)
|
self.activeExtruderChanged.connect(self._updateNextStack)
|
||||||
self._updateNextStack()
|
self._updateNextStack()
|
||||||
|
|
||||||
|
def _generateUniqueName(self):
|
||||||
|
return "SettingOverrideInstanceContainer-%s" % uuid.uuid1()
|
||||||
|
|
||||||
def __deepcopy__(self, memo):
|
def __deepcopy__(self, memo):
|
||||||
## Create a fresh decorator object
|
## Create a fresh decorator object
|
||||||
deep_copy = SettingOverrideDecorator()
|
deep_copy = SettingOverrideDecorator()
|
||||||
|
|
||||||
## Copy the instance
|
## Copy the instance
|
||||||
instance_container = copy.deepcopy(self._stack.getContainer(0), memo)
|
instance_container = copy.deepcopy(self._stack.getContainer(0), memo)
|
||||||
|
|
||||||
|
# A unique name must be added, or replaceContainer will not replace it
|
||||||
|
instance_container.setMetaDataEntry("id", self._generateUniqueName)
|
||||||
|
|
||||||
## Set the copied instance as the first (and only) instance container of the stack.
|
## Set the copied instance as the first (and only) instance container of the stack.
|
||||||
deep_copy._stack.replaceContainer(0, instance_container)
|
deep_copy._stack.replaceContainer(0, instance_container)
|
||||||
|
|
||||||
|
@ -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 reader that reads gzipped g-code.
|
## A file reader that reads 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 processGCodeStream(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.processGCodeStream(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…
x
Reference in New Issue
Block a user