diff --git a/cura/QualityManager.py b/cura/QualityManager.py index 42ef297559..76a0c86a5f 100644 --- a/cura/QualityManager.py +++ b/cura/QualityManager.py @@ -32,16 +32,16 @@ class QualityManager: # \param quality_name # \param machine_definition (Optional) \type{DefinitionContainerInterface} If nothing is # specified then the currently selected machine definition is used. - # \param material_containers (Optional) \type{List[InstanceContainer]} If nothing is specified then - # the current set of selected materials is used. + # \param material_containers_metadata If nothing is specified then the + # current set of selected materials is used. # \return the matching quality container \type{InstanceContainer} - def findQualityByName(self, quality_name: str, machine_definition: Optional["DefinitionContainerInterface"] = None, material_containers: List[InstanceContainer] = None) -> Optional[InstanceContainer]: + def findQualityByName(self, quality_name: str, machine_definition: Optional["DefinitionContainerInterface"] = None, material_containers_metadata: Optional[List[Dict[str, Any]]] = None) -> Optional[InstanceContainer]: criteria = {"type": "quality", "name": quality_name} - result = self._getFilteredContainersForStack(machine_definition, material_containers, **criteria) + result = self._getFilteredContainersForStack(machine_definition, material_containers_metadata, **criteria) # Fall back to using generic materials and qualities if nothing could be found. - if not result and material_containers and len(material_containers) == 1: - basic_materials = self._getBasicMaterialMetadatas(material_containers[0].getMetaData()) + if not result and material_containers_metadata and len(material_containers_metadata) == 1: + basic_materials = self._getBasicMaterialMetadatas(material_containers_metadata[0]) result = self._getFilteredContainersForStack(machine_definition, basic_materials, **criteria) return result[0] if result else None @@ -107,18 +107,18 @@ class QualityManager: # \param quality_type \type{str} the name of the quality type to search for. # \param machine_definition (Optional) \type{InstanceContainer} If nothing is # specified then the currently selected machine definition is used. - # \param material_containers (Optional) \type{List[InstanceContainer]} If nothing is specified then - # the current set of selected materials is used. + # \param material_containers_metadata If nothing is specified then the + # current set of selected materials is used. # \return the matching quality container \type{InstanceContainer} - def findQualityByQualityType(self, quality_type: str, machine_definition: Optional["DefinitionContainerInterface"] = None, material_containers: List[InstanceContainer] = None, **kwargs) -> InstanceContainer: + def findQualityByQualityType(self, quality_type: str, machine_definition: Optional["DefinitionContainerInterface"] = None, material_containers_metadata: Optional[List[Dict[str, Any]]] = None, **kwargs) -> InstanceContainer: criteria = kwargs criteria["type"] = "quality" if quality_type: criteria["quality_type"] = quality_type - result = self._getFilteredContainersForStack(machine_definition, material_containers, **criteria) + result = self._getFilteredContainersForStack(machine_definition, material_containers_metadata, **criteria) # Fall back to using generic materials and qualities if nothing could be found. - if not result and material_containers and len(material_containers) == 1: - basic_materials = self._getBasicMaterialMetadatas(material_containers[0].getMetaData()) + if not result and material_containers_metadata and len(material_containers_metadata) == 1: + basic_materials = self._getBasicMaterialMetadatas(material_containers_metadata[0]) if basic_materials: result = self._getFilteredContainersForStack(machine_definition, basic_materials, **criteria) return result[0] if result else None @@ -236,7 +236,7 @@ class QualityManager: def _getFilteredContainers(self, **kwargs): return self._getFilteredContainersForStack(None, None, **kwargs) - def _getFilteredContainersForStack(self, machine_definition: "DefinitionContainerInterface" = None, material_metadata: List[Dict[str, Any]] = None, **kwargs): + def _getFilteredContainersForStack(self, machine_definition: "DefinitionContainerInterface" = None, material_metadata: Optional[List[Dict[str, Any]]] = None, **kwargs): # Fill in any default values. if machine_definition is None: machine_definition = Application.getInstance().getGlobalContainerStack().getBottom() diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py index be302d2a6f..8abe627f3d 100644 --- a/cura/Settings/ContainerManager.py +++ b/cura/Settings/ContainerManager.py @@ -4,7 +4,7 @@ import os.path import urllib import uuid -from typing import Dict, Union +from typing import Any, Dict, List, Union from PyQt5.QtCore import QObject, QUrl, QVariant from UM.FlameProfiler import pyqtSlot @@ -677,27 +677,29 @@ class ContainerManager(QObject): machine_definition = global_stack.getBottom() active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks() - material_containers = [stack.material for stack in active_stacks] + if active_stacks is None: + return "" + material_metadatas = [stack.material.getMetaData() for stack in active_stacks] result = self._duplicateQualityOrQualityChangesForMachineType(quality_name, base_name, QualityManager.getInstance().getParentMachineDefinition(machine_definition), - material_containers) + material_metadatas) return result[0].getName() if result else "" ## Duplicate a quality or quality changes profile specific to a machine type # - # \param quality_name \type{str} the name of the quality or quality changes container to duplicate. - # \param base_name \type{str} the desired name for the new container. - # \param machine_definition \type{DefinitionContainer} - # \param material_instances \type{List[InstanceContainer]} - # \return \type{str} the name of the newly created container. - def _duplicateQualityOrQualityChangesForMachineType(self, quality_name, base_name, machine_definition, material_instances): + # \param quality_name The name of the quality or quality changes container to duplicate. + # \param base_name The desired name for the new container. + # \param machine_definition The machine with the specific machine type. + # \param material_metadatas Metadata of materials + # \return List of duplicated quality profiles. + def _duplicateQualityOrQualityChangesForMachineType(self, quality_name: str, base_name: str, machine_definition: DefinitionContainer, material_metadatas: List[Dict[str, Any]]) -> List[InstanceContainer]: Logger.log("d", "Attempting to duplicate the quality %s", quality_name) if base_name is None: base_name = quality_name # Try to find a Quality with the name. - container = QualityManager.getInstance().findQualityByName(quality_name, machine_definition, material_instances) + container = QualityManager.getInstance().findQualityByName(quality_name, machine_definition, material_metadatas) if container: Logger.log("d", "We found a quality to duplicate.") return self._duplicateQualityForMachineType(container, base_name, machine_definition) @@ -706,7 +708,7 @@ class ContainerManager(QObject): return self._duplicateQualityChangesForMachineType(quality_name, base_name, machine_definition) # Duplicate a quality profile - def _duplicateQualityForMachineType(self, quality_container, base_name, machine_definition): + def _duplicateQualityForMachineType(self, quality_container, base_name, machine_definition) -> List[InstanceContainer]: if base_name is None: base_name = quality_container.getName() new_name = self._container_registry.uniqueName(base_name) @@ -730,7 +732,7 @@ class ContainerManager(QObject): return new_change_instances # Duplicate a quality changes container - def _duplicateQualityChangesForMachineType(self, quality_changes_name, base_name, machine_definition): + def _duplicateQualityChangesForMachineType(self, quality_changes_name, base_name, machine_definition) -> List[InstanceContainer]: new_change_instances = [] for container in QualityManager.getInstance().findQualityChangesByName(quality_changes_name, machine_definition): diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index e4e48ae6fd..9a3f529355 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -768,7 +768,7 @@ class MachineManager(QObject): if quality_type: candidate_quality = quality_manager.findQualityByQualityType(quality_type, quality_manager.getWholeMachineDefinition(global_stack.definition), - [material_container]) + [material_container.getMetaData()]) if not candidate_quality or isinstance(candidate_quality, type(self._empty_quality_changes_container)): Logger.log("d", "Attempting to find fallback quality") @@ -923,13 +923,13 @@ class MachineManager(QObject): # find qualities for extruders for extruder_stack in extruder_stacks: - material = extruder_stack.material + material_metadata = extruder_stack.material.getMetaData() # TODO: fix this if self._new_material_container and extruder_stack.getId() == self._active_container_stack.getId(): - material = self._new_material_container + material_metadata = self._new_material_container.getMetaData() - quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material]) + quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material_metadata]) if not quality: # No quality profile is found for this quality type. @@ -979,12 +979,6 @@ class MachineManager(QObject): Logger.log("e", "Could not find the global quality changes container with name %s", quality_changes_name) return None - material = global_container_stack.material - - # find a quality type that matches both machine and materials - if self._new_material_container and self._active_container_stack.getId() == global_container_stack.getId(): - material = self._new_material_container - # For the global stack, find a quality which matches the quality_type in # the quality changes profile and also satisfies any material constraints. quality_type = global_quality_changes.getMetaDataEntry("quality_type") @@ -1004,12 +998,12 @@ class MachineManager(QObject): if not quality_changes: quality_changes = self._empty_quality_changes_container - material = extruder_stack.material + material_metadata = extruder_stack.material.getMetaData() if self._new_material_container and self._active_container_stack.getId() == extruder_stack.getId(): - material = self._new_material_container + material_metadata = self._new_material_container.getMetaData() - quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material]) + quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material_metadata]) if not quality: # No quality profile found for this quality type. @@ -1022,7 +1016,7 @@ class MachineManager(QObject): }) # append the global quality changes - global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material], global_quality = "True") + global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, global_quality = "True") # if there is not global quality but we're using a single extrusion machine, copy the quality of the first extruder - CURA-4482 if not global_quality and len(extruder_stacks) == 1: