Merge branch '3.1' of https://github.com/Ultimaker/Cura into 3.1

This commit is contained in:
Diego Prado Gesto 2017-11-23 15:42:02 +01:00
commit f0dca021d8
10 changed files with 159 additions and 33 deletions

View file

@ -152,7 +152,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if not definitions:
definition_container = DefinitionContainer(container_id)
definition_container.deserialize(archive.open(each_definition_container_file).read().decode("utf-8"))
definition_container.deserialize(archive.open(each_definition_container_file).read().decode("utf-8"),
file_name = each_definition_container_file)
else:
definition_container = definitions[0]
@ -208,7 +209,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
instance_container = InstanceContainer(container_id)
# Deserialize InstanceContainer by converting read data from bytes to string
instance_container.deserialize(archive.open(each_instance_container_file).read().decode("utf-8"))
instance_container.deserialize(archive.open(each_instance_container_file).read().decode("utf-8"),
file_name = each_instance_container_file)
instance_container_list.append(instance_container)
container_type = instance_container.getMetaDataEntry("type")
@ -378,7 +380,7 @@ 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_file_content):
def _overrideExtruderStack(self, global_stack, extruder_file_content, extruder_stack_file):
# Get extruder position first
extruder_config = configparser.ConfigParser()
extruder_config.read_string(extruder_file_content)
@ -394,7 +396,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
return None
# Override the given extruder stack
extruder_stack.deserialize(extruder_file_content)
extruder_stack.deserialize(extruder_file_content, file_name = extruder_stack_file)
# return the new ExtruderStack
return extruder_stack
@ -484,7 +486,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
definitions = self._container_registry.findDefinitionContainers(id = container_id)
if not definitions:
definition_container = DefinitionContainer(container_id)
definition_container.deserialize(archive.open(definition_container_file).read().decode("utf-8"))
definition_container.deserialize(archive.open(definition_container_file).read().decode("utf-8"),
file_name = definition_container_file)
self._container_registry.addContainer(definition_container)
Job.yieldThread()
@ -502,18 +505,21 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if not materials:
material_container = xml_material_profile(container_id)
material_container.deserialize(archive.open(material_container_file).read().decode("utf-8"))
material_container.deserialize(archive.open(material_container_file).read().decode("utf-8"),
file_name = material_container_file)
containers_to_add.append(material_container)
else:
material_container = materials[0]
if not material_container.isReadOnly(): # Only create new materials if they are not read only.
if self._resolve_strategies["material"] == "override":
material_container.deserialize(archive.open(material_container_file).read().decode("utf-8"))
material_container.deserialize(archive.open(material_container_file).read().decode("utf-8"),
file_name = material_container_file)
elif self._resolve_strategies["material"] == "new":
# Note that we *must* deserialize it with a new ID, as multiple containers will be
# auto created & added.
material_container = xml_material_profile(self.getNewId(container_id))
material_container.deserialize(archive.open(material_container_file).read().decode("utf-8"))
material_container.deserialize(archive.open(material_container_file).read().decode("utf-8"),
file_name = material_container_file)
containers_to_add.append(material_container)
material_containers.append(material_container)
@ -540,7 +546,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
instance_container = InstanceContainer(container_id)
# Deserialize InstanceContainer by converting read data from bytes to string
instance_container.deserialize(serialized)
instance_container.deserialize(serialized, file_name = instance_container_file)
container_type = instance_container.getMetaDataEntry("type")
Job.yieldThread()
@ -562,7 +568,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
else:
if self._resolve_strategies["machine"] == "override" or self._resolve_strategies["machine"] is None:
instance_container = user_containers[0]
instance_container.deserialize(archive.open(instance_container_file).read().decode("utf-8"))
instance_container.deserialize(archive.open(instance_container_file).read().decode("utf-8"),
file_name = instance_container_file)
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.
@ -595,7 +602,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# 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.deserialize(archive.open(instance_container_file).read().decode("utf-8"),
file_name = instance_container_file)
instance_container.setDirty(True)
elif self._resolve_strategies[container_type] == "new":
@ -656,7 +664,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# There is a machine, check if it has authentication data. If so, keep that data.
network_authentication_id = container_stacks[0].getMetaDataEntry("network_authentication_id")
network_authentication_key = container_stacks[0].getMetaDataEntry("network_authentication_key")
container_stacks[0].deserialize(archive.open(global_stack_file).read().decode("utf-8"))
container_stacks[0].deserialize(archive.open(global_stack_file).read().decode("utf-8"),
file_name = global_stack_file)
if network_authentication_id:
container_stacks[0].addMetaDataEntry("network_authentication_id", network_authentication_id)
if network_authentication_key:
@ -666,7 +675,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# create a new global stack
stack = GlobalStack(global_stack_id_new)
# Deserialize stack by converting read data from bytes to string
stack.deserialize(archive.open(global_stack_file).read().decode("utf-8"))
stack.deserialize(archive.open(global_stack_file).read().decode("utf-8"),
file_name = global_stack_file)
# Ensure a unique ID and name
stack._id = global_stack_id_new
@ -706,7 +716,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if self._resolve_strategies["machine"] == "override":
if global_stack.getProperty("machine_extruder_count", "value") > 1:
# deserialize new extruder stack over the current ones (if any)
stack = self._overrideExtruderStack(global_stack, extruder_file_content)
stack = self._overrideExtruderStack(global_stack, extruder_file_content, extruder_stack_file)
if stack is None:
continue
@ -726,7 +736,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
extruder_config.write(tmp_string_io)
extruder_file_content = tmp_string_io.getvalue()
stack.deserialize(extruder_file_content)
stack.deserialize(extruder_file_content, file_name = extruder_stack_file)
# Ensure a unique ID and name
stack._id = new_id
@ -780,6 +790,36 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
for stack in [global_stack] + extruder_stacks:
stack.replaceContainer(_ContainerIndexes.Quality, empty_quality_container)
# Fix quality:
# The quality specified in an old project file can be wrong, for example, for UM2, it should be "um2_normal"
# but instead it was "normal". This should be fixed by setting it to the correct quality.
# Note that this only seems to happen on single-extrusion machines on the global stack, so we only apply the
# fix for that
quality = global_stack.quality
if quality.getId() not in ("empty", "empty_quality"):
quality_type = quality.getMetaDataEntry("quality_type")
quality_containers = self._container_registry.findInstanceContainers(definition = global_stack.definition.getId(),
type = "quality",
quality_type = quality_type)
if quality_containers:
global_stack.quality = quality_containers[0]
else:
# the quality_type of the quality profile cannot be found.
# this can happen if a quality_type has been removed in a newer version, for example:
# "extra_coarse" is removed from 2.7 to 3.0
# in this case, the quality will be reset to "normal"
quality_containers = self._container_registry.findInstanceContainers(
definition = global_stack.definition.getId(),
type = "quality",
quality_type = "normal")
if quality_containers:
global_stack.quality = quality_containers[0]
else:
# This should not happen!
Logger.log("e", "Cannot find quality normal for global stack [%s] [%s]",
global_stack.getId(), global_stack.definition.getId())
global_stack.quality = self._container_registry.findInstanceContainers(id = "empty_quality")
# Replacing the old containers if resolve is "new".
# When resolve is "new", some containers will get renamed, so all the other containers that reference to those
# MUST get updated too.

View file

@ -116,7 +116,10 @@ class VersionUpgrade30to31(VersionUpgrade):
all_quality_changes = self._getSingleExtrusionMachineQualityChanges(parser)
# Note that DO NOT!!! use the quality_changes returned from _getSingleExtrusionMachineQualityChanges().
# Those are loaded from the hard drive which are original files that haven't been upgraded yet.
if len(all_quality_changes) == 1 and not parser.has_option("metadata", "extruder"):
# NOTE 2: The number can be 0 or 1 depends on whether you are loading it from the qualities folder or
# from a project file. When you load from a project file, the custom profile may not be in cura
# yet, so you will get 0.
if len(all_quality_changes) <= 1 and not parser.has_option("metadata", "extruder"):
self._createExtruderQualityChangesForSingleExtrusionMachine(filename, parser)
# Update version numbers
@ -199,7 +202,7 @@ class VersionUpgrade30to31(VersionUpgrade):
def _createExtruderQualityChangesForSingleExtrusionMachine(self, filename, global_quality_changes):
suffix = "_" + quote_plus(global_quality_changes["general"]["name"].lower())
machine_name = filename.strip("." + os.sep).replace(suffix, "")
machine_name = os.path.os.path.basename(filename).replace(".inst.cfg", "").replace(suffix, "")
new_filename = machine_name + "_" + "fdmextruder" + suffix
extruder_quality_changes_parser = configparser.ConfigParser()

View file

@ -422,11 +422,11 @@ class XmlMaterialProfile(InstanceContainer):
return version * 1000000 + setting_version
## Overridden from InstanceContainer
def deserialize(self, serialized):
def deserialize(self, serialized, file_name = None):
containers_to_add = []
# update the serialized data first
from UM.Settings.Interfaces import ContainerInterface
serialized = ContainerInterface.deserialize(self, serialized)
serialized = ContainerInterface.deserialize(self, serialized, file_name)
try:
data = ET.fromstring(serialized)