From 6a3a23a7254ee5c69d23cace4bce71cc47eb564e Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 15 Aug 2019 13:11:45 +0200 Subject: [PATCH 1/4] Add time logging about how long it took to construct the container tree CURA-6600 --- cura/Machines/ContainerTree.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cura/Machines/ContainerTree.py b/cura/Machines/ContainerTree.py index 129bcba5e8..2f641973ac 100644 --- a/cura/Machines/ContainerTree.py +++ b/cura/Machines/ContainerTree.py @@ -8,7 +8,7 @@ from UM.Settings.Interfaces import ContainerInterface from cura.Machines.MachineNode import MachineNode from typing import Dict - +import time ## This class contains a look-up tree for which containers are available at # which stages of configuration. # @@ -32,12 +32,15 @@ class ContainerTree: ## Builds the initial container tree. def _loadAll(self): Logger.log("i", "Building container tree.") + start_time = time.time() all_stacks = ContainerRegistry.getInstance().findContainerStacks() for stack in all_stacks: definition_id = stack.definition.getId() if definition_id not in self.machines: self.machines[definition_id] = MachineNode(definition_id) + Logger.log("d", "Building the container tree took %s seconds", time.time() - start_time) + ## When a printer gets added, we need to build up the tree for that container. def _machineAdded(self, definition_container: ContainerInterface): if not isinstance(definition_container, DefinitionContainer): From c0f70c447e3bbda10437552dc1e2f725e32f0f10 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 15 Aug 2019 13:32:42 +0200 Subject: [PATCH 2/4] Ensure that the materials are loaded again CURA-6600 --- cura/Machines/MaterialManager.py | 43 +++++++++----------------------- cura/Settings/MachineManager.py | 2 +- 2 files changed, 13 insertions(+), 32 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 8f363817f4..69c014e8ef 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -190,41 +190,22 @@ class MaterialManager(QObject): # def getMaterialNode(self, machine_definition_id: str, nozzle_name: Optional[str], buildplate_name: Optional[str], diameter: float, root_material_id: str) -> Optional["MaterialNode"]: - # round the diameter to get the approximate diameter - rounded_diameter = str(round(diameter)) - if rounded_diameter not in self._diameter_machine_nozzle_buildplate_material_map: - Logger.log("i", "Cannot find materials with diameter [%s] (rounded to [%s]) for root material id [%s]", - diameter, rounded_diameter, root_material_id) + container_tree = ContainerTree.getInstance() + machine_node = container_tree.machines.get(machine_definition_id) + if machine_node is None: + Logger.log("w", "Could not find machine with definition %s in the container tree", machine_definition_id) return None - # If there are nozzle materials, get the nozzle-specific material - machine_nozzle_buildplate_material_map = self._diameter_machine_nozzle_buildplate_material_map[rounded_diameter] # type: Dict[str, MaterialNode] - machine_node = machine_nozzle_buildplate_material_map.get(machine_definition_id) - nozzle_node = None - buildplate_node = None + variant_node = machine_node.variants.get(nozzle_name) + if variant_node is None: + Logger.log("w", "Could not find variant %s for machine with definition %s in the container tree", nozzle_name, machine_definition_id ) + return None - # Fallback for "fdmprinter" if the machine-specific materials cannot be found - if machine_node is None: - machine_node = machine_nozzle_buildplate_material_map.get(self._default_machine_definition_id) - if machine_node is not None and nozzle_name is not None: - nozzle_node = machine_node.getChildNode(nozzle_name) - if nozzle_node is not None and buildplate_name is not None: - buildplate_node = nozzle_node.getChildNode(buildplate_name) + material_node = variant_node.materials.get(root_material_id) - # Fallback mechanism of finding materials: - # 1. buildplate-specific material - # 2. nozzle-specific material - # 3. machine-specific material - # 4. generic material (for fdmprinter) - nodes_to_check = [buildplate_node, nozzle_node, machine_node, - machine_nozzle_buildplate_material_map.get(self._default_machine_definition_id)] - - material_node = None - for node in nodes_to_check: - if node is not None: - material_node = node.material_map.get(root_material_id) - if material_node: - break + if material_node is None: + Logger.log("w", "Could not find material %s for machine with definition %s and variant %s in the container tree", root_material_id, machine_definition_id, nozzle_name) + return None return material_node diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py index b0ab349d86..c454b59a00 100755 --- a/cura/Settings/MachineManager.py +++ b/cura/Settings/MachineManager.py @@ -1253,7 +1253,7 @@ class MachineManager(QObject): if self._global_container_stack is None: return if material_node: - self._global_container_stack.extruders[position].material = CuraContainerRegistry.getInstance().findContainers(id = material_node.container_id) + self._global_container_stack.extruders[position].material = CuraContainerRegistry.getInstance().findContainers(id = material_node.container_id)[0] root_material_id = material_node.getMetaDataEntry("base_file", None) else: self._global_container_stack.extruders[position].material = empty_material_container From 76729360e1d0c9b572fe17c7eaca938533fd7321 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Thu, 15 Aug 2019 13:33:17 +0200 Subject: [PATCH 3/4] Remove unused code CURA-6600 --- cura/Machines/MaterialManager.py | 65 -------------------------------- 1 file changed, 65 deletions(-) diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py index 69c014e8ef..c63c04e195 100644 --- a/cura/Machines/MaterialManager.py +++ b/cura/Machines/MaterialManager.py @@ -83,71 +83,6 @@ class MaterialManager(QObject): self._favorites = set(cura.CuraApplication.CuraApplication.getInstance().getPreferences().getValue("cura/favorite_materials").split(";")) self.materialsUpdated.emit() - def __addMaterialMetadataIntoLookupTree(self, material_metadata: Dict[str, Any]) -> None: - material_id = material_metadata["id"] - - # We don't store empty material in the lookup tables - if material_id == "empty_material": - return - - root_material_id = material_metadata["base_file"] - definition = material_metadata["definition"] - approximate_diameter = str(material_metadata["approximate_diameter"]) - - if approximate_diameter not in self._diameter_machine_nozzle_buildplate_material_map: - self._diameter_machine_nozzle_buildplate_material_map[approximate_diameter] = {} - - machine_nozzle_buildplate_material_map = self._diameter_machine_nozzle_buildplate_material_map[ - approximate_diameter] - if definition not in machine_nozzle_buildplate_material_map: - machine_nozzle_buildplate_material_map[definition] = MaterialNode() - - # This is a list of information regarding the intermediate nodes: - # nozzle -> buildplate - nozzle_name = material_metadata.get("variant_name") - buildplate_name = material_metadata.get("buildplate_name") - intermediate_node_info_list = [(nozzle_name, VariantType.NOZZLE), - (buildplate_name, VariantType.BUILD_PLATE), - ] - - variant_manager = cura.CuraApplication.CuraApplication.getInstance().getVariantManager() - - machine_node = machine_nozzle_buildplate_material_map[definition] - current_node = machine_node - current_intermediate_node_info_idx = 0 - error_message = None # type: Optional[str] - while current_intermediate_node_info_idx < len(intermediate_node_info_list): - variant_name, variant_type = intermediate_node_info_list[current_intermediate_node_info_idx] - if variant_name is not None: - # The new material has a specific variant, so it needs to be added to that specific branch in the tree. - variant = variant_manager.getVariantNode(definition, variant_name, variant_type) - if variant is None: - error_message = "Material {id} contains a variant {name} that does not exist.".format( - id = material_metadata["id"], name = variant_name) - break - - # Update the current node to advance to a more specific branch - if variant_name not in current_node.children_map: - current_node.children_map[variant_name] = MaterialNode() - current_node = current_node.children_map[variant_name] - - current_intermediate_node_info_idx += 1 - - if error_message is not None: - Logger.log("e", "%s It will not be added into the material lookup tree.", error_message) - CuraContainerRegistry.getInstance().addWrongContainerId(material_metadata["id"]) - return - - # Add the material to the current tree node, which is the deepest (the most specific) branch we can find. - # Sanity check: Make sure that there is no duplicated materials. - if root_material_id in current_node.material_map: - Logger.log("e", "Duplicated material [%s] with root ID [%s]. It has already been added.", - material_id, root_material_id) - ConfigurationErrorMessage.getInstance().addFaultyContainers(root_material_id) - return - - current_node.material_map[root_material_id] = MaterialNode(material_metadata) - def getMaterialGroup(self, root_material_id: str) -> Optional[MaterialGroup]: return self._material_group_map.get(root_material_id) From fb509a069228f4e57d85b95bad8c4134e4ee7701 Mon Sep 17 00:00:00 2001 From: Ghostkeeper Date: Thu, 15 Aug 2019 13:40:46 +0200 Subject: [PATCH 4/4] Fix setting the global quality node Otherwise you'd get a KeyError there. Contributes to issue CURA-6600. --- cura/Machines/QualityManager.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py index b141434437..ce552ea657 100644 --- a/cura/Machines/QualityManager.py +++ b/cura/Machines/QualityManager.py @@ -1,11 +1,10 @@ # Copyright (c) 2019 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -from typing import TYPE_CHECKING, Optional, cast, Dict, List, Set +from typing import TYPE_CHECKING, Optional, Dict -from PyQt5.QtCore import QObject, QTimer, pyqtSignal, pyqtSlot +from PyQt5.QtCore import QObject, pyqtSignal, pyqtSlot -from UM.ConfigurationErrorMessage import ConfigurationErrorMessage from UM.Logger import Logger from UM.Util import parseBool from UM.Settings.InstanceContainer import InstanceContainer @@ -117,7 +116,7 @@ class QualityManager(QObject): nozzle_name = extruder.variant.getName() material_base = extruder.material.getMetaDataEntry("base_file") if nozzle_name not in machine_node.variants or material_base not in machine_node.variants[nozzle_name].materials: - # The printer has no variant/material-specific quality profiles. Return the global quality profiles. + # The printer has no variant/material-specific quality profiles. Use the global quality profiles. qualities_per_type_per_extruder[extruder_nr] = machine_node.global_qualities else: # Use the actually specialised quality profiles. @@ -126,8 +125,8 @@ class QualityManager(QObject): # Create the quality group for each available type. quality_groups = {} for quality_type, global_quality_node in machine_node.global_qualities.items(): - quality_groups[quality_type].node_for_global = global_quality_node quality_groups[quality_type] = QualityGroup(name = global_quality_node.getMetaDataEntry("name", "Unnamed profile"), quality_type = quality_type) + quality_groups[quality_type].node_for_global = global_quality_node for extruder, qualities_per_type in qualities_per_type_per_extruder: quality_groups[quality_type].nodes_for_extruders[extruder] = qualities_per_type[quality_type]