resources/quality/ultimaker3/um3_aa0.8_TPU_Not_Supported_Quality.inst.cfg
resources/quality/ultimaker3/um3_aa0.8_TPU_Not_Supported_Superdraft_Quality.inst.cfg
This commit is contained in:
maukcc 2017-05-18 09:50:23 +02:00
commit d57701c7ef
199 changed files with 4940 additions and 558 deletions

View file

@ -1,3 +1,6 @@
# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
from UM.Workspace.WorkspaceReader import WorkspaceReader
from UM.Application import Application
@ -43,6 +46,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
self._extruder_stack_suffix = "." + ContainerRegistry.getMimeTypeForContainer(ExtruderStack).preferredSuffix
self._global_stack_suffix = "." + ContainerRegistry.getMimeTypeForContainer(GlobalStack).preferredSuffix
# Certain instance container types are ignored because we make the assumption that only we make those types
# of containers. They are:
# - quality
# - variant
self._ignored_instance_container_types = {"quality", "variant"}
self._resolve_strategies = {}
self._id_mapping = {}
@ -180,6 +189,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
num_user_settings = 0
quality_changes_conflict = False
definition_changes_conflict = False
for each_instance_container_file in instance_container_files:
container_id = self._stripFileToId(each_instance_container_file)
instance_container = InstanceContainer(container_id)
@ -205,14 +215,12 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if definition_changes:
if definition_changes[0] != instance_container:
definition_changes_conflict = True
elif container_type == "quality":
# If the quality name is not set (either by quality or changes, set it now)
# Quality changes should always override this (as they are "on top")
if quality_name == "":
quality_name = instance_container.getName()
quality_type = instance_container.getName()
elif container_type == "user":
num_user_settings += len(instance_container._instances)
elif container_type in self._ignored_instance_container_types:
# Ignore certain instance container types
Logger.log("w", "Ignoring instance container [%s] with type [%s]", container_id, container_type)
continue
Job.yieldThread()
@ -303,6 +311,19 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
return WorkspaceReader.PreReadResult.accepted
## Overrides an ExtruderStack in the given GlobalStack and returns the new ExtruderStack.
def _overrideExtruderStack(self, global_stack, extruder_index, extruder_file_content):
extruder_index_str = str(extruder_index)
extruder_stack = global_stack.extruders[extruder_index_str]
old_extruder_stack_id = extruder_stack.getId()
# override the given extruder stack
extruder_stack.deserialize(extruder_file_content)
# return the new ExtruderStack
return extruder_stack
## Read the project file
# Add all the definitions / materials / quality changes that do not exist yet. Then it loads
# all the stacks into the container registry. In some cases it will reuse the container for the global stack.
@ -355,12 +376,23 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
global_stack_id_original = self._stripFileToId(global_stack_file)
global_stack_id_new = global_stack_id_original
global_stack_need_rename = False
extruder_stack_id_map = {} # new and old ExtruderStack IDs map
if self._resolve_strategies["machine"] == "new":
# We need a new id if the id already exists
if self._container_registry.findContainerStacks(id = global_stack_id_original):
global_stack_id_new = self.getNewId(global_stack_id_original)
global_stack_need_rename = True
for each_extruder_stack_file in extruder_stack_files:
old_container_id = self._stripFileToId(each_extruder_stack_file)
new_container_id = old_container_id
if self._container_registry.findContainerStacks(id = old_container_id):
# get a new name for this extruder
new_container_id = self.getNewId(old_container_id)
extruder_stack_id_map[old_container_id] = new_container_id
# TODO: For the moment we use pretty naive existence checking. If the ID is the same, we assume in quite a few
# TODO: cases that the container loaded is the same (most notable in materials & definitions).
# TODO: It might be possible that we need to add smarter checking in the future.
@ -414,13 +446,35 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
quality_and_definition_changes_instance_containers = []
for instance_container_file in instance_container_files:
container_id = self._stripFileToId(instance_container_file)
serialized = archive.open(instance_container_file).read().decode("utf-8")
# HACK! we ignore the "metadata/type = quality" instance containers!
parser = configparser.ConfigParser()
parser.read_string(serialized)
if not parser.has_option("metadata", "type"):
Logger.log("w", "Cannot find metadata/type in %s, ignoring it", instance_container_file)
continue
if parser.get("metadata", "type") == "quality":
continue
instance_container = InstanceContainer(container_id)
# Deserialize InstanceContainer by converting read data from bytes to string
instance_container.deserialize(archive.open(instance_container_file).read().decode("utf-8"))
instance_container.deserialize(serialized)
container_type = instance_container.getMetaDataEntry("type")
Job.yieldThread()
if container_type == "user":
#
# IMPORTANT:
# If an instance container (or maybe other type of container) exists, and user chooses "Create New",
# we need to rename this container and all references to it, and changing those references are VERY
# HARD.
#
if container_type in self._ignored_instance_container_types:
# Ignore certain instance container types
Logger.log("w", "Ignoring instance container [%s] with type [%s]", container_id, container_type)
continue
elif container_type == "user":
# Check if quality changes already exists.
user_containers = self._container_registry.findInstanceContainers(id = container_id)
if not user_containers:
@ -432,9 +486,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
instance_container.setDirty(True)
elif self._resolve_strategies["machine"] == "new":
# The machine is going to get a spiffy new name, so ensure that the id's of user settings match.
extruder_id = instance_container.getMetaDataEntry("extruder", None)
if extruder_id:
new_extruder_id = self.getNewId(extruder_id)
old_extruder_id = instance_container.getMetaDataEntry("extruder", None)
if old_extruder_id:
new_extruder_id = extruder_stack_id_map[old_extruder_id]
new_id = new_extruder_id + "_current_settings"
instance_container._id = new_id
instance_container.setName(new_id)
@ -454,26 +508,30 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# Check if quality changes already exists.
changes_containers = self._container_registry.findInstanceContainers(id = container_id)
if not changes_containers:
# no existing containers with the same ID, so we can safely add the new one
containers_to_add.append(instance_container)
else:
# we have found existing container with the same ID, so we need to resolve according to the
# selected strategy.
if self._resolve_strategies[container_type] == "override":
instance_container = changes_containers[0]
instance_container.deserialize(archive.open(instance_container_file).read().decode("utf-8"))
instance_container.setDirty(True)
elif self._resolve_strategies[container_type] == "new":
# TODO: how should we handle the case "new" for quality_changes and definition_changes?
instance_container.setName(self._container_registry.uniqueName(instance_container.getName()))
new_changes_container_id = self.getNewId(instance_container.getId())
instance_container._id = new_changes_container_id
instance_container.setName(new_changes_container_id)
# TODO: we don't know the following is correct or not, need to verify
# AND REFACTOR!!!
if self._resolve_strategies["machine"] == "new":
# The machine is going to get a spiffy new name, so ensure that the id's of user settings match.
extruder_id = instance_container.getMetaDataEntry("extruder", None)
if extruder_id:
new_extruder_id = self.getNewId(extruder_id)
old_extruder_id = instance_container.getMetaDataEntry("extruder", None)
if old_extruder_id:
new_extruder_id = extruder_stack_id_map[old_extruder_id]
instance_container.setMetaDataEntry("extruder", new_extruder_id)
machine_id = instance_container.getMetaDataEntry("machine", None)
@ -563,18 +621,36 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
try:
for index, extruder_stack_file in enumerate(extruder_stack_files):
container_id = self._stripFileToId(extruder_stack_file)
extruder_file_content = archive.open(extruder_stack_file, "r").read().decode("utf-8")
container_stacks = self._container_registry.findContainerStacks(id = container_id)
if container_stacks:
# this container stack already exists, try to resolve
stack = container_stacks[0]
if self._resolve_strategies["machine"] == "override":
pass # do nothing
# NOTE: This is the same code as those in the lower part
# deserialize new extruder stack over the current ones
stack = self._overrideExtruderStack(global_stack, index, extruder_file_content)
elif self._resolve_strategies["machine"] == "new":
# create a new extruder stack from this one
new_id = self.getNewId(container_id)
new_id = extruder_stack_id_map[container_id]
stack = ExtruderStack(new_id)
stack.deserialize(archive.open(extruder_stack_file).read().decode("utf-8"))
# HACK: the global stack can have a new name, so we need to make sure that this extruder stack
# references to the new name instead of the old one. Normally, this can be done after
# deserialize() by setting the metadata, but in the case of ExtruderStack, deserialize()
# also does addExtruder() to its machine stack, so we have to make sure that it's pointing
# to the right machine BEFORE deserialization.
extruder_config = configparser.ConfigParser()
extruder_config.read_string(extruder_file_content)
extruder_config.set("metadata", "machine", global_stack_id_new)
tmp_string_io = io.StringIO()
extruder_config.write(tmp_string_io)
extruder_file_content = tmp_string_io.getvalue()
stack.deserialize(extruder_file_content)
# Ensure a unique ID and name
stack._id = new_id
@ -583,37 +659,34 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
extruder_stacks_added.append(stack)
containers_added.append(stack)
else:
# No extruder stack with the same ID can be found
if self._resolve_strategies["machine"] == "override":
global_stacks = self._container_registry.findContainerStacks(id = global_stack_id_original)
# deserialize new extruder stack over the current ones
if global_stacks:
old_extruder_stack_id = global_stacks[0].extruders[index].getId()
# HACK delete file
self._container_registry._deleteFiles(global_stacks[0].extruders[index])
global_stacks[0].extruders[index].deserialize(archive.open(extruder_stack_file).read().decode("utf-8"))
# HACK
global_stacks[0]._extruders = global_stacks[0]._extruders[:2]
# HACK update cache
del self._container_registry._id_container_cache[old_extruder_stack_id]
new_extruder_stack_id = global_stacks[0].extruders[index].getId()
self._container_registry._id_container_cache[new_extruder_stack_id] = global_stacks[0].extruders[index]
stack = self._overrideExtruderStack(global_stack, index, extruder_file_content)
stack = global_stacks[0].extruders[index]
else:
Logger.log("w", "Could not find global stack, while I expected it: %s" % global_stack_id_original)
elif self._resolve_strategies["machine"] == "new":
# container not found, create a new one
stack = ExtruderStack(container_id)
stack.deserialize(archive.open(extruder_stack_file).read().decode("utf-8"))
# HACK: the global stack can have a new name, so we need to make sure that this extruder stack
# references to the new name instead of the old one. Normally, this can be done after
# deserialize() by setting the metadata, but in the case of ExtruderStack, deserialize()
# also does addExtruder() to its machine stack, so we have to make sure that it's pointing
# to the right machine BEFORE deserialization.
extruder_config = configparser.ConfigParser()
extruder_config.read_string(extruder_file_content)
extruder_config.set("metadata", "machine", global_stack_id_new)
tmp_string_io = io.StringIO()
extruder_config.write(tmp_string_io)
extruder_file_content = tmp_string_io.getvalue()
stack.deserialize(extruder_file_content)
self._container_registry.addContainer(stack)
extruder_stacks_added.append(stack)
containers_added.append(stack)
else:
Logger.log("w", "Unknown resolve strategy: %s" % str(self._resolve_strategies["machine"]))
if global_stack_need_rename:
if stack.getMetaDataEntry("machine"):
stack.setMetaDataEntry("machine", global_stack_id_new)
extruder_stacks.append(stack)
except:
Logger.logException("w", "We failed to serialize the stack. Trying to clean up.")
@ -649,13 +722,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if self._resolve_strategies[changes_container_type] == "new":
# Quality changes needs to get a new ID, added to registry and to the right stacks
for each_changes_container in quality_and_definition_changes_instance_containers:
old_id = each_changes_container.getId()
each_changes_container.setName(self._container_registry.uniqueName(each_changes_container.getName()))
# We're not really supposed to change the ID in normal cases, but this is an exception.
each_changes_container._id = self.getNewId(each_changes_container.getId())
# The container was not added yet, as it didn't have an unique ID. It does now, so add it.
self._container_registry.addContainer(each_changes_container)
# NOTE: The renaming and giving new IDs are possibly redundant because they are done in the
# instance container loading part.
new_id = each_changes_container.getId()
# Find the old (current) changes container in the global stack
if changes_container_type == "quality_changes":
@ -672,7 +741,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# Replace the quality/definition changes container if it's in the GlobalStack
# NOTE: we can get an empty container here, but the IDs will not match,
# so this comparison is fine.
if old_container.getId() == old_id:
if self._id_mapping.get(old_container.getId()) == new_id:
if changes_container_type == "quality_changes":
global_stack.qualityChanges = each_changes_container
elif changes_container_type == "definition_changes":
@ -695,7 +764,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# NOTE: we can get an empty container here, but the IDs will not match,
# so this comparison is fine.
if changes_container.getId() == old_id:
if self._id_mapping.get(changes_container.getId()) == new_id:
if changes_container_type == "quality_changes":
each_extruder_stack.qualityChanges = each_changes_container
elif changes_container_type == "definition_changes":