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":

View file

@ -7,6 +7,7 @@ from cura.Settings.ExtruderManager import ExtruderManager
import zipfile
from io import StringIO
import copy
import configparser
class ThreeMFWorkspaceWriter(WorkspaceWriter):
@ -48,6 +49,16 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
Preferences.getInstance().writeToFile(preferences_string)
archive.writestr(preferences_file, preferences_string.getvalue())
# Save Cura version
version_file = zipfile.ZipInfo("Cura/version.ini")
version_config_parser = configparser.ConfigParser()
version_config_parser.add_section("versions")
version_config_parser.set("versions", "cura_version", Application.getStaticVersion())
version_file_string = StringIO()
version_config_parser.write(version_file_string)
archive.writestr(version_file, version_file_string.getvalue())
# Close the archive & reset states.
archive.close()
mesh_writer.setStoreArchive(False)

View file

@ -79,7 +79,7 @@ The initial and final printing temperatures reduce the amount of oozing during P
Initial and final printing temperature settings have been tuned for higher quality results. For all materials the initial print temperature is 5 degrees above the default value.
*Printing temperature of the materials
The printing temperature of the materials in the material profiles is now the same as the printing temperature for the Normal Quality profile.
The printing temperature of the materials in the material profiles is now the same as the printing temperature for the Fine profile.
*Improved PLA-PVA layer adhesion
The PVA jerk and acceleration have been optimized to improve the layer adhesion between PVA and PLA.

View file

@ -14,7 +14,7 @@ from UM.Settings.DefinitionContainer import DefinitionContainer
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Logger import Logger
from cura.Settings.CuraContainerRegistry import CuraContainerRegistry
from cura.CuraApplication import CuraApplication
from cura.Settings.ExtruderManager import ExtruderManager
import UM.i18n
@ -99,6 +99,7 @@ class MachineSettingsAction(MachineAction):
definition = container_stack.getBottom()
definition_changes_container.setDefinition(definition)
definition_changes_container.addMetaDataEntry("type", "definition_changes")
definition_changes_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
self._container_registry.addContainer(definition_changes_container)
container_stack.definitionChanges = definition_changes_container

View file

