|
@@ -282,243 +282,6 @@ class CuraContainerStack(ContainerStack):
|
|
|
|
|
|
self._containers = new_containers
|
|
|
|
|
|
- ## 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()
|
|
|
- # has_variants can be overridden in other containers and stacks.
|
|
|
- # In the case of UM2, it is overridden in the GlobalStack
|
|
|
- if not self.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 global variant that should be used as "default". This is used for the buildplates.
|
|
|
- #
|
|
|
- # 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 global variant:
|
|
|
- # - If the machine definition does not have a metadata entry "has_variant_buildplates" 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" and "hardware_type" with value "buildplate".
|
|
|
- # - If the machine definition has a metadata entry "preferred_variant_buildplate", 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 findDefaultVariantBuildplate(self) -> Optional[ContainerInterface]:
|
|
|
- definition = self._getMachineDefinition()
|
|
|
- # has_variant_buildplates can be overridden in other containers and stacks.
|
|
|
- # In the case of UM2, it is overridden in the GlobalStack
|
|
|
- if not self.getMetaDataEntry("has_variant_buildplates"):
|
|
|
- # 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", hardware_type = "buildplate")
|
|
|
- if variants:
|
|
|
- variant = variants[0]
|
|
|
-
|
|
|
- preferred_variant_buildplate_id = definition.getMetaDataEntry("preferred_variant_buildplate")
|
|
|
- if preferred_variant_buildplate_id:
|
|
|
- preferred_variant_buildplates = ContainerRegistry.getInstance().findInstanceContainers(id = preferred_variant_buildplate_id, definition = definition_id, type = "variant")
|
|
|
- if preferred_variant_buildplates:
|
|
|
- variant = preferred_variant_buildplates[0]
|
|
|
- else:
|
|
|
- Logger.log("w", "The preferred variant buildplate \"{variant}\" of stack {stack} does not exist or is not a variant.",
|
|
|
- variant = preferred_variant_buildplate_id, stack = self.id)
|
|
|
- # And leave it at the default variant.
|
|
|
-
|
|
|
- if variant:
|
|
|
- return variant
|
|
|
-
|
|
|
- Logger.log("w", "Could not find a valid default buildplate 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".
|
|
|
- # - The material should have an approximate diameter that matches the machine
|
|
|
- # - 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
|
|
|
-
|
|
|
- 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_material:
|
|
|
- search_criteria["name"] = self.material.name
|
|
|
- else:
|
|
|
- preferred_material = definition.getMetaDataEntry("preferred_material")
|
|
|
- if preferred_material:
|
|
|
- search_criteria["id"] = preferred_material
|
|
|
-
|
|
|
- approximate_material_diameter = str(round(self.getProperty("material_diameter", "value")))
|
|
|
- search_criteria["approximate_diameter"] = approximate_material_diameter
|
|
|
-
|
|
|
- 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 not materials:
|
|
|
- Logger.log("w", "Could not find a valid material for stack {stack}", stack = self.id)
|
|
|
- return None
|
|
|
-
|
|
|
- for material in materials:
|
|
|
- # Prefer a read-only material
|
|
|
- if ContainerRegistry.getInstance().isReadOnly(material.getId()):
|
|
|
- return material
|
|
|
-
|
|
|
- return materials[0]
|
|
|
-
|
|
|
-
|
|
|
- ## Find the quality that should be used as "default" quality.
|
|
|
- #
|
|
|
- # This will search for qualities that match the current definition and pick the preferred one,
|
|
|
- # if specified by the machine definition.
|
|
|
- #
|
|
|
- # \return The container that should be used as default, or None if nothing was found.
|
|
|
- def findDefaultQuality(self) -> Optional[ContainerInterface]:
|
|
|
- definition = self._getMachineDefinition()
|
|
|
- registry = ContainerRegistry.getInstance()
|
|
|
- material_container = self.material if self.material.getId() not in (self._empty_material.getId(), self._empty_instance_container.getId()) else 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_quality:
|
|
|
- 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._empty_instance_container:
|
|
|
- material_search_criteria["definition"] = material_container.getMetaDataEntry("definition")
|
|
|
-
|
|
|
- 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.findInstanceContainersMetadata(**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["id"]
|
|
|
-
|
|
|
- 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.
|