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