From 1c605a5108771add6f3fd180f5073f5c33391eab Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 23 Jan 2018 10:58:43 +0100 Subject: [PATCH] Fix different strategies for machine and quality in project loading CURA-4839 --- cura/Settings/CuraContainerRegistry.py | 38 +++++++++++++-------- cura/Settings/ExtruderManager.py | 1 - cura/Settings/ExtruderStack.py | 1 - plugins/3MFReader/ThreeMFWorkspaceReader.py | 20 +++++++++-- 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 7231fa1f72..5d81188750 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -449,7 +449,13 @@ class CuraContainerRegistry(ContainerRegistry): if not extruder_stacks: self.addExtruderStackForSingleExtrusionMachine(container, "fdmextruder") - def addExtruderStackForSingleExtrusionMachine(self, machine, extruder_id): + # + # new_global_quality_changes is optional. It is only used in project loading for a scenario like this: + # - override the current machine + # - create new for custom quality profile + # new_global_quality_changes is the new global quality changes container in this scenario. + # + def addExtruderStackForSingleExtrusionMachine(self, machine, extruder_id, new_global_quality_changes = None): new_extruder_id = extruder_id extruder_definitions = self.findDefinitionContainers(id = new_extruder_id) @@ -545,8 +551,12 @@ class CuraContainerRegistry(ContainerRegistry): quality_id = "empty_quality" extruder_stack.setQualityById(quality_id) - if machine.qualityChanges.getId() not in ("empty", "empty_quality_changes"): - extruder_quality_changes_container = self.findInstanceContainers(name = machine.qualityChanges.getName(), extruder = extruder_id) + machine_quality_changes = machine.qualityChanges + if new_global_quality_changes is not None: + machine_quality_changes = new_global_quality_changes + + if machine_quality_changes.getId() not in ("empty", "empty_quality_changes"): + extruder_quality_changes_container = self.findInstanceContainers(name = machine_quality_changes.getName(), extruder = extruder_id) if extruder_quality_changes_container: extruder_quality_changes_container = extruder_quality_changes_container[0] @@ -556,34 +566,34 @@ class CuraContainerRegistry(ContainerRegistry): # Some extruder quality_changes containers can be created at runtime as files in the qualities # folder. Those files won't be loaded in the registry immediately. So we also need to search # the folder to see if the quality_changes exists. - extruder_quality_changes_container = self._findQualityChangesContainerInCuraFolder(machine.qualityChanges.getName()) + extruder_quality_changes_container = self._findQualityChangesContainerInCuraFolder(machine_quality_changes.getName()) if extruder_quality_changes_container: quality_changes_id = extruder_quality_changes_container.getId() extruder_stack.setQualityChangesById(quality_changes_id) else: # if we still cannot find a quality changes container for the extruder, create a new one - container_name = machine.qualityChanges.getName() + container_name = machine_quality_changes.getName() container_id = self.uniqueName(extruder_stack.getId() + "_qc_" + container_name) extruder_quality_changes_container = InstanceContainer(container_id) extruder_quality_changes_container.setName(container_name) extruder_quality_changes_container.addMetaDataEntry("type", "quality_changes") extruder_quality_changes_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion) extruder_quality_changes_container.addMetaDataEntry("extruder", extruder_stack.definition.getId()) - extruder_quality_changes_container.addMetaDataEntry("quality_type", machine.qualityChanges.getMetaDataEntry("quality_type")) - extruder_quality_changes_container.setDefinition(machine.qualityChanges.getDefinition().getId()) + extruder_quality_changes_container.addMetaDataEntry("quality_type", machine_quality_changes.getMetaDataEntry("quality_type")) + extruder_quality_changes_container.setDefinition(machine_quality_changes.getDefinition().getId()) self.addContainer(extruder_quality_changes_container) extruder_stack.qualityChanges = extruder_quality_changes_container if not extruder_quality_changes_container: Logger.log("w", "Could not find quality_changes named [%s] for extruder [%s]", - machine.qualityChanges.getName(), extruder_stack.getId()) + machine_quality_changes.getName(), extruder_stack.getId()) else: # move all per-extruder settings to the extruder's quality changes - for qc_setting_key in machine.qualityChanges.getAllKeys(): + for qc_setting_key in machine_quality_changes.getAllKeys(): settable_per_extruder = machine.getProperty(qc_setting_key, "settable_per_extruder") if settable_per_extruder: - setting_value = machine.qualityChanges.getProperty(qc_setting_key, "value") + setting_value = machine_quality_changes.getProperty(qc_setting_key, "value") setting_definition = machine.getSettingDefinition(qc_setting_key) new_instance = SettingInstance(setting_definition, definition_changes) @@ -592,7 +602,7 @@ class CuraContainerRegistry(ContainerRegistry): extruder_quality_changes_container.addInstance(new_instance) extruder_quality_changes_container.setDirty(True) - machine.qualityChanges.removeInstance(qc_setting_key, postpone_emit=True) + machine_quality_changes.removeInstance(qc_setting_key, postpone_emit=True) else: extruder_stack.setQualityChangesById("empty_quality_changes") @@ -600,8 +610,8 @@ class CuraContainerRegistry(ContainerRegistry): # Also need to fix the other qualities that are suitable for this machine. Those quality changes may still have # per-extruder settings in the container for the machine instead of the extruder. - if machine.qualityChanges.getId() not in ("empty", "empty_quality_changes"): - quality_changes_machine_definition_id = machine.qualityChanges.getDefinition().getId() + if machine_quality_changes.getId() not in ("empty", "empty_quality_changes"): + quality_changes_machine_definition_id = machine_quality_changes.getDefinition().getId() else: whole_machine_definition = machine.definition machine_entry = machine.definition.getMetaDataEntry("machine") @@ -621,7 +631,7 @@ class CuraContainerRegistry(ContainerRegistry): qc_groups[qc_name] = [] qc_groups[qc_name].append(qc) # try to find from the quality changes cura directory too - quality_changes_container = self._findQualityChangesContainerInCuraFolder(machine.qualityChanges.getName()) + quality_changes_container = self._findQualityChangesContainerInCuraFolder(machine_quality_changes.getName()) if quality_changes_container: qc_groups[qc_name].append(quality_changes_container) diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py index 6b52c629d0..f9f0fbb401 100755 --- a/cura/Settings/ExtruderManager.py +++ b/cura/Settings/ExtruderManager.py @@ -504,7 +504,6 @@ class ExtruderManager(QObject): ## Updates the material container to a material that matches the material diameter set for the printer def updateMaterialForDiameter(self, extruder_position: int): - global_stack = Application.getInstance().getGlobalContainerStack() if not global_stack: return diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py index 204b0e2dae..0854964898 100644 --- a/cura/Settings/ExtruderStack.py +++ b/cura/Settings/ExtruderStack.py @@ -60,7 +60,6 @@ class ExtruderStack(CuraContainerStack): keys_to_copy = ["material_diameter", "machine_nozzle_size"] # these will be copied over to all extruders for key in keys_to_copy: - # Since material_diameter is not on the extruder definition, we need to add it here # WARNING: this might be very dangerous and should be refactored ASAP! definition = stack.getSettingDefinition(key) diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py index 059a1c5d1f..3267bf486f 100755 --- a/plugins/3MFReader/ThreeMFWorkspaceReader.py +++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py @@ -558,6 +558,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader): instance_container_files = [name for name in cura_file_names if name.endswith(self._instance_container_suffix)] user_instance_containers = [] quality_and_definition_changes_instance_containers = [] + quality_changes_instance_containers = [] for instance_container_file in instance_container_files: container_id = self._stripFileToId(instance_container_file) serialized = archive.open(instance_container_file).read().decode("utf-8") @@ -663,6 +664,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader): # The ID already exists, but nothing in the values changed, so do nothing. pass quality_and_definition_changes_instance_containers.append(instance_container) + if container_type == "quality_changes": + quality_changes_instance_containers.append(instance_container) if container_type == "definition_changes": definition_changes_extruder_count = instance_container.getProperty("machine_extruder_count", "value") @@ -787,7 +790,19 @@ class ThreeMFWorkspaceReader(WorkspaceReader): # If not extruder stacks were saved in the project file (pre 3.1) create one manually # We re-use the container registry's addExtruderStackForSingleExtrusionMachine method for this if not extruder_stacks: - stack = self._container_registry.addExtruderStackForSingleExtrusionMachine(global_stack, "fdmextruder") + # If we choose to override a machine but to create a new custom quality profile, the custom quality + # profile is not immediately applied to the global_stack, so this fix for single extrusion machines + # will use the current custom quality profile on the existing machine. The extra optional argument + # in that function is used in thia case to specify a new global stack quality_changes container so + # the fix can correctly create and copy over the custom quality settings to the newly created extruder. + new_global_quality_changes = None + if self._resolve_strategies["quality_changes"] == "new" and len(quality_changes_instance_containers) > 0: + new_global_quality_changes = quality_changes_instance_containers[0] + stack = self._container_registry.addExtruderStackForSingleExtrusionMachine(global_stack, "fdmextruder", + new_global_quality_changes) + if new_global_quality_changes is not None: + quality_changes_instance_containers.append(stack.qualityChanges) + quality_and_definition_changes_instance_containers.append(stack.qualityChanges) if global_stack.quality.getId() in ("empty", "empty_quality"): stack.quality = empty_quality_container if self._resolve_strategies["machine"] == "override": @@ -1028,8 +1043,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader): stack.setNextStack(global_stack) stack.containersChanged.emit(stack.getTop()) else: - if quality_has_been_changed: - CuraApplication.getInstance().getMachineManager().activeQualityChanged.emit() + CuraApplication.getInstance().getMachineManager().activeQualityChanged.emit() # Actually change the active machine. Application.getInstance().setGlobalContainerStack(global_stack)