From eded0f02974c31e84e0c6dc505f234f68af7ea81 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 5 Nov 2018 11:17:39 +0100 Subject: [PATCH 1/4] Make quality manager also include profiles with same GUID in fallback. This ensures that if a (duplicated) material does not have a generic variant, that the material it was copied from will be added to the fallback list. CURA-5898 --- cura/Machines/MaterialManager.py | 26 ++++++++++++++++++++++++-- cura/Machines/QualityManager.py | 12 +++++++----- 2 files changed, 31 insertions(+), 7 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 1a204c020b..cbe1d10656 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -12,6 +12,7 @@ from UM.Application import Application from UM.ConfigurationErrorMessage import ConfigurationErrorMessage from UM.Logger import Logger from UM.Settings.ContainerRegistry import ContainerRegistry +from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.SettingFunction import SettingFunction from UM.Util import parseBool @@ -298,7 +299,7 @@ class MaterialManager(QObject): def getRootMaterialIDWithoutDiameter(self, root_material_id: str) -> str: return self._diameter_material_map.get(root_material_id, "") - def getMaterialGroupListByGUID(self, guid: str) -> Optional[list]: + def getMaterialGroupListByGUID(self, guid: str) -> Optional[List[MaterialGroup]]: return self._guid_material_groups_map.get(guid) # @@ -446,6 +447,28 @@ class MaterialManager(QObject): material_diameter, root_material_id) return node + # There are 2 ways to get fallback materials; + # - A fallback by type (@sa getFallbackMaterialIdByMaterialType), which adds the generic version of this material + # - A fallback by GUID; If a material has been duplicated, it should also check if the original materials do have + # a GUID. This should only be done if the material itself does not have a quality just yet. + def getFallBackMaterialIdsByMaterial(self, material: InstanceContainer) -> List[str]: + results = [] # List[str] + + material_groups = self.getMaterialGroupListByGUID(material.getMetaDataEntry("GUID")) + for material_group in material_groups: + if material_group.name != material.getId(): + # If the material in the group is read only, put it at the front of the list (since that is the most + # likely one to get a result) + if material_group.is_read_only: + results.insert(0, material_group.name) + else: + results.append(material_group.name) + + fallback = self.getFallbackMaterialIdByMaterialType(material.getMetaDataEntry("material")) + if fallback is not None: + results.append(fallback) + return results + # # Used by QualityManager. Built-in quality profiles may be based on generic material IDs such as "generic_pla". # For materials such as ultimaker_pla_orange, no quality profiles may be found, so we should fall back to use @@ -602,7 +625,6 @@ class MaterialManager(QObject): container_to_add.setDirty(True) self._container_registry.addContainer(container_to_add) - # if the duplicated material was favorite then the new material should also be added to favorite. if root_material_id in self.getFavorites(): self.addFavorite(new_base_id) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index ce19624c21..60a6820772 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -259,11 +259,13 @@ class QualityManager(QObject): root_material_id = self._material_manager.getRootMaterialIDWithoutDiameter(root_material_id) root_material_id_list.append(root_material_id) - # Also try to get the fallback material - material_type = extruder.material.getMetaDataEntry("material") - fallback_root_material_id = self._material_manager.getFallbackMaterialIdByMaterialType(material_type) - if fallback_root_material_id: - root_material_id_list.append(fallback_root_material_id) + # Also try to get the fallback materials + fallback_ids = self._material_manager.getFallBackMaterialIdsByMaterial(extruder.material) + + if fallback_ids: + root_material_id_list.extend(fallback_ids) + root_material_id_list = list(set(root_material_id_list)) # Weed out duplicates + # Here we construct a list of nodes we want to look for qualities with the highest priority first. # The use case is that, when we look for qualities for a machine, we first want to search in the following From 412e5977a6c24d7c2553daecf74e57b473af8851 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 5 Nov 2018 11:30:02 +0100 Subject: [PATCH 2/4] Fix type issues --- cura/CuraApplication.py | 2 +- cura/Machines/MaterialManager.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 5323f1b0fa..0610d8da86 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -128,7 +128,7 @@ if TYPE_CHECKING: numpy.seterr(all = "ignore") try: - from cura.CuraVersion import CuraVersion, CuraBuildType, CuraDebugMode, CuraSDKVersion + from cura.CuraVersion import CuraVersion, CuraBuildType, CuraDebugMode, CuraSDKVersion # type: ignore except ImportError: CuraVersion = "master" # [CodeStyle: Reflecting imported value] CuraBuildType = "" diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index cbe1d10656..4f7646b341 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -452,10 +452,10 @@ class MaterialManager(QObject): # - A fallback by GUID; If a material has been duplicated, it should also check if the original materials do have # a GUID. This should only be done if the material itself does not have a quality just yet. def getFallBackMaterialIdsByMaterial(self, material: InstanceContainer) -> List[str]: - results = [] # List[str] + results = [] # type: List[str] material_groups = self.getMaterialGroupListByGUID(material.getMetaDataEntry("GUID")) - for material_group in material_groups: + for material_group in material_groups: # type: ignore if material_group.name != material.getId(): # If the material in the group is read only, put it at the front of the list (since that is the most # likely one to get a result) From 93467dc29f4adeb8e606ee130dc2fa1f1411550d Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Mon, 5 Nov 2018 17:28:36 +0100 Subject: [PATCH 3/4] Ensure that weeding out the duplicates doesn't mess up the order CURA-5898 --- cura/Machines/QualityManager.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index 60a6820772..fc8262de52 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -1,7 +1,7 @@ # Copyright (c) 2018 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import TYPE_CHECKING, Optional, cast, Dict, List +from typing import TYPE_CHECKING, Optional, cast, Dict, List, Set from PyQt5.QtCore import QObject, QTimer, pyqtSignal, pyqtSlot @@ -264,8 +264,10 @@ class QualityManager(QObject): if fallback_ids: root_material_id_list.extend(fallback_ids) - root_material_id_list = list(set(root_material_id_list)) # Weed out duplicates + # Weed out duplicates while preserving the order. + seen = set() # type: Set[str] + root_material_id_list = [x for x in root_material_id_list if x not in seen and not seen.add(x)] # type: ignore # Here we construct a list of nodes we want to look for qualities with the highest priority first. # The use case is that, when we look for qualities for a machine, we first want to search in the following From 9c9e81b30c5b17f2e8e948aecbf8af1e0a31a701 Mon Sep 17 00:00:00 2001 From: Lipu Fei Date: Tue, 6 Nov 2018 11:04:16 +0100 Subject: [PATCH 4/4] Move InstanceContainer import into type checking closure CURA-5898 --- cura/Machines/MaterialManager.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 4f7646b341..2b41718975 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -12,7 +12,6 @@ from UM.Application import Application from UM.ConfigurationErrorMessage import ConfigurationErrorMessage from UM.Logger import Logger from UM.Settings.ContainerRegistry import ContainerRegistry -from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.SettingFunction import SettingFunction from UM.Util import parseBool @@ -22,6 +21,7 @@ from .VariantType import VariantType if TYPE_CHECKING: from UM.Settings.DefinitionContainer import DefinitionContainer + from UM.Settings.InstanceContainer import InstanceContainer from cura.Settings.GlobalStack import GlobalStack from cura.Settings.ExtruderStack import ExtruderStack @@ -451,7 +451,7 @@ class MaterialManager(QObject): # - A fallback by type (@sa getFallbackMaterialIdByMaterialType), which adds the generic version of this material # - A fallback by GUID; If a material has been duplicated, it should also check if the original materials do have # a GUID. This should only be done if the material itself does not have a quality just yet. - def getFallBackMaterialIdsByMaterial(self, material: InstanceContainer) -> List[str]: + def getFallBackMaterialIdsByMaterial(self, material: "InstanceContainer") -> List[str]: results = [] # type: List[str] material_groups = self.getMaterialGroupListByGUID(material.getMetaDataEntry("GUID"))