From 838e49f3daf4198bc8d5d14a176020be4b469af7 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Wed, 29 Nov 2017 14:33:04 +0100 Subject: [PATCH] Pass just metadata through quality manager instead of full containers Where we only need metadata, we should pass metadata instead of full containers. Also add some type hinting. Contributes to issue CURA-4243. --- cura/QualityManager.py | 26 +++++++++++++------------- cura/Settings/ContainerManager.py | 26 ++++++++++++++------------ cura/Settings/MachineManager.py | 22 ++++++++-------------- 3 files changed, 35 insertions(+), 39 deletions(-) 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: