mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-08-06 13:34:01 -06:00
Merge pull request #4184 from Ultimaker/CURA-5570_beyond_comprehension
CURA-5570 More decision points in material and quality lookup!
This commit is contained in:
commit
152005ab14
24 changed files with 790 additions and 241 deletions
|
@ -118,11 +118,12 @@ if TYPE_CHECKING:
|
|||
numpy.seterr(all = "ignore")
|
||||
|
||||
try:
|
||||
from cura.CuraVersion import CuraVersion, CuraBuildType, CuraDebugMode
|
||||
from cura.CuraVersion import CuraVersion, CuraBuildType, CuraDebugMode, CuraSDKVersion
|
||||
except ImportError:
|
||||
CuraVersion = "master" # [CodeStyle: Reflecting imported value]
|
||||
CuraBuildType = ""
|
||||
CuraDebugMode = False
|
||||
CuraSDKVerion = ""
|
||||
|
||||
|
||||
class CuraApplication(QtApplication):
|
||||
|
@ -913,6 +914,7 @@ class CuraApplication(QtApplication):
|
|||
engine.rootContext().setContextProperty("CuraApplication", self)
|
||||
engine.rootContext().setContextProperty("PrintInformation", self._print_information)
|
||||
engine.rootContext().setContextProperty("CuraActions", self._cura_actions)
|
||||
engine.rootContext().setContextProperty("CuraSDKVersion", CuraSDKVersion)
|
||||
|
||||
qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type")
|
||||
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
from collections import defaultdict, OrderedDict
|
||||
import copy
|
||||
import uuid
|
||||
from typing import Dict, cast
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
from typing import Dict, Optional, TYPE_CHECKING
|
||||
|
||||
from PyQt5.Qt import QTimer, QObject, pyqtSignal, pyqtSlot
|
||||
|
||||
|
@ -18,6 +17,7 @@ from UM.Util import parseBool
|
|||
|
||||
from .MaterialNode import MaterialNode
|
||||
from .MaterialGroup import MaterialGroup
|
||||
from .VariantType import VariantType
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from UM.Settings.DefinitionContainer import DefinitionContainer
|
||||
|
@ -47,7 +47,7 @@ class MaterialManager(QObject):
|
|||
|
||||
self._fallback_materials_map = dict() # material_type -> generic material metadata
|
||||
self._material_group_map = dict() # root_material_id -> MaterialGroup
|
||||
self._diameter_machine_variant_material_map = dict() # approximate diameter str -> dict(machine_definition_id -> MaterialNode)
|
||||
self._diameter_machine_nozzle_buildplate_material_map = dict() # approximate diameter str -> dict(machine_definition_id -> MaterialNode)
|
||||
|
||||
# We're using these two maps to convert between the specific diameter material id and the generic material id
|
||||
# because the generic material ids are used in qualities and definitions, while the specific diameter material is meant
|
||||
|
@ -187,52 +187,78 @@ class MaterialManager(QObject):
|
|||
self._diameter_material_map[root_material_id] = default_root_material_id
|
||||
|
||||
# Map #4
|
||||
# "machine" -> "variant_name" -> "root material ID" -> specific material InstanceContainer
|
||||
# Construct the "machine" -> "variant" -> "root material ID" -> specific material InstanceContainer
|
||||
self._diameter_machine_variant_material_map = dict()
|
||||
# "machine" -> "nozzle name" -> "buildplate name" -> "root material ID" -> specific material InstanceContainer
|
||||
self._diameter_machine_nozzle_buildplate_material_map = dict()
|
||||
for material_metadata in material_metadatas.values():
|
||||
# We don't store empty material in the lookup tables
|
||||
if material_metadata["id"] == "empty_material":
|
||||
continue
|
||||
|
||||
root_material_id = material_metadata["base_file"]
|
||||
definition = material_metadata["definition"]
|
||||
approximate_diameter = material_metadata["approximate_diameter"]
|
||||
|
||||
if approximate_diameter not in self._diameter_machine_variant_material_map:
|
||||
self._diameter_machine_variant_material_map[approximate_diameter] = {}
|
||||
|
||||
machine_variant_material_map = self._diameter_machine_variant_material_map[approximate_diameter]
|
||||
if definition not in machine_variant_material_map:
|
||||
machine_variant_material_map[definition] = MaterialNode()
|
||||
|
||||
machine_node = machine_variant_material_map[definition]
|
||||
variant_name = material_metadata.get("variant_name")
|
||||
if not variant_name:
|
||||
# if there is no variant, this material is for the machine, so put its metadata in the machine node.
|
||||
machine_node.material_map[root_material_id] = MaterialNode(material_metadata)
|
||||
else:
|
||||
# this material is variant-specific, so we save it in a variant-specific node under the
|
||||
# machine-specific node
|
||||
|
||||
# Check first if the variant exist in the manager
|
||||
existing_variant = self._application.getVariantManager().getVariantNode(definition, variant_name)
|
||||
if existing_variant is not None:
|
||||
if variant_name not in machine_node.children_map:
|
||||
machine_node.children_map[variant_name] = MaterialNode()
|
||||
|
||||
variant_node = machine_node.children_map[variant_name]
|
||||
if root_material_id in variant_node.material_map: # We shouldn't have duplicated variant-specific materials for the same machine.
|
||||
ConfigurationErrorMessage.getInstance().addFaultyContainers(root_material_id)
|
||||
continue
|
||||
variant_node.material_map[root_material_id] = MaterialNode(material_metadata)
|
||||
else:
|
||||
# Add this container id to the wrong containers list in the registry
|
||||
Logger.log("w", "Not adding {id} to the material manager because the variant does not exist.".format(id = material_metadata["id"]))
|
||||
self._container_registry.addWrongContainerId(material_metadata["id"])
|
||||
self.__addMaterialMetadataIntoLookupTree(material_metadata)
|
||||
|
||||
self.materialsUpdated.emit()
|
||||
|
||||
def __addMaterialMetadataIntoLookupTree(self, material_metadata: dict) -> None:
|
||||
material_id = material_metadata["id"]
|
||||
|
||||
# We don't store empty material in the lookup tables
|
||||
if material_id == "empty_material":
|
||||
return
|
||||
|
||||
root_material_id = material_metadata["base_file"]
|
||||
definition = material_metadata["definition"]
|
||||
approximate_diameter = material_metadata["approximate_diameter"]
|
||||
|
||||
if approximate_diameter not in self._diameter_machine_nozzle_buildplate_material_map:
|
||||
self._diameter_machine_nozzle_buildplate_material_map[approximate_diameter] = {}
|
||||
|
||||
machine_nozzle_buildplate_material_map = self._diameter_machine_nozzle_buildplate_material_map[
|
||||
approximate_diameter]
|
||||
if definition not in machine_nozzle_buildplate_material_map:
|
||||
machine_nozzle_buildplate_material_map[definition] = MaterialNode()
|
||||
|
||||
# This is a list of information regarding the intermediate nodes:
|
||||
# nozzle -> buildplate
|
||||
nozzle_name = material_metadata.get("variant_name")
|
||||
buildplate_name = material_metadata.get("buildplate_name")
|
||||
intermediate_node_info_list = [(nozzle_name, VariantType.NOZZLE),
|
||||
(buildplate_name, VariantType.BUILD_PLATE),
|
||||
]
|
||||
|
||||
variant_manager = self._application.getVariantManager()
|
||||
|
||||
machine_node = machine_nozzle_buildplate_material_map[definition]
|
||||
current_node = machine_node
|
||||
current_intermediate_node_info_idx = 0
|
||||
error_message = None # type: Optional[str]
|
||||
while current_intermediate_node_info_idx < len(intermediate_node_info_list):
|
||||
variant_name, variant_type = intermediate_node_info_list[current_intermediate_node_info_idx]
|
||||
if variant_name is not None:
|
||||
# The new material has a specific variant, so it needs to be added to that specific branch in the tree.
|
||||
variant = variant_manager.getVariantNode(definition, variant_name, variant_type)
|
||||
if variant is None:
|
||||
error_message = "Material {id} contains a variant {name} that does not exist.".format(
|
||||
id = material_metadata["id"], name = variant_name)
|
||||
break
|
||||
|
||||
# Update the current node to advance to a more specific branch
|
||||
if variant_name not in current_node.children_map:
|
||||
current_node.children_map[variant_name] = MaterialNode()
|
||||
current_node = current_node.children_map[variant_name]
|
||||
|
||||
current_intermediate_node_info_idx += 1
|
||||
|
||||
if error_message is not None:
|
||||
Logger.log("e", "%s It will not be added into the material lookup tree.", error_message)
|
||||
self._container_registry.addWrongContainerId(material_metadata["id"])
|
||||
return
|
||||
|
||||
# Add the material to the current tree node, which is the deepest (the most specific) branch we can find.
|
||||
# Sanity check: Make sure that there is no duplicated materials.
|
||||
if root_material_id in current_node.material_map:
|
||||
Logger.log("e", "Duplicated material [%s] with root ID [%s]. It has already been added.",
|
||||
material_id, root_material_id)
|
||||
ConfigurationErrorMessage.getInstance().addFaultyContainers(root_material_id)
|
||||
return
|
||||
|
||||
current_node.material_map[root_material_id] = MaterialNode(material_metadata)
|
||||
|
||||
def _updateMaps(self):
|
||||
Logger.log("i", "Updating material lookup data ...")
|
||||
self.initialize()
|
||||
|
@ -263,45 +289,52 @@ class MaterialManager(QObject):
|
|||
#
|
||||
# Return a dict with all root material IDs (k) and ContainerNodes (v) that's suitable for the given setup.
|
||||
#
|
||||
def getAvailableMaterials(self, machine_definition: "DefinitionContainer", extruder_variant_name: Optional[str],
|
||||
diameter: float) -> Dict[str, MaterialNode]:
|
||||
def getAvailableMaterials(self, machine_definition: "DefinitionContainer", nozzle_name: Optional[str],
|
||||
buildplate_name: Optional[str], diameter: float) -> Dict[str, MaterialNode]:
|
||||
# round the diameter to get the approximate diameter
|
||||
rounded_diameter = str(round(diameter))
|
||||
if rounded_diameter not in self._diameter_machine_variant_material_map:
|
||||
if rounded_diameter not in self._diameter_machine_nozzle_buildplate_material_map:
|
||||
Logger.log("i", "Cannot find materials with diameter [%s] (rounded to [%s])", diameter, rounded_diameter)
|
||||
return dict()
|
||||
|
||||
machine_definition_id = machine_definition.getId()
|
||||
|
||||
# If there are variant materials, get the variant material
|
||||
machine_variant_material_map = self._diameter_machine_variant_material_map[rounded_diameter]
|
||||
machine_node = machine_variant_material_map.get(machine_definition_id)
|
||||
default_machine_node = machine_variant_material_map.get(self._default_machine_definition_id)
|
||||
variant_node = None
|
||||
if extruder_variant_name is not None and machine_node is not None:
|
||||
variant_node = machine_node.getChildNode(extruder_variant_name)
|
||||
# If there are nozzle-and-or-buildplate materials, get the nozzle-and-or-buildplate material
|
||||
machine_nozzle_buildplate_material_map = self._diameter_machine_nozzle_buildplate_material_map[rounded_diameter]
|
||||
machine_node = machine_nozzle_buildplate_material_map.get(machine_definition_id)
|
||||
default_machine_node = machine_nozzle_buildplate_material_map.get(self._default_machine_definition_id)
|
||||
nozzle_node = None
|
||||
buildplate_node = None
|
||||
if nozzle_name is not None and machine_node is not None:
|
||||
nozzle_node = machine_node.getChildNode(nozzle_name)
|
||||
# Get buildplate node if possible
|
||||
if nozzle_node is not None and buildplate_name is not None:
|
||||
buildplate_node = nozzle_node.getChildNode(buildplate_name)
|
||||
|
||||
nodes_to_check = [variant_node, machine_node, default_machine_node]
|
||||
nodes_to_check = [buildplate_node, nozzle_node, machine_node, default_machine_node]
|
||||
|
||||
# Fallback mechanism of finding materials:
|
||||
# 1. variant-specific material
|
||||
# 2. machine-specific material
|
||||
# 3. generic material (for fdmprinter)
|
||||
# 1. buildplate-specific material
|
||||
# 2. nozzle-specific material
|
||||
# 3. machine-specific material
|
||||
# 4. generic material (for fdmprinter)
|
||||
machine_exclude_materials = machine_definition.getMetaDataEntry("exclude_materials", [])
|
||||
|
||||
material_id_metadata_dict = dict() # type: Dict[str, MaterialNode]
|
||||
for node in nodes_to_check:
|
||||
if node is not None:
|
||||
# Only exclude the materials that are explicitly specified in the "exclude_materials" field.
|
||||
# Do not exclude other materials that are of the same type.
|
||||
for material_id, node in node.material_map.items():
|
||||
if material_id in machine_exclude_materials:
|
||||
Logger.log("d", "Exclude material [%s] for machine [%s]",
|
||||
material_id, machine_definition.getId())
|
||||
continue
|
||||
material_id_metadata_dict = dict() # type: Dict[str, MaterialNode]
|
||||
for current_node in nodes_to_check:
|
||||
if current_node is None:
|
||||
continue
|
||||
|
||||
if material_id not in material_id_metadata_dict:
|
||||
material_id_metadata_dict[material_id] = node
|
||||
# Only exclude the materials that are explicitly specified in the "exclude_materials" field.
|
||||
# Do not exclude other materials that are of the same type.
|
||||
for material_id, node in current_node.material_map.items():
|
||||
if material_id in machine_exclude_materials:
|
||||
Logger.log("d", "Exclude material [%s] for machine [%s]",
|
||||
material_id, machine_definition.getId())
|
||||
continue
|
||||
|
||||
if material_id not in material_id_metadata_dict:
|
||||
material_id_metadata_dict[material_id] = node
|
||||
|
||||
return material_id_metadata_dict
|
||||
|
||||
|
@ -310,13 +343,14 @@ class MaterialManager(QObject):
|
|||
#
|
||||
def getAvailableMaterialsForMachineExtruder(self, machine: "GlobalStack",
|
||||
extruder_stack: "ExtruderStack") -> Optional[dict]:
|
||||
variant_name = None
|
||||
buildplate_name = machine.getBuildplateName()
|
||||
nozzle_name = None
|
||||
if extruder_stack.variant.getId() != "empty_variant":
|
||||
variant_name = extruder_stack.variant.getName()
|
||||
nozzle_name = extruder_stack.variant.getName()
|
||||
diameter = extruder_stack.approximateMaterialDiameter
|
||||
|
||||
# Fetch the available materials (ContainerNode) for the current active machine and extruder setup.
|
||||
return self.getAvailableMaterials(machine.definition, variant_name, diameter)
|
||||
return self.getAvailableMaterials(machine.definition, nozzle_name, buildplate_name, diameter)
|
||||
|
||||
#
|
||||
# Gets MaterialNode for the given extruder and machine with the given material name.
|
||||
|
@ -324,32 +358,36 @@ class MaterialManager(QObject):
|
|||
# 1. the given machine doesn't have materials;
|
||||
# 2. cannot find any material InstanceContainers with the given settings.
|
||||
#
|
||||
def getMaterialNode(self, machine_definition_id: str, extruder_variant_name: Optional[str],
|
||||
diameter: float, root_material_id: str) -> Optional["InstanceContainer"]:
|
||||
def getMaterialNode(self, machine_definition_id: str, nozzle_name: Optional[str],
|
||||
buildplate_name: Optional[str], diameter: float, root_material_id: str) -> Optional["InstanceContainer"]:
|
||||
# round the diameter to get the approximate diameter
|
||||
rounded_diameter = str(round(diameter))
|
||||
if rounded_diameter not in self._diameter_machine_variant_material_map:
|
||||
if rounded_diameter not in self._diameter_machine_nozzle_buildplate_material_map:
|
||||
Logger.log("i", "Cannot find materials with diameter [%s] (rounded to [%s]) for root material id [%s]",
|
||||
diameter, rounded_diameter, root_material_id)
|
||||
return None
|
||||
|
||||
# If there are variant materials, get the variant material
|
||||
machine_variant_material_map = self._diameter_machine_variant_material_map[rounded_diameter]
|
||||
machine_node = machine_variant_material_map.get(machine_definition_id)
|
||||
variant_node = None
|
||||
# If there are nozzle materials, get the nozzle-specific material
|
||||
machine_nozzle_buildplate_material_map = self._diameter_machine_nozzle_buildplate_material_map[rounded_diameter]
|
||||
machine_node = machine_nozzle_buildplate_material_map.get(machine_definition_id)
|
||||
nozzle_node = None
|
||||
buildplate_node = None
|
||||
|
||||
# Fallback for "fdmprinter" if the machine-specific materials cannot be found
|
||||
if machine_node is None:
|
||||
machine_node = machine_variant_material_map.get(self._default_machine_definition_id)
|
||||
if machine_node is not None and extruder_variant_name is not None:
|
||||
variant_node = machine_node.getChildNode(extruder_variant_name)
|
||||
machine_node = machine_nozzle_buildplate_material_map.get(self._default_machine_definition_id)
|
||||
if machine_node is not None and nozzle_name is not None:
|
||||
nozzle_node = machine_node.getChildNode(nozzle_name)
|
||||
if nozzle_node is not None and buildplate_name is not None:
|
||||
buildplate_node = nozzle_node.getChildNode(buildplate_name)
|
||||
|
||||
# Fallback mechanism of finding materials:
|
||||
# 1. variant-specific material
|
||||
# 2. machine-specific material
|
||||
# 3. generic material (for fdmprinter)
|
||||
nodes_to_check = [variant_node, machine_node,
|
||||
machine_variant_material_map.get(self._default_machine_definition_id)]
|
||||
# 1. buildplate-specific material
|
||||
# 2. nozzle-specific material
|
||||
# 3. machine-specific material
|
||||
# 4. generic material (for fdmprinter)
|
||||
nodes_to_check = [buildplate_node, nozzle_node, machine_node,
|
||||
machine_nozzle_buildplate_material_map.get(self._default_machine_definition_id)]
|
||||
|
||||
material_node = None
|
||||
for node in nodes_to_check:
|
||||
|
@ -366,7 +404,8 @@ class MaterialManager(QObject):
|
|||
# 1. the given machine doesn't have materials;
|
||||
# 2. cannot find any material InstanceContainers with the given settings.
|
||||
#
|
||||
def getMaterialNodeByType(self, global_stack: "GlobalStack", position: str, extruder_variant_name: str, material_guid: str) -> Optional["MaterialNode"]:
|
||||
def getMaterialNodeByType(self, global_stack: "GlobalStack", position: str, nozzle_name: str,
|
||||
buildplate_name: Optional[str], material_guid: str) -> Optional["MaterialNode"]:
|
||||
node = None
|
||||
machine_definition = global_stack.definition
|
||||
extruder_definition = global_stack.extruders[position].definition
|
||||
|
@ -385,7 +424,7 @@ class MaterialManager(QObject):
|
|||
Logger.log("i", "Cannot find materials with guid [%s] ", material_guid)
|
||||
return None
|
||||
|
||||
node = self.getMaterialNode(machine_definition.getId(), extruder_variant_name,
|
||||
node = self.getMaterialNode(machine_definition.getId(), nozzle_name, buildplate_name,
|
||||
material_diameter, root_material_id)
|
||||
return node
|
||||
|
||||
|
@ -413,13 +452,17 @@ class MaterialManager(QObject):
|
|||
else:
|
||||
return None
|
||||
|
||||
## Get default material for given global stack, extruder position and extruder variant name
|
||||
## Get default material for given global stack, extruder position and extruder nozzle name
|
||||
# you can provide the extruder_definition and then the position is ignored (useful when building up global stack in CuraStackBuilder)
|
||||
def getDefaultMaterial(self, global_stack: "GlobalStack", position: str, extruder_variant_name: Optional[str], extruder_definition: Optional["DefinitionContainer"] = None) -> Optional["MaterialNode"]:
|
||||
def getDefaultMaterial(self, global_stack: "GlobalStack", position: str, nozzle_name: Optional[str],
|
||||
extruder_definition: Optional["DefinitionContainer"] = None) -> Optional["MaterialNode"]:
|
||||
node = None
|
||||
|
||||
buildplate_name = global_stack.getBuildplateName()
|
||||
machine_definition = global_stack.definition
|
||||
if extruder_definition is None:
|
||||
extruder_definition = global_stack.extruders[position].definition
|
||||
|
||||
if extruder_definition and parseBool(global_stack.getMetaDataEntry("has_materials", False)):
|
||||
# At this point the extruder_definition is not None
|
||||
material_diameter = extruder_definition.getProperty("material_diameter", "value")
|
||||
|
@ -428,7 +471,7 @@ class MaterialManager(QObject):
|
|||
approximate_material_diameter = str(round(material_diameter))
|
||||
root_material_id = machine_definition.getMetaDataEntry("preferred_material")
|
||||
root_material_id = self.getRootMaterialIDForDiameter(root_material_id, approximate_material_diameter)
|
||||
node = self.getMaterialNode(machine_definition.getId(), extruder_variant_name,
|
||||
node = self.getMaterialNode(machine_definition.getId(), nozzle_name, buildplate_name,
|
||||
material_diameter, root_material_id)
|
||||
return node
|
||||
|
||||
|
@ -515,8 +558,8 @@ class MaterialManager(QObject):
|
|||
if container_to_copy.getMetaDataEntry("definition") != "fdmprinter":
|
||||
new_id += "_" + container_to_copy.getMetaDataEntry("definition")
|
||||
if container_to_copy.getMetaDataEntry("variant_name"):
|
||||
variant_name = container_to_copy.getMetaDataEntry("variant_name")
|
||||
new_id += "_" + variant_name.replace(" ", "_")
|
||||
nozzle_name = container_to_copy.getMetaDataEntry("variant_name")
|
||||
new_id += "_" + nozzle_name.replace(" ", "_")
|
||||
|
||||
new_container = copy.deepcopy(container_to_copy)
|
||||
new_container.getMetaData()["id"] = new_id
|
||||
|
|
|
@ -8,7 +8,7 @@ from UM.Logger import Logger
|
|||
from UM.Qt.ListModel import ListModel
|
||||
from UM.Util import parseBool
|
||||
|
||||
from cura.Machines.VariantManager import VariantType
|
||||
from cura.Machines.VariantType import VariantType
|
||||
|
||||
|
||||
class BuildPlateModel(ListModel):
|
||||
|
|
|
@ -8,6 +8,8 @@ from UM.Logger import Logger
|
|||
from UM.Qt.ListModel import ListModel
|
||||
from UM.Util import parseBool
|
||||
|
||||
from cura.Machines.VariantType import VariantType
|
||||
|
||||
|
||||
class NozzleModel(ListModel):
|
||||
IdRole = Qt.UserRole + 1
|
||||
|
@ -43,7 +45,6 @@ class NozzleModel(ListModel):
|
|||
self.setItems([])
|
||||
return
|
||||
|
||||
from cura.Machines.VariantManager import VariantType
|
||||
variant_node_dict = self._variant_manager.getVariantNodes(global_stack, VariantType.NOZZLE)
|
||||
if not variant_node_dict:
|
||||
self.setItems([])
|
||||
|
|
|
@ -45,7 +45,7 @@ class QualityManager(QObject):
|
|||
self._empty_quality_container = self._application.empty_quality_container
|
||||
self._empty_quality_changes_container = self._application.empty_quality_changes_container
|
||||
|
||||
self._machine_variant_material_quality_type_to_quality_dict = {} # for quality lookup
|
||||
self._machine_nozzle_buildplate_material_quality_type_to_quality_dict = {} # for quality lookup
|
||||
self._machine_quality_type_to_quality_changes_dict = {} # for quality_changes lookup
|
||||
|
||||
self._default_machine_definition_id = "fdmprinter"
|
||||
|
@ -64,10 +64,10 @@ class QualityManager(QObject):
|
|||
|
||||
def initialize(self):
|
||||
# Initialize the lookup tree for quality profiles with following structure:
|
||||
# <machine> -> <variant> -> <material>
|
||||
# -> <material>
|
||||
# <machine> -> <nozzle> -> <buildplate> -> <material>
|
||||
# <machine> -> <material>
|
||||
|
||||
self._machine_variant_material_quality_type_to_quality_dict = {} # for quality lookup
|
||||
self._machine_nozzle_buildplate_material_quality_type_to_quality_dict = {} # for quality lookup
|
||||
self._machine_quality_type_to_quality_changes_dict = {} # for quality_changes lookup
|
||||
|
||||
quality_metadata_list = self._container_registry.findContainersMetadata(type = "quality")
|
||||
|
@ -79,53 +79,41 @@ class QualityManager(QObject):
|
|||
quality_type = metadata["quality_type"]
|
||||
|
||||
root_material_id = metadata.get("material")
|
||||
variant_name = metadata.get("variant")
|
||||
nozzle_name = metadata.get("variant")
|
||||
buildplate_name = metadata.get("buildplate")
|
||||
is_global_quality = metadata.get("global_quality", False)
|
||||
is_global_quality = is_global_quality or (root_material_id is None and variant_name is None)
|
||||
is_global_quality = is_global_quality or (root_material_id is None and nozzle_name is None and buildplate_name is None)
|
||||
|
||||
# Sanity check: material+variant and is_global_quality cannot be present at the same time
|
||||
if is_global_quality and (root_material_id or variant_name):
|
||||
if is_global_quality and (root_material_id or nozzle_name):
|
||||
ConfigurationErrorMessage.getInstance().addFaultyContainers(metadata["id"])
|
||||
continue
|
||||
|
||||
if definition_id not in self._machine_variant_material_quality_type_to_quality_dict:
|
||||
self._machine_variant_material_quality_type_to_quality_dict[definition_id] = QualityNode()
|
||||
machine_node = cast(QualityNode, self._machine_variant_material_quality_type_to_quality_dict[definition_id])
|
||||
if definition_id not in self._machine_nozzle_buildplate_material_quality_type_to_quality_dict:
|
||||
self._machine_nozzle_buildplate_material_quality_type_to_quality_dict[definition_id] = QualityNode()
|
||||
machine_node = cast(QualityNode, self._machine_nozzle_buildplate_material_quality_type_to_quality_dict[definition_id])
|
||||
|
||||
if is_global_quality:
|
||||
# For global qualities, save data in the machine node
|
||||
machine_node.addQualityMetadata(quality_type, metadata)
|
||||
continue
|
||||
|
||||
if variant_name is not None:
|
||||
# If variant_name is specified in the quality/quality_changes profile, check if material is specified,
|
||||
# too.
|
||||
if variant_name not in machine_node.children_map:
|
||||
machine_node.children_map[variant_name] = QualityNode()
|
||||
variant_node = cast(QualityNode, machine_node.children_map[variant_name])
|
||||
current_node = machine_node
|
||||
intermediate_node_info_list = [nozzle_name, buildplate_name, root_material_id]
|
||||
current_intermediate_node_info_idx = 0
|
||||
|
||||
if root_material_id is None:
|
||||
# If only variant_name is specified but material is not, add the quality/quality_changes metadata
|
||||
# into the current variant node.
|
||||
variant_node.addQualityMetadata(quality_type, metadata)
|
||||
else:
|
||||
# If only variant_name and material are both specified, go one level deeper: create a material node
|
||||
# under the current variant node, and then add the quality/quality_changes metadata into the
|
||||
# material node.
|
||||
if root_material_id not in variant_node.children_map:
|
||||
variant_node.children_map[root_material_id] = QualityNode()
|
||||
material_node = cast(QualityNode, variant_node.children_map[root_material_id])
|
||||
while current_intermediate_node_info_idx < len(intermediate_node_info_list):
|
||||
node_name = intermediate_node_info_list[current_intermediate_node_info_idx]
|
||||
if node_name is not None:
|
||||
# There is specific information, update the current node to go deeper so we can add this quality
|
||||
# at the most specific branch in the lookup tree.
|
||||
if node_name not in current_node.children_map:
|
||||
current_node.children_map[node_name] = QualityNode()
|
||||
current_node = cast(QualityNode, current_node.children_map[node_name])
|
||||
|
||||
material_node.addQualityMetadata(quality_type, metadata)
|
||||
current_intermediate_node_info_idx += 1
|
||||
|
||||
else:
|
||||
# If variant_name is not specified, check if material is specified.
|
||||
if root_material_id is not None:
|
||||
if root_material_id not in machine_node.children_map:
|
||||
machine_node.children_map[root_material_id] = QualityNode()
|
||||
material_node = cast(QualityNode, machine_node.children_map[root_material_id])
|
||||
|
||||
material_node.addQualityMetadata(quality_type, metadata)
|
||||
current_node.addQualityMetadata(quality_type, metadata)
|
||||
|
||||
# Initialize the lookup tree for quality_changes profiles with following structure:
|
||||
# <machine> -> <quality_type> -> <name>
|
||||
|
@ -217,8 +205,8 @@ class QualityManager(QObject):
|
|||
# To find the quality container for the GlobalStack, check in the following fall-back manner:
|
||||
# (1) the machine-specific node
|
||||
# (2) the generic node
|
||||
machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(machine_definition_id)
|
||||
default_machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(self._default_machine_definition_id)
|
||||
machine_node = self._machine_nozzle_buildplate_material_quality_type_to_quality_dict.get(machine_definition_id)
|
||||
default_machine_node = self._machine_nozzle_buildplate_material_quality_type_to_quality_dict.get(self._default_machine_definition_id)
|
||||
nodes_to_check = [machine_node, default_machine_node]
|
||||
|
||||
# Iterate over all quality_types in the machine node
|
||||
|
@ -238,16 +226,19 @@ class QualityManager(QObject):
|
|||
quality_group_dict[quality_type] = quality_group
|
||||
break
|
||||
|
||||
buildplate_name = machine.getBuildplateName()
|
||||
|
||||
# Iterate over all extruders to find quality containers for each extruder
|
||||
for position, extruder in machine.extruders.items():
|
||||
variant_name = None
|
||||
nozzle_name = None
|
||||
if extruder.variant.getId() != "empty_variant":
|
||||
variant_name = extruder.variant.getName()
|
||||
nozzle_name = extruder.variant.getName()
|
||||
|
||||
# This is a list of root material IDs to use for searching for suitable quality profiles.
|
||||
# The root material IDs in this list are in prioritized order.
|
||||
root_material_id_list = []
|
||||
has_material = False # flag indicating whether this extruder has a material assigned
|
||||
root_material_id = None
|
||||
if extruder.material.getId() != "empty_material":
|
||||
has_material = True
|
||||
root_material_id = extruder.material.getMetaDataEntry("base_file")
|
||||
|
@ -264,34 +255,39 @@ class QualityManager(QObject):
|
|||
# Here we construct a list of nodes we want to look for qualities with the highest priority first.
|
||||
# The use case is that, when we look for qualities for a machine, we first want to search in the following
|
||||
# order:
|
||||
# 1. machine-variant-and-material-specific qualities if exist
|
||||
# 2. machine-variant-specific qualities if exist
|
||||
# 3. machine-material-specific qualities if exist
|
||||
# 4. machine-specific qualities if exist
|
||||
# 5. generic qualities if exist
|
||||
# 1. machine-nozzle-buildplate-and-material-specific qualities if exist
|
||||
# 2. machine-nozzle-and-material-specific qualities if exist
|
||||
# 3. machine-nozzle-specific qualities if exist
|
||||
# 4. machine-material-specific qualities if exist
|
||||
# 5. machine-specific qualities if exist
|
||||
# 6. generic qualities if exist
|
||||
# Each points above can be represented as a node in the lookup tree, so here we simply put those nodes into
|
||||
# the list with priorities as the order. Later, we just need to loop over each node in this list and fetch
|
||||
# qualities from there.
|
||||
node_info_list_0 = [nozzle_name, buildplate_name, root_material_id]
|
||||
nodes_to_check = []
|
||||
|
||||
if variant_name:
|
||||
# In this case, we have both a specific variant and a specific material
|
||||
variant_node = machine_node.getChildNode(variant_name)
|
||||
if variant_node and has_material:
|
||||
for root_material_id in root_material_id_list:
|
||||
material_node = variant_node.getChildNode(root_material_id)
|
||||
if material_node:
|
||||
nodes_to_check.append(material_node)
|
||||
break
|
||||
nodes_to_check.append(variant_node)
|
||||
# This function tries to recursively find the deepest (the most specific) branch and add those nodes to
|
||||
# the search list in the order described above. So, by iterating over that search node list, we first look
|
||||
# in the more specific branches and then the less specific (generic) ones.
|
||||
def addNodesToCheck(node, nodes_to_check_list, node_info_list, node_info_idx):
|
||||
if node_info_idx < len(node_info_list):
|
||||
node_name = node_info_list[node_info_idx]
|
||||
if node_name is not None:
|
||||
current_node = node.getChildNode(node_name)
|
||||
if current_node is not None and has_material:
|
||||
addNodesToCheck(current_node, nodes_to_check_list, node_info_list, node_info_idx + 1)
|
||||
|
||||
# In this case, we only have a specific material but NOT a variant
|
||||
if has_material:
|
||||
for root_material_id in root_material_id_list:
|
||||
material_node = machine_node.getChildNode(root_material_id)
|
||||
if material_node:
|
||||
nodes_to_check.append(material_node)
|
||||
break
|
||||
if has_material:
|
||||
for rmid in root_material_id_list:
|
||||
material_node = node.getChildNode(rmid)
|
||||
if material_node:
|
||||
nodes_to_check_list.append(material_node)
|
||||
break
|
||||
|
||||
nodes_to_check_list.append(node)
|
||||
|
||||
addNodesToCheck(machine_node, nodes_to_check, node_info_list_0, 0)
|
||||
|
||||
nodes_to_check += [machine_node, default_machine_node]
|
||||
for node in nodes_to_check:
|
||||
|
@ -309,8 +305,8 @@ class QualityManager(QObject):
|
|||
quality_group_dict[quality_type] = quality_group
|
||||
|
||||
quality_group = quality_group_dict[quality_type]
|
||||
quality_group.nodes_for_extruders[position] = quality_node
|
||||
break
|
||||
if position not in quality_group.nodes_for_extruders:
|
||||
quality_group.nodes_for_extruders[position] = quality_node
|
||||
|
||||
# Update availabilities for each quality group
|
||||
self._updateQualityGroupsAvailability(machine, quality_group_dict.values())
|
||||
|
@ -323,8 +319,8 @@ class QualityManager(QObject):
|
|||
# To find the quality container for the GlobalStack, check in the following fall-back manner:
|
||||
# (1) the machine-specific node
|
||||
# (2) the generic node
|
||||
machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(machine_definition_id)
|
||||
default_machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(
|
||||
machine_node = self._machine_nozzle_buildplate_material_quality_type_to_quality_dict.get(machine_definition_id)
|
||||
default_machine_node = self._machine_nozzle_buildplate_material_quality_type_to_quality_dict.get(
|
||||
self._default_machine_definition_id)
|
||||
nodes_to_check = [machine_node, default_machine_node]
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from enum import Enum
|
||||
from collections import OrderedDict
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
|
@ -11,20 +10,13 @@ from UM.Settings.ContainerRegistry import ContainerRegistry
|
|||
from UM.Util import parseBool
|
||||
|
||||
from cura.Machines.ContainerNode import ContainerNode
|
||||
from cura.Machines.VariantType import VariantType, ALL_VARIANT_TYPES
|
||||
from cura.Settings.GlobalStack import GlobalStack
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from UM.Settings.DefinitionContainer import DefinitionContainer
|
||||
|
||||
|
||||
class VariantType(Enum):
|
||||
BUILD_PLATE = "buildplate"
|
||||
NOZZLE = "nozzle"
|
||||
|
||||
|
||||
ALL_VARIANT_TYPES = (VariantType.BUILD_PLATE, VariantType.NOZZLE)
|
||||
|
||||
|
||||
#
|
||||
# VariantManager is THE place to look for a specific variant. It maintains two variant lookup tables with the following
|
||||
# structure:
|
||||
|
|
15
cura/Machines/VariantType.py
Normal file
15
cura/Machines/VariantType.py
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Copyright (c) 2018 Ultimaker B.V.
|
||||
# Cura is released under the terms of the LGPLv3 or higher.
|
||||
|
||||
from enum import Enum
|
||||
|
||||
|
||||
class VariantType(Enum):
|
||||
BUILD_PLATE = "buildplate"
|
||||
NOZZLE = "nozzle"
|
||||
|
||||
|
||||
ALL_VARIANT_TYPES = (VariantType.BUILD_PLATE, VariantType.NOZZLE)
|
||||
|
||||
|
||||
__all__ = ["VariantType", "ALL_VARIANT_TYPES"]
|
|
@ -8,7 +8,7 @@ from UM.Logger import Logger
|
|||
from UM.Settings.Interfaces import DefinitionContainerInterface
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
|
||||
from cura.Machines.VariantManager import VariantType
|
||||
from cura.Machines.VariantType import VariantType
|
||||
from .GlobalStack import GlobalStack
|
||||
from .ExtruderStack import ExtruderStack
|
||||
|
||||
|
|
|
@ -55,6 +55,12 @@ class GlobalStack(CuraContainerStack):
|
|||
return "machine_stack"
|
||||
return configuration_type
|
||||
|
||||
def getBuildplateName(self) -> Optional[str]:
|
||||
name = None
|
||||
if self.variant.getId() != "empty_variant":
|
||||
name = self.variant.getName()
|
||||
return name
|
||||
|
||||
## Add an extruder to the list of extruders of this stack.
|
||||
#
|
||||
# \param extruder The extruder to add.
|
||||
|
|
|
@ -1256,13 +1256,17 @@ class MachineManager(QObject):
|
|||
else:
|
||||
position_list = [position]
|
||||
|
||||
buildplate_name = None
|
||||
if self._global_container_stack.variant.getId() != "empty_variant":
|
||||
buildplate_name = self._global_container_stack.variant.getName()
|
||||
|
||||
for position_item in position_list:
|
||||
extruder = self._global_container_stack.extruders[position_item]
|
||||
|
||||
current_material_base_name = extruder.material.getMetaDataEntry("base_file")
|
||||
current_variant_name = None
|
||||
current_nozzle_name = None
|
||||
if extruder.variant.getId() != self._empty_variant_container.getId():
|
||||
current_variant_name = extruder.variant.getMetaDataEntry("name")
|
||||
current_nozzle_name = extruder.variant.getMetaDataEntry("name")
|
||||
|
||||
from UM.Settings.Interfaces import PropertyEvaluationContext
|
||||
from cura.Settings.CuraContainerStack import _ContainerIndexes
|
||||
|
@ -1271,7 +1275,8 @@ class MachineManager(QObject):
|
|||
material_diameter = extruder.getProperty("material_diameter", "value", context)
|
||||
candidate_materials = self._material_manager.getAvailableMaterials(
|
||||
self._global_container_stack.definition,
|
||||
current_variant_name,
|
||||
current_nozzle_name,
|
||||
buildplate_name,
|
||||
material_diameter)
|
||||
|
||||
if not candidate_materials:
|
||||
|
@ -1284,7 +1289,7 @@ class MachineManager(QObject):
|
|||
continue
|
||||
|
||||
# The current material is not available, find the preferred one
|
||||
material_node = self._material_manager.getDefaultMaterial(self._global_container_stack, position_item, current_variant_name)
|
||||
material_node = self._material_manager.getDefaultMaterial(self._global_container_stack, position_item, current_nozzle_name)
|
||||
if material_node is not None:
|
||||
self._setMaterial(position_item, material_node)
|
||||
|
||||
|
@ -1326,7 +1331,12 @@ class MachineManager(QObject):
|
|||
for extruder_configuration in configuration.extruderConfigurations:
|
||||
position = str(extruder_configuration.position)
|
||||
variant_container_node = self._variant_manager.getVariantNode(self._global_container_stack.definition.getId(), extruder_configuration.hotendID)
|
||||
material_container_node = self._material_manager.getMaterialNodeByType(self._global_container_stack, position, extruder_configuration.hotendID, extruder_configuration.material.guid)
|
||||
material_container_node = self._material_manager.getMaterialNodeByType(self._global_container_stack,
|
||||
position,
|
||||
extruder_configuration.hotendID,
|
||||
configuration.buildplateConfiguration,
|
||||
extruder_configuration.material.guid)
|
||||
|
||||
if variant_container_node:
|
||||
self._setVariantNode(position, variant_container_node)
|
||||
else:
|
||||
|
@ -1389,12 +1399,17 @@ class MachineManager(QObject):
|
|||
def setMaterialById(self, position: str, root_material_id: str) -> None:
|
||||
if self._global_container_stack is None:
|
||||
return
|
||||
buildplate_name = None
|
||||
if self._global_container_stack.variant.getId() != "empty_variant":
|
||||
buildplate_name = self._global_container_stack.variant.getName()
|
||||
|
||||
machine_definition_id = self._global_container_stack.definition.id
|
||||
position = str(position)
|
||||
extruder_stack = self._global_container_stack.extruders[position]
|
||||
variant_name = extruder_stack.variant.getName()
|
||||
nozzle_name = extruder_stack.variant.getName()
|
||||
material_diameter = extruder_stack.approximateMaterialDiameter
|
||||
material_node = self._material_manager.getMaterialNode(machine_definition_id, variant_name, material_diameter, root_material_id)
|
||||
material_node = self._material_manager.getMaterialNode(machine_definition_id, nozzle_name, buildplate_name,
|
||||
material_diameter, root_material_id)
|
||||
self.setMaterial(position, material_node)
|
||||
|
||||
## global_stack: if you want to provide your own global_stack instead of the current active one
|
||||
|
|
|
@ -24,6 +24,7 @@ from UM.MimeTypeDatabase import MimeTypeDatabase, MimeType
|
|||
from UM.Job import Job
|
||||
from UM.Preferences import Preferences
|
||||
|
||||
from cura.Machines.VariantType import VariantType
|
||||
from cura.Settings.CuraStackBuilder import CuraStackBuilder
|
||||
from cura.Settings.ExtruderStack import ExtruderStack
|
||||
from cura.Settings.GlobalStack import GlobalStack
|
||||
|
@ -889,7 +890,6 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
parser = self._machine_info.variant_info.parser
|
||||
variant_name = parser["general"]["name"]
|
||||
|
||||
from cura.Machines.VariantManager import VariantType
|
||||
variant_type = VariantType.BUILD_PLATE
|
||||
|
||||
node = variant_manager.getVariantNode(global_stack.definition.getId(), variant_name, variant_type)
|
||||
|
@ -905,7 +905,6 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
parser = extruder_info.variant_info.parser
|
||||
|
||||
variant_name = parser["general"]["name"]
|
||||
from cura.Machines.VariantManager import VariantType
|
||||
variant_type = VariantType.NOZZLE
|
||||
|
||||
node = variant_manager.getVariantNode(global_stack.definition.getId(), variant_name, variant_type)
|
||||
|
@ -929,12 +928,16 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
|
|||
root_material_id = extruder_info.root_material_id
|
||||
root_material_id = self._old_new_materials.get(root_material_id, root_material_id)
|
||||
|
||||
build_plate_id = global_stack.variant.getId()
|
||||
|
||||
# get material diameter of this extruder
|
||||
machine_material_diameter = extruder_stack.materialDiameter
|
||||
material_node = material_manager.getMaterialNode(global_stack.definition.getId(),
|
||||
extruder_stack.variant.getName(),
|
||||
build_plate_id,
|
||||
machine_material_diameter,
|
||||
root_material_id)
|
||||
|
||||
if material_node is not None and material_node.getContainer() is not None:
|
||||
extruder_stack.material = material_node.getContainer()
|
||||
|
||||
|
|
|
@ -6,21 +6,22 @@ import io
|
|||
import json #To parse the product-to-id mapping file.
|
||||
import os.path #To find the product-to-id mapping.
|
||||
import sys
|
||||
from typing import Any, Dict, List, Optional, cast
|
||||
from typing import Any, Dict, List, Optional, Tuple, cast
|
||||
import xml.etree.ElementTree as ET
|
||||
from typing import Dict
|
||||
from typing import Iterator
|
||||
|
||||
from UM.Resources import Resources
|
||||
from UM.Logger import Logger
|
||||
from cura.CuraApplication import CuraApplication
|
||||
import UM.Dictionary
|
||||
from UM.Settings.InstanceContainer import InstanceContainer
|
||||
from UM.Settings.ContainerRegistry import ContainerRegistry
|
||||
from UM.ConfigurationErrorMessage import ConfigurationErrorMessage
|
||||
|
||||
from cura.CuraApplication import CuraApplication
|
||||
from cura.Machines.VariantType import VariantType
|
||||
|
||||
from .XmlMaterialValidator import XmlMaterialValidator
|
||||
|
||||
|
||||
## Handles serializing and deserializing material containers from an XML file
|
||||
class XmlMaterialProfile(InstanceContainer):
|
||||
CurrentFdmMaterialVersion = "1.3"
|
||||
|
@ -269,7 +270,6 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
buildplate_dict = {} # type: Dict[str, Any]
|
||||
for variant_name, variant_dict in machine_variant_map[definition_id].items():
|
||||
variant_type = variant_dict["variant_node"].metadata["hardware_type"]
|
||||
from cura.Machines.VariantManager import VariantType
|
||||
variant_type = VariantType(variant_type)
|
||||
if variant_type == VariantType.NOZZLE:
|
||||
# The hotend identifier is not the containers name, but its "name".
|
||||
|
@ -693,74 +693,38 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
if buildplate_id is None:
|
||||
continue
|
||||
|
||||
from cura.Machines.VariantManager import VariantType
|
||||
variant_manager = CuraApplication.getInstance().getVariantManager()
|
||||
variant_node = variant_manager.getVariantNode(machine_id, buildplate_id,
|
||||
variant_type = VariantType.BUILD_PLATE)
|
||||
if not variant_node:
|
||||
continue
|
||||
|
||||
buildplate_compatibility = machine_compatibility
|
||||
buildplate_recommended = machine_compatibility
|
||||
settings = buildplate.iterfind("./um:setting", self.__namespaces)
|
||||
for entry in settings:
|
||||
key = entry.get("key")
|
||||
if key in self.__unmapped_settings:
|
||||
if key == "hardware compatible":
|
||||
buildplate_compatibility = self._parseCompatibleValue(entry.text)
|
||||
elif key == "hardware recommended":
|
||||
buildplate_recommended = self._parseCompatibleValue(entry.text)
|
||||
else:
|
||||
Logger.log("d", "Unsupported material setting %s", key)
|
||||
_, buildplate_unmapped_settings_dict = self._getSettingsDictForNode(buildplate)
|
||||
|
||||
buildplate_compatibility = buildplate_unmapped_settings_dict.get("hardware compatible",
|
||||
machine_compatibility)
|
||||
buildplate_recommended = buildplate_unmapped_settings_dict.get("hardware recommended",
|
||||
machine_compatibility)
|
||||
|
||||
buildplate_map["buildplate_compatible"][buildplate_id] = buildplate_compatibility
|
||||
buildplate_map["buildplate_recommended"][buildplate_id] = buildplate_recommended
|
||||
|
||||
hotends = machine.iterfind("./um:hotend", self.__namespaces)
|
||||
for hotend in hotends:
|
||||
# The "id" field for hotends in material profiles are actually
|
||||
# The "id" field for hotends in material profiles is actually name
|
||||
hotend_name = hotend.get("id")
|
||||
if hotend_name is None:
|
||||
continue
|
||||
|
||||
variant_manager = CuraApplication.getInstance().getVariantManager()
|
||||
variant_node = variant_manager.getVariantNode(machine_id, hotend_name)
|
||||
variant_node = variant_manager.getVariantNode(machine_id, hotend_name, VariantType.NOZZLE)
|
||||
if not variant_node:
|
||||
continue
|
||||
|
||||
hotend_compatibility = machine_compatibility
|
||||
hotend_setting_values = {}
|
||||
settings = hotend.iterfind("./um:setting", self.__namespaces)
|
||||
for entry in settings:
|
||||
key = entry.get("key")
|
||||
if key in self.__material_settings_setting_map:
|
||||
if key == "processing temperature graph": #This setting has no setting text but subtags.
|
||||
graph_nodes = entry.iterfind("./um:point", self.__namespaces)
|
||||
graph_points = []
|
||||
for graph_node in graph_nodes:
|
||||
flow = float(graph_node.get("flow"))
|
||||
temperature = float(graph_node.get("temperature"))
|
||||
graph_points.append([flow, temperature])
|
||||
hotend_setting_values[self.__material_settings_setting_map[key]] = str(graph_points)
|
||||
else:
|
||||
hotend_setting_values[self.__material_settings_setting_map[key]] = entry.text
|
||||
elif key in self.__unmapped_settings:
|
||||
if key == "hardware compatible":
|
||||
hotend_compatibility = self._parseCompatibleValue(entry.text)
|
||||
else:
|
||||
Logger.log("d", "Unsupported material setting %s", key)
|
||||
|
||||
# Add namespaced Cura-specific settings
|
||||
settings = hotend.iterfind("./cura:setting", self.__namespaces)
|
||||
for entry in settings:
|
||||
value = entry.text
|
||||
if value.lower() == "yes":
|
||||
value = True
|
||||
elif value.lower() == "no":
|
||||
value = False
|
||||
key = entry.get("key")
|
||||
hotend_setting_values[key] = value
|
||||
hotend_mapped_settings, hotend_unmapped_settings = self._getSettingsDictForNode(hotend)
|
||||
hotend_compatibility = hotend_unmapped_settings.get("hardware compatible", machine_compatibility)
|
||||
|
||||
# Generate container ID for the hotend-specific material container
|
||||
new_hotend_specific_material_id = self.getId() + "_" + machine_id + "_" + hotend_name.replace(" ", "_")
|
||||
|
||||
# Same as machine compatibility, keep the derived material containers consistent with the parent material
|
||||
|
@ -785,7 +749,7 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
new_hotend_material.getMetaData()["buildplate_recommended"] = buildplate_map["buildplate_recommended"]
|
||||
|
||||
cached_hotend_setting_properties = cached_machine_setting_properties.copy()
|
||||
cached_hotend_setting_properties.update(hotend_setting_values)
|
||||
cached_hotend_setting_properties.update(hotend_mapped_settings)
|
||||
|
||||
new_hotend_material.setCachedValues(cached_hotend_setting_properties)
|
||||
|
||||
|
@ -794,6 +758,61 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
if is_new_material:
|
||||
containers_to_add.append(new_hotend_material)
|
||||
|
||||
#
|
||||
# Build plates in hotend
|
||||
#
|
||||
buildplates = hotend.iterfind("./um:buildplate", self.__namespaces)
|
||||
for buildplate in buildplates:
|
||||
# The "id" field for buildplate in material profiles is actually name
|
||||
buildplate_name = buildplate.get("id")
|
||||
if buildplate_name is None:
|
||||
continue
|
||||
|
||||
variant_manager = CuraApplication.getInstance().getVariantManager()
|
||||
variant_node = variant_manager.getVariantNode(machine_id, buildplate_name, VariantType.BUILD_PLATE)
|
||||
if not variant_node:
|
||||
continue
|
||||
|
||||
buildplate_mapped_settings, buildplate_unmapped_settings = self._getSettingsDictForNode(buildplate)
|
||||
buildplate_compatibility = buildplate_unmapped_settings.get("hardware compatible",
|
||||
buildplate_map["buildplate_compatible"])
|
||||
buildplate_recommended = buildplate_unmapped_settings.get("hardware recommended",
|
||||
buildplate_map["buildplate_recommended"])
|
||||
|
||||
# Generate container ID for the hotend-and-buildplate-specific material container
|
||||
new_hotend_and_buildplate_specific_material_id = new_hotend_specific_material_id + "_" + buildplate_name.replace(" ", "_")
|
||||
|
||||
# Same as machine compatibility, keep the derived material containers consistent with the parent material
|
||||
if ContainerRegistry.getInstance().isLoaded(new_hotend_and_buildplate_specific_material_id):
|
||||
new_hotend_and_buildplate_material = ContainerRegistry.getInstance().findContainers(id = new_hotend_and_buildplate_specific_material_id)[0]
|
||||
is_new_material = False
|
||||
else:
|
||||
new_hotend_and_buildplate_material = XmlMaterialProfile(new_hotend_and_buildplate_specific_material_id)
|
||||
is_new_material = True
|
||||
|
||||
new_hotend_and_buildplate_material.setMetaData(copy.deepcopy(new_hotend_material.getMetaData()))
|
||||
new_hotend_and_buildplate_material.getMetaData()["id"] = new_hotend_and_buildplate_specific_material_id
|
||||
new_hotend_and_buildplate_material.getMetaData()["name"] = self.getName()
|
||||
new_hotend_and_buildplate_material.getMetaData()["variant_name"] = hotend_name
|
||||
new_hotend_and_buildplate_material.getMetaData()["buildplate_name"] = buildplate_name
|
||||
new_hotend_and_buildplate_material.setDefinition(machine_id)
|
||||
# Don't use setMetadata, as that overrides it for all materials with same base file
|
||||
new_hotend_and_buildplate_material.getMetaData()["compatible"] = buildplate_compatibility
|
||||
new_hotend_and_buildplate_material.getMetaData()["machine_manufacturer"] = machine_manufacturer
|
||||
new_hotend_and_buildplate_material.getMetaData()["definition"] = machine_id
|
||||
new_hotend_and_buildplate_material.getMetaData()["buildplate_compatible"] = buildplate_compatibility
|
||||
new_hotend_and_buildplate_material.getMetaData()["buildplate_recommended"] = buildplate_recommended
|
||||
|
||||
cached_hotend_and_buildplate_setting_properties = cached_hotend_setting_properties.copy()
|
||||
cached_hotend_and_buildplate_setting_properties.update(buildplate_mapped_settings)
|
||||
|
||||
new_hotend_and_buildplate_material.setCachedValues(cached_hotend_and_buildplate_setting_properties)
|
||||
|
||||
new_hotend_and_buildplate_material._dirty = False
|
||||
|
||||
if is_new_material:
|
||||
containers_to_add.append(new_hotend_and_buildplate_material)
|
||||
|
||||
# there is only one ID for a machine. Once we have reached here, it means we have already found
|
||||
# a workable ID for that machine, so there is no need to continue
|
||||
break
|
||||
|
@ -801,6 +820,54 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
for container_to_add in containers_to_add:
|
||||
ContainerRegistry.getInstance().addContainer(container_to_add)
|
||||
|
||||
@classmethod
|
||||
def _getSettingsDictForNode(cls, node) -> Tuple[dict, dict]:
|
||||
node_mapped_settings_dict = dict()
|
||||
node_unmapped_settings_dict = dict()
|
||||
|
||||
# Fetch settings in the "um" namespace
|
||||
um_settings = node.iterfind("./um:setting", cls.__namespaces)
|
||||
for um_setting_entry in um_settings:
|
||||
setting_key = um_setting_entry.get("key")
|
||||
|
||||
# Mapped settings
|
||||
if setting_key in cls.__material_settings_setting_map:
|
||||
if setting_key == "processing temperature graph": # This setting has no setting text but subtags.
|
||||
graph_nodes = um_setting_entry.iterfind("./um:point", cls.__namespaces)
|
||||
graph_points = []
|
||||
for graph_node in graph_nodes:
|
||||
flow = float(graph_node.get("flow"))
|
||||
temperature = float(graph_node.get("temperature"))
|
||||
graph_points.append([flow, temperature])
|
||||
node_mapped_settings_dict[cls.__material_settings_setting_map[setting_key]] = str(
|
||||
graph_points)
|
||||
else:
|
||||
node_mapped_settings_dict[cls.__material_settings_setting_map[setting_key]] = um_setting_entry.text
|
||||
|
||||
# Unmapped settings
|
||||
elif setting_key in cls.__unmapped_settings:
|
||||
if setting_key in ("hardware compatible", "hardware recommended"):
|
||||
node_unmapped_settings_dict[setting_key] = cls._parseCompatibleValue(um_setting_entry.text)
|
||||
|
||||
# Unknown settings
|
||||
else:
|
||||
Logger.log("w", "Unsupported material setting %s", setting_key)
|
||||
|
||||
# Fetch settings in the "cura" namespace
|
||||
cura_settings = node.iterfind("./cura:setting", cls.__namespaces)
|
||||
for cura_setting_entry in cura_settings:
|
||||
value = cura_setting_entry.text
|
||||
if value.lower() == "yes":
|
||||
value = True
|
||||
elif value.lower() == "no":
|
||||
value = False
|
||||
key = cura_setting_entry.get("key")
|
||||
|
||||
# Cura settings are all mapped
|
||||
node_mapped_settings_dict[key] = value
|
||||
|
||||
return node_mapped_settings_dict, node_unmapped_settings_dict
|
||||
|
||||
@classmethod
|
||||
def deserializeMetadata(cls, serialized: str, container_id: str) -> List[Dict[str, Any]]:
|
||||
result_metadata = [] #All the metadata that we found except the base (because the base is returned).
|
||||
|
@ -983,6 +1050,36 @@ class XmlMaterialProfile(InstanceContainer):
|
|||
|
||||
result_metadata.append(new_hotend_material_metadata)
|
||||
|
||||
#
|
||||
# Buildplates in Hotends
|
||||
#
|
||||
buildplates = hotend.iterfind("./um:buildplate", cls.__namespaces)
|
||||
for buildplate in buildplates:
|
||||
# The "id" field for buildplate in material profiles is actually name
|
||||
buildplate_name = buildplate.get("id")
|
||||
if buildplate_name is None:
|
||||
continue
|
||||
|
||||
buildplate_mapped_settings, buildplate_unmapped_settings = cls._getSettingsDictForNode(buildplate)
|
||||
buildplate_compatibility = buildplate_unmapped_settings.get("hardware compatible",
|
||||
buildplate_map["buildplate_compatible"])
|
||||
buildplate_recommended = buildplate_unmapped_settings.get("hardware recommended",
|
||||
buildplate_map["buildplate_recommended"])
|
||||
|
||||
# Generate container ID for the hotend-and-buildplate-specific material container
|
||||
new_hotend_and_buildplate_specific_material_id = new_hotend_specific_material_id + "_" + buildplate_name.replace(
|
||||
" ", "_")
|
||||
|
||||
new_hotend_and_buildplate_material_metadata = {}
|
||||
new_hotend_and_buildplate_material_metadata.update(new_hotend_material_metadata)
|
||||
new_hotend_and_buildplate_material_metadata["id"] = new_hotend_and_buildplate_specific_material_id
|
||||
new_hotend_and_buildplate_material_metadata["buildplate_name"] = buildplate_name
|
||||
new_hotend_and_buildplate_material_metadata["compatible"] = buildplate_compatibility
|
||||
new_hotend_and_buildplate_material_metadata["buildplate_compatible"] = buildplate_compatibility
|
||||
new_hotend_and_buildplate_material_metadata["buildplate_recommended"] = buildplate_recommended
|
||||
|
||||
result_metadata.append(new_hotend_and_buildplate_material_metadata)
|
||||
|
||||
# there is only one ID for a machine. Once we have reached here, it means we have already found
|
||||
# a workable ID for that machine, so there is no need to continue
|
||||
break
|
||||
|
|
|
@ -2127,6 +2127,7 @@
|
|||
"type": "float",
|
||||
"default_value": 60,
|
||||
"value": "default_material_bed_temperature",
|
||||
"resolve": "max(extruderValues('material_bed_temperature'))",
|
||||
"minimum_value": "-273.15",
|
||||
"minimum_value_warning": "0",
|
||||
"maximum_value_warning": "130",
|
||||
|
|
|
@ -231,8 +231,8 @@ UM.MainWindow
|
|||
onObjectRemoved: settingsMenu.removeItem(object)
|
||||
}
|
||||
|
||||
// TODO Temporary hidden, add back again when feature ready
|
||||
// BuildplateMenu { title: catalog.i18nc("@title:menu", "&Build plate"); visible: Cura.MachineManager.hasVariantBuildplates }
|
||||
// TODO Only show in dev mode. Remove check when feature ready
|
||||
BuildplateMenu { title: catalog.i18nc("@title:menu", "&Build plate"); visible: CuraSDKVersion == "dev" ? Cura.MachineManager.hasVariantBuildplates : false }
|
||||
ProfileMenu { title: catalog.i18nc("@title:menu", "&Profile"); }
|
||||
|
||||
MenuSeparator { }
|
||||
|
|
|
@ -476,8 +476,8 @@ Column
|
|||
{
|
||||
id: buildplateRow
|
||||
height: UM.Theme.getSize("sidebar_setup").height
|
||||
// TODO Temporary hidden, add back again when feature ready
|
||||
visible: false //Cura.MachineManager.hasVariantBuildplates && !sidebar.hideSettings
|
||||
// TODO Only show in dev mode. Remove check when feature ready
|
||||
visible: CuraSDKVersion == "dev" ? Cura.MachineManager.hasVariantBuildplates && !sidebar.hideSettings : false
|
||||
|
||||
anchors
|
||||
{
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
[general]
|
||||
version = 4
|
||||
name = Extra Fine
|
||||
definition = ultimaker_s5
|
||||
|
||||
[metadata]
|
||||
setting_version = 5
|
||||
type = quality
|
||||
quality_type = high
|
||||
weight = 1
|
||||
material = generic_abs
|
||||
variant = AA 0.4
|
||||
buildplate = Aluminum
|
||||
|
||||
[values]
|
||||
cool_min_speed = 12
|
||||
layer_height_0 = 0.17
|
||||
machine_nozzle_cool_down_speed = 0.8
|
||||
machine_nozzle_heat_up_speed = 1.5
|
||||
material_bed_temperature = 90
|
||||
material_bed_temperature_layer_0 = 100
|
||||
material_print_temperature = =default_material_print_temperature + 5
|
||||
material_initial_print_temperature = =material_print_temperature - 15
|
||||
material_final_print_temperature = =material_print_temperature - 20
|
||||
prime_blob_enable = False
|
||||
prime_tower_enable = False
|
||||
speed_print = 50
|
||||
speed_layer_0 = =math.ceil(speed_print * 20 / 50)
|
||||
speed_topbottom = =math.ceil(speed_print * 30 / 50)
|
||||
speed_wall = =math.ceil(speed_print * 30 / 50)
|
||||
|
||||
infill_line_width = =round(line_width * 0.4 / 0.35, 2)
|
||||
speed_infill = =math.ceil(speed_print * 40 / 50)
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
[general]
|
||||
version = 4
|
||||
name = Extra Fine
|
||||
definition = ultimaker_s5
|
||||
|
||||
[metadata]
|
||||
setting_version = 5
|
||||
type = quality
|
||||
quality_type = high
|
||||
weight = 1
|
||||
material = generic_cpe_plus
|
||||
variant = AA 0.4
|
||||
buildplate = Aluminum
|
||||
|
||||
[values]
|
||||
acceleration_enabled = True
|
||||
acceleration_print = 4000
|
||||
cool_fan_speed_max = 50
|
||||
cool_min_speed = 5
|
||||
infill_line_width = =round(line_width * 0.35 / 0.35, 2)
|
||||
infill_overlap = 0
|
||||
infill_wipe_dist = 0
|
||||
jerk_enabled = True
|
||||
jerk_print = 25
|
||||
layer_height_0 = 0.17
|
||||
machine_min_cool_heat_time_window = 15
|
||||
machine_nozzle_cool_down_speed = 0.85
|
||||
machine_nozzle_heat_up_speed = 1.5
|
||||
material_bed_temperature = 105
|
||||
material_bed_temperature_layer_0 = 115
|
||||
material_final_print_temperature = =material_print_temperature - 10
|
||||
material_initial_print_temperature = =material_print_temperature - 5
|
||||
material_print_temperature = =default_material_print_temperature + 2
|
||||
material_print_temperature_layer_0 = =material_print_temperature
|
||||
multiple_mesh_overlap = 0
|
||||
prime_blob_enable = False
|
||||
prime_tower_enable = True
|
||||
prime_tower_wipe_enabled = True
|
||||
retraction_combing = off
|
||||
retraction_extrusion_window = 1
|
||||
retraction_hop = 0.2
|
||||
retraction_hop_enabled = False
|
||||
retraction_hop_only_when_collides = True
|
||||
skin_overlap = 20
|
||||
speed_layer_0 = =math.ceil(speed_print * 20 / 40)
|
||||
speed_print = 40
|
||||
speed_topbottom = =math.ceil(speed_print * 30 / 35)
|
||||
|
||||
speed_wall = =math.ceil(speed_print * 35 / 40)
|
||||
speed_wall_0 = =math.ceil(speed_wall * 30 / 35)
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_z_distance = =layer_height
|
||||
wall_0_inset = 0
|
|
@ -0,0 +1,32 @@
|
|||
[general]
|
||||
version = 4
|
||||
name = Extra Fine
|
||||
definition = ultimaker_s5
|
||||
|
||||
[metadata]
|
||||
setting_version = 5
|
||||
type = quality
|
||||
quality_type = high
|
||||
weight = 1
|
||||
material = generic_cpe
|
||||
variant = AA 0.4
|
||||
buildplate = Aluminum
|
||||
|
||||
[values]
|
||||
cool_min_speed = 12
|
||||
layer_height_0 = 0.17
|
||||
machine_nozzle_cool_down_speed = 0.85
|
||||
machine_nozzle_heat_up_speed = 1.5
|
||||
material_bed_temperature = 80
|
||||
material_bed_temperature_layer_0 = 90
|
||||
material_print_temperature = =default_material_print_temperature - 5
|
||||
material_initial_print_temperature = =material_print_temperature - 5
|
||||
material_final_print_temperature = =material_print_temperature - 10
|
||||
prime_blob_enable = False
|
||||
speed_print = 50
|
||||
speed_layer_0 = =math.ceil(speed_print * 20 / 50)
|
||||
speed_topbottom = =math.ceil(speed_print * 30 / 50)
|
||||
speed_wall = =math.ceil(speed_print * 30 / 50)
|
||||
|
||||
infill_pattern = zigzag
|
||||
speed_infill = =math.ceil(speed_print * 40 / 50)
|
|
@ -0,0 +1,71 @@
|
|||
[general]
|
||||
version = 4
|
||||
name = Extra Fine
|
||||
definition = ultimaker_s5
|
||||
|
||||
[metadata]
|
||||
setting_version = 5
|
||||
type = quality
|
||||
quality_type = high
|
||||
weight = 1
|
||||
material = generic_pc
|
||||
variant = AA 0.4
|
||||
buildplate = Aluminum
|
||||
|
||||
[values]
|
||||
acceleration_enabled = True
|
||||
acceleration_print = 4000
|
||||
adhesion_type = brim
|
||||
brim_width = 10
|
||||
cool_fan_full_at_height = =layer_height_0 + layer_height
|
||||
cool_fan_speed_max = 50
|
||||
cool_min_layer_time_fan_speed_max = 5
|
||||
cool_min_speed = 8
|
||||
infill_line_width = =round(line_width * 0.4 / 0.35, 2)
|
||||
infill_overlap = 0
|
||||
infill_overlap_mm = 0.05
|
||||
infill_pattern = triangles
|
||||
infill_wipe_dist = 0.1
|
||||
jerk_enabled = True
|
||||
jerk_print = 25
|
||||
layer_height_0 = 0.17
|
||||
machine_min_cool_heat_time_window = 15
|
||||
machine_nozzle_cool_down_speed = 0.85
|
||||
machine_nozzle_heat_up_speed = 1.5
|
||||
material_bed_temperature = 115
|
||||
material_bed_temperature_layer_0 = 125
|
||||
material_final_print_temperature = =material_print_temperature - 10
|
||||
material_initial_print_temperature = =material_print_temperature - 5
|
||||
material_print_temperature = =default_material_print_temperature - 10
|
||||
material_standby_temperature = 100
|
||||
multiple_mesh_overlap = 0
|
||||
ooze_shield_angle = 40
|
||||
prime_blob_enable = False
|
||||
prime_tower_enable = True
|
||||
prime_tower_wipe_enabled = True
|
||||
raft_airgap = 0.25
|
||||
raft_interface_thickness = =max(layer_height * 1.5, 0.225)
|
||||
retraction_count_max = 80
|
||||
retraction_extrusion_window = 1
|
||||
retraction_hop = 2
|
||||
retraction_hop_only_when_collides = True
|
||||
retraction_min_travel = 0.8
|
||||
retraction_prime_speed = 15
|
||||
skin_overlap = 30
|
||||
speed_layer_0 = =math.ceil(speed_print * 25 / 50)
|
||||
speed_print = 50
|
||||
speed_topbottom = =math.ceil(speed_print * 25 / 50)
|
||||
|
||||
speed_wall = =math.ceil(speed_print * 40 / 50)
|
||||
speed_wall_0 = =math.ceil(speed_wall * 25 / 40)
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_interface_density = 87.5
|
||||
support_interface_pattern = lines
|
||||
switch_extruder_prime_speed = 15
|
||||
switch_extruder_retraction_amount = 20
|
||||
switch_extruder_retraction_speeds = 35
|
||||
wall_0_inset = 0
|
||||
wall_line_width_x = =round(line_width * 0.4 / 0.35, 2)
|
||||
wall_thickness = 1.2
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
[general]
|
||||
version = 4
|
||||
name = Fast
|
||||
definition = ultimaker_s5
|
||||
|
||||
[metadata]
|
||||
setting_version = 5
|
||||
type = quality
|
||||
quality_type = draft
|
||||
weight = -2
|
||||
material = generic_abs
|
||||
variant = AA 0.8
|
||||
buildplate = Aluminum
|
||||
|
||||
[values]
|
||||
layer_height_0 = 0.3
|
||||
line_width = =machine_nozzle_size * 0.875
|
||||
material_bed_temperature = 90
|
||||
material_bed_temperature_layer_0 = 100
|
||||
material_print_temperature = =default_material_print_temperature + 20
|
||||
material_standby_temperature = 100
|
||||
prime_blob_enable = False
|
||||
speed_print = 50
|
||||
speed_topbottom = =math.ceil(speed_print * 30 / 50)
|
||||
speed_wall = =math.ceil(speed_print * 40 / 50)
|
||||
speed_wall_0 = =math.ceil(speed_wall * 30 / 40)
|
||||
retract_at_layer_change = False
|
|
@ -0,0 +1,43 @@
|
|||
[general]
|
||||
version = 4
|
||||
name = Fast - Experimental
|
||||
definition = ultimaker_s5
|
||||
|
||||
[metadata]
|
||||
setting_version = 5
|
||||
type = quality
|
||||
quality_type = draft
|
||||
weight = -2
|
||||
material = generic_cpe_plus
|
||||
variant = AA 0.8
|
||||
buildplate = Aluminum
|
||||
|
||||
[values]
|
||||
brim_width = 14
|
||||
cool_fan_full_at_height = =layer_height_0 + 14 * layer_height
|
||||
infill_before_walls = True
|
||||
layer_height_0 = 0.3
|
||||
line_width = =machine_nozzle_size * 0.9375
|
||||
machine_nozzle_cool_down_speed = 0.9
|
||||
machine_nozzle_heat_up_speed = 1.4
|
||||
material_bed_temperature = 105
|
||||
material_bed_temperature_layer_0 = 115
|
||||
material_print_temperature = =default_material_print_temperature - 10
|
||||
material_print_temperature_layer_0 = =material_print_temperature
|
||||
material_standby_temperature = 100
|
||||
prime_blob_enable = False
|
||||
prime_tower_enable = True
|
||||
retraction_combing = off
|
||||
retraction_hop = 0.1
|
||||
retraction_hop_enabled = False
|
||||
skin_overlap = 0
|
||||
speed_layer_0 = =math.ceil(speed_print * 15 / 50)
|
||||
speed_print = 50
|
||||
speed_slowdown_layers = 15
|
||||
speed_topbottom = =math.ceil(speed_print * 35 / 50)
|
||||
speed_wall = =math.ceil(speed_print * 40 / 50)
|
||||
speed_wall_0 = =math.ceil(speed_wall * 35 / 40)
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_line_width = =round(line_width * 0.6 / 0.7, 2)
|
||||
support_z_distance = =layer_height
|
||||
top_bottom_thickness = 1.2
|
|
@ -0,0 +1,29 @@
|
|||
[general]
|
||||
version = 4
|
||||
name = Fast
|
||||
definition = ultimaker_s5
|
||||
|
||||
[metadata]
|
||||
setting_version = 5
|
||||
type = quality
|
||||
quality_type = draft
|
||||
weight = -2
|
||||
material = generic_cpe
|
||||
variant = AA 0.8
|
||||
buildplate = Aluminum
|
||||
|
||||
[values]
|
||||
brim_width = 15
|
||||
layer_height_0 = 0.3
|
||||
line_width = =machine_nozzle_size * 0.875
|
||||
material_bed_temperature = 80
|
||||
material_bed_temperature_layer_0 = 90
|
||||
material_print_temperature = =default_material_print_temperature + 15
|
||||
material_standby_temperature = 100
|
||||
prime_blob_enable = False
|
||||
prime_tower_enable = True
|
||||
speed_print = 40
|
||||
speed_topbottom = =math.ceil(speed_print * 25 / 40)
|
||||
speed_wall = =math.ceil(speed_print * 30 / 40)
|
||||
|
||||
jerk_travel = 50
|
|
@ -0,0 +1,36 @@
|
|||
[general]
|
||||
version = 4
|
||||
name = Fast - Experimental
|
||||
definition = ultimaker_s5
|
||||
|
||||
[metadata]
|
||||
setting_version = 5
|
||||
type = quality
|
||||
quality_type = draft
|
||||
weight = 0
|
||||
material = generic_pc
|
||||
variant = AA 0.8
|
||||
buildplate = Aluminum
|
||||
|
||||
[values]
|
||||
brim_width = 10
|
||||
cool_fan_full_at_height = =layer_height_0 + 14 * layer_height
|
||||
infill_before_walls = True
|
||||
layer_height_0 = 0.3
|
||||
line_width = =machine_nozzle_size * 0.875
|
||||
material_bed_temperature = 115
|
||||
material_bed_temperature_layer_0 = 125
|
||||
material_print_temperature = =default_material_print_temperature - 5
|
||||
material_print_temperature_layer_0 = =material_print_temperature
|
||||
material_standby_temperature = 100
|
||||
prime_blob_enable = False
|
||||
raft_airgap = 0.5
|
||||
raft_margin = 15
|
||||
skin_overlap = 0
|
||||
speed_layer_0 = =math.ceil(speed_print * 15 / 50)
|
||||
speed_print = 50
|
||||
speed_slowdown_layers = 15
|
||||
speed_topbottom = =math.ceil(speed_print * 25 / 50)
|
||||
speed_wall = =math.ceil(speed_print * 40 / 50)
|
||||
speed_wall_0 = =math.ceil(speed_wall * 30 / 40)
|
||||
support_line_width = =round(line_width * 0.6 / 0.7, 2)
|
|
@ -0,0 +1,53 @@
|
|||
[general]
|
||||
version = 4
|
||||
name = Fast
|
||||
definition = ultimaker_s5
|
||||
|
||||
[metadata]
|
||||
setting_version = 5
|
||||
type = quality
|
||||
quality_type = draft
|
||||
weight = -2
|
||||
material = generic_pp
|
||||
variant = AA 0.8
|
||||
buildplate = Aluminum
|
||||
|
||||
[values]
|
||||
brim_width = 25
|
||||
cool_min_layer_time_fan_speed_max = 6
|
||||
cool_min_speed = 17
|
||||
top_skin_expand_distance = =line_width * 2
|
||||
infill_before_walls = True
|
||||
infill_line_width = =round(line_width * 0.7 / 0.8, 2)
|
||||
infill_pattern = tetrahedral
|
||||
jerk_prime_tower = =math.ceil(jerk_print * 25 / 25)
|
||||
jerk_support = =math.ceil(jerk_print * 25 / 25)
|
||||
jerk_wall_0 = =math.ceil(jerk_wall * 15 / 25)
|
||||
material_bed_temperature_layer_0 = =material_bed_temperature + 5
|
||||
material_print_temperature = =default_material_print_temperature - 2
|
||||
material_print_temperature_layer_0 = =default_material_print_temperature + 2
|
||||
material_standby_temperature = 100
|
||||
multiple_mesh_overlap = 0.2
|
||||
prime_tower_enable = True
|
||||
prime_tower_flow = 100
|
||||
prime_tower_min_volume = 10
|
||||
retract_at_layer_change = False
|
||||
retraction_count_max = 12
|
||||
retraction_extra_prime_amount = 0.5
|
||||
retraction_hop = 0.5
|
||||
retraction_min_travel = 1.5
|
||||
retraction_prime_speed = 15
|
||||
skin_line_width = =round(line_width * 0.78 / 0.8, 2)
|
||||
|
||||
speed_wall_x = =math.ceil(speed_wall * 30 / 30)
|
||||
support_bottom_distance = =support_z_distance
|
||||
support_line_width = =round(line_width * 0.7 / 0.8, 2)
|
||||
support_offset = =line_width
|
||||
switch_extruder_prime_speed = 15
|
||||
switch_extruder_retraction_amount = 20
|
||||
switch_extruder_retraction_speeds = 45
|
||||
top_bottom_thickness = 1.6
|
||||
travel_compensate_overlapping_walls_0_enabled = False
|
||||
wall_0_wipe_dist = =line_width * 2
|
||||
wall_line_width_x = =round(line_width * 0.8 / 0.8, 2)
|
||||
wall_thickness = 1.6
|
Loading…
Add table
Add a link
Reference in a new issue