mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-15 02:37:49 -06:00
Move code to set default variant/material/quality to CuraContainerStack
This allows us to eventually make sure everything uses the same code.
This commit is contained in:
parent
8682eb1486
commit
0a0353da82
2 changed files with 262 additions and 200 deletions
|
@ -1,12 +1,14 @@
|
||||||
# Copyright (c) 2017 Ultimaker B.V.
|
# Copyright (c) 2017 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the AGPLv3 or higher.
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
from typing import Any
|
import os.path
|
||||||
|
|
||||||
|
from typing import Any, Optional
|
||||||
|
|
||||||
from PyQt5.QtCore import pyqtProperty, pyqtSlot, pyqtSignal
|
from PyQt5.QtCore import pyqtProperty, pyqtSlot, pyqtSignal
|
||||||
|
|
||||||
from UM.Decorators import override
|
from UM.Decorators import override
|
||||||
|
from UM.Logger import Logger
|
||||||
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
|
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
|
||||||
from UM.Settings.ContainerStack import ContainerStack, InvalidContainerStackError
|
from UM.Settings.ContainerStack import ContainerStack, InvalidContainerStackError
|
||||||
from UM.Settings.InstanceContainer import InstanceContainer
|
from UM.Settings.InstanceContainer import InstanceContainer
|
||||||
|
@ -95,15 +97,28 @@ class CuraContainerStack(ContainerStack):
|
||||||
|
|
||||||
## Set the quality container by an ID.
|
## Set the quality container by an ID.
|
||||||
#
|
#
|
||||||
|
# This will search for the specified container and set it. If no container was found, an error will be raised.
|
||||||
|
# There is a special value for ID, which is "default". The "default" value indicates the quality should be set
|
||||||
|
# to whatever the machine definition specifies as "preferred" container, or a fallback value. See findDefaultQuality
|
||||||
|
# for details.
|
||||||
|
#
|
||||||
# \param new_quality_id The ID of the new quality container.
|
# \param new_quality_id The ID of the new quality container.
|
||||||
#
|
#
|
||||||
# \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
|
# \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
|
||||||
def setQualityById(self, new_quality_id: str) -> None:
|
def setQualityById(self, new_quality_id: str) -> None:
|
||||||
quality = ContainerRegistry.getInstance().findInstanceContainers(id = new_quality_id)
|
quality = self._empty_instance_container
|
||||||
if quality:
|
if new_quality_id == "default":
|
||||||
self.setQuality(quality[0])
|
new_quality = self.findDefaultQuality()
|
||||||
|
if new_quality:
|
||||||
|
quality = new_quality
|
||||||
else:
|
else:
|
||||||
raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_quality_id))
|
qualities = ContainerRegistry.getInstance().findInstanceContainers(id = new_quality_id)
|
||||||
|
if qualities:
|
||||||
|
quality = qualities[0]
|
||||||
|
else:
|
||||||
|
raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_quality_id))
|
||||||
|
|
||||||
|
self.setQuality(quality)
|
||||||
|
|
||||||
## Get the quality container.
|
## Get the quality container.
|
||||||
#
|
#
|
||||||
|
@ -120,15 +135,28 @@ class CuraContainerStack(ContainerStack):
|
||||||
|
|
||||||
## Set the material container by an ID.
|
## Set the material container by an ID.
|
||||||
#
|
#
|
||||||
|
# This will search for the specified container and set it. If no container was found, an error will be raised.
|
||||||
|
# There is a special value for ID, which is "default". The "default" value indicates the quality should be set
|
||||||
|
# to whatever the machine definition specifies as "preferred" container, or a fallback value. See findDefaultMaterial
|
||||||
|
# for details.
|
||||||
|
#
|
||||||
# \param new_quality_changes_id The ID of the new material container.
|
# \param new_quality_changes_id The ID of the new material container.
|
||||||
#
|
#
|
||||||
# \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
|
# \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
|
||||||
def setMaterialById(self, new_material_id: str) -> None:
|
def setMaterialById(self, new_material_id: str) -> None:
|
||||||
material = ContainerRegistry.getInstance().findInstanceContainers(id = new_material_id)
|
material = self._empty_instance_container
|
||||||
if material:
|
if new_material_id == "default":
|
||||||
self.setMaterial(material[0])
|
new_material = self.findDefaultMaterial()
|
||||||
|
if new_material:
|
||||||
|
material = new_material
|
||||||
else:
|
else:
|
||||||
raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_material_id))
|
materials = ContainerRegistry.getInstance().findInstanceContainers(id = new_material_id)
|
||||||
|
if materials:
|
||||||
|
material = materials[0]
|
||||||
|
else:
|
||||||
|
raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_material_id))
|
||||||
|
|
||||||
|
self.setMaterial(material)
|
||||||
|
|
||||||
## Get the material container.
|
## Get the material container.
|
||||||
#
|
#
|
||||||
|
@ -145,16 +173,28 @@ class CuraContainerStack(ContainerStack):
|
||||||
|
|
||||||
## Set the variant container by an ID.
|
## Set the variant container by an ID.
|
||||||
#
|
#
|
||||||
|
# This will search for the specified container and set it. If no container was found, an error will be raised.
|
||||||
|
# There is a special value for ID, which is "default". The "default" value indicates the quality should be set
|
||||||
|
# to whatever the machine definition specifies as "preferred" container, or a fallback value. See findDefaultVariant
|
||||||
|
# for details.
|
||||||
|
#
|
||||||
# \param new_quality_changes_id The ID of the new variant container.
|
# \param new_quality_changes_id The ID of the new variant container.
|
||||||
#
|
#
|
||||||
# \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
|
# \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
|
||||||
def setVariantById(self, new_variant_id: str) -> None:
|
def setVariantById(self, new_variant_id: str) -> None:
|
||||||
variant = ContainerRegistry.getInstance().findInstanceContainers(id = new_variant_id)
|
variant = self._empty_instance_container
|
||||||
if variant:
|
if new_variant_id == "default":
|
||||||
self.setVariant(variant[0])
|
new_variant = self.findDefaultVariant()
|
||||||
|
if new_variant:
|
||||||
|
variant = new_variant
|
||||||
else:
|
else:
|
||||||
raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_variant_id))
|
variants = ContainerRegistry.getInstance().findInstanceContainers(id = new_variant_id)
|
||||||
|
if variants:
|
||||||
|
variant = variants[0]
|
||||||
|
else:
|
||||||
|
raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_variant_id))
|
||||||
|
|
||||||
|
self.setVariant(variant)
|
||||||
|
|
||||||
## Get the variant container.
|
## Get the variant container.
|
||||||
#
|
#
|
||||||
|
@ -328,9 +368,216 @@ class CuraContainerStack(ContainerStack):
|
||||||
|
|
||||||
self._containers = new_containers
|
self._containers = new_containers
|
||||||
|
|
||||||
def _onContainersChanged(self, container):
|
## Find the variant that should be used as "default" variant.
|
||||||
|
#
|
||||||
|
# This will search for variants that match the current definition and pick the preferred one,
|
||||||
|
# if specified by the machine definition.
|
||||||
|
#
|
||||||
|
# The following criteria are used to find the default variant:
|
||||||
|
# - If the machine definition does not have a metadata entry "has_variants" set to True, return None
|
||||||
|
# - The definition of the variant should be the same as the machine definition for this stack.
|
||||||
|
# - The container should have a metadata entry "type" with value "variant".
|
||||||
|
# - If the machine definition has a metadata entry "preferred_variant", filter the variant IDs based on that.
|
||||||
|
#
|
||||||
|
# \return The container that should be used as default, or None if nothing was found or the machine does not use variants.
|
||||||
|
#
|
||||||
|
# \note This method assumes the stack has a valid machine definition.
|
||||||
|
def findDefaultVariant(self) -> Optional[ContainerInterface]:
|
||||||
|
definition = self._getMachineDefinition()
|
||||||
|
if not definition.getMetaDataEntry("has_variants"):
|
||||||
|
# If the machine does not use variants, we should never set a variant.
|
||||||
|
return None
|
||||||
|
|
||||||
|
# First add any variant. Later, overwrite with preference if the preference is valid.
|
||||||
|
variant = None
|
||||||
|
definition_id = self._findInstanceContainerDefinitionId(definition)
|
||||||
|
variants = ContainerRegistry.getInstance().findInstanceContainers(definition = definition_id, type = "variant")
|
||||||
|
if variants:
|
||||||
|
variant = variants[0]
|
||||||
|
|
||||||
|
preferred_variant_id = definition.getMetaDataEntry("preferred_variant")
|
||||||
|
if preferred_variant_id:
|
||||||
|
preferred_variants = ContainerRegistry.getInstance().findInstanceContainers(id = preferred_variant_id, definition = definition_id, type = "variant")
|
||||||
|
if preferred_variants:
|
||||||
|
variant = preferred_variants[0]
|
||||||
|
else:
|
||||||
|
Logger.log("w", "The preferred variant \"{variant}\" of stack {stack} does not exist or is not a variant.", variant = preferred_variant_id, stack = self.id)
|
||||||
|
# And leave it at the default variant.
|
||||||
|
|
||||||
|
if variant:
|
||||||
|
return variant
|
||||||
|
|
||||||
|
Logger.log("w", "Could not find a valid default variant for stack {stack}", stack = self.id)
|
||||||
|
return None
|
||||||
|
|
||||||
|
## Find the material that should be used as "default" material.
|
||||||
|
#
|
||||||
|
# This will search for materials that match the current definition and pick the preferred one,
|
||||||
|
# if specified by the machine definition.
|
||||||
|
#
|
||||||
|
# The following criteria are used to find the default material:
|
||||||
|
# - If the machine definition does not have a metadata entry "has_materials" set to True, return None
|
||||||
|
# - If the machine definition has a metadata entry "has_machine_materials", the definition of the material should
|
||||||
|
# be the same as the machine definition for this stack. Otherwise, the definition should be "fdmprinter".
|
||||||
|
# - The container should have a metadata entry "type" with value "material".
|
||||||
|
# - If the machine definition has a metadata entry "has_variants" and set to True, the "variant" metadata entry of
|
||||||
|
# the material should be the same as the ID of the variant in the stack. Only applies if "has_machine_materials" is also True.
|
||||||
|
# - If the stack currently has a material set, try to find a material that matches the current material by name.
|
||||||
|
# - Otherwise, if the machine definition has a metadata entry "preferred_material", try to find a material that matches the specified ID.
|
||||||
|
#
|
||||||
|
# \return The container that should be used as default, or None if nothing was found or the machine does not use materials.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
def findDefaultMaterial(self) -> Optional[ContainerInterface]:
|
||||||
|
definition = self._getMachineDefinition()
|
||||||
|
if not definition.getMetaDataEntry("has_materials"):
|
||||||
|
# Machine does not use materials, never try to set it.
|
||||||
|
return None
|
||||||
|
|
||||||
|
material = None
|
||||||
|
search_criteria = {"type": "material"}
|
||||||
|
if definition.getMetaDataEntry("has_machine_materials"):
|
||||||
|
search_criteria["definition"] = self._findInstanceContainerDefinitionId(definition)
|
||||||
|
|
||||||
|
if definition.getMetaDataEntry("has_variants"):
|
||||||
|
search_criteria["variant"] = self.variant.id
|
||||||
|
else:
|
||||||
|
search_criteria["definition"] = "fdmprinter"
|
||||||
|
|
||||||
|
if self.material != self._empty_instance_container:
|
||||||
|
search_criteria["name"] = self.material.name
|
||||||
|
else:
|
||||||
|
preferred_material = definition.getMetaDataEntry("preferred_material")
|
||||||
|
if preferred_material:
|
||||||
|
search_criteria["id"] = preferred_material
|
||||||
|
|
||||||
|
materials = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
|
||||||
|
if not materials:
|
||||||
|
Logger.log("w", "The preferred material \"{material}\" could not be found for stack {stack}", material = preferred_material, stack = self.id)
|
||||||
|
# We failed to find any materials matching the specified criteria, drop some specific criteria and try to find
|
||||||
|
# a material that sort-of matches what we want.
|
||||||
|
search_criteria.pop("variant", None)
|
||||||
|
search_criteria.pop("id", None)
|
||||||
|
search_criteria.pop("name", None)
|
||||||
|
materials = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
|
||||||
|
|
||||||
|
if materials:
|
||||||
|
return materials[0]
|
||||||
|
|
||||||
|
Logger.log("w", "Could not find a valid material for stack {stack}", stack = self.id)
|
||||||
|
return None
|
||||||
|
|
||||||
|
def findDefaultQuality(self) -> Optional[ContainerInterface]:
|
||||||
|
definition = self._getMachineDefinition()
|
||||||
|
registry = ContainerRegistry.getInstance()
|
||||||
|
material_container = self.material if self.material != self._empty_instance_container else None
|
||||||
|
|
||||||
|
quality = None
|
||||||
|
search_criteria = {"type": "quality"}
|
||||||
|
|
||||||
|
if definition.getMetaDataEntry("has_machine_quality"):
|
||||||
|
search_criteria["definition"] = self._findInstanceContainerDefinitionId(definition)
|
||||||
|
|
||||||
|
if definition.getMetaDataEntry("has_materials") and material_container:
|
||||||
|
search_criteria["material"] = material_container.id
|
||||||
|
else:
|
||||||
|
search_criteria["definition"] = "fdmprinter"
|
||||||
|
|
||||||
|
if self.quality != self._empty_instance_container:
|
||||||
|
search_criteria["name"] = self.quality.name
|
||||||
|
else:
|
||||||
|
preferred_quality = definition.getMetaDataEntry("preferred_quality")
|
||||||
|
if preferred_quality:
|
||||||
|
search_criteria["id"] = preferred_quality
|
||||||
|
|
||||||
|
containers = registry.findInstanceContainers(**search_criteria)
|
||||||
|
if containers:
|
||||||
|
return containers[0]
|
||||||
|
|
||||||
|
if "material" in search_criteria:
|
||||||
|
# First check if we can solve our material not found problem by checking if we can find quality containers
|
||||||
|
# that are assigned to the parents of this material profile.
|
||||||
|
try:
|
||||||
|
inherited_files = material_container.getInheritedFiles()
|
||||||
|
except AttributeError: # Material_container does not support inheritance.
|
||||||
|
inherited_files = []
|
||||||
|
|
||||||
|
if inherited_files:
|
||||||
|
for inherited_file in inherited_files:
|
||||||
|
# Extract the ID from the path we used to load the file.
|
||||||
|
search_criteria["material"] = os.path.basename(inherited_file).split(".")[0]
|
||||||
|
containers = registry.findInstanceContainers(**search_criteria)
|
||||||
|
if containers:
|
||||||
|
return containers[0]
|
||||||
|
|
||||||
|
# We still weren't able to find a quality for this specific material.
|
||||||
|
# Try to find qualities for a generic version of the material.
|
||||||
|
material_search_criteria = {"type": "material", "material": material_container.getMetaDataEntry("material"), "color_name": "Generic"}
|
||||||
|
if definition.getMetaDataEntry("has_machine_quality"):
|
||||||
|
if self.material != self._em:
|
||||||
|
material_search_criteria["definition"] = material_container.getDefinition().id
|
||||||
|
|
||||||
|
if definition.getMetaDataEntry("has_variants"):
|
||||||
|
material_search_criteria["variant"] = material_container.getMetaDataEntry("variant")
|
||||||
|
else:
|
||||||
|
material_search_criteria["definition"] = self._findInstanceContainerDefinitionId(definition)
|
||||||
|
|
||||||
|
if definition.getMetaDataEntry("has_variants") and self.variant != self._empty_instance_container:
|
||||||
|
material_search_criteria["variant"] = self.variant.id
|
||||||
|
else:
|
||||||
|
material_search_criteria["definition"] = "fdmprinter"
|
||||||
|
material_containers = registry.findInstanceContainers(**material_search_criteria)
|
||||||
|
# Try all materials to see if there is a quality profile available.
|
||||||
|
for material_container in material_containers:
|
||||||
|
search_criteria["material"] = material_container.getId()
|
||||||
|
|
||||||
|
containers = registry.findInstanceContainers(**search_criteria)
|
||||||
|
if containers:
|
||||||
|
return containers[0]
|
||||||
|
|
||||||
|
if "name" in search_criteria or "id" in search_criteria:
|
||||||
|
# If a quality by this name can not be found, try a wider set of search criteria
|
||||||
|
search_criteria.pop("name", None)
|
||||||
|
search_criteria.pop("id", None)
|
||||||
|
|
||||||
|
containers = registry.findInstanceContainers(**search_criteria)
|
||||||
|
if containers:
|
||||||
|
return containers[0]
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
## protected:
|
||||||
|
|
||||||
|
# Helper to make sure we emit a PyQt signal on container changes.
|
||||||
|
def _onContainersChanged(self, container: Any) -> None:
|
||||||
self.pyqtContainersChanged.emit()
|
self.pyqtContainersChanged.emit()
|
||||||
|
|
||||||
|
# Helper that can be overridden to get the "machine" definition, that is, the definition that defines the machine
|
||||||
|
# and its properties rather than, for example, the extruder. Defaults to simply returning the definition property.
|
||||||
|
def _getMachineDefinition(self) -> ContainerInterface:
|
||||||
|
return self.definition
|
||||||
|
|
||||||
|
## Find the ID that should be used when searching for instance containers for a specified definition.
|
||||||
|
#
|
||||||
|
# This handles the situation where the definition specifies we should use a different definition when
|
||||||
|
# searching for instance containers.
|
||||||
|
#
|
||||||
|
# \param machine_definition The definition to find the "quality definition" for.
|
||||||
|
#
|
||||||
|
# \return The ID of the definition container to use when searching for instance containers.
|
||||||
|
@classmethod
|
||||||
|
def _findInstanceContainerDefinitionId(cls, machine_definition: DefinitionContainer) -> str:
|
||||||
|
quality_definition = machine_definition.getMetaDataEntry("quality_definition")
|
||||||
|
if not quality_definition:
|
||||||
|
return machine_definition.id
|
||||||
|
|
||||||
|
definitions = ContainerRegistry.getInstance().findDefinitionContainers(id = quality_definition)
|
||||||
|
if not definitions:
|
||||||
|
Logger.log("w", "Unable to find parent definition {parent} for machine {machine}", parent = quality_definition, machine = machine_definition.id)
|
||||||
|
return machine_definition.id
|
||||||
|
|
||||||
|
return cls._findInstanceContainerDefinitionId(definitions[0])
|
||||||
|
|
||||||
## private:
|
## private:
|
||||||
|
|
||||||
# Private helper class to keep track of container positions and their types.
|
# Private helper class to keep track of container positions and their types.
|
||||||
|
|
|
@ -148,188 +148,3 @@ class CuraStackBuilder:
|
||||||
cls.__registry.addContainer(user_container)
|
cls.__registry.addContainer(user_container)
|
||||||
|
|
||||||
return stack
|
return stack
|
||||||
|
|
||||||
# Convenience variable
|
|
||||||
# It should get set before any private functions are called so the privates do not need to
|
|
||||||
# re-get the container registry.
|
|
||||||
__registry = None # type: ContainerRegistry
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def __setStackQuality(cls, stack: CuraContainerStack, quality_id: str, machine_definition: DefinitionContainer) -> None:
|
|
||||||
if quality_id != "default":
|
|
||||||
# Specific quality ID specified, so use that.
|
|
||||||
stack.setQualityById(quality_id)
|
|
||||||
return
|
|
||||||
|
|
||||||
quality = None
|
|
||||||
|
|
||||||
container_registry = ContainerRegistry.getInstance()
|
|
||||||
search_criteria = { "type": "quality" }
|
|
||||||
|
|
||||||
if definition.getMetaDataEntry("has_machine_quality"):
|
|
||||||
search_criteria["definition"] = self.getQualityDefinitionId(definition)
|
|
||||||
|
|
||||||
if definition.getMetaDataEntry("has_materials") and material_container:
|
|
||||||
search_criteria["material"] = material_container.id
|
|
||||||
else:
|
|
||||||
search_criteria["definition"] = "fdmprinter"
|
|
||||||
|
|
||||||
if preferred_quality_name and preferred_quality_name != "empty":
|
|
||||||
search_criteria["name"] = preferred_quality_name
|
|
||||||
else:
|
|
||||||
preferred_quality = definition.getMetaDataEntry("preferred_quality")
|
|
||||||
if preferred_quality:
|
|
||||||
search_criteria["id"] = preferred_quality
|
|
||||||
|
|
||||||
containers = container_registry.findInstanceContainers(**search_criteria)
|
|
||||||
if containers:
|
|
||||||
return containers[0]
|
|
||||||
|
|
||||||
if "material" in search_criteria:
|
|
||||||
# First check if we can solve our material not found problem by checking if we can find quality containers
|
|
||||||
# that are assigned to the parents of this material profile.
|
|
||||||
try:
|
|
||||||
inherited_files = material_container.getInheritedFiles()
|
|
||||||
except AttributeError: # Material_container does not support inheritance.
|
|
||||||
inherited_files = []
|
|
||||||
|
|
||||||
if inherited_files:
|
|
||||||
for inherited_file in inherited_files:
|
|
||||||
# Extract the ID from the path we used to load the file.
|
|
||||||
search_criteria["material"] = os.path.basename(inherited_file).split(".")[0]
|
|
||||||
containers = container_registry.findInstanceContainers(**search_criteria)
|
|
||||||
if containers:
|
|
||||||
return containers[0]
|
|
||||||
# We still weren't able to find a quality for this specific material.
|
|
||||||
# Try to find qualities for a generic version of the material.
|
|
||||||
material_search_criteria = { "type": "material", "material": material_container.getMetaDataEntry("material"), "color_name": "Generic"}
|
|
||||||
if definition.getMetaDataEntry("has_machine_quality"):
|
|
||||||
if material_container:
|
|
||||||
material_search_criteria["definition"] = material_container.getDefinition().id
|
|
||||||
|
|
||||||
if definition.getMetaDataEntry("has_variants"):
|
|
||||||
material_search_criteria["variant"] = material_container.getMetaDataEntry("variant")
|
|
||||||
else:
|
|
||||||
material_search_criteria["definition"] = self.getQualityDefinitionId(definition)
|
|
||||||
|
|
||||||
if definition.getMetaDataEntry("has_variants") and variant_container:
|
|
||||||
material_search_criteria["variant"] = self.getQualityVariantId(definition, variant_container)
|
|
||||||
else:
|
|
||||||
material_search_criteria["definition"] = "fdmprinter"
|
|
||||||
material_containers = container_registry.findInstanceContainers(**material_search_criteria)
|
|
||||||
# Try all materials to see if there is a quality profile available.
|
|
||||||
for material_container in material_containers:
|
|
||||||
search_criteria["material"] = material_container.getId()
|
|
||||||
|
|
||||||
containers = container_registry.findInstanceContainers(**search_criteria)
|
|
||||||
if containers:
|
|
||||||
return containers[0]
|
|
||||||
|
|
||||||
if "name" in search_criteria or "id" in search_criteria:
|
|
||||||
# If a quality by this name can not be found, try a wider set of search criteria
|
|
||||||
search_criteria.pop("name", None)
|
|
||||||
search_criteria.pop("id", None)
|
|
||||||
|
|
||||||
containers = container_registry.findInstanceContainers(**search_criteria)
|
|
||||||
if containers:
|
|
||||||
return containers[0]
|
|
||||||
|
|
||||||
# Notify user that we were unable to find a matching quality
|
|
||||||
message = Message(catalog.i18nc("@info:status", "Unable to find a quality profile for this combination. Default settings will be used instead."))
|
|
||||||
message.show()
|
|
||||||
return self._empty_quality_container
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def __setStackMaterial(cls, stack: CuraContainerStack, material_id: str, machine_definition: DefinitionContainer) -> None:
|
|
||||||
if not machine_definition.getMetaDataEntry("has_materials"):
|
|
||||||
# Machine does not use materials, never try to set it.
|
|
||||||
return
|
|
||||||
|
|
||||||
if material_id != "default":
|
|
||||||
# Specific material ID specified, so use that.
|
|
||||||
stack.setMaterialById(material_id)
|
|
||||||
return
|
|
||||||
|
|
||||||
# If material_id is "default", find a default material to use for this stack.
|
|
||||||
# First add any material. Later, overwrite with preference if the preference is valid.
|
|
||||||
material = None
|
|
||||||
search_criteria = { "type": "material" }
|
|
||||||
if machine_definition.getMetaDataEntry("has_machine_materials"):
|
|
||||||
search_criteria["definition"] = cls.__findInstanceContainerDefinitionId(machine_definition)
|
|
||||||
|
|
||||||
if machine_definition.getMetaDataEntry("has_variants"):
|
|
||||||
search_criteria["variant"] = stack.variant.id
|
|
||||||
else:
|
|
||||||
search_criteria["definition"] = "fdmprinter"
|
|
||||||
|
|
||||||
preferred_material = machine_definition.getMetaDataEntry("preferred_material")
|
|
||||||
if preferred_material:
|
|
||||||
search_criteria["id"] = preferred_material
|
|
||||||
|
|
||||||
materials = cls.__registry.findInstanceContainers(**search_criteria)
|
|
||||||
if not materials:
|
|
||||||
Logger.log("w", "The preferred material \"{material}\" could not be found for stack {stack}", material = preferred_material, stack = stack.id)
|
|
||||||
search_criteria.pop("variant", None)
|
|
||||||
search_criteria.pop("id", None)
|
|
||||||
materials = cls.__registry.findInstanceContainers(**search_criteria)
|
|
||||||
|
|
||||||
if materials:
|
|
||||||
stack.setMaterial(materials[0])
|
|
||||||
else:
|
|
||||||
Logger.log("w", "Could not find a valid material for stack {stack}", stack = stack.id)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def __setStackVariant(cls, stack: CuraContainerStack, variant_id: str, machine_definition: DefinitionContainer) -> None:
|
|
||||||
if not machine_definition.getMetaDataEntry("has_variants"):
|
|
||||||
# If the machine does not use variants, we should never set a variant.
|
|
||||||
return
|
|
||||||
|
|
||||||
if variant_id != "default":
|
|
||||||
# If we specify a specific variant ID, use that and do nothing else.
|
|
||||||
stack.setVariantById(variant_id)
|
|
||||||
return
|
|
||||||
|
|
||||||
# When the id is "default", look up the variant based on machine definition etc.
|
|
||||||
# First add any variant. Later, overwrite with preference if the preference is valid.
|
|
||||||
variant = None
|
|
||||||
|
|
||||||
definition_id = cls.__findInstanceContainerDefinitionId(machine_definition.id)
|
|
||||||
variants = cls.__registry.findInstanceContainers(definition = definition_id, type = "variant")
|
|
||||||
if variants:
|
|
||||||
variant = variants[0]
|
|
||||||
|
|
||||||
preferred_variant_id = machine_definition.getMetaDataEntry("preferred_variant")
|
|
||||||
if preferred_variant_id:
|
|
||||||
preferred_variants = cls.__registry.findInstanceContainers(id = preferred_variant_id, definition = definition_id, type = "variant")
|
|
||||||
if len(preferred_variants) >= 1:
|
|
||||||
variant = preferred_variants[0]
|
|
||||||
else:
|
|
||||||
Logger.log("w", "The preferred variant \"{variant}\" of stack {stack} does not exist or is not a variant.", variant = preferred_variant_id, stack = stack.id)
|
|
||||||
# And leave it at the default variant.
|
|
||||||
|
|
||||||
if variant:
|
|
||||||
stack.setVariant(variant)
|
|
||||||
else:
|
|
||||||
Logger.log("w", "Could not find a valid default variant for stack {stack}", stack = stack.id)
|
|
||||||
|
|
||||||
## Find the ID that should be used when searching for instance containers for a specified definition.
|
|
||||||
#
|
|
||||||
# This handles the situation where the definition specifies we should use a different definition when
|
|
||||||
# searching for instance containers.
|
|
||||||
#
|
|
||||||
# \param machine_definition The definition to find the "quality definition" for.
|
|
||||||
#
|
|
||||||
# \return The ID of the definition container to use when searching for instance containers.
|
|
||||||
@classmethod
|
|
||||||
def __findInstanceContainerDefinitionId(cls, machine_definition: DefinitionContainer) -> str:
|
|
||||||
quality_definition = machine_definition.getMetaDataEntry("quality_definition")
|
|
||||||
if not quality_definition:
|
|
||||||
return machine_definition.id
|
|
||||||
|
|
||||||
definitions = cls.__registry.findDefinitionContainers(id = quality_definition)
|
|
||||||
if not definitions:
|
|
||||||
Logger.log("w", "Unable to find parent definition {parent} for machine {machine}", parent = quality_definition, machine = machine_definition.id)
|
|
||||||
return machine_definition.id
|
|
||||||
|
|
||||||
return cls.__findInstanceContainerDefinitionId(definitions[0])
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue