mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-15 10:47:49 -06:00
Handle materials which don't have any quality profiles of their own. Moved the quality_type computation code into the QualityManager.
Contributes to CURA-2477 Profile menu should only contain valid options for all materials
This commit is contained in:
parent
f909ffca2e
commit
cd45ef496b
3 changed files with 94 additions and 65 deletions
|
@ -44,6 +44,29 @@ class QualityManager:
|
||||||
criteria = {"type": "quality_changes", "name": quality_changes_name}
|
criteria = {"type": "quality_changes", "name": quality_changes_name}
|
||||||
return self._getFilteredContainersForStack(machine_definition, [], **criteria)
|
return self._getFilteredContainersForStack(machine_definition, [], **criteria)
|
||||||
|
|
||||||
|
## Fetch the list of available quality types for this combination of machine definition and materials.
|
||||||
|
#
|
||||||
|
# \param machine_definition \type{DefinitionContainer}
|
||||||
|
# \param material_containers \type{List[InstanceContainer]}
|
||||||
|
# \return \type{List[str]}
|
||||||
|
def findAllQualityTypesForMachineAndMaterials(self, machine_definition, material_containers):
|
||||||
|
# Determine the common set of quality types which can be
|
||||||
|
# applied to all of the materials for this machine.
|
||||||
|
quality_type_dict = self.__fetchQualityTypeDictForMaterial(machine_definition, material_containers[0])
|
||||||
|
common_quality_types = set(quality_type_dict.keys())
|
||||||
|
for material_container in material_containers[1:]:
|
||||||
|
next_quality_type_dict = self.__fetchQualityTypeDictForMaterial(machine_definition, material_container)
|
||||||
|
common_quality_types.intersection_update(set(next_quality_type_dict.keys()))
|
||||||
|
|
||||||
|
return list(common_quality_types)
|
||||||
|
|
||||||
|
def __fetchQualityTypeDictForMaterial(self, machine_definition, material):
|
||||||
|
qualities = self.findAllQualitiesForMachineMaterial(machine_definition, material)
|
||||||
|
quality_type_dict = {}
|
||||||
|
for quality in qualities:
|
||||||
|
quality_type_dict[quality.getMetaDataEntry("quality_type")] = quality
|
||||||
|
return quality_type_dict
|
||||||
|
|
||||||
## Find a quality container by quality type.
|
## Find a quality container by quality type.
|
||||||
#
|
#
|
||||||
# \param quality_type \type{str} the name of the quality type to search for.
|
# \param quality_type \type{str} the name of the quality type to search for.
|
||||||
|
@ -51,12 +74,36 @@ class QualityManager:
|
||||||
# specified then the currently selected machine definition is used.
|
# specified then the currently selected machine definition is used.
|
||||||
# \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 containers \type{List[ContainerInstance]}
|
# \return the matching quality container \type{ContainerInstance}
|
||||||
def findQualityByQualityType(self, quality_type, machine_definition=None, material_containers=None):
|
def findQualityByQualityType(self, quality_type, machine_definition=None, material_containers=None):
|
||||||
criteria = {"type": "quality"}
|
criteria = {"type": "quality"}
|
||||||
if quality_type:
|
if quality_type:
|
||||||
criteria["quality_type"] = quality_type
|
criteria["quality_type"] = quality_type
|
||||||
return self._getFilteredContainersForStack(machine_definition, material_containers, **criteria)
|
result = self._getFilteredContainersForStack(machine_definition, material_containers, **criteria)
|
||||||
|
|
||||||
|
# Fall back to using generic materials and qualities if nothing could be found.
|
||||||
|
if not result and material_containers and len(material_containers) == 1:
|
||||||
|
basic_material = self._getBasicMaterial(material_containers[0])
|
||||||
|
result = self._getFilteredContainersForStack(machine_definition, [basic_material], **criteria)
|
||||||
|
return result[0] if result else None
|
||||||
|
|
||||||
|
def findAllQualitiesForMachineMaterial(self, machine_definition, material_container):
|
||||||
|
criteria = {"type": "quality" }
|
||||||
|
result = self._getFilteredContainersForStack(machine_definition, [material_container], **criteria)
|
||||||
|
if not result:
|
||||||
|
basic_material = self._getBasicMaterial(material_container)
|
||||||
|
result = self._getFilteredContainersForStack(machine_definition, [basic_material], **criteria)
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _getBasicMaterial(self, material_container):
|
||||||
|
base_material = material_container.getMetaDataEntry("material")
|
||||||
|
if base_material:
|
||||||
|
# There is a basic material specified
|
||||||
|
criteria = { "type": "material", "name": base_material, "definition": "fdmprinter" }
|
||||||
|
containers = UM.Settings.ContainerRegistry.getInstance().findInstanceContainers(**criteria)
|
||||||
|
return containers[0] if containers else None
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
def _getFilteredContainers(self, **kwargs):
|
def _getFilteredContainers(self, **kwargs):
|
||||||
return self._getFilteredContainersForStack(None, None, **kwargs)
|
return self._getFilteredContainersForStack(None, None, **kwargs)
|
||||||
|
|
|
@ -8,7 +8,6 @@ from UM.Application import Application
|
||||||
from UM.Preferences import Preferences
|
from UM.Preferences import Preferences
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.Message import Message
|
from UM.Message import Message
|
||||||
from UM.Settings.SettingRelation import RelationType
|
|
||||||
|
|
||||||
import UM.Settings
|
import UM.Settings
|
||||||
|
|
||||||
|
@ -562,26 +561,18 @@ class MachineManager(QObject):
|
||||||
# See if the requested quality type is available in the new situation.
|
# See if the requested quality type is available in the new situation.
|
||||||
machine_definition = self._active_container_stack.getBottom()
|
machine_definition = self._active_container_stack.getBottom()
|
||||||
quality_manager = QualityManager.getInstance()
|
quality_manager = QualityManager.getInstance()
|
||||||
candidate_qualities = quality_manager.findQualityByQualityType(quality_type,
|
candidate_quality = quality_manager.findQualityByQualityType(quality_type,
|
||||||
quality_manager.getWholeMachineDefinition(machine_definition),
|
quality_manager.getWholeMachineDefinition(machine_definition),
|
||||||
[material_container])
|
[material_container])
|
||||||
if not candidate_qualities:
|
if not candidate_quality:
|
||||||
# Fall back to normal quality
|
# Fall back to a quality
|
||||||
quality_containers = quality_manager.findQualityByQualityType("normal",
|
new_quality_id = quality_manager.findQualityByQualityType(None,
|
||||||
quality_manager.getWholeMachineDefinition(machine_definition),
|
quality_manager.getWholeMachineDefinition(machine_definition),
|
||||||
[material_container])
|
[material_container])
|
||||||
if quality_containers:
|
|
||||||
new_quality_id = quality_containers[0].getId()
|
|
||||||
else:
|
|
||||||
# There is no normal quality for this machine/variant/material combination
|
|
||||||
quality_containers = quality_manager.findQualityByQualityType(None,
|
|
||||||
quality_manager.getWholeMachineDefinition(machine_definition),
|
|
||||||
[material_container])
|
|
||||||
new_quality_id = quality_containers[0].getId()
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if not old_quality_changes:
|
if not old_quality_changes:
|
||||||
new_quality_id = candidate_qualities[0].getId()
|
new_quality_id = candidate_quality.getId()
|
||||||
|
|
||||||
self.setActiveQuality(new_quality_id)
|
self.setActiveQuality(new_quality_id)
|
||||||
|
|
||||||
|
@ -622,10 +613,11 @@ class MachineManager(QObject):
|
||||||
# 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()
|
quality_name = containers[0].getName()
|
||||||
|
quality_type = containers[0].getMetaDataEntry("quality_type")
|
||||||
|
|
||||||
# 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":
|
||||||
new_quality_settings_list = self._determineQualityAndQualityChangesForQuality(quality_name)
|
new_quality_settings_list = self._determineQualityAndQualityChangesForQualityType(quality_type)
|
||||||
elif container_type == "quality_changes":
|
elif container_type == "quality_changes":
|
||||||
new_quality_settings_list = self._determineQualityAndQualityChangesForQualityChanges(quality_name)
|
new_quality_settings_list = self._determineQualityAndQualityChangesForQualityChanges(quality_name)
|
||||||
else:
|
else:
|
||||||
|
@ -661,26 +653,28 @@ class MachineManager(QObject):
|
||||||
#
|
#
|
||||||
# \param quality_name \type{str} the name of the quality.
|
# \param quality_name \type{str} the name of the quality.
|
||||||
# \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes".
|
# \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes".
|
||||||
def _determineQualityAndQualityChangesForQuality(self, quality_name):
|
def _determineQualityAndQualityChangesForQualityType(self, quality_type):
|
||||||
|
quality_manager = QualityManager.getInstance()
|
||||||
result = []
|
result = []
|
||||||
empty_quality_changes = self._empty_quality_changes_container
|
empty_quality_changes = self._empty_quality_changes_container
|
||||||
|
|
||||||
# Find the values for the global stack.
|
|
||||||
global_container_stack = self._global_container_stack
|
global_container_stack = self._global_container_stack
|
||||||
global_machine_definition = QualityManager.getInstance().getParentMachineDefinition(global_container_stack.getBottom())
|
global_machine_definition = quality_manager.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.
|
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
for stack in ExtruderManager.getInstance().getActiveExtruderStacks():
|
if extruder_stacks:
|
||||||
material = stack.findContainer(type="material")
|
stacks = extruder_stacks
|
||||||
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:
|
else:
|
||||||
result.append({"stack": stack, "quality": stack_qualities[0], "quality_changes": empty_quality_changes})
|
stacks = [global_container_stack]
|
||||||
|
|
||||||
|
for stack in stacks:
|
||||||
|
material = stack.findContainer(type="material")
|
||||||
|
quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material])
|
||||||
|
result.append({"stack": stack, "quality": quality, "quality_changes": empty_quality_changes})
|
||||||
|
|
||||||
|
if extruder_stacks:
|
||||||
|
# Add an extra entry for the global stack.
|
||||||
|
result.append({"stack": global_container_stack, "quality": result[0]["quality"],
|
||||||
|
"quality_changes": empty_quality_changes})
|
||||||
return result
|
return result
|
||||||
|
|
||||||
## Determine the quality and quality changes settings for the current machine for a quality changes name.
|
## Determine the quality and quality changes settings for the current machine for a quality changes name.
|
||||||
|
@ -699,12 +693,11 @@ class MachineManager(QObject):
|
||||||
# For the global stack, find a quality which matches the quality_type in
|
# For the global stack, find a quality which matches the quality_type in
|
||||||
# the quality changes profile and also satisfies any material constraints.
|
# the quality changes profile and also satisfies any material constraints.
|
||||||
quality_type = global_quality_changes.getMetaDataEntry("quality_type")
|
quality_type = global_quality_changes.getMetaDataEntry("quality_type")
|
||||||
global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material])[0]
|
global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material])
|
||||||
|
|
||||||
result.append({"stack": global_container_stack, "quality": global_quality, "quality_changes": global_quality_changes})
|
|
||||||
|
|
||||||
# Find the values for each extruder.
|
# Find the values for each extruder.
|
||||||
for stack in ExtruderManager.getInstance().getActiveExtruderStacks():
|
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
|
for stack in extruder_stacks:
|
||||||
machine_definition = quality_manager.getParentMachineDefinition(stack.getBottom())
|
machine_definition = quality_manager.getParentMachineDefinition(stack.getBottom())
|
||||||
quality_changes_profiles = quality_manager.findQualityChangesByName(quality_changes_name, machine_definition)
|
quality_changes_profiles = quality_manager.findQualityChangesByName(quality_changes_name, machine_definition)
|
||||||
if quality_changes_profiles:
|
if quality_changes_profiles:
|
||||||
|
@ -713,10 +706,17 @@ class MachineManager(QObject):
|
||||||
quality_changes = global_quality_changes
|
quality_changes = global_quality_changes
|
||||||
|
|
||||||
material = stack.findContainer(type="material")
|
material = stack.findContainer(type="material")
|
||||||
quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material])[0]
|
quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material])
|
||||||
|
|
||||||
result.append({"stack": stack, "quality": quality, "quality_changes": quality_changes})
|
result.append({"stack": stack, "quality": quality, "quality_changes": quality_changes})
|
||||||
|
|
||||||
|
if extruder_stacks:
|
||||||
|
# Duplicate the quality from the 1st extruder into the global stack. If anyone
|
||||||
|
# then looks in the global stack, they should get a reasonable view.
|
||||||
|
result.append({"stack": global_container_stack, "quality": result[0]["quality"], "quality_changes": global_quality_changes})
|
||||||
|
else:
|
||||||
|
result.append({"stack": global_container_stack, "quality": global_quality, "quality_changes": global_quality_changes})
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _replaceQualityOrQualityChangesInStack(self, stack, container, postpone_emit = False):
|
def _replaceQualityOrQualityChangesInStack(self, stack, container, postpone_emit = False):
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel
|
from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel
|
||||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
|
||||||
|
|
||||||
|
from cura.QualityManager import QualityManager
|
||||||
from cura.Settings.ExtruderManager import ExtruderManager
|
from cura.Settings.ExtruderManager import ExtruderManager
|
||||||
|
|
||||||
## QML Model for listing the current list of valid quality profiles.
|
## QML Model for listing the current list of valid quality profiles.
|
||||||
|
@ -28,36 +28,18 @@ class ProfilesModel(InstanceContainersModel):
|
||||||
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
|
||||||
if extruder_stacks:
|
if extruder_stacks:
|
||||||
# Multi-extruder machine detected.
|
# Multi-extruder machine detected.
|
||||||
|
materials = [stack.findContainer(type="material") for stack in extruder_stacks]
|
||||||
# Determine the common set of quality types which can be
|
|
||||||
# applied to all of the materials for this machine.
|
|
||||||
quality_type_dict = self.__fetchQualityTypeDictForStack(extruder_stacks[0], global_machine_definition)
|
|
||||||
common_quality_types = set(quality_type_dict.keys())
|
|
||||||
for stack in extruder_stacks[1:]:
|
|
||||||
next_quality_type_dict = self.__fetchQualityTypeDictForStack(stack, global_machine_definition)
|
|
||||||
common_quality_types.intersection_update(set(next_quality_type_dict.keys()))
|
|
||||||
|
|
||||||
return [quality_type_dict[quality_type] for quality_type in common_quality_types]
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Machine with one extruder.
|
# Machine with one extruder.
|
||||||
quality_type_dict = self.__fetchQualityTypeDictForStack(global_container_stack, global_machine_definition)
|
materials = [global_container_stack.findContainer(type="material")]
|
||||||
return list(quality_type_dict.values())
|
|
||||||
return []
|
|
||||||
|
|
||||||
def __fetchQualityTypeDictForStack(self, stack, global_machine_definition):
|
|
||||||
criteria = {"type": "quality" }
|
|
||||||
if global_machine_definition.getMetaDataEntry("has_machine_quality", False):
|
|
||||||
criteria["definition"] = global_machine_definition.getId()
|
|
||||||
if global_machine_definition.getMetaDataEntry("has_materials", False):
|
|
||||||
material = stack.findContainer(type="material")
|
|
||||||
criteria["material"] = material.getId()
|
|
||||||
else:
|
|
||||||
criteria["definition"] = "fdmprinter"
|
|
||||||
|
|
||||||
qualities = ContainerRegistry.getInstance().findInstanceContainers(**criteria)
|
|
||||||
|
|
||||||
|
quality_types = QualityManager.getInstance().findAllQualityTypesForMachineAndMaterials(global_machine_definition,
|
||||||
|
materials)
|
||||||
|
# Map the list of quality_types to InstanceContainers
|
||||||
|
qualities = QualityManager.getInstance().findAllQualitiesForMachineMaterial(global_machine_definition,
|
||||||
|
materials[0])
|
||||||
quality_type_dict = {}
|
quality_type_dict = {}
|
||||||
for quality in qualities:
|
for quality in qualities:
|
||||||
quality_type_dict[quality.getMetaDataEntry("quality_type")] = quality
|
quality_type_dict[quality.getMetaDataEntry("quality_type")] = quality
|
||||||
return quality_type_dict
|
|
||||||
|
return [quality_type_dict[quality_type] for quality_type in quality_types]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue