mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-08 07:27:29 -06:00
WIP: add getQaulityChangesGroup()
This commit is contained in:
parent
27169e883c
commit
d84ea07e9e
3 changed files with 113 additions and 50 deletions
|
@ -43,4 +43,4 @@ class ContainerNode:
|
||||||
return self.container
|
return self.container
|
||||||
|
|
||||||
def __str__(self) -> str:
|
def __str__(self) -> str:
|
||||||
return "ContainerNode[%s]" % self.metadata.get("id")
|
return "%s[%s]" % (self.__class__.__name__, self.metadata.get("id"))
|
||||||
|
|
|
@ -27,30 +27,48 @@ from cura.Machines.ContainerNode import ContainerNode
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
class QualityChangesGroup:
|
class QualityChangesGroup(ContainerGroup):
|
||||||
__slots__ = ("name", "qc_for_global", "qc_for_extruders_dict")
|
|
||||||
|
|
||||||
def __init__(self, name: str):
|
def __init__(self, name: str, parent = None):
|
||||||
self.name = name # type: str
|
super().__init__(name, parent)
|
||||||
self.qc_for_global = None # type: Optional["QualityNode"]
|
|
||||||
self.qc_for_extruders_dict = dict() # <extruder_id> -> QualityNode
|
def addNode(self, node: "QualityNode"):
|
||||||
|
# TODO: in 3.2 and earlier, a quality_changes container may have a field called "extruder" which contains the
|
||||||
|
# extruder definition ID it belongs to. But, in fact, we only need to know the following things:
|
||||||
|
# 1. which machine a custom profile is suitable for,
|
||||||
|
# 2. if this profile is for the GlobalStack,
|
||||||
|
# 3. if this profile is for an ExtruderStack and which one (the position).
|
||||||
|
#
|
||||||
|
# So, it is preferred to have a field like this:
|
||||||
|
# extruder_position = 1
|
||||||
|
# instead of this:
|
||||||
|
# extruder = custom_extruder_1
|
||||||
|
#
|
||||||
|
# An upgrade needs to be done if we want to do it this way. Before that, we use the extruder's definition
|
||||||
|
# to figure out its position.
|
||||||
|
#
|
||||||
|
extruder_definition_id = node.metadata.get("extruder")
|
||||||
|
if extruder_definition_id:
|
||||||
|
container_registry = Application.getInstance().getContainerRegistry()
|
||||||
|
metadata_list = container_registry.findDefinitionContainersMetadata(id = extruder_definition_id)
|
||||||
|
if not metadata_list:
|
||||||
|
raise RuntimeError("%s cannot get metadata for extruder definition [%s]" %
|
||||||
|
(self, extruder_definition_id))
|
||||||
|
extruder_definition_metadata = metadata_list[0]
|
||||||
|
extruder_position = str(extruder_definition_metadata["position"])
|
||||||
|
|
||||||
|
if extruder_position in self.nodes_for_extruders:
|
||||||
|
raise RuntimeError("%s tries to overwrite the existing nodes_for_extruders position [%s] %s with %s" %
|
||||||
|
(self, extruder_position, self.node_for_global, node))
|
||||||
|
|
||||||
|
self.nodes_for_extruders[extruder_position] = node
|
||||||
|
|
||||||
def addMetadata(self, metadata: dict):
|
|
||||||
extruder_id = metadata.get("extruder")
|
|
||||||
if extruder_id is not None:
|
|
||||||
self.qc_for_extruders_dict[extruder_id] = QualityNode(metadata)
|
|
||||||
else:
|
else:
|
||||||
self.qc_for_global = QualityNode(metadata)
|
# This is a quality_changes for the GlobalStack
|
||||||
|
if self.node_for_global is not None:
|
||||||
def getContainerForGlobalStack(self) -> "InstanceContainer":
|
raise RuntimeError("%s tries to overwrite the existing node_for_global %s with %s" %
|
||||||
return self.qc_for_global.getContainer()
|
(self, self.node_for_global, node))
|
||||||
|
self.node_for_global = node
|
||||||
def getContainerForExtruderStack(self, extruder_definition_id: str) -> Optional["InstanceContainer"]:
|
|
||||||
qc_node = self.qc_for_extruders_dict.get(extruder_definition_id)
|
|
||||||
container = None
|
|
||||||
if qc_node is not None:
|
|
||||||
container = qc_node.getContainer()
|
|
||||||
return container
|
|
||||||
|
|
||||||
|
|
||||||
class QualityGroup(ContainerGroup):
|
class QualityGroup(ContainerGroup):
|
||||||
|
@ -60,20 +78,20 @@ class QualityGroup(ContainerGroup):
|
||||||
self.quality_type = quality_type
|
self.quality_type = quality_type
|
||||||
self.is_available = False
|
self.is_available = False
|
||||||
|
|
||||||
|
#
|
||||||
|
# QualityNode is used for BOTH quality and quality_changes containers.
|
||||||
|
#
|
||||||
class QualityNode(ContainerNode):
|
class QualityNode(ContainerNode):
|
||||||
__slots__ = ("metadata", "container", "quality_type_map", "children_map")
|
|
||||||
|
|
||||||
def __init__(self, metadata = None):
|
def __init__(self, metadata: Optional[dict] = None):
|
||||||
super().__init__(metadata = metadata)
|
super().__init__(metadata = metadata)
|
||||||
self.quality_type_map = {}
|
self.quality_type_map = {} # quality_type -> QualityNode for InstanceContainer
|
||||||
|
|
||||||
|
|
||||||
def addQualityMetadata(self, quality_type: str, metadata: dict):
|
def addQualityMetadata(self, quality_type: str, metadata: dict):
|
||||||
if quality_type not in self.quality_type_map:
|
if quality_type not in self.quality_type_map:
|
||||||
self.quality_type_map[quality_type] = QualityNode(metadata)
|
self.quality_type_map[quality_type] = QualityNode(metadata)
|
||||||
|
|
||||||
def getQualityNode(self, quality_type: str):
|
def getQualityNode(self, quality_type: str) -> Optional["QualityNode"]:
|
||||||
return self.quality_type_map.get(quality_type)
|
return self.quality_type_map.get(quality_type)
|
||||||
|
|
||||||
def addQualityChangesMetadata(self, quality_type: str, metadata: dict):
|
def addQualityChangesMetadata(self, quality_type: str, metadata: dict):
|
||||||
|
@ -84,8 +102,8 @@ class QualityNode(ContainerNode):
|
||||||
name = metadata["name"]
|
name = metadata["name"]
|
||||||
if name not in quality_type_node.children_map:
|
if name not in quality_type_node.children_map:
|
||||||
quality_type_node.children_map[name] = QualityChangesGroup(name)
|
quality_type_node.children_map[name] = QualityChangesGroup(name)
|
||||||
qc_group = quality_type_node.children_map[name]
|
quality_changes_group = quality_type_node.children_map[name]
|
||||||
qc_group.addMetadata(metadata)
|
quality_changes_group.addNode(QualityNode(metadata))
|
||||||
|
|
||||||
|
|
||||||
class QualityManager(QObject):
|
class QualityManager(QObject):
|
||||||
|
@ -164,6 +182,11 @@ class QualityManager(QObject):
|
||||||
|
|
||||||
material_node.addQualityMetadata(quality_type, metadata)
|
material_node.addQualityMetadata(quality_type, metadata)
|
||||||
|
|
||||||
|
# Initialize quality
|
||||||
|
self._initializeQualityChangesTables()
|
||||||
|
|
||||||
|
|
||||||
|
def _initializeQualityChangesTables(self):
|
||||||
# Initialize the lookup tree for quality_changes profiles with following structure:
|
# Initialize the lookup tree for quality_changes profiles with following structure:
|
||||||
# <machine> -> <quality_type> -> <name>
|
# <machine> -> <quality_type> -> <name>
|
||||||
quality_changes_metadata_list = self._container_registry.findContainersMetadata(type = "quality_changes")
|
quality_changes_metadata_list = self._container_registry.findContainersMetadata(type = "quality_changes")
|
||||||
|
@ -180,6 +203,51 @@ class QualityManager(QObject):
|
||||||
|
|
||||||
machine_node.addQualityChangesMetadata(quality_type, metadata)
|
machine_node.addQualityChangesMetadata(quality_type, metadata)
|
||||||
|
|
||||||
|
# Updates the given quality groups' availabilities according to which extruders are being used/ enabled.
|
||||||
|
def _updateQualityGroupsAvailability(self, machine: "GlobalStack", quality_group_list):
|
||||||
|
used_extruders = set()
|
||||||
|
# TODO: This will change after the Machine refactoring
|
||||||
|
for i in range(machine.getProperty("machine_extruder_count", "value")):
|
||||||
|
used_extruders.add(str(i))
|
||||||
|
|
||||||
|
# Update the "is_available" flag for each quality group.
|
||||||
|
for quality_group in quality_group_list:
|
||||||
|
is_available = True
|
||||||
|
if quality_group.node_for_global is None:
|
||||||
|
is_available = False
|
||||||
|
if is_available:
|
||||||
|
for position in used_extruders:
|
||||||
|
if position not in quality_group.nodes_for_extruders:
|
||||||
|
is_available = False
|
||||||
|
break
|
||||||
|
|
||||||
|
quality_group.is_available = is_available
|
||||||
|
|
||||||
|
# Returns a dict of "custom profile name" -> QualityChangesGroup
|
||||||
|
def getQualityChangesGroup(self, machine: "GlobalStack") -> dict:
|
||||||
|
# TODO: How to make this simpler?
|
||||||
|
# Get machine definition ID
|
||||||
|
machine_definition_id = self._default_machine_definition_id
|
||||||
|
if parseBool(machine.getMetaDataEntry("has_machine_quality", False)):
|
||||||
|
machine_definition_id = machine.getMetaDataEntry("quality_definition")
|
||||||
|
if machine_definition_id is None:
|
||||||
|
machine_definition_id = machine.definition.getId()
|
||||||
|
|
||||||
|
machine_node = self._machine_quality_type_to_quality_changes_dict.get(machine_definition_id)
|
||||||
|
if not machine_node:
|
||||||
|
raise RuntimeError("Cannot find node for machine def [%s] in QualityChanges lookup table" % machine_definition_id)
|
||||||
|
|
||||||
|
# iterate over all quality_types in the machine node
|
||||||
|
quality_changes_group_dict = dict()
|
||||||
|
for quality_type, quality_changes_node in machine_node.quality_type_map.items():
|
||||||
|
for quality_changes_name, quality_changes_group in quality_changes_node.children_map.items():
|
||||||
|
quality_changes_group_dict[quality_changes_name] = quality_changes_group
|
||||||
|
|
||||||
|
# Update availabilities for each quality group
|
||||||
|
self._updateQualityGroupsAvailability(machine, quality_changes_group_dict.values())
|
||||||
|
|
||||||
|
return quality_changes_group_dict
|
||||||
|
|
||||||
def getQualityGroups(self, machine: "GlobalStack") -> dict:
|
def getQualityGroups(self, machine: "GlobalStack") -> dict:
|
||||||
# TODO: How to make this simpler, including the fallbacks.
|
# TODO: How to make this simpler, including the fallbacks.
|
||||||
# Get machine definition ID
|
# Get machine definition ID
|
||||||
|
@ -191,7 +259,7 @@ class QualityManager(QObject):
|
||||||
|
|
||||||
machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(machine_definition_id)
|
machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(machine_definition_id)
|
||||||
if not machine_node:
|
if not machine_node:
|
||||||
Logger.log("e", "Cannot find node for machine def [%s] in quality lookup table", machine_definition_id)
|
raise RuntimeError("Cannot find node for machine def [%s] in Quality lookup table" % machine_definition_id)
|
||||||
|
|
||||||
# iterate over all quality_types in the machine node
|
# iterate over all quality_types in the machine node
|
||||||
quality_group_dict = {}
|
quality_group_dict = {}
|
||||||
|
@ -268,23 +336,8 @@ class QualityManager(QObject):
|
||||||
|
|
||||||
quality_group.nodes_for_extruders[position] = quality_node
|
quality_group.nodes_for_extruders[position] = quality_node
|
||||||
|
|
||||||
used_extruders = set()
|
# Update availabilities for each quality group
|
||||||
# TODO: This will change after the Machine refactoring
|
self._updateQualityGroupsAvailability(machine, quality_group_dict.values())
|
||||||
for i in range(machine.getProperty("machine_extruder_count", "value")):
|
|
||||||
used_extruders.add(str(i))
|
|
||||||
|
|
||||||
# Update the "is_available" flag for each quality group.
|
|
||||||
for quality_group in quality_group_dict.values():
|
|
||||||
is_available = True
|
|
||||||
if quality_group.node_for_global is None:
|
|
||||||
is_available = False
|
|
||||||
if is_available:
|
|
||||||
for position in used_extruders:
|
|
||||||
if position not in quality_group.nodes_for_extruders:
|
|
||||||
is_available = False
|
|
||||||
break
|
|
||||||
|
|
||||||
quality_group.is_available = is_available
|
|
||||||
|
|
||||||
return quality_group_dict
|
return quality_group_dict
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
# Copyright (c) 2016 Ultimaker B.V.
|
# Copyright (c) 2018 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the AGPLv3 or higher.
|
# Cura is released under the terms of the LGPLv2 or higher.
|
||||||
from UM.Extension import Extension
|
from UM.Extension import Extension
|
||||||
|
|
||||||
from PyQt5.QtCore import QObject
|
from PyQt5.QtCore import QObject
|
||||||
|
@ -12,6 +12,7 @@ class TestTool(Extension, QObject):
|
||||||
|
|
||||||
self.addMenuItem("Test material manager", self._testMaterialManager)
|
self.addMenuItem("Test material manager", self._testMaterialManager)
|
||||||
self.addMenuItem("Test get quality", self._testGetQuality)
|
self.addMenuItem("Test get quality", self._testGetQuality)
|
||||||
|
self.addMenuItem("Test get quality changes", self.testGetQualityChanges)
|
||||||
|
|
||||||
def _testMaterialManager(self):
|
def _testMaterialManager(self):
|
||||||
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
||||||
|
@ -24,4 +25,13 @@ class TestTool(Extension, QObject):
|
||||||
result_dict = {}
|
result_dict = {}
|
||||||
global_stack = CuraApplication.getInstance().getMachineManager()._global_container_stack
|
global_stack = CuraApplication.getInstance().getMachineManager()._global_container_stack
|
||||||
result = CuraApplication.getInstance()._quality_manager.getQualityGroups(global_stack)
|
result = CuraApplication.getInstance()._quality_manager.getQualityGroups(global_stack)
|
||||||
|
print("!!!!!!!!!!!!!!!!!!!")
|
||||||
|
|
||||||
|
def testGetQualityChanges(self):
|
||||||
|
print("!!!!!!!!!!!!!!!!!!!")
|
||||||
|
|
||||||
|
from cura.CuraApplication import CuraApplication
|
||||||
|
result_dict = {}
|
||||||
|
global_stack = CuraApplication.getInstance().getMachineManager()._global_container_stack
|
||||||
|
result = CuraApplication.getInstance()._quality_manager.getQualityChangesGroup(global_stack)
|
||||||
|
print("!!!!!!!!!!!!!!!!!!!")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue