Browse Source

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.
Ghostkeeper 7 years ago
parent
commit
838e49f3da
3 changed files with 35 additions and 39 deletions
  1. 13 13
      cura/QualityManager.py
  2. 14 12
      cura/Settings/ContainerManager.py
  3. 8 14
      cura/Settings/MachineManager.py

+ 13 - 13
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()

+ 14 - 12
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):

+ 8 - 14
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: