mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-06-04 11:14:21 +08:00
Correctly update the quality profiles in the extruders when changing quality changes, taking the different materials into account.
Contributes to CURA-2320 Filtering Quality-Changes profiles on material?
This commit is contained in:
parent
fc69b110f3
commit
4bb6ddaf28
@ -40,9 +40,9 @@ class QualityManager:
|
|||||||
# \param material_containers (Optional) \type{List[ContainerInstance]} If nothing is specified then
|
# \param material_containers (Optional) \type{List[ContainerInstance]} If nothing is specified then
|
||||||
# the current set of selected materials is used.
|
# the current set of selected materials is used.
|
||||||
# \return the matching quality changes containers \type{List[ContainerInstance]}
|
# \return the matching quality changes containers \type{List[ContainerInstance]}
|
||||||
def findQualityChangesByName(self, quality_changes_name, machine_definition=None, material_containers=None):
|
def findQualityChangesByName(self, quality_changes_name, machine_definition=None):
|
||||||
criteria = {"type": "quality_changes", "name": quality_changes_name}
|
criteria = {"type": "quality_changes", "name": quality_changes_name}
|
||||||
return self._getFilteredContainersForStack(machine_definition, material_containers, **criteria)
|
return self._getFilteredContainersForStack(machine_definition, [], **criteria)
|
||||||
|
|
||||||
## Find a quality container by quality type.
|
## Find a quality container by quality type.
|
||||||
#
|
#
|
||||||
@ -67,8 +67,6 @@ class QualityManager:
|
|||||||
if quality_definition is not None:
|
if quality_definition is not None:
|
||||||
machine_definition = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=quality_definition)[0]
|
machine_definition = UM.Settings.ContainerRegistry.getInstance().findDefinitionContainers(id=quality_definition)[0]
|
||||||
|
|
||||||
machine_definition = self.getParentMachineDefinition(machine_definition)
|
|
||||||
|
|
||||||
if material_containers is None:
|
if material_containers is None:
|
||||||
active_stacks = cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
|
active_stacks = cura.Settings.ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
|
||||||
material_containers = [stack.findContainer(type="material") for stack in active_stacks]
|
material_containers = [stack.findContainer(type="material") for stack in active_stacks]
|
||||||
@ -76,11 +74,13 @@ class QualityManager:
|
|||||||
criteria = kwargs
|
criteria = kwargs
|
||||||
filter_by_material = False
|
filter_by_material = False
|
||||||
|
|
||||||
if machine_definition.getMetaDataEntry("has_machine_quality"):
|
machine_definition = self.getParentMachineDefinition(machine_definition)
|
||||||
definition_id = machine_definition.getMetaDataEntry("quality_definition", machine_definition.getId())
|
whole_machine_definition = self.getWholeMachineDefinition(machine_definition)
|
||||||
|
if whole_machine_definition.getMetaDataEntry("has_machine_quality"):
|
||||||
|
definition_id = machine_definition.getMetaDataEntry("quality_definition", whole_machine_definition.getId())
|
||||||
criteria["definition"] = definition_id
|
criteria["definition"] = definition_id
|
||||||
|
|
||||||
filter_by_material = machine_definition.getMetaDataEntry("has_materials")
|
filter_by_material = whole_machine_definition.getMetaDataEntry("has_materials")
|
||||||
|
|
||||||
# Stick the material IDs in a set
|
# Stick the material IDs in a set
|
||||||
if material_containers is None or len(material_containers) == 0:
|
if material_containers is None or len(material_containers) == 0:
|
||||||
@ -90,6 +90,12 @@ class QualityManager:
|
|||||||
for material_instance in material_containers:
|
for material_instance in material_containers:
|
||||||
material_ids.add(material_instance.getId())
|
material_ids.add(material_instance.getId())
|
||||||
|
|
||||||
|
|
||||||
|
if machine_definition.getMetaDataEntry("type") == "extruder":
|
||||||
|
extruder_id = machine_definition.getId()
|
||||||
|
else:
|
||||||
|
extruder_id = None
|
||||||
|
|
||||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria)
|
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria)
|
||||||
|
|
||||||
result = []
|
result = []
|
||||||
@ -97,6 +103,8 @@ class QualityManager:
|
|||||||
# If the machine specifies we should filter by material, exclude containers that do not match any active material.
|
# If the machine specifies we should filter by material, exclude containers that do not match any active material.
|
||||||
if filter_by_material and container.getMetaDataEntry("material") not in material_ids:
|
if filter_by_material and container.getMetaDataEntry("material") not in material_ids:
|
||||||
continue
|
continue
|
||||||
|
if extruder_id != container.getMetaDataEntry("extruder"):
|
||||||
|
continue
|
||||||
result.append(container)
|
result.append(container)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@ -130,3 +138,18 @@ class QualityManager:
|
|||||||
extruder_position = machine_definition.getMetaDataEntry("position")
|
extruder_position = machine_definition.getMetaDataEntry("position")
|
||||||
parent_extruder_id = parent_machine.getMetaDataEntry("machine_extruder_trains")[extruder_position]
|
parent_extruder_id = parent_machine.getMetaDataEntry("machine_extruder_trains")[extruder_position]
|
||||||
return container_registry.findDefinitionContainers(id=parent_extruder_id)[0]
|
return container_registry.findDefinitionContainers(id=parent_extruder_id)[0]
|
||||||
|
|
||||||
|
## Get the whole/global machine definition from an extruder definition.
|
||||||
|
#
|
||||||
|
# \param machine_definition \type{DefinitionContainer} This may be a normal machine definition or
|
||||||
|
# an extruder definition.
|
||||||
|
# \return \type{DefinitionContainer}
|
||||||
|
def getWholeMachineDefinition(self, machine_definition):
|
||||||
|
machine_entry = machine_definition.getMetaDataEntry("machine")
|
||||||
|
if machine_entry is None:
|
||||||
|
# This already is a 'global' machine definition.
|
||||||
|
return machine_definition
|
||||||
|
else:
|
||||||
|
container_registry = UM.Settings.ContainerRegistry.getInstance()
|
||||||
|
whole_machine = container_registry.findDefinitionContainers(id=machine_entry)[0]
|
||||||
|
return whole_machine
|
||||||
|
@ -303,19 +303,25 @@ class ExtruderManager(QObject):
|
|||||||
for name in self._extruder_trains[machine_id]:
|
for name in self._extruder_trains[machine_id]:
|
||||||
yield self._extruder_trains[machine_id][name]
|
yield self._extruder_trains[machine_id][name]
|
||||||
|
|
||||||
## Returns a generator that will iterate over the global stack and per-extruder stacks.
|
## Returns a list containing the global stack and active extruder stacks.
|
||||||
#
|
#
|
||||||
# The first generated element is the global container stack. After that any extruder stacks are generated.
|
# The first element is the global container stack, followed by any extruder stacks.
|
||||||
|
# \return \type{List[ContainerStack]}
|
||||||
def getActiveGlobalAndExtruderStacks(self):
|
def getActiveGlobalAndExtruderStacks(self):
|
||||||
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||||
if not global_stack:
|
if not global_stack:
|
||||||
return
|
return None
|
||||||
|
|
||||||
yield global_stack
|
result = [global_stack]
|
||||||
|
result.extend(self.getActiveExtruderStacks())
|
||||||
|
return result
|
||||||
|
|
||||||
global_id = global_stack.getId()
|
## Returns the list of active extruder stacks.
|
||||||
for name in self._extruder_trains[global_id]:
|
#
|
||||||
yield self._extruder_trains[global_id][name]
|
# \return \type{List[ContainerStack]} a list of
|
||||||
|
def getActiveExtruderStacks(self):
|
||||||
|
global_stack = UM.Application.getInstance().getGlobalContainerStack()
|
||||||
|
return list(self._extruder_trains[global_stack.getId()].values()) if global_stack else []
|
||||||
|
|
||||||
def __globalContainerStackChanged(self):
|
def __globalContainerStackChanged(self):
|
||||||
self._addCurrentMachineExtruders()
|
self._addCurrentMachineExtruders()
|
||||||
|
@ -19,7 +19,6 @@ from . import ExtruderManager
|
|||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
catalog = i18nCatalog("cura")
|
catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
import time
|
|
||||||
import os
|
import os
|
||||||
|
|
||||||
class MachineManager(QObject):
|
class MachineManager(QObject):
|
||||||
@ -602,92 +601,33 @@ class MachineManager(QObject):
|
|||||||
# \param quality_id The quality_id of either a quality or a quality_changes
|
# \param quality_id The quality_id of either a quality or a quality_changes
|
||||||
@pyqtSlot(str)
|
@pyqtSlot(str)
|
||||||
def setActiveQuality(self, quality_id):
|
def setActiveQuality(self, quality_id):
|
||||||
|
self.blurSettings.emit()
|
||||||
|
|
||||||
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_id)
|
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(id = quality_id)
|
||||||
if not containers or not self._global_container_stack:
|
if not containers or not self._global_container_stack:
|
||||||
return
|
return
|
||||||
|
|
||||||
Logger.log("d", "Attempting to change the active quality to %s", quality_id)
|
Logger.log("d", "Attempting to change the active quality to %s", quality_id)
|
||||||
|
|
||||||
self.blurSettings.emit()
|
|
||||||
|
|
||||||
quality_changes_container = self._empty_quality_changes_container
|
|
||||||
|
|
||||||
# Quality profile come in two flavours: type=quality and type=quality_changes
|
# Quality profile come in two flavours: type=quality and type=quality_changes
|
||||||
# If we found a quality_changes profile then look up its parent quality profile.
|
# If we found a quality_changes profile then look up its parent quality profile.
|
||||||
container_type = containers[0].getMetaDataEntry("type")
|
container_type = containers[0].getMetaDataEntry("type")
|
||||||
|
quality_name = containers[0].getName()
|
||||||
|
|
||||||
# Get quality container and optionally the quality_changes container.
|
# Get quality container and optionally the quality_changes container.
|
||||||
if container_type == "quality":
|
if container_type == "quality":
|
||||||
quality_container = containers[0]
|
new_quality_settings_list = self._determineQualityAndQualityChangesForQuality(quality_name)
|
||||||
|
|
||||||
elif container_type == "quality_changes":
|
elif container_type == "quality_changes":
|
||||||
quality_changes_container = containers[0]
|
new_quality_settings_list = self._determineQualityAndQualityChangesForQualityChanges(quality_name)
|
||||||
# Find a suitable quality container to match this quality changes container.
|
|
||||||
containers = QualityManager.getInstance().findQualityByQualityType(quality_changes_container.getMetaDataEntry("quality_type"))
|
|
||||||
if not containers:
|
|
||||||
Logger.log("e", "Could not find quality %s for changes %s, not changing quality", quality_changes_container.getMetaDataEntry("quality"), quality_changes_container.getId())
|
|
||||||
return
|
|
||||||
quality_container = containers[0]
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
Logger.log("e", "Tried to set quality to a container that is not of the right type")
|
Logger.log("e", "Tried to set quality to a container that is not of the right type")
|
||||||
return
|
return
|
||||||
|
|
||||||
quality_type = quality_container.getMetaDataEntry("quality_type")
|
|
||||||
if not quality_type:
|
|
||||||
quality_type = quality_changes_container.getName()
|
|
||||||
|
|
||||||
# Find and swap in the quality changes containers for the global stack and each extruder stack.
|
|
||||||
stacks = list(ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks())
|
|
||||||
name_changed_connect_stacks = [] # Connect these stacks to the name changed callback
|
name_changed_connect_stacks = [] # Connect these stacks to the name changed callback
|
||||||
for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
|
for setting_info in new_quality_settings_list:
|
||||||
if stack != self._global_container_stack:
|
stack = setting_info["stack"]
|
||||||
# Must be an extruder stack. Use the ID of the extruders as specified by the machine definition.
|
stack_quality = setting_info["quality"]
|
||||||
extruder_id = QualityManager.getInstance().getParentMachineDefinition(stack.getBottom()).getId()
|
stack_quality_changes = setting_info["quality_changes"]
|
||||||
else:
|
|
||||||
extruder_id = None
|
|
||||||
criteria = { "quality_type": quality_type, "type": "quality", "extruder": extruder_id }
|
|
||||||
|
|
||||||
# Filter candidate quality containers by the current material in the stack.
|
|
||||||
material = stack.findContainer(type = "material")
|
|
||||||
if material and material is not self._empty_material_container:
|
|
||||||
criteria["material"] = material.getId()
|
|
||||||
|
|
||||||
# Apply a filter when machines have their own specific quality profiles.
|
|
||||||
if self._global_container_stack.getMetaDataEntry("has_machine_quality"):
|
|
||||||
criteria["definition"] = self.activeQualityDefinitionId
|
|
||||||
else:
|
|
||||||
criteria["definition"] = "fdmprinter"
|
|
||||||
|
|
||||||
# Find the new quality container.
|
|
||||||
stack_quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria)
|
|
||||||
if not stack_quality:
|
|
||||||
# Search again, except this time drop any extruder requirement. We should now get
|
|
||||||
# the same quality container as the one needed for the global stack.
|
|
||||||
criteria.pop("extruder")
|
|
||||||
stack_quality = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria)
|
|
||||||
if not stack_quality:
|
|
||||||
stack_quality = quality_container
|
|
||||||
else:
|
|
||||||
stack_quality = stack_quality[0]
|
|
||||||
else:
|
|
||||||
stack_quality = stack_quality[0]
|
|
||||||
|
|
||||||
# Find the new quality changes if one has been specified.
|
|
||||||
if quality_changes_container != self._empty_quality_changes_container:
|
|
||||||
changes = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(
|
|
||||||
type="quality_changes",
|
|
||||||
quality_type=stack_quality.getMetaDataEntry("quality_type"),
|
|
||||||
name = quality_changes_container.getName(), extruder = extruder_id)
|
|
||||||
if changes:
|
|
||||||
stack_quality_changes = changes[0]
|
|
||||||
else:
|
|
||||||
Logger.log("w", "Unable to find quality changes container. Using empty container instead")
|
|
||||||
print(stack_quality.getMetaDataEntry("quality_type"), quality_changes_container.getName(), extruder_id)
|
|
||||||
stack_quality_changes = self._empty_quality_changes_container
|
|
||||||
else:
|
|
||||||
# This is case of quality container and the no-op quality changes container.
|
|
||||||
stack_quality_changes = self._empty_quality_changes_container
|
|
||||||
|
|
||||||
name_changed_connect_stacks.append(stack_quality)
|
name_changed_connect_stacks.append(stack_quality)
|
||||||
name_changed_connect_stacks.append(stack_quality_changes)
|
name_changed_connect_stacks.append(stack_quality_changes)
|
||||||
@ -696,8 +636,9 @@ class MachineManager(QObject):
|
|||||||
|
|
||||||
# Send emits that are postponed in replaceContainer.
|
# Send emits that are postponed in replaceContainer.
|
||||||
# Here the stacks are finished replacing and every value can be resolved based on the current state.
|
# Here the stacks are finished replacing and every value can be resolved based on the current state.
|
||||||
for stack in stacks:
|
for setting_info in new_quality_settings_list:
|
||||||
stack.sendPostponedEmits()
|
setting_info["stack"].sendPostponedEmits()
|
||||||
|
|
||||||
# Connect to onQualityNameChanged
|
# Connect to onQualityNameChanged
|
||||||
for stack in name_changed_connect_stacks:
|
for stack in name_changed_connect_stacks:
|
||||||
stack.nameChanged.connect(self._onQualityNameChanged)
|
stack.nameChanged.connect(self._onQualityNameChanged)
|
||||||
@ -707,6 +648,69 @@ class MachineManager(QObject):
|
|||||||
|
|
||||||
self.activeQualityChanged.emit()
|
self.activeQualityChanged.emit()
|
||||||
|
|
||||||
|
## Determine the quality and quality changes settings for the current machine for a quality name.
|
||||||
|
#
|
||||||
|
# \param quality_name \type{str} the name of the quality.
|
||||||
|
# \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes".
|
||||||
|
def _determineQualityAndQualityChangesForQuality(self, quality_name):
|
||||||
|
result = []
|
||||||
|
empty_quality_changes = self._empty_quality_changes_container
|
||||||
|
|
||||||
|
# Find the values for the global stack.
|
||||||
|
global_container_stack = self._global_container_stack
|
||||||
|
global_machine_definition = QualityManager.getInstance().getParentMachineDefinition(global_container_stack.getBottom())
|
||||||
|
material = global_container_stack.findContainer(type="material")
|
||||||
|
global_quality = QualityManager.getInstance().findQualityByName(quality_name, global_machine_definition, [material])[0]
|
||||||
|
result.append({"stack": global_container_stack, "quality": global_quality, "quality_changes": empty_quality_changes})
|
||||||
|
|
||||||
|
# Find the values for each extruder.
|
||||||
|
for stack in ExtruderManager.getInstance().getActiveExtruderStacks():
|
||||||
|
# machine_definition = QualityManager.getInstance().getParentMachineDefinition(stack.getBottom())
|
||||||
|
material = stack.findContainer(type="material")
|
||||||
|
stack_qualities = QualityManager.getInstance().findQualityByName(quality_name, global_machine_definition, [material])
|
||||||
|
if not stack_qualities:
|
||||||
|
# Fall back on the values used for the global stack.
|
||||||
|
result.append({"stack": stack, "quality": global_quality, "quality_changes": empty_quality_changes})
|
||||||
|
else:
|
||||||
|
result.append({"stack": stack, "quality": stack_qualities[0], "quality_changes": empty_quality_changes})
|
||||||
|
return result
|
||||||
|
|
||||||
|
## Determine the quality and quality changes settings for the current machine for a quality changes name.
|
||||||
|
#
|
||||||
|
# \param quality_changes_name \type{str} the name of the quality changes.
|
||||||
|
# \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes".
|
||||||
|
def _determineQualityAndQualityChangesForQualityChanges(self, quality_changes_name):
|
||||||
|
result = []
|
||||||
|
quality_manager = QualityManager.getInstance()
|
||||||
|
|
||||||
|
global_container_stack = self._global_container_stack
|
||||||
|
global_machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.getBottom())
|
||||||
|
global_quality_changes = quality_manager.findQualityChangesByName(quality_changes_name, global_machine_definition)[0]
|
||||||
|
material = global_container_stack.findContainer(type="material")
|
||||||
|
|
||||||
|
# For the global stack, find a quality which matches the quality_type in
|
||||||
|
# the quality changes profile and also satisfies any material constraints.
|
||||||
|
quality_type = global_quality_changes.getMetaDataEntry("quality_type")
|
||||||
|
global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material])[0]
|
||||||
|
|
||||||
|
result.append({"stack": global_container_stack, "quality": global_quality, "quality_changes": global_quality_changes})
|
||||||
|
|
||||||
|
# Find the values for each extruder.
|
||||||
|
for stack in ExtruderManager.getInstance().getActiveExtruderStacks():
|
||||||
|
machine_definition = quality_manager.getParentMachineDefinition(stack.getBottom())
|
||||||
|
quality_changes_profiles = quality_manager.findQualityChangesByName(quality_changes_name, machine_definition)
|
||||||
|
if quality_changes_profiles:
|
||||||
|
quality_changes = quality_changes_profiles[0]
|
||||||
|
else:
|
||||||
|
quality_changes = global_quality_changes
|
||||||
|
|
||||||
|
material = stack.findContainer(type="material")
|
||||||
|
quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material])[0]
|
||||||
|
|
||||||
|
result.append({"stack": stack, "quality": quality, "quality_changes": quality_changes})
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
def _replaceQualityOrQualityChangesInStack(self, stack, container, postpone_emit = False):
|
def _replaceQualityOrQualityChangesInStack(self, stack, container, postpone_emit = False):
|
||||||
# Disconnect the signal handling from the old container.
|
# Disconnect the signal handling from the old container.
|
||||||
old_container = stack.findContainer(type=container.getMetaDataEntry("type"))
|
old_container = stack.findContainer(type=container.getMetaDataEntry("type"))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user