diff --git a/cura/Machines/Models/IntentCategoryModel.py b/cura/Machines/Models/IntentCategoryModel.py new file mode 100644 index 0000000000..fb93c771a0 --- /dev/null +++ b/cura/Machines/Models/IntentCategoryModel.py @@ -0,0 +1,14 @@ +#Copyright (c) 2019 Ultimaker B.V. +#Cura is released under the terms of the LGPLv3 or higher. + +from UM.Qt.ListModel import ListModel +from cura.Settings.IntentManager import IntentManager + +class IntentCategoryModel(ListModel): + def __init__(self, intent_category: str): + self._intent_category = intent_category + + def update(self): + available_intents = IntentManager.getInstance().currentAvailableIntents() + result = filter(lambda intent: intent.getMetaDataEntry("intent_category") == self._intent_category, available_intents) + super().update(result) \ No newline at end of file diff --git a/cura/Settings/IntentManager.py b/cura/Settings/IntentManager.py new file mode 100644 index 0000000000..3fb2657b00 --- /dev/null +++ b/cura/Settings/IntentManager.py @@ -0,0 +1,95 @@ +#Copyright (c) 2019 Ultimaker B.V. +#Cura is released under the terms of the LGPLv3 or higher. + +from PyQt5.QtCore import pyqtProperty, pyqtSignal +from typing import List, Tuple, TYPE_CHECKING +from cura.CuraApplication import CuraApplication +from cura.Machines.QualityManager import QualityManager +from cura.Settings.MachineManager import MachineManager +from UM.Settings.ContainerRegistry import ContainerRegistry + +if TYPE_CHECKING: + from UM.Settings.InstanceContainer import InstanceContainer + +## Front-end for querying which intents are available for a certain +# configuration. +# +# CURRENTLY THIS CLASS CONTAINS ONLY SOME PSEUDOCODE OF WHAT WE ARE SUPPOSED +# TO IMPLEMENT. +class IntentManager: + __instance = None + + def __init__(self) -> None: + MachineManager.activeStackChanged.connect(self.configurationChanged) + self.configurationChanged.connect(self.selectDefaultIntent) + pass + + @classmethod + def getInstance(cls): + if not cls.__instance: + cls.__instance = IntentManager() + return cls.__instance + + configurationChanged = pyqtSignal + + def intentMetadatas(self, definition_id: str, nozzle_id: str, material_id: str) -> List[str]: + #Return list of available intent profiles for any configuration. + #Use ContainerRegistry.findContainersMetadata for this. + return [] + + def intentCategories(self, definition_id: str, nozzle_id: str, material_id: str) -> List[str]: + categories = set() + for intent in self.intentMetadatas(definition_id, nozzle_id, material_id): + categories.add(intent["intent_category"]) + return list(categories) + + ## List of intents to be displayed in the interface. + # + # For the interface this will have to be broken up into the different + # intent categories. That is up to the model there. + # + # \return A list of tuples of intent_category and quality_type. The actual + # instance may vary per extruder. + @pyqtProperty("QVariantList", notify = configurationChanged) + def currentAvailableIntents(self) -> List[Tuple[str, str]]: + final_intent_ids = {metadata["id"] for metadata in ContainerRegistry.getInstance().findContainersMetadata(type = "intent", definition = current_definition_id)} #All intents that match the global stack. + for extruder in all_extruders: + extruder_intent_ids = {metadata["id"] for metadata in self.intentMetadatas(current_definition_id, extruder_nozzle_id, extruder_material_id)} + final_intent_ids = final_intent_ids.intersection(extruder_intent_ids) + + result = set() + for intent_id in final_intent_ids: + intent = ContainerRegistry.getInstance().findContainers(id = intent_id)[0] + result.add((intent.getMetaDataEntry("intent_category"), intent.getMetaDataEntry("quality_type"))) + return list(result) + + ## List of intent categories to be displayed in the interface. + @pyqtProperty("QVariantList", notify = configurationChanged) + def currentAvailableIntentCategories(self) -> List[str]: + final_intent_categories = {metadata["intent_category"] for metadata in ContainerRegistry.getInstance().findContainersMetadata(type = "intent", definition = current_definition_id)} + for extruder in all_extruders: + final_intent_categories = final_intent_categories.intersection(self.intentCategories()) + return list(final_intent_categories) + + def defaultIntent(self) -> Tuple[str, str]: + default_quality_type = QualityManager.getInstance().getDefaultQualityType().quality_type + for intent in self.currentAvailableIntents(): + if intent.getMetaDataEntry("intent_category") == "default" and intent.getMetaDataEntry("quality_type") == default_quality_type: + return intent + else: #Fallback: Preferred quality type is not available for default category. + for intent in self.currentAvailableIntents(): + if intent.getMetaDataEntry("intent_category") == "default": + return intent + else: #Fallback: No default category. + if self.currentAvailableIntents(): + return self.currentAvailableIntents()[0] + else: + return CuraApplication.empty_intent_container + + def selectIntent(self, intent_category, quality_type): + for extruder in all_extruders: + extruder_stack.intent = ContainerRegistry.getInstance().findContainers(type = "intent", definition = current_definition_id, variant = extruder_nozzle_id, material = extruder_material_id)[0] + + def selectDefaultIntent(self) -> None: + category, quality_type = self.defaultIntent() + self.selectIntent(category, quality_type) \ No newline at end of file