@ -341,7 +341,6 @@ Cura.MachineAction
sourceComponent: numericTextFieldWithUnit
property var propertyProvider: gantryHeightProvider
property string unit: catalog.i18nc("@label", "mm")
property bool forceUpdateOnChange: false
}
Item { width: UM.Theme.getSize("default_margin").width; height: UM.Theme.getSize("default_margin").height }
@ -385,7 +384,6 @@ Cura.MachineAction
sourceComponent: numericTextFieldWithUnit
property var propertyProvider: materialDiameterProvider
property string unit: catalog.i18nc("@label", "mm")
property bool forceUpdateOnChange: false
}
Label
{
@ -399,7 +397,6 @@ Cura.MachineAction
sourceComponent: numericTextFieldWithUnit
property var propertyProvider: machineNozzleSizeProvider
property string unit: catalog.i18nc("@label", "mm")
property bool forceUpdateOnChange: false
}
}
}
@ -550,7 +547,6 @@ Cura.MachineAction
sourceComponent: numericTextFieldWithUnit
property var propertyProvider: extruderNozzleSizeProvider
property string unit: catalog.i18nc("@label", "mm")
property bool forceUpdateOnChange: false
}
Label
@ -564,6 +560,7 @@ Cura.MachineAction
property var propertyProvider: extruderOffsetXProvider
property string unit: catalog.i18nc("@label", "mm")
property bool forceUpdateOnChange: true
property bool allowNegative: true
}
Label
{
@ -576,6 +573,7 @@ Cura.MachineAction
property var propertyProvider: extruderOffsetYProvider
property string unit: catalog.i18nc("@label", "mm")
property bool forceUpdateOnChange: true
property bool allowNegative: true
}
}
@ -655,17 +653,21 @@ Cura.MachineAction
Item {
height: textField.height
width: textField.width
property bool _allowNegative: (typeof(allowNegative) === 'undefined') ? false : allowNegative
property bool _forceUpdateOnChange: (typeof(forceUpdateOnChange) === 'undefined') ? false: forceUpdateOnChange
TextField
{
id: textField
text: (propertyProvider.properties.value) ? propertyProvider.properties.value : ""
validator: RegExpValidator { regExp: /[0-9\.]{0,6}/ }
validator: RegExpValidator { regExp: _allowNegative ? /-?[0-9\.]{0,6}/ : /[0-9\.]{0,6}/ }
onEditingFinished:
{
if (propertyProvider && text != propertyProvider.properties.value)
{
propertyProvider.setPropertyValue("value", text);
if(forceUpdateOnChange)
if(_forceUpdateOnChange)
{
var extruderIndex = ExtruderManager.activeExtruderIndex;
manager.forceUpdate();

View file

@ -11,7 +11,7 @@ from UM.Application import Application
catalog = i18nCatalog("cura")
import UM.Settings.InstanceContainer
from cura.CuraApplication import CuraApplication
## The Ultimaker Original can have a few revisions & upgrades. This action helps with selecting them, so they are added
# as a variant.
@ -49,6 +49,7 @@ class UMOUpgradeSelection(MachineAction):
definition = global_container_stack.getBottom()
definition_changes_container.setDefinition(definition)
definition_changes_container.addMetaDataEntry("type", "definition_changes")
definition_changes_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
UM.Settings.ContainerRegistry.ContainerRegistry.getInstance().addContainer(definition_changes_container)
# Insert definition_changes between the definition and the variant

View file

@ -142,6 +142,16 @@ class VersionUpgrade22to24(VersionUpgrade):
config.write(output)
return [filename], [output.getvalue()]
def upgradeQuality(self, serialised, filename):
config = configparser.ConfigParser(interpolation = None)
config.read_string(serialised) # Read the input string as config file.
config.set("metadata", "type", "quality_changes") # Update metadata/type to quality_changes
config.set("general", "version", "2") # Just bump the version number. That is all we need for now.
output = io.StringIO()
config.write(output)
return [filename], [output.getvalue()]
def getCfgVersion(self, serialised):
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)

View file

@ -21,9 +21,9 @@ def getMetaData():
# From To Upgrade function
("machine_instance", 2000000): ("machine_stack", 3000000, upgrade.upgradeMachineInstance),
("extruder_train", 2000000): ("extruder_train", 3000000, upgrade.upgradeExtruderTrain),
("preferences", 3000000): ("preferences", 4000000, upgrade.upgradePreferences)
},
("preferences", 3000000): ("preferences", 4000000, upgrade.upgradePreferences),
("quality", 2000000): ("quality_changes", 2000000, upgrade.upgradeQuality),
},
"sources": {
"machine_stack": {
"get_version": upgrade.getCfgVersion,

View file

@ -5,6 +5,7 @@ import configparser #To parse the files we need to upgrade and write the new fil
import io #To serialise configparser output to a string.
from UM.VersionUpgrade import VersionUpgrade
from cura.CuraApplication import CuraApplication
_removed_settings = { #Settings that were removed in 2.5.
"start_layers_at_same_position",
@ -86,11 +87,17 @@ class VersionUpgrade25to26(VersionUpgrade):
parser["values"][replacement] = parser["values"][replaced_setting] #Copy to replacement before removing the original!
del replaced_setting
#Change the version number in the file.
if parser.has_section("general"):
parser["general"]["setting_version"] = "1"
for each_section in ("general", "metadata"):
if not parser.has_section(each_section):
parser.add_section(each_section)
# Change the version number in the file.
parser["metadata"]["setting_version"] = str(CuraApplication.SettingVersion)
# Update version
parser["general"]["version"] = "2"
#Re-serialise the file.
output = io.StringIO()
parser.write(output)
return [filename], [output.getvalue()]
return [filename], [output.getvalue()]

View file

@ -18,14 +18,16 @@ def getMetaData():
"api": 3
},
"version_upgrade": {
# From To Upgrade function
("preferences", 4000000): ("preferences", 4000001, upgrade.upgradePreferences),
("quality", 2000000): ("quality", 2000001, upgrade.upgradeInstanceContainer),
("variant", 2000000): ("variant", 2000001, upgrade.upgradeInstanceContainer), #We can re-use upgradeContainerStack since there is nothing specific to quality, variant or user profiles being changed.
("user", 2000000): ("user", 2000001, upgrade.upgradeInstanceContainer)
# From To Upgrade function
("preferences", 4000000): ("preferences", 4000001, upgrade.upgradePreferences),
# NOTE: All the instance containers share the same general/version, so we have to update all of them
# if any is updated.
("quality_changes", 2000000): ("quality_changes", 2000001, upgrade.upgradeInstanceContainer),
("user", 2000000): ("user", 2000001, upgrade.upgradeInstanceContainer),
("quality", 2000000): ("quality", 2000001, upgrade.upgradeInstanceContainer),
},
"sources": {
"quality": {
"quality_changes": {
"get_version": upgrade.getCfgVersion,
"location": {"./quality"}
},
@ -36,7 +38,7 @@ def getMetaData():
"user": {
"get_version": upgrade.getCfgVersion,
"location": {"./user"}
}
},
}
}

View file

@ -159,10 +159,10 @@ class XmlMaterialProfile(InstanceContainer):
for key, value in metadata.items():
builder.start(key)
# Normally value is a string.
# Nones get handled well.
if isinstance(value, bool):
value = str(value) # parseBool in deserialize expects 'True'.
if value is not None: #Nones get handled well by the builder.
#Otherwise the builder always expects a string.
#Deserialize expects the stringified version.
value = str(value)
builder.data(value)
builder.end(key)