diff --git a/cura/Settings/GlobalStack.py b/cura/Settings/GlobalStack.py index e49b1a25de..b00ff1a1f1 100755 --- a/cura/Settings/GlobalStack.py +++ b/cura/Settings/GlobalStack.py @@ -61,6 +61,12 @@ class GlobalStack(CuraContainerStack): # already have the maximum number of extruders. def addExtruder(self, extruder: ContainerStack) -> None: extruder_count = self.getProperty("machine_extruder_count", "value") + + if extruder_count <= 1: + Logger.log("i", "Not adding extruder[%s] to [%s] because it is a single-extrusion machine.", + extruder.id, self.id) + return + if extruder_count and len(self._extruders) + 1 > extruder_count: Logger.log("w", "Adding extruder {meta} to {id} but its extruder count is {count}".format(id = self.id, count = extruder_count, meta = str(extruder.getMetaData()))) return @@ -73,7 +79,9 @@ class GlobalStack(CuraContainerStack): if any(item.getId() == extruder.id for item in self._extruders.values()): Logger.log("w", "Extruder [%s] has already been added to this stack [%s]", extruder.id, self._id) return + self._extruders[position] = extruder + Logger.log("i", "Extruder[%s] added to [%s] at position [%s]", extruder.id, self.id, position) ## Overridden from ContainerStack # diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 3d4812a677..8fdb120189 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -17,6 +17,7 @@ from .WorkspaceDialog import WorkspaceDialog import xml.etree.ElementTree as ET +from cura.Settings.CuraStackBuilder import CuraStackBuilder from cura.Settings.ExtruderManager import ExtruderManager from cura.Settings.ExtruderStack import ExtruderStack from cura.Settings.GlobalStack import GlobalStack @@ -665,6 +666,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader): Logger.log("e", "Resolve strategy of %s for machine is not supported", self._resolve_strategies["machine"]) + # Create a new definition_changes container if it was empty + if stack.definitionChanges == self._container_registry.getEmptyInstanceContainer(): + stack.setDefinitionChanges(CuraStackBuilder.createDefinitionChangesContainer(stack, stack._id + "_settings")) global_stack = stack Job.yieldThread() except: @@ -674,51 +678,65 @@ class ThreeMFWorkspaceReader(WorkspaceReader): self._container_registry.removeContainer(container.getId()) return + # + # Use the number of extruders from the global stack instead of the number of extruder stacks this project file + # contains. The Custom FDM Printer can have multiple extruders, but the actual number of extruders in used is + # defined in the global stack. + # Because for single-extrusion machines, there won't be an extruder stack, so relying on the the extruder count + # in the global stack can avoid problems in those cases. + # + extruder_count_from_global_stack = global_stack.getProperty("machine_extruder_count", "value") + # -- # load extruder stack files - try: - for extruder_stack_file in extruder_stack_files: - container_id = self._stripFileToId(extruder_stack_file) - extruder_file_content = archive.open(extruder_stack_file, "r").read().decode("utf-8") + if extruder_count_from_global_stack > 1: + try: + for extruder_stack_file in extruder_stack_files: + container_id = self._stripFileToId(extruder_stack_file) + extruder_file_content = archive.open(extruder_stack_file, "r").read().decode("utf-8") - if self._resolve_strategies["machine"] == "override": - # deserialize new extruder stack over the current ones - stack = self._overrideExtruderStack(global_stack, extruder_file_content) + if self._resolve_strategies["machine"] == "override": + # deserialize new extruder stack over the current ones + stack = self._overrideExtruderStack(global_stack, extruder_file_content) - elif self._resolve_strategies["machine"] == "new": - new_id = extruder_stack_id_map[container_id] - stack = ExtruderStack(new_id) + elif self._resolve_strategies["machine"] == "new": + new_id = extruder_stack_id_map[container_id] + stack = ExtruderStack(new_id) - # HACK: the global stack can have a new name, so we need to make sure that this extruder stack - # references to the new name instead of the old one. Normally, this can be done after - # deserialize() by setting the metadata, but in the case of ExtruderStack, deserialize() - # also does addExtruder() to its machine stack, so we have to make sure that it's pointing - # to the right machine BEFORE deserialization. - extruder_config = configparser.ConfigParser() - extruder_config.read_string(extruder_file_content) - extruder_config.set("metadata", "machine", global_stack_id_new) - tmp_string_io = io.StringIO() - extruder_config.write(tmp_string_io) - extruder_file_content = tmp_string_io.getvalue() + # HACK: the global stack can have a new name, so we need to make sure that this extruder stack + # references to the new name instead of the old one. Normally, this can be done after + # deserialize() by setting the metadata, but in the case of ExtruderStack, deserialize() + # also does addExtruder() to its machine stack, so we have to make sure that it's pointing + # to the right machine BEFORE deserialization. + extruder_config = configparser.ConfigParser() + extruder_config.read_string(extruder_file_content) + extruder_config.set("metadata", "machine", global_stack_id_new) + tmp_string_io = io.StringIO() + extruder_config.write(tmp_string_io) + extruder_file_content = tmp_string_io.getvalue() - stack.deserialize(extruder_file_content) + stack.deserialize(extruder_file_content) - # Ensure a unique ID and name - stack._id = new_id + # Ensure a unique ID and name + stack._id = new_id - self._container_registry.addContainer(stack) - extruder_stacks_added.append(stack) - containers_added.append(stack) - else: - Logger.log("w", "Unknown resolve strategy: %s", self._resolve_strategies["machine"]) + self._container_registry.addContainer(stack) + extruder_stacks_added.append(stack) + containers_added.append(stack) + else: + Logger.log("w", "Unknown resolve strategy: %s", self._resolve_strategies["machine"]) - extruder_stacks.append(stack) - except: - Logger.logException("w", "We failed to serialize the stack. Trying to clean up.") - # Something went really wrong. Try to remove any data that we added. - for container in containers_added: - self._container_registry.removeContainer(container.getId()) - return + # Create a new definition_changes container if it was empty + if stack.definitionChanges == self._container_registry.getEmptyInstanceContainer(): + stack.setDefinitionChanges(CuraStackBuilder.createDefinitionChangesContainer(stack, stack._id + "_settings")) + + extruder_stacks.append(stack) + except: + Logger.logException("w", "We failed to serialize the stack. Trying to clean up.") + # Something went really wrong. Try to remove any data that we added. + for container in containers_added: + self._container_registry.removeContainer(container.getId()) + return # # Replacing the old containers if resolve is "new". @@ -823,9 +841,6 @@ class ThreeMFWorkspaceReader(WorkspaceReader): if extruder_stacks: for stack in extruder_stacks: ExtruderManager.getInstance().registerExtruder(stack, global_stack.getId()) - else: - # Machine has no extruders, but it needs to be registered with the extruder manager. - ExtruderManager.getInstance().registerExtruder(None, global_stack.getId()) Logger.log("d", "Workspace loading is notifying rest of the code of changes...") diff --git a/plugins/3MFWriter/ThreeMFWorkspaceWriter.py b/plugins/3MFWriter/ThreeMFWorkspaceWriter.py index f805936ab5..0a915d610e 100644 --- a/plugins/3MFWriter/ThreeMFWorkspaceWriter.py +++ b/plugins/3MFWriter/ThreeMFWorkspaceWriter.py @@ -2,11 +2,9 @@ from UM.Workspace.WorkspaceWriter import WorkspaceWriter from UM.Application import Application from UM.Preferences import Preferences from UM.Settings.ContainerRegistry import ContainerRegistry -from UM.Settings.ContainerStack import ContainerStack from cura.Settings.ExtruderManager import ExtruderManager import zipfile from io import StringIO -import copy import configparser diff --git a/plugins/SliceInfoPlugin/SliceInfo.py b/plugins/SliceInfoPlugin/SliceInfo.py index 0af9c85607..57df84ffc4 100755 --- a/plugins/SliceInfoPlugin/SliceInfo.py +++ b/plugins/SliceInfoPlugin/SliceInfo.py @@ -76,8 +76,11 @@ class SliceInfo(Extension): data["active_machine"] = {"definition_id": global_container_stack.definition.getId(), "manufacturer": global_container_stack.definition.getMetaData().get("manufacturer","")} data["extruders"] = [] - extruders = list(ExtruderManager.getInstance().getMachineExtruders(global_container_stack.getId())) - extruders = sorted(extruders, key = lambda extruder: extruder.getMetaDataEntry("position")) + extruder_count = len(global_container_stack.extruders) + extruders = [] + if extruder_count > 1: + extruders = list(ExtruderManager.getInstance().getMachineExtruders(global_container_stack.getId())) + extruders = sorted(extruders, key = lambda extruder: extruder.getMetaDataEntry("position")) if not extruders: extruders = [global_container_stack]