mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-08 06:23:59 -06:00
Merge branch 'feature_intent_container_tree' of github.com:Ultimaker/Cura into feature_intent_interface
This commit is contained in:
commit
b00b8c8c58
27 changed files with 603 additions and 239 deletions
|
@ -83,6 +83,9 @@ class ContainerManager(QObject):
|
|||
# Update: In order for QML to use objects and sub objects, those (sub) objects must all be QObject. Is that what we want?
|
||||
@pyqtSlot("QVariant", str, str)
|
||||
def setContainerMetaDataEntry(self, container_node: "ContainerNode", entry_name: str, entry_value: str) -> bool:
|
||||
if container_node.container is None:
|
||||
Logger.log("w", "Container node {0} doesn't have a container.".format(container_node.container_id))
|
||||
return False
|
||||
root_material_id = container_node.container.getMetaDataEntry("base_file", "")
|
||||
if cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry().isReadOnly(root_material_id):
|
||||
Logger.log("w", "Cannot set metadata of read-only container %s.", root_material_id)
|
||||
|
@ -341,6 +344,9 @@ class ContainerManager(QObject):
|
|||
@pyqtSlot("QVariant")
|
||||
def unlinkMaterial(self, material_node: "MaterialNode") -> None:
|
||||
# Get the material group
|
||||
if material_node.container is None:
|
||||
Logger.log("w", "Material node {0} doesn't have a container.".format(material_node.container_id))
|
||||
return
|
||||
material_group = MaterialManager.getInstance().getMaterialGroup(material_node.container.getMetaDataEntry("base_file", ""))
|
||||
|
||||
if material_group is None:
|
||||
|
|
|
@ -28,7 +28,7 @@ from . import GlobalStack
|
|||
|
||||
import cura.CuraApplication
|
||||
from cura.Settings.cura_empty_instance_containers import empty_quality_container
|
||||
from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
|
||||
from cura.Machines.ContainerTree import ContainerTree
|
||||
from cura.ReaderWriters.ProfileReader import NoProfileException, ProfileReader
|
||||
|
||||
from UM.i18n import i18nCatalog
|
||||
|
@ -177,6 +177,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if not global_stack:
|
||||
return {"status": "error", "message": catalog.i18nc("@info:status Don't translate the XML tags <filename>!", "Can't import profile from <filename>{0}</filename> before a printer is added.", file_name)}
|
||||
container_tree = ContainerTree.getInstance()
|
||||
|
||||
machine_extruders = []
|
||||
for position in sorted(global_stack.extruders):
|
||||
|
@ -226,7 +227,7 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
# Make sure we have a profile_definition in the file:
|
||||
if profile_definition is None:
|
||||
break
|
||||
machine_definitions = self.findDefinitionContainers(id = profile_definition)
|
||||
machine_definitions = self.findContainers(id = profile_definition)
|
||||
if not machine_definitions:
|
||||
Logger.log("e", "Incorrect profile [%s]. Unknown machine type [%s]", file_name, profile_definition)
|
||||
return {"status": "error",
|
||||
|
@ -236,8 +237,8 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
|
||||
# Get the expected machine definition.
|
||||
# i.e.: We expect gcode for a UM2 Extended to be defined as normal UM2 gcode...
|
||||
profile_definition = getMachineDefinitionIDForQualitySearch(machine_definition)
|
||||
expected_machine_definition = getMachineDefinitionIDForQualitySearch(global_stack.definition)
|
||||
profile_definition = container_tree.machines[machine_definition.getId()].quality_definition
|
||||
expected_machine_definition = container_tree.machines[global_stack.definition.getId()].quality_definition
|
||||
|
||||
# And check if the profile_definition matches either one (showing error if not):
|
||||
if profile_definition != expected_machine_definition:
|
||||
|
@ -380,14 +381,13 @@ class CuraContainerRegistry(ContainerRegistry):
|
|||
global_stack = Application.getInstance().getGlobalContainerStack()
|
||||
if global_stack is None:
|
||||
return None
|
||||
definition_id = getMachineDefinitionIDForQualitySearch(global_stack.definition)
|
||||
definition_id = ContainerTree.getInstance().machines[global_stack.definition.getId()].quality_definition
|
||||
profile.setDefinition(definition_id)
|
||||
|
||||
# Check to make sure the imported profile actually makes sense in context of the current configuration.
|
||||
# This prevents issues where importing a "draft" profile for a machine without "draft" qualities would report as
|
||||
# successfully imported but then fail to show up.
|
||||
quality_manager = cura.CuraApplication.CuraApplication.getInstance()._quality_manager
|
||||
quality_group_dict = quality_manager.getQualityGroupsForMachineDefinition(global_stack)
|
||||
quality_group_dict = ContainerTree.getInstance().getCurrentQualityGroups()
|
||||
# "not_supported" profiles can be imported.
|
||||
if quality_type != empty_quality_container.getMetaDataEntry("quality_type") and quality_type not in quality_group_dict:
|
||||
return catalog.i18nc("@info:status", "Could not find a quality type {0} for the current configuration.", quality_type)
|
||||
|
|
|
@ -24,8 +24,8 @@ from UM.Signal import postponeSignals, CompressTechnique
|
|||
|
||||
import cura.CuraApplication # Imported like this to prevent circular references.
|
||||
|
||||
from cura.Machines.ContainerNode import ContainerNode
|
||||
from cura.Machines.ContainerTree import ContainerTree
|
||||
from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch, QualityManager
|
||||
from cura.Machines.MaterialManager import MaterialManager
|
||||
|
||||
from cura.PrinterOutput.PrinterOutputDevice import PrinterOutputDevice, ConnectionType
|
||||
|
@ -37,7 +37,7 @@ from cura.Settings.ExtruderManager import ExtruderManager
|
|||
from cura.Settings.ExtruderStack import ExtruderStack
|
||||
from cura.Settings.cura_empty_instance_containers import (empty_definition_changes_container, empty_variant_container,
|
||||
empty_material_container, empty_quality_container,
|
||||
empty_quality_changes_container)
|
||||
empty_quality_changes_container, empty_intent_container)
|
||||
|
||||
from .CuraStackBuilder import CuraStackBuilder
|
||||
|
||||
|
@ -600,6 +600,8 @@ class MachineManager(QObject):
|
|||
global_container_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||
if not global_container_stack:
|
||||
return False
|
||||
if not self.activeQualityGroup:
|
||||
return False
|
||||
return self.activeQualityGroup.is_available
|
||||
|
||||
@pyqtProperty(bool, notify = activeQualityGroupChanged)
|
||||
|
@ -703,9 +705,10 @@ class MachineManager(QObject):
|
|||
# \returns DefinitionID (string) if found, empty string otherwise
|
||||
@pyqtProperty(str, notify = globalContainerChanged)
|
||||
def activeQualityDefinitionId(self) -> str:
|
||||
if self._global_container_stack:
|
||||
return getMachineDefinitionIDForQualitySearch(self._global_container_stack.definition)
|
||||
return ""
|
||||
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||
if not global_stack:
|
||||
return ""
|
||||
return ContainerTree.getInstance().machines[global_stack.definition.getId()].quality_definition
|
||||
|
||||
## Gets how the active definition calls variants
|
||||
# Caveat: per-definition-variant-title is currently not translated (though the fallback is)
|
||||
|
@ -1128,12 +1131,11 @@ class MachineManager(QObject):
|
|||
self.activeQualityChangesGroupChanged.emit()
|
||||
|
||||
def _fixQualityChangesGroupToNotSupported(self, quality_changes_group: "QualityChangesGroup") -> None:
|
||||
nodes = [quality_changes_group.node_for_global] + list(quality_changes_group.nodes_for_extruders.values())
|
||||
containers = [n.container for n in nodes if n is not None]
|
||||
for container in containers:
|
||||
if container:
|
||||
container.setMetaDataEntry("quality_type", "not_supported")
|
||||
metadatas = [quality_changes_group.metadata_for_global] + list(quality_changes_group.metadata_per_extruder.values())
|
||||
for metadata in metadatas:
|
||||
metadata["quality_type"] = "not_supported" # This actually changes the metadata of the container since they are stored by reference!
|
||||
quality_changes_group.quality_type = "not_supported"
|
||||
quality_changes_group.intent_category = "default"
|
||||
|
||||
def _setQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup") -> None:
|
||||
if self._global_container_stack is None:
|
||||
|
@ -1142,16 +1144,22 @@ class MachineManager(QObject):
|
|||
# A custom quality can be created based on "not supported".
|
||||
# In that case, do not set quality containers to empty.
|
||||
quality_group = None
|
||||
if quality_type != "not_supported":
|
||||
quality_group_dict = QualityManager.getInstance().getQualityGroups(self._global_container_stack)
|
||||
quality_group = quality_group_dict.get(quality_type)
|
||||
if quality_type != "not_supported": # Find the quality group that the quality changes was based on.
|
||||
quality_group = ContainerTree.getInstance().getCurrentQualityGroups().get(quality_type)
|
||||
if quality_group is None:
|
||||
self._fixQualityChangesGroupToNotSupported(quality_changes_group)
|
||||
|
||||
container_registry = cura.CuraApplication.CuraApplication.getInstance().getContainerRegistry()
|
||||
quality_changes_container = empty_quality_changes_container
|
||||
quality_container = empty_quality_container # type: Optional[InstanceContainer]
|
||||
if quality_changes_group.node_for_global and quality_changes_group.node_for_global.container:
|
||||
quality_changes_container = cast(InstanceContainer, quality_changes_group.node_for_global.container)
|
||||
if quality_changes_group.metadata_for_global:
|
||||
global_containers = container_registry.findContainers(id = quality_changes_group.metadata_for_global["id"])
|
||||
if global_containers:
|
||||
quality_changes_container = global_containers[0]
|
||||
if quality_changes_group.metadata_for_global:
|
||||
containers = container_registry.findContainers(id = quality_changes_group.metadata_for_global["id"])
|
||||
if containers:
|
||||
quality_changes_container = cast(InstanceContainer, containers[0])
|
||||
if quality_group is not None and quality_group.node_for_global and quality_group.node_for_global.container:
|
||||
quality_container = quality_group.node_for_global.container
|
||||
|
||||
|
@ -1159,21 +1167,25 @@ class MachineManager(QObject):
|
|||
self._global_container_stack.qualityChanges = quality_changes_container
|
||||
|
||||
for position, extruder in self._global_container_stack.extruders.items():
|
||||
quality_changes_node = quality_changes_group.nodes_for_extruders.get(position)
|
||||
quality_node = None
|
||||
if quality_group is not None:
|
||||
quality_node = quality_group.nodes_for_extruders.get(position)
|
||||
|
||||
quality_changes_container = empty_quality_changes_container
|
||||
quality_container = empty_quality_container
|
||||
if quality_changes_node and quality_changes_node.container:
|
||||
quality_changes_container = cast(InstanceContainer, quality_changes_node.container)
|
||||
quality_changes_metadata = quality_changes_group.metadata_per_extruder.get(position)
|
||||
if quality_changes_metadata:
|
||||
containers = container_registry.findContainers(id = quality_changes_metadata["id"])
|
||||
if containers:
|
||||
quality_changes_container = cast(InstanceContainer, containers[0])
|
||||
if quality_node and quality_node.container:
|
||||
quality_container = quality_node.container
|
||||
|
||||
extruder.quality = quality_container
|
||||
extruder.qualityChanges = quality_changes_container
|
||||
|
||||
self.setIntentByCategory(quality_changes_group.intent_category)
|
||||
|
||||
self.activeQualityGroupChanged.emit()
|
||||
self.activeQualityChangesGroupChanged.emit()
|
||||
|
||||
|
@ -1193,7 +1205,7 @@ class MachineManager(QObject):
|
|||
def _setMaterial(self, position: str, material_node: Optional["MaterialNode"] = None) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
if material_node:
|
||||
if material_node and material_node.container:
|
||||
material_container = material_node.container
|
||||
self._global_container_stack.extruders[position].material = material_container
|
||||
root_material_id = material_container.getMetaDataEntry("base_file", None)
|
||||
|
@ -1247,6 +1259,9 @@ class MachineManager(QObject):
|
|||
# The current quality type is not available so we use the preferred quality type if it's available,
|
||||
# otherwise use one of the available quality types.
|
||||
quality_type = sorted(list(available_quality_types))[0]
|
||||
if self._global_container_stack is None:
|
||||
Logger.log("e", "Global stack not present!")
|
||||
return
|
||||
preferred_quality_type = self._global_container_stack.getMetaDataEntry("preferred_quality_type")
|
||||
if preferred_quality_type in available_quality_types:
|
||||
quality_type = preferred_quality_type
|
||||
|
@ -1470,9 +1485,7 @@ class MachineManager(QObject):
|
|||
if self._global_container_stack is None:
|
||||
return
|
||||
# Get all the quality groups for this global stack and filter out by quality_type
|
||||
quality_group_dict = self._application.getQualityManager().getQualityGroups(self._global_container_stack)
|
||||
quality_group = quality_group_dict[quality_type]
|
||||
self.setQualityGroup(quality_group)
|
||||
self.setQualityGroup(ContainerTree.getInstance().getCurrentQualityGroups()[quality_type])
|
||||
|
||||
## Optionally provide global_stack if you want to use your own
|
||||
# The active global_stack is treated differently.
|
||||
|
@ -1503,6 +1516,32 @@ class MachineManager(QObject):
|
|||
if not no_dialog and self.hasUserSettings and self._application.getPreferences().getValue("cura/active_mode") == 1:
|
||||
self._application.discardOrKeepProfileChanges()
|
||||
|
||||
## Change the intent category of the current printer.
|
||||
#
|
||||
# All extruders can change their profiles. If an intent profile is
|
||||
# available with the desired intent category, that one will get chosen.
|
||||
# Otherwise the intent profile will be left to the empty profile, which
|
||||
# represents the "default" intent category.
|
||||
# \param intent_category The intent category to change to.
|
||||
def setIntentByCategory(self, intent_category: str) -> None:
|
||||
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||
if global_stack is None:
|
||||
return
|
||||
container_tree = ContainerTree.getInstance()
|
||||
for extruder in global_stack.extruderList:
|
||||
definition_id = global_stack.definition.getId()
|
||||
variant_name = extruder.variant.getName()
|
||||
material_base_file = extruder.material.getMetaDataEntry("base_file")
|
||||
quality_id = extruder.quality.getId()
|
||||
quality_node = container_tree.machines[definition_id].variants[variant_name].materials[material_base_file].qualities[quality_id]
|
||||
|
||||
for intent_node in quality_node.intents.values():
|
||||
if intent_node.intent_category == intent_category: # Found an intent with the correct category.
|
||||
extruder.intent = intent_node.container
|
||||
break
|
||||
else: # No intent had the correct category.
|
||||
extruder.intent = empty_intent_container
|
||||
|
||||
@pyqtProperty(QObject, fset = setQualityGroup, notify = activeQualityGroupChanged)
|
||||
def activeQualityGroup(self) -> Optional["QualityGroup"]:
|
||||
global_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||
|
@ -1557,7 +1596,7 @@ class MachineManager(QObject):
|
|||
@pyqtProperty(bool, notify = activeQualityGroupChanged)
|
||||
def hasNotSupportedQuality(self) -> bool:
|
||||
global_container_stack = cura.CuraApplication.CuraApplication.getInstance().getGlobalContainerStack()
|
||||
return global_container_stack and global_container_stack.quality == empty_quality_container and global_container_stack.qualityChanges == empty_quality_changes_container
|
||||
return (not global_container_stack is None) and global_container_stack.quality == empty_quality_container and global_container_stack.qualityChanges == empty_quality_changes_container
|
||||
|
||||
def _updateUponMaterialMetadataChange(self) -> None:
|
||||
if self._global_container_stack is None:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue