From f625fa8a90e97a7486ef15f6f264c5f74a56b3b6 Mon Sep 17 00:00:00 2001 From: Diego Prado Gesto Date: Tue, 6 Mar 2018 16:08:50 +0100 Subject: [PATCH] CURA-4870 Add function to set the configuration from the printer back to Cura. Change the hash function to compare by GUID instead of type. Show the material name instead of type in the list. --- cura/Machines/MaterialGroup.py | 3 +- cura/Machines/MaterialManager.py | 30 +++++++++++++++++++ .../ExtruderConfigurationModel.py | 10 ++++--- cura/PrinterOutput/ExtruderOutputModel.py | 3 +- cura/PrinterOutput/PrinterOutputModel.py | 1 - cura/Settings/MachineManager.py | 30 ++++++++++++++++--- .../ConfigurationListView.qml | 1 - .../PrintCoreConfiguration.qml | 2 +- 8 files changed, 66 insertions(+), 14 deletions(-) diff --git a/cura/Machines/MaterialGroup.py b/cura/Machines/MaterialGroup.py index 009778943a..75ab51182c 100644 --- a/cura/Machines/MaterialGroup.py +++ b/cura/Machines/MaterialGroup.py @@ -15,10 +15,11 @@ # so "generic_abs_ultimaker3", "generic_abs_ultimaker3_AA_0.4", etc. # class MaterialGroup: - __slots__ = ("name", "root_material_node", "derived_material_node_list") + __slots__ = ("name", "is_read_only", "root_material_node", "derived_material_node_list") def __init__(self, name: str): self.name = name + self.is_read_only = False self.root_material_node = None self.derived_material_node_list = [] diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 98e4f67f82..4bad33b890 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -87,6 +87,7 @@ class MaterialManager(QObject): root_material_id = material_metadata.get("base_file") if root_material_id not in self._material_group_map: self._material_group_map[root_material_id] = MaterialGroup(root_material_id) + self._material_group_map[root_material_id].is_read_only = self._container_registry.isReadOnly(root_material_id) group = self._material_group_map[root_material_id] # We only add root materials here @@ -325,6 +326,35 @@ class MaterialManager(QObject): return material_node + # + # Gets MaterialNode for the given extruder and machine with the given material type. + # Returns None if: + # 1. the given machine doesn't have materials; + # 2. cannot find any material InstanceContainers with the given settings. + # + def getMaterialNodeByType(self, global_stack: "GlobalStack", extruder_variant_name: str, material_guid: str) -> Optional["MaterialNode"]: + node = None + machine_definition = global_stack.definition + if parseBool(machine_definition.getMetaDataEntry("has_materials", False)): + material_diameter = machine_definition.getProperty("material_diameter", "value") + if isinstance(material_diameter, SettingFunction): + material_diameter = material_diameter(global_stack) + + # Look at the guid to material dictionary + root_material_id = None + for material_group in self._guid_material_groups_map[material_guid]: + if material_group.is_read_only: + root_material_id = material_group.root_material_node.metadata["id"] + break + + if not root_material_id: + Logger.log("i", "Cannot find materials with guid [%s] ", material_guid) + return None + + node = self.getMaterialNode(machine_definition.getId(), extruder_variant_name, + material_diameter, root_material_id) + return node + # # 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 diff --git a/cura/PrinterOutput/ExtruderConfigurationModel.py b/cura/PrinterOutput/ExtruderConfigurationModel.py index 7aa8785ae9..072adfc24e 100644 --- a/cura/PrinterOutput/ExtruderConfigurationModel.py +++ b/cura/PrinterOutput/ExtruderConfigurationModel.py @@ -24,7 +24,7 @@ class ExtruderConfigurationModel(QObject): def setMaterial(self, material): self._material = material - @pyqtProperty(str, fset = setMaterial, notify = extruderConfigurationChanged) + @pyqtProperty(QObject, fset = setMaterial, notify = extruderConfigurationChanged) def material(self): return self._material @@ -36,12 +36,14 @@ class ExtruderConfigurationModel(QObject): return self._hotend_id def __str__(self): - if self._material is None or self._hotend_id is None: + if self._material is None or self._hotend_id is None or self.material.type is None: return "No information" - return "Position: " + str(self._position) + " - Material: " + self._material + " - HotendID: " + self._hotend_id + return "Position: " + str(self._position) + " - Material: " + self._material.type + " - HotendID: " + self._hotend_id def __eq__(self, other): return hash(self) == hash(other) + # Calculating a hash function using the position of the extruder, the material GUID and the hotend id to check if is + # unique within a set def __hash__(self): - return hash(self._position) ^ hash(self._material) ^ hash(self._hotend_id) \ No newline at end of file + return hash(self._position) ^ (hash(self._material.guid) if self.material is not None else hash(0)) ^ hash(self._hotend_id) \ No newline at end of file diff --git a/cura/PrinterOutput/ExtruderOutputModel.py b/cura/PrinterOutput/ExtruderOutputModel.py index d74b3a90d5..a639d428f9 100644 --- a/cura/PrinterOutput/ExtruderOutputModel.py +++ b/cura/PrinterOutput/ExtruderOutputModel.py @@ -81,7 +81,6 @@ class ExtruderOutputModel(QObject): def _updateExtruderConfiguration(self): self._extruder_configuration.position = self._position - self._extruder_configuration.material = self._active_material.type if self.activeMaterial is not None else None + self._extruder_configuration.material = self._active_material self._extruder_configuration.hotendID = self._hotend_id - print("Recalculating extruder configuration:", self._extruder_configuration) self.extruderConfigurationChanged.emit() diff --git a/cura/PrinterOutput/PrinterOutputModel.py b/cura/PrinterOutput/PrinterOutputModel.py index 19365b9cc6..f59cc1bece 100644 --- a/cura/PrinterOutput/PrinterOutputModel.py +++ b/cura/PrinterOutput/PrinterOutputModel.py @@ -253,5 +253,4 @@ class PrinterOutputModel(QObject): self._printer_configuration.printerType = self._type self._printer_configuration.extruderConfigurations = [extruder.extruderConfiguration for extruder in self._extruders] self._printer_configuration.buildplateConfiguration = None # TODO Add the buildplate information - print("Recalculating printer configuration", self.name, ":", self._printer_configuration) self.configurationChanged.emit() diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index 0cde440fd8..6e0679e11c 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -20,7 +20,6 @@ from UM.Logger import Logger from UM.Message import Message from UM.Settings.ContainerRegistry import ContainerRegistry -from UM.Settings.InstanceContainer import InstanceContainer from UM.Settings.SettingFunction import SettingFunction from UM.Signal import postponeSignals, CompressTechnique @@ -28,6 +27,7 @@ from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch from cura.PrinterOutputDevice import PrinterOutputDevice from cura.PrinterOutput.ConfigurationModel import ConfigurationModel from cura.PrinterOutput.ExtruderConfigurationModel import ExtruderConfigurationModel +from cura.PrinterOutput.MaterialOutputModel import MaterialOutputModel from cura.Settings.ExtruderManager import ExtruderManager from .CuraStackBuilder import CuraStackBuilder @@ -124,7 +124,8 @@ class MachineManager(QObject): if containers: containers[0].nameChanged.connect(self._onMaterialNameChanged) - self._material_manager = self._application._material_manager + self._material_manager = self._application.getMaterialManager() + self._variant_manager = self._application.getVariantManager() self._quality_manager = self._application.getQualityManager() # When the materials lookup table gets updated, it can mean that a material has its name changed, which should @@ -176,12 +177,21 @@ class MachineManager(QObject): if not self._global_container_stack: return + # Create the configuration model with the current data in Cura self._current_printer_configuration.printerType = self._global_container_stack.definition.getName() self._current_printer_configuration.extruderConfigurations = [] for extruder in self._global_container_stack.extruders.values(): extruder_configuration = ExtruderConfigurationModel() + # For compare just the GUID is needed at this moment + mat_type = extruder.material.getMetaDataEntry("material") if extruder.material != self._empty_material_container else None + mat_guid = extruder.material.getMetaDataEntry("GUID") if extruder.material != self._empty_material_container else None + mat_color = extruder.material.getMetaDataEntry("color_name") if extruder.material != self._empty_material_container else None + mat_brand = extruder.material.getMetaDataEntry("brand") if extruder.material != self._empty_material_container else None + mat_name = extruder.material.getMetaDataEntry("name") if extruder.material != self._empty_material_container else None + material_model = MaterialOutputModel(mat_guid, mat_type, mat_color, mat_brand, mat_name) + extruder_configuration.position = int(extruder.getMetaDataEntry("position")) - extruder_configuration.material = extruder.material.getName() if extruder.material != self._empty_material_container else None + extruder_configuration.material = material_model extruder_configuration.hotendID = extruder.variant.getName() if extruder.variant != self._empty_variant_container else None self._current_printer_configuration.extruderConfigurations.append(extruder_configuration) @@ -197,7 +207,8 @@ class MachineManager(QObject): @pyqtSlot(QObject) def applyRemoteConfiguration(self, configuration: ConfigurationModel): - print("Applying remote configuration", configuration) + for extruder_configuration in configuration.extruderConfigurations: + self.setConfiguration(extruder_configuration.position, extruder_configuration.hotendID, extruder_configuration.material.guid) @pyqtProperty("QVariantList", notify = outputDevicesChanged) def printerOutputDevices(self): @@ -355,6 +366,7 @@ class MachineManager(QObject): Logger.log("w", "Failed creating a new machine!") def _checkStacksHaveErrors(self) -> bool: + return False time_start = time.time() if self._global_container_stack is None: #No active machine. return False @@ -1018,6 +1030,16 @@ class MachineManager(QObject): self._updateMaterialWithVariant(None) # Update all materials self._updateQualityWithMaterial() + def setConfiguration(self, position, variant_name, material_guid): + position = str(position) + variant_container_node = self._variant_manager.getVariantNode(self._global_container_stack.definition.getId(), variant_name) + material_container_node = self._material_manager.getMaterialNodeByType(self._global_container_stack, variant_name, material_guid) + with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue): + self._setVariantNode(position, variant_container_node) + self._setMaterial(position, material_container_node) + self._updateMaterialWithVariant(position) + self._updateQualityWithMaterial() + @pyqtSlot(str, "QVariant") def setMaterial(self, position, container_node): position = str(position) diff --git a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml index 00de9d0003..f476383169 100644 --- a/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml +++ b/resources/qml/Menus/ConfigurationMenu/ConfigurationListView.qml @@ -46,7 +46,6 @@ Column target: outputDevice onUniqueConfigurationsChanged: { // FIXME For now the model should be removed and then created again, otherwise changes in the printer don't automatically update the UI - print("Update unique configurations") configurationList.model = null configurationList.model = outputDevice.uniqueConfigurations } diff --git a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml index 74ecc114c7..d34252adc4 100644 --- a/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml +++ b/resources/qml/Menus/ConfigurationMenu/PrintCoreConfiguration.qml @@ -69,7 +69,7 @@ Column Label { id: materialLabel - text: printCoreConfiguration.material + text: printCoreConfiguration.material.name elide: Text.ElideRight width: parent.width font: UM.Theme.getFont("default_bold")