mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-08-14 22:05:59 +08:00
Refactor material lookup tree creation
This commit is contained in:
parent
5320d05b20
commit
a7448e4970
@ -192,9 +192,16 @@ class MaterialManager(QObject):
|
|||||||
# "machine" -> "nozzle name" -> "buildplate name" -> "root material ID" -> specific material InstanceContainer
|
# "machine" -> "nozzle name" -> "buildplate name" -> "root material ID" -> specific material InstanceContainer
|
||||||
self._diameter_machine_nozzle_buildplate_material_map = dict()
|
self._diameter_machine_nozzle_buildplate_material_map = dict()
|
||||||
for material_metadata in material_metadatas.values():
|
for material_metadata in material_metadatas.values():
|
||||||
|
self.__addMaterialMetadataIntoLookupTree(material_metadata)
|
||||||
|
|
||||||
|
self.materialsUpdated.emit()
|
||||||
|
|
||||||
|
def __addMaterialMetadataIntoLookupTree(self, material_metadata: dict) -> None:
|
||||||
|
material_id = material_metadata["id"]
|
||||||
|
|
||||||
# We don't store empty material in the lookup tables
|
# We don't store empty material in the lookup tables
|
||||||
if material_metadata["id"] == "empty_material":
|
if material_id == "empty_material":
|
||||||
continue
|
return
|
||||||
|
|
||||||
root_material_id = material_metadata["base_file"]
|
root_material_id = material_metadata["base_file"]
|
||||||
definition = material_metadata["definition"]
|
definition = material_metadata["definition"]
|
||||||
@ -203,62 +210,56 @@ class MaterialManager(QObject):
|
|||||||
if approximate_diameter not in self._diameter_machine_nozzle_buildplate_material_map:
|
if approximate_diameter not in self._diameter_machine_nozzle_buildplate_material_map:
|
||||||
self._diameter_machine_nozzle_buildplate_material_map[approximate_diameter] = {}
|
self._diameter_machine_nozzle_buildplate_material_map[approximate_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:
|
if definition not in machine_nozzle_buildplate_material_map:
|
||||||
machine_nozzle_buildplate_material_map[definition] = MaterialNode()
|
machine_nozzle_buildplate_material_map[definition] = MaterialNode()
|
||||||
|
|
||||||
machine_node = machine_nozzle_buildplate_material_map[definition]
|
# This is a list of information regarding the intermediate nodes:
|
||||||
|
# nozzle -> buildplate
|
||||||
nozzle_name = material_metadata.get("variant_name")
|
nozzle_name = material_metadata.get("variant_name")
|
||||||
buildplate_name = material_metadata.get("buildplate_name")
|
buildplate_name = material_metadata.get("buildplate_name")
|
||||||
if not nozzle_name:
|
intermediate_node_info_list = [(nozzle_name, VariantType.NOZZLE),
|
||||||
# if there is no nozzle, this material is for the machine, so put its metadata in the machine node.
|
(buildplate_name, VariantType.BUILD_PLATE),
|
||||||
machine_node.material_map[root_material_id] = MaterialNode(material_metadata)
|
]
|
||||||
else:
|
|
||||||
# this material is nozzle-specific, so we save it in a nozzle-specific node under the
|
|
||||||
# machine-specific node
|
|
||||||
|
|
||||||
# Check first if the nozzle exists in the manager
|
variant_manager = self._application.getVariantManager()
|
||||||
existing_nozzle = variant_manager.getVariantNode(definition, nozzle_name, VariantType.NOZZLE)
|
|
||||||
if existing_nozzle is not None:
|
|
||||||
if nozzle_name not in machine_node.children_map:
|
|
||||||
machine_node.children_map[nozzle_name] = MaterialNode()
|
|
||||||
|
|
||||||
nozzle_node = machine_node.children_map[nozzle_name]
|
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
|
||||||
|
|
||||||
# Check build plate node
|
# Update the current node to advance to a more specific branch
|
||||||
if not buildplate_name:
|
if variant_name not in current_node.children_map:
|
||||||
# if there is no buildplate, this material is for the machine, so put its metadata in the machine node.
|
current_node.children_map[variant_name] = MaterialNode()
|
||||||
if root_material_id in nozzle_node.material_map: # We shouldn't have duplicated nozzle-specific materials for the same machine.
|
current_node = current_node.children_map[variant_name]
|
||||||
ConfigurationErrorMessage.getInstance().addFaultyContainers(root_material_id)
|
|
||||||
continue
|
|
||||||
nozzle_node.material_map[root_material_id] = MaterialNode(material_metadata)
|
|
||||||
else:
|
|
||||||
# this material is nozzle-and-buildplate-specific, so we save it in a buildplate-specific node
|
|
||||||
# under the machine-specific node
|
|
||||||
|
|
||||||
# Check first if the buildplate exists in the manager
|
current_intermediate_node_info_idx += 1
|
||||||
existing_buildplate = variant_manager.getVariantNode(definition, buildplate_name, VariantType.BUILD_PLATE)
|
|
||||||
if existing_buildplate is not None:
|
|
||||||
if buildplate_name not in nozzle_node.children_map:
|
|
||||||
nozzle_node.children_map[buildplate_name] = MaterialNode()
|
|
||||||
|
|
||||||
buildplate_node = nozzle_node.children_map[buildplate_name]
|
if error_message is not None:
|
||||||
if root_material_id in buildplate_node.material_map: # We shouldn't have duplicated nozzle-and-buildplate-specific materials for the same machine.
|
Logger.log("e", "%s It will not be added into the material lookup tree.", error_message)
|
||||||
ConfigurationErrorMessage.getInstance().addFaultyContainers(root_material_id)
|
|
||||||
continue
|
|
||||||
buildplate_node.material_map[root_material_id] = MaterialNode(material_metadata)
|
|
||||||
|
|
||||||
else:
|
|
||||||
# Add this container id to the wrong containers list in the registry
|
|
||||||
Logger.log("w", "Not adding {id} to the material manager because the buildplate does not exist.".format(id = material_metadata["id"]))
|
|
||||||
self._container_registry.addWrongContainerId(material_metadata["id"])
|
self._container_registry.addWrongContainerId(material_metadata["id"])
|
||||||
|
return
|
||||||
|
|
||||||
else:
|
# Add the material to the current tree node, which is the deepest (the most specific) branch we can find.
|
||||||
# Add this container id to the wrong containers list in the registry
|
# Sanity check: Make sure that there is no duplicated materials.
|
||||||
Logger.log("w", "Not adding {id} to the material manager because the nozzle does not exist.".format(id = material_metadata["id"]))
|
if root_material_id in current_node.material_map:
|
||||||
self._container_registry.addWrongContainerId(material_metadata["id"])
|
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
|
||||||
|
|
||||||
self.materialsUpdated.emit()
|
current_node.material_map[root_material_id] = MaterialNode(material_metadata)
|
||||||
|
|
||||||
def _updateMaps(self):
|
def _updateMaps(self):
|
||||||
Logger.log("i", "Updating material lookup data ...")
|
Logger.log("i", "Updating material lookup data ...")
|
||||||
@ -290,7 +291,7 @@ class MaterialManager(QObject):
|
|||||||
#
|
#
|
||||||
# Return a dict with all root material IDs (k) and ContainerNodes (v) that's suitable for the given setup.
|
# Return a dict with all root material IDs (k) and ContainerNodes (v) that's suitable for the given setup.
|
||||||
#
|
#
|
||||||
def getAvailableMaterials(self, machine_definition: "DefinitionContainer", extruder_nozzle_name: Optional[str],
|
def getAvailableMaterials(self, machine_definition: "DefinitionContainer", nozzle_name: Optional[str],
|
||||||
buildplate_name: Optional[str], diameter: float) -> Dict[str, MaterialNode]:
|
buildplate_name: Optional[str], diameter: float) -> Dict[str, MaterialNode]:
|
||||||
# round the diameter to get the approximate diameter
|
# round the diameter to get the approximate diameter
|
||||||
rounded_diameter = str(round(diameter))
|
rounded_diameter = str(round(diameter))
|
||||||
@ -306,8 +307,8 @@ class MaterialManager(QObject):
|
|||||||
default_machine_node = machine_nozzle_buildplate_material_map.get(self._default_machine_definition_id)
|
default_machine_node = machine_nozzle_buildplate_material_map.get(self._default_machine_definition_id)
|
||||||
nozzle_node = None
|
nozzle_node = None
|
||||||
buildplate_node = None
|
buildplate_node = None
|
||||||
if extruder_nozzle_name is not None and machine_node is not None:
|
if nozzle_name is not None and machine_node is not None:
|
||||||
nozzle_node = machine_node.getChildNode(extruder_nozzle_name)
|
nozzle_node = machine_node.getChildNode(nozzle_name)
|
||||||
# Get buildplate node if possible
|
# Get buildplate node if possible
|
||||||
if nozzle_node is not None and buildplate_name is not None:
|
if nozzle_node is not None and buildplate_name is not None:
|
||||||
buildplate_node = nozzle_node.getChildNode(buildplate_name)
|
buildplate_node = nozzle_node.getChildNode(buildplate_name)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user