diff --git a/.gitignore b/.gitignore
index bb6bd49add..1db07180c0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,6 +11,10 @@ resources/firmware
resources/materials
LC_MESSAGES
.cache
+*.qmlc
+
+#MacOS
+.DS_Store
# Editors and IDEs.
*kdev*
@@ -37,6 +41,7 @@ plugins/X3GWriter
plugins/FlatProfileExporter
plugins/ProfileFlattener
plugins/cura-god-mode-plugin
+plugins/cura-big-flame-graph
#Build stuff
CMakeCache.txt
diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py
index 7a42acd376..7e047cae0a 100755
--- a/cura/CuraApplication.py
+++ b/cura/CuraApplication.py
@@ -294,6 +294,7 @@ class CuraApplication(QtApplication):
z_seam_y
infill
infill_sparse_density
+ gradual_infill_steps
material
material_print_temperature
material_bed_temperature
@@ -331,6 +332,7 @@ class CuraApplication(QtApplication):
blackmagic
print_sequence
infill_mesh
+ cutting_mesh
experimental
""".replace("\n", ";").replace(" ", ""))
diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py
index ab63e4034d..c6412e2f6f 100644
--- a/cura/PrintInformation.py
+++ b/cura/PrintInformation.py
@@ -52,6 +52,19 @@ class PrintInformation(QObject):
super().__init__(parent)
self._current_print_time = Duration(None, self)
+ self._print_times_per_feature = {
+ "none": Duration(None, self),
+ "inset_0": Duration(None, self),
+ "inset_x": Duration(None, self),
+ "skin": Duration(None, self),
+ "support": Duration(None, self),
+ "skirt": Duration(None, self),
+ "infill": Duration(None, self),
+ "support_infill": Duration(None, self),
+ "travel": Duration(None, self),
+ "retract": Duration(None, self),
+ "support_interface": Duration(None, self)
+ }
self._material_lengths = []
self._material_weights = []
@@ -93,6 +106,10 @@ class PrintInformation(QObject):
def currentPrintTime(self):
return self._current_print_time
+ @pyqtProperty("QVariantMap", notify = currentPrintTimeChanged)
+ def printTimesPerFeature(self):
+ return self._print_times_per_feature
+
materialLengthsChanged = pyqtSignal()
@pyqtProperty("QVariantList", notify = materialLengthsChanged)
@@ -111,12 +128,16 @@ class PrintInformation(QObject):
def materialCosts(self):
return self._material_costs
- def _onPrintDurationMessage(self, total_time, material_amounts):
- if total_time != total_time: # Check for NaN. Engine can sometimes give us weird values.
- Logger.log("w", "Received NaN for print duration message")
- self._current_print_time.setDuration(0)
- else:
- self._current_print_time.setDuration(total_time)
+ def _onPrintDurationMessage(self, time_per_feature, material_amounts):
+ total_time = 0
+ for feature, time in time_per_feature.items():
+ if time != time: # Check for NaN. Engine can sometimes give us weird values.
+ self._print_times_per_feature[feature].setDuration(0)
+ Logger.log("w", "Received NaN for print duration message")
+ continue
+ total_time += time
+ self._print_times_per_feature[feature].setDuration(time)
+ self._current_print_time.setDuration(total_time)
self.currentPrintTimeChanged.emit()
diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py
index 72b94a6f8d..a4dbcc4ca1 100644
--- a/cura/Settings/CuraContainerRegistry.py
+++ b/cura/Settings/CuraContainerRegistry.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2016 Ultimaker B.V.
+# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
import os
@@ -41,6 +41,14 @@ class CuraContainerRegistry(ContainerRegistry):
if type(container) == ContainerStack:
container = self._convertContainerStack(container)
+ if isinstance(container, InstanceContainer) and type(container) != type(self.getEmptyInstanceContainer()):
+ #Check against setting version of the definition.
+ required_setting_version = int(container.getDefinition().getMetaDataEntry("setting_version"))
+ actual_setting_version = int(container.getMetaDataEntry("setting_version", default = 0))
+ if required_setting_version != actual_setting_version:
+ Logger.log("w", "Instance container {container_id} is outdated. Its setting version is {actual_setting_version} but it should be {required_setting_version}.".format(container_id = container.getId(), actual_setting_version = actual_setting_version, required_setting_version = required_setting_version))
+ return #Don't add.
+
super().addContainer(container)
## Create a name that is not empty and unique
diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py
index 6f475a5ff9..d14f2d04c9 100755
--- a/cura/Settings/CuraContainerStack.py
+++ b/cura/Settings/CuraContainerStack.py
@@ -5,7 +5,8 @@ import os.path
from typing import Any, Optional
-from PyQt5.QtCore import pyqtProperty, pyqtSlot, pyqtSignal
+from PyQt5.QtCore import pyqtProperty, pyqtSignal
+from UM.FlameProfiler import pyqtSlot
from UM.Decorators import override
from UM.Logger import Logger
@@ -65,8 +66,8 @@ class CuraContainerStack(ContainerStack):
## Set the quality changes container.
#
# \param new_quality_changes The new quality changes container. It is expected to have a "type" metadata entry with the value "quality_changes".
- def setQualityChanges(self, new_quality_changes: InstanceContainer) -> None:
- self.replaceContainer(_ContainerIndexes.QualityChanges, new_quality_changes)
+ def setQualityChanges(self, new_quality_changes: InstanceContainer, postpone_emit = False) -> None:
+ self.replaceContainer(_ContainerIndexes.QualityChanges, new_quality_changes, postpone_emit = postpone_emit)
## Set the quality changes container by an ID.
#
@@ -92,8 +93,8 @@ class CuraContainerStack(ContainerStack):
## Set the quality container.
#
# \param new_quality The new quality container. It is expected to have a "type" metadata entry with the value "quality".
- def setQuality(self, new_quality: InstanceContainer) -> None:
- self.replaceContainer(_ContainerIndexes.Quality, new_quality)
+ def setQuality(self, new_quality: InstanceContainer, postpone_emit = False) -> None:
+ self.replaceContainer(_ContainerIndexes.Quality, new_quality, postpone_emit = postpone_emit)
## Set the quality container by an ID.
#
@@ -130,8 +131,8 @@ class CuraContainerStack(ContainerStack):
## Set the material container.
#
# \param new_quality_changes The new material container. It is expected to have a "type" metadata entry with the value "quality_changes".
- def setMaterial(self, new_material: InstanceContainer) -> None:
- self.replaceContainer(_ContainerIndexes.Material, new_material)
+ def setMaterial(self, new_material: InstanceContainer, postpone_emit = False) -> None:
+ self.replaceContainer(_ContainerIndexes.Material, new_material, postpone_emit = postpone_emit)
## Set the material container by an ID.
#
@@ -253,6 +254,14 @@ class CuraContainerStack(ContainerStack):
def definition(self) -> DefinitionContainer:
return self._containers[_ContainerIndexes.Definition]
+ @override(ContainerStack)
+ def getBottom(self) -> "DefinitionContainer":
+ return self.definition
+
+ @override(ContainerStack)
+ def getTop(self) -> "InstanceContainer":
+ return self.userChanges
+
## Check whether the specified setting has a 'user' value.
#
# A user value here is defined as the setting having a value in either
diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py
index 359cd74f09..5a2e0cb818 100755
--- a/cura/Settings/ExtruderManager.py
+++ b/cura/Settings/ExtruderManager.py
@@ -16,7 +16,11 @@ from UM.Settings.InstanceContainer import InstanceContainer
from UM.Settings.SettingFunction import SettingFunction
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.DefinitionContainer import DefinitionContainer
-from typing import Optional, List
+from typing import Optional, List, TYPE_CHECKING, Union
+
+if TYPE_CHECKING:
+ from cura.Settings.ExtruderStack import ExtruderStack
+
## Manages all existing extruder stacks.
#
@@ -166,7 +170,7 @@ class ExtruderManager(QObject):
self._selected_object_extruders = []
self.selectedObjectExtrudersChanged.emit()
- def getActiveExtruderStack(self) -> ContainerStack:
+ def getActiveExtruderStack(self) -> Optional["ExtruderStack"]:
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
@@ -176,7 +180,7 @@ class ExtruderManager(QObject):
return None
## Get an extruder stack by index
- def getExtruderStack(self, index):
+ def getExtruderStack(self, index) -> Optional["ExtruderStack"]:
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
if global_container_stack.getId() in self._extruder_trains:
@@ -185,7 +189,7 @@ class ExtruderManager(QObject):
return None
## Get all extruder stacks
- def getExtruderStacks(self):
+ def getExtruderStacks(self) -> List["ExtruderStack"]:
result = []
for i in range(self.extruderCount):
result.append(self.getExtruderStack(i))
@@ -397,7 +401,7 @@ class ExtruderManager(QObject):
# list.
#
# \return A list of extruder stacks.
- def getUsedExtruderStacks(self):
+ def getUsedExtruderStacks(self) -> List["ContainerStack"]:
global_stack = Application.getInstance().getGlobalContainerStack()
container_registry = ContainerRegistry.getInstance()
@@ -451,7 +455,7 @@ class ExtruderManager(QObject):
## Removes the container stack and user profile for the extruders for a specific machine.
#
# \param machine_id The machine to remove the extruders for.
- def removeMachineExtruders(self, machine_id):
+ def removeMachineExtruders(self, machine_id: str):
for extruder in self.getMachineExtruders(machine_id):
containers = ContainerRegistry.getInstance().findInstanceContainers(type = "user", extruder = extruder.getId())
for container in containers:
@@ -461,7 +465,7 @@ class ExtruderManager(QObject):
## Returns extruders for a specific machine.
#
# \param machine_id The machine to get the extruders of.
- def getMachineExtruders(self, machine_id):
+ def getMachineExtruders(self, machine_id: str):
if machine_id not in self._extruder_trains:
return []
return [self._extruder_trains[machine_id][name] for name in self._extruder_trains[machine_id]]
@@ -470,7 +474,7 @@ class ExtruderManager(QObject):
#
# The first element is the global container stack, followed by any extruder stacks.
# \return \type{List[ContainerStack]}
- def getActiveGlobalAndExtruderStacks(self):
+ def getActiveGlobalAndExtruderStacks(self) -> Optional[List[Union["ExtruderStack", "GlobalStack"]]]:
global_stack = Application.getInstance().getGlobalContainerStack()
if not global_stack:
return None
@@ -482,7 +486,7 @@ class ExtruderManager(QObject):
## Returns the list of active extruder stacks.
#
# \return \type{List[ContainerStack]} a list of
- def getActiveExtruderStacks(self):
+ def getActiveExtruderStacks(self) -> List["ExtruderStack"]:
global_stack = Application.getInstance().getGlobalContainerStack()
result = []
diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py
index 74680bb293..7491f8aa93 100644
--- a/cura/Settings/ExtrudersModel.py
+++ b/cura/Settings/ExtrudersModel.py
@@ -1,11 +1,11 @@
# Copyright (c) 2016 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
-from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty, pyqtSlot
+from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty, QTimer
import UM.Qt.ListModel
from UM.Application import Application
-
+import UM.FlameProfiler
from cura.Settings.ExtruderManager import ExtruderManager
## Model that holds extruders.
@@ -58,6 +58,11 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
self.addRoleName(self.MaterialRole, "material")
self.addRoleName(self.VariantRole, "variant")
+ self._update_extruder_timer = QTimer()
+ self._update_extruder_timer.setInterval(100)
+ self._update_extruder_timer.setSingleShot(True)
+ self._update_extruder_timer.timeout.connect(self.__updateExtruders)
+
self._add_global = False
self._simple_names = False
@@ -111,28 +116,33 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
active_extruder_stack.containersChanged.connect(self._onExtruderStackContainersChanged)
self._active_extruder_stack = active_extruder_stack
-
def _onExtruderStackContainersChanged(self, container):
- # The ExtrudersModel needs to be updated when the material-name or -color changes, because the user identifies extruders by material-name
- self._updateExtruders()
+ # Update when there is an empty container or material change
+ if container.getMetaDataEntry("type") == "material" or container.getMetaDataEntry("type") is None:
+ # The ExtrudersModel needs to be updated when the material-name or -color changes, because the user identifies extruders by material-name
+ self._updateExtruders()
+
modelChanged = pyqtSignal()
+ def _updateExtruders(self):
+ self._update_extruder_timer.start()
+
## Update the list of extruders.
#
# This should be called whenever the list of extruders changes.
- def _updateExtruders(self):
+ @UM.FlameProfiler.profile
+ def __updateExtruders(self):
changed = False
if self.rowCount() != 0:
changed = True
items = []
-
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
if self._add_global:
- material = global_container_stack.findContainer({ "type": "material" })
+ material = global_container_stack.material
color = material.getMetaDataEntry("color_code", default = self.defaultColors[0]) if material else self.defaultColors[0]
item = {
"id": global_container_stack.getId(),
@@ -147,9 +157,6 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
machine_extruder_count = global_container_stack.getProperty("machine_extruder_count", "value")
manager = ExtruderManager.getInstance()
for extruder in manager.getMachineExtruders(global_container_stack.getId()):
- extruder_name = extruder.getName()
- material = extruder.findContainer({ "type": "material" })
- variant = extruder.findContainer({"type": "variant"})
position = extruder.getMetaDataEntry("position", default = "0") # Get the position
try:
position = int(position)
@@ -157,6 +164,9 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
position = -1
if position >= machine_extruder_count:
continue
+ extruder_name = extruder.getName()
+ material = extruder.material
+ variant = extruder.variant
default_color = self.defaultColors[position] if position >= 0 and position < len(self.defaultColors) else self.defaultColors[0]
color = material.getMetaDataEntry("color_code", default = default_color) if material else default_color
diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py
index 2e44a60deb..0eafd33e94 100755
--- a/cura/Settings/MachineManager.py
+++ b/cura/Settings/MachineManager.py
@@ -11,21 +11,18 @@ from UM.Application import Application
from UM.Preferences import Preferences
from UM.Logger import Logger
from UM.Message import Message
-from UM.Decorators import deprecated
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.InstanceContainer import InstanceContainer
-from UM.Settings.SettingDefinition import SettingDefinition
from UM.Settings.SettingFunction import SettingFunction
-from UM.Settings.Validator import ValidatorState
from UM.Signal import postponeSignals
+import UM.FlameProfiler
from cura.QualityManager import QualityManager
from cura.PrinterOutputDevice import PrinterOutputDevice
from cura.Settings.ExtruderManager import ExtruderManager
-from .GlobalStack import GlobalStack
from .CuraStackBuilder import CuraStackBuilder
from UM.i18n import i18nCatalog
@@ -35,15 +32,28 @@ from typing import TYPE_CHECKING, Optional
if TYPE_CHECKING:
from UM.Settings.DefinitionContainer import DefinitionContainer
+ from cura.Settings.CuraContainerStack import CuraContainerStack
+ from cura.Settings.GlobalStack import GlobalStack
import os
+
class MachineManager(QObject):
def __init__(self, parent = None):
super().__init__(parent)
- self._active_container_stack = None # type: ContainerStack
- self._global_container_stack = None # type: ContainerStack
+ self._active_container_stack = None # type: CuraContainerStack
+ self._global_container_stack = None # type: GlobalStack
+
+ self._error_check_timer = QTimer()
+ self._error_check_timer.setInterval(250)
+ self._error_check_timer.setSingleShot(True)
+ self._error_check_timer.timeout.connect(self._updateStacksHaveErrors)
+
+ self._instance_container_timer = QTimer()
+ self._instance_container_timer.setInterval(250)
+ self._instance_container_timer.setSingleShot(True)
+ self._instance_container_timer.timeout.connect(self.__onInstanceContainersChanged)
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
## When the global container is changed, active material probably needs to be updated.
@@ -94,11 +104,6 @@ class MachineManager(QObject):
self._material_incompatible_message = Message(catalog.i18nc("@info:status",
"The selected material is incompatible with the selected machine or configuration."))
- self._error_check_timer = QTimer()
- self._error_check_timer.setInterval(250)
- self._error_check_timer.setSingleShot(True)
- self._error_check_timer.timeout.connect(self._updateStacksHaveErrors)
-
globalContainerChanged = pyqtSignal() # Emitted whenever the global stack is changed (ie: when changing between printers, changing a global profile, but not when changing a value)
activeMaterialChanged = pyqtSignal()
activeVariantChanged = pyqtSignal()
@@ -134,7 +139,7 @@ class MachineManager(QObject):
return self._printer_output_devices
@pyqtProperty(int, constant=True)
- def totalNumberOfSettings(self):
+ def totalNumberOfSettings(self) -> int:
return len(ContainerRegistry.getInstance().findDefinitionContainers(id="fdmprinter")[0].getAllKeys())
def _onHotendIdChanged(self, index: Union[str, int], hotend_id: str) -> None:
@@ -158,7 +163,7 @@ class MachineManager(QObject):
else:
Logger.log("w", "No variant found for printer definition %s with id %s" % (self._global_container_stack.getBottom().getId(), hotend_id))
- def _onMaterialIdChanged(self, index, material_id):
+ def _onMaterialIdChanged(self, index: Union[str, int], material_id: str):
if not self._global_container_stack:
return
@@ -290,8 +295,7 @@ class MachineManager(QObject):
quality = self._global_container_stack.quality
quality.nameChanged.connect(self._onQualityNameChanged)
-
- self._updateStacksHaveErrors()
+ self._error_check_timer.start()
## Update self._stacks_valid according to _checkStacksForErrors and emit if change.
def _updateStacksHaveErrors(self):
@@ -308,23 +312,23 @@ class MachineManager(QObject):
if not self._active_container_stack:
self._active_container_stack = self._global_container_stack
- self._updateStacksHaveErrors()
+ self._error_check_timer.start()
if old_active_container_stack != self._active_container_stack:
# Many methods and properties related to the active quality actually depend
# on _active_container_stack. If it changes, then the properties change.
self.activeQualityChanged.emit()
- def _onInstanceContainersChanged(self, container):
- container_type = container.getMetaDataEntry("type")
-
+ def __onInstanceContainersChanged(self):
+ self.activeQualityChanged.emit()
self.activeVariantChanged.emit()
self.activeMaterialChanged.emit()
- self.activeQualityChanged.emit()
+ self._error_check_timer.start()
- self._updateStacksHaveErrors()
+ def _onInstanceContainersChanged(self, container):
+ self._instance_container_timer.start()
- def _onPropertyChanged(self, key, property_name):
+ def _onPropertyChanged(self, key: str, property_name: str):
if property_name == "value":
# Notify UI items, such as the "changed" star in profile pull down menu.
self.activeStackValueChanged.emit()
@@ -408,7 +412,7 @@ class MachineManager(QObject):
## Delete a user setting from the global stack and all extruder stacks.
# \param key \type{str} the name of the key to delete
@pyqtSlot(str)
- def clearUserSettingAllCurrentStacks(self, key):
+ def clearUserSettingAllCurrentStacks(self, key: str):
if not self._global_container_stack:
return
@@ -465,7 +469,7 @@ class MachineManager(QObject):
return ""
@pyqtProperty("QObject", notify = globalContainerChanged)
- def activeMachine(self) -> GlobalStack:
+ def activeMachine(self) -> "GlobalStack":
return self._global_container_stack
@pyqtProperty(str, notify = activeStackChanged)
@@ -564,7 +568,7 @@ class MachineManager(QObject):
# \return The layer height of the currently active quality profile. If
# there is no quality profile, this returns 0.
@pyqtProperty(float, notify=activeQualityChanged)
- def activeQualityLayerHeight(self):
+ def activeQualityLayerHeight(self) -> float:
if not self._global_container_stack:
return 0
@@ -581,7 +585,7 @@ class MachineManager(QObject):
value = value(self._global_container_stack)
return value
- return 0 #No quality profile.
+ return 0 # No quality profile.
## Get the Material ID associated with the currently active material
# \returns MaterialID (string) if found, empty string otherwise
@@ -603,7 +607,7 @@ class MachineManager(QObject):
return ""
@pyqtProperty(str, notify=activeQualityChanged)
- def activeQualityName(self):
+ def activeQualityName(self) -> str:
if self._active_container_stack and self._global_container_stack:
quality = self._global_container_stack.qualityChanges
if quality and not isinstance(quality, type(self._empty_quality_changes_container)):
@@ -614,7 +618,7 @@ class MachineManager(QObject):
return ""
@pyqtProperty(str, notify=activeQualityChanged)
- def activeQualityId(self):
+ def activeQualityId(self) -> str:
if self._active_container_stack:
quality = self._active_container_stack.qualityChanges
if quality and not isinstance(quality, type(self._empty_quality_changes_container)):
@@ -625,7 +629,7 @@ class MachineManager(QObject):
return ""
@pyqtProperty(str, notify=activeQualityChanged)
- def globalQualityId(self):
+ def globalQualityId(self) -> str:
if self._global_container_stack:
quality = self._global_container_stack.qualityChanges
if quality and not isinstance(quality, type(self._empty_quality_changes_container)):
@@ -636,7 +640,7 @@ class MachineManager(QObject):
return ""
@pyqtProperty(str, notify = activeQualityChanged)
- def activeQualityType(self):
+ def activeQualityType(self) -> str:
if self._active_container_stack:
quality = self._active_container_stack.quality
if quality:
@@ -644,7 +648,7 @@ class MachineManager(QObject):
return ""
@pyqtProperty(bool, notify = activeQualityChanged)
- def isActiveQualitySupported(self):
+ def isActiveQualitySupported(self) -> bool:
if self._active_container_stack:
quality = self._active_container_stack.quality
if quality:
@@ -658,7 +662,7 @@ class MachineManager(QObject):
# \todo Ideally, this method would be named activeQualityId(), and the other one
# would be named something like activeQualityOrQualityChanges() for consistency
@pyqtProperty(str, notify = activeQualityChanged)
- def activeQualityContainerId(self):
+ def activeQualityContainerId(self) -> str:
# We're using the active stack instead of the global stack in case the list of qualities differs per extruder
if self._global_container_stack:
quality = self._active_container_stack.quality
@@ -667,7 +671,7 @@ class MachineManager(QObject):
return ""
@pyqtProperty(str, notify = activeQualityChanged)
- def activeQualityChangesId(self):
+ def activeQualityChangesId(self) -> str:
if self._active_container_stack:
changes = self._active_container_stack.qualityChanges
if changes and changes.getId() != "empty":
@@ -676,7 +680,7 @@ class MachineManager(QObject):
## Check if a container is read_only
@pyqtSlot(str, result = bool)
- def isReadOnly(self, container_id) -> bool:
+ def isReadOnly(self, container_id: str) -> bool:
containers = ContainerRegistry.getInstance().findInstanceContainers(id = container_id)
if not containers or not self._active_container_stack:
return True
@@ -684,7 +688,7 @@ class MachineManager(QObject):
## Copy the value of the setting of the current extruder to all other extruders as well as the global container.
@pyqtSlot(str)
- def copyValueToExtruders(self, key):
+ def copyValueToExtruders(self, key: str):
if not self._active_container_stack or self._global_container_stack.getProperty("machine_extruder_count", "value") <= 1:
return
@@ -698,7 +702,7 @@ class MachineManager(QObject):
## Set the active material by switching out a container
# Depending on from/to material+current variant, a quality profile is chosen and set.
@pyqtSlot(str)
- def setActiveMaterial(self, material_id):
+ def setActiveMaterial(self, material_id: str):
with postponeSignals(*self._getContainerChangedSignals(), compress = True):
containers = ContainerRegistry.getInstance().findInstanceContainers(id = material_id)
if not containers or not self._active_container_stack:
@@ -714,7 +718,7 @@ class MachineManager(QObject):
Logger.log("w", "While trying to set the active material, no material was found to replace it.")
return
- if old_quality_changes and old_quality_changes.getId() == "empty_quality_changes":
+ if old_quality_changes and isinstance(old_quality_changes, type(self._empty_quality_changes_container)):
old_quality_changes = None
self.blurSettings.emit()
@@ -747,7 +751,7 @@ class MachineManager(QObject):
candidate_quality = quality_manager.findQualityByQualityType(quality_type,
quality_manager.getWholeMachineDefinition(machine_definition),
[material_container])
- if not candidate_quality or candidate_quality.getId() == "empty_quality":
+ if not candidate_quality or isinstance(candidate_quality, type(self._empty_quality_changes_container)):
# Fall back to a quality (which must be compatible with all other extruders)
new_qualities = quality_manager.findAllUsableQualitiesForMachineAndExtruders(
self._global_container_stack, ExtruderManager.getInstance().getExtruderStacks())
@@ -763,7 +767,7 @@ class MachineManager(QObject):
self.setActiveQuality(new_quality_id)
@pyqtSlot(str)
- def setActiveVariant(self, variant_id):
+ def setActiveVariant(self, variant_id: str):
with postponeSignals(*self._getContainerChangedSignals(), compress = True):
containers = ContainerRegistry.getInstance().findInstanceContainers(id = variant_id)
if not containers or not self._active_container_stack:
@@ -786,7 +790,7 @@ class MachineManager(QObject):
## set the active quality
# \param quality_id The quality_id of either a quality or a quality_changes
@pyqtSlot(str)
- def setActiveQuality(self, quality_id):
+ def setActiveQuality(self, quality_id: str):
with postponeSignals(*self._getContainerChangedSignals(), compress = True):
self.blurSettings.emit()
@@ -823,8 +827,8 @@ class MachineManager(QObject):
name_changed_connect_stacks.append(stack_quality)
name_changed_connect_stacks.append(stack_quality_changes)
- self._replaceQualityOrQualityChangesInStack(stack, stack_quality)
- self._replaceQualityOrQualityChangesInStack(stack, stack_quality_changes)
+ self._replaceQualityOrQualityChangesInStack(stack, stack_quality, postpone_emit=True)
+ self._replaceQualityOrQualityChangesInStack(stack, stack_quality_changes, postpone_emit=True)
# Send emits that are postponed in replaceContainer.
# Here the stacks are finished replacing and every value can be resolved based on the current state.
@@ -844,7 +848,8 @@ class MachineManager(QObject):
#
# \param quality_name \type{str} the name of the quality.
# \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes".
- def determineQualityAndQualityChangesForQualityType(self, quality_type):
+ @UM.FlameProfiler.profile
+ def determineQualityAndQualityChangesForQualityType(self, quality_type: str):
quality_manager = QualityManager.getInstance()
result = []
empty_quality_changes = self._empty_quality_changes_container
@@ -881,7 +886,7 @@ class MachineManager(QObject):
#
# \param quality_changes_name \type{str} the name of the quality changes.
# \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes".
- def _determineQualityAndQualityChangesForQualityChanges(self, quality_changes_name):
+ def _determineQualityAndQualityChangesForQualityChanges(self, quality_changes_name: str):
result = []
quality_manager = QualityManager.getInstance()
@@ -937,18 +942,18 @@ class MachineManager(QObject):
return result
- def _replaceQualityOrQualityChangesInStack(self, stack, container, postpone_emit = False):
+ def _replaceQualityOrQualityChangesInStack(self, stack: "CuraContainerStack", container: "InstanceContainer", postpone_emit = False):
# Disconnect the signal handling from the old container.
container_type = container.getMetaDataEntry("type")
if container_type == "quality":
stack.quality.nameChanged.disconnect(self._onQualityNameChanged)
- stack.setQuality(container)
+ stack.setQuality(container, postpone_emit = postpone_emit)
stack.qualityChanges.nameChanged.connect(self._onQualityNameChanged)
elif container_type == "quality_changes" or container_type is None:
# If the container is an empty container, we need to change the quality_changes.
# Quality can never be set to empty.
stack.qualityChanges.nameChanged.disconnect(self._onQualityNameChanged)
- stack.setQualityChanges(container)
+ stack.setQualityChanges(container, postpone_emit = postpone_emit)
stack.qualityChanges.nameChanged.connect(self._onQualityNameChanged)
self._onQualityNameChanged()
@@ -956,7 +961,7 @@ class MachineManager(QObject):
Application.getInstance().discardOrKeepProfileChanges()
@pyqtProperty(str, notify = activeVariantChanged)
- def activeVariantName(self):
+ def activeVariantName(self) -> str:
if self._active_container_stack:
variant = self._active_container_stack.variant
if variant:
@@ -965,7 +970,7 @@ class MachineManager(QObject):
return ""
@pyqtProperty(str, notify = activeVariantChanged)
- def activeVariantId(self):
+ def activeVariantId(self) -> str:
if self._active_container_stack:
variant = self._active_container_stack.variant
if variant:
@@ -974,7 +979,7 @@ class MachineManager(QObject):
return ""
@pyqtProperty(str, notify = globalContainerChanged)
- def activeDefinitionId(self):
+ def activeDefinitionId(self) -> str:
if self._global_container_stack:
definition = self._global_container_stack.getBottom()
if definition:
@@ -983,7 +988,7 @@ class MachineManager(QObject):
return ""
@pyqtProperty(str, notify=globalContainerChanged)
- def activeDefinitionName(self):
+ def activeDefinitionName(self) -> str:
if self._global_container_stack:
definition = self._global_container_stack.getBottom()
if definition:
@@ -995,7 +1000,7 @@ class MachineManager(QObject):
# \returns DefinitionID (string) if found, empty string otherwise
# \sa getQualityDefinitionId
@pyqtProperty(str, notify = globalContainerChanged)
- def activeQualityDefinitionId(self):
+ def activeQualityDefinitionId(self) -> str:
if self._global_container_stack:
return self.getQualityDefinitionId(self._global_container_stack.getBottom())
return ""
@@ -1004,14 +1009,14 @@ class MachineManager(QObject):
# This is normally the id of the definition itself, but machines can specify a different definition to inherit qualities from
# \param definition (DefinitionContainer) machine definition
# \returns DefinitionID (string) if found, empty string otherwise
- def getQualityDefinitionId(self, definition):
+ def getQualityDefinitionId(self, definition: "DefinitionContainer") -> str:
return QualityManager.getInstance().getParentMachineDefinition(definition).getId()
## Get the Variant ID to use to select quality profiles for the currently active variant
# \returns VariantID (string) if found, empty string otherwise
# \sa getQualityVariantId
@pyqtProperty(str, notify = activeVariantChanged)
- def activeQualityVariantId(self):
+ def activeQualityVariantId(self) -> str:
if self._active_container_stack:
variant = self._active_container_stack.variant
if variant:
@@ -1022,9 +1027,9 @@ class MachineManager(QObject):
# This is normally the id of the variant itself, but machines can specify a different definition
# to inherit qualities from, which has consequences for the variant to use as well
# \param definition (DefinitionContainer) machine definition
- # \param variant (DefinitionContainer) variant definition
+ # \param variant (InstanceContainer) variant definition
# \returns VariantID (string) if found, empty string otherwise
- def getQualityVariantId(self, definition, variant):
+ def getQualityVariantId(self, definition: "DefinitionContainer", variant: "InstanceContainer") -> str:
variant_id = variant.getId()
definition_id = definition.getId()
quality_definition_id = self.getQualityDefinitionId(definition)
@@ -1036,7 +1041,7 @@ class MachineManager(QObject):
## Gets how the active definition calls variants
# Caveat: per-definition-variant-title is currently not translated (though the fallback is)
@pyqtProperty(str, notify = globalContainerChanged)
- def activeDefinitionVariantsName(self):
+ def activeDefinitionVariantsName(self) -> str:
fallback_title = catalog.i18nc("@label", "Nozzle")
if self._global_container_stack:
return self._global_container_stack.getBottom().getMetaDataEntry("variants_name", fallback_title)
@@ -1044,7 +1049,7 @@ class MachineManager(QObject):
return fallback_title
@pyqtSlot(str, str)
- def renameMachine(self, machine_id, new_name):
+ def renameMachine(self, machine_id: str, new_name: str):
containers = ContainerRegistry.getInstance().findContainerStacks(id = machine_id)
if containers:
new_name = self._createUniqueName("machine", containers[0].getName(), new_name, containers[0].getBottom().getName())
@@ -1052,7 +1057,7 @@ class MachineManager(QObject):
self.globalContainerChanged.emit()
@pyqtSlot(str)
- def removeMachine(self, machine_id):
+ def removeMachine(self, machine_id: str):
# If the machine that is being removed is the currently active machine, set another machine as the active machine.
activate_new_machine = (self._global_container_stack and self._global_container_stack.getId() == machine_id)
@@ -1070,14 +1075,14 @@ class MachineManager(QObject):
@pyqtProperty(bool, notify = globalContainerChanged)
- def hasMaterials(self):
+ def hasMaterials(self) -> bool:
if self._global_container_stack:
return bool(self._global_container_stack.getMetaDataEntry("has_materials", False))
return False
@pyqtProperty(bool, notify = globalContainerChanged)
- def hasVariants(self):
+ def hasVariants(self) -> bool:
if self._global_container_stack:
return bool(self._global_container_stack.getMetaDataEntry("has_variants", False))
@@ -1086,7 +1091,7 @@ class MachineManager(QObject):
## Property to indicate if a machine has "specialized" material profiles.
# Some machines have their own material profiles that "override" the default catch all profiles.
@pyqtProperty(bool, notify = globalContainerChanged)
- def filterMaterialsByMachine(self):
+ def filterMaterialsByMachine(self) -> bool:
if self._global_container_stack:
return bool(self._global_container_stack.getMetaDataEntry("has_machine_materials", False))
@@ -1095,7 +1100,7 @@ class MachineManager(QObject):
## Property to indicate if a machine has "specialized" quality profiles.
# Some machines have their own quality profiles that "override" the default catch all profiles.
@pyqtProperty(bool, notify = globalContainerChanged)
- def filterQualityByMachine(self):
+ def filterQualityByMachine(self) -> bool:
if self._global_container_stack:
return bool(self._global_container_stack.getMetaDataEntry("has_machine_quality", False))
return False
@@ -1104,7 +1109,7 @@ class MachineManager(QObject):
# \param machine_id string machine id to get the definition ID of
# \returns DefinitionID (string) if found, None otherwise
@pyqtSlot(str, result = str)
- def getDefinitionByMachineId(self, machine_id):
+ def getDefinitionByMachineId(self, machine_id: str) -> str:
containers = ContainerRegistry.getInstance().findContainerStacks(id=machine_id)
if containers:
return containers[0].getBottom().getId()
@@ -1113,22 +1118,6 @@ class MachineManager(QObject):
def createMachineManager(engine=None, script_engine=None):
return MachineManager()
- def _updateVariantContainer(self, definition: "DefinitionContainer"):
- if not definition.getMetaDataEntry("has_variants"):
- return self._empty_variant_container
- machine_definition_id = Application.getInstance().getMachineManager().getQualityDefinitionId(definition)
- containers = []
- preferred_variant = definition.getMetaDataEntry("preferred_variant")
- if preferred_variant:
- containers = ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = machine_definition_id, id = preferred_variant)
- if not containers:
- containers = ContainerRegistry.getInstance().findInstanceContainers(type = "variant", definition = machine_definition_id)
-
- if containers:
- return containers[0]
-
- return self._empty_variant_container
-
def _updateMaterialContainer(self, definition: "DefinitionContainer", stack: "ContainerStack", variant_container: Optional["InstanceContainer"] = None, preferred_material_name: Optional[str] = None):
if not definition.getMetaDataEntry("has_materials"):
return self._empty_material_container
@@ -1166,110 +1155,6 @@ class MachineManager(QObject):
Logger.log("w", "Unable to find a material container with provided criteria, returning an empty one instead.")
return self._empty_material_container
- def _updateQualityContainer(self, definition: "DefinitionContainer", variant_container: "ContainerStack", material_container = None, preferred_quality_name: Optional[str] = None):
- container_registry = ContainerRegistry.getInstance()
- search_criteria = { "type": "quality" }
-
- if definition.getMetaDataEntry("has_machine_quality"):
- search_criteria["definition"] = self.getQualityDefinitionId(definition)
-
- if definition.getMetaDataEntry("has_materials") and material_container:
- search_criteria["material"] = material_container.id
- else:
- search_criteria["definition"] = "fdmprinter"
-
- if preferred_quality_name and preferred_quality_name != "empty":
- search_criteria["name"] = preferred_quality_name
- else:
- preferred_quality = definition.getMetaDataEntry("preferred_quality")
- if preferred_quality:
- search_criteria["id"] = preferred_quality
-
- containers = container_registry.findInstanceContainers(**search_criteria)
- if containers:
- return containers[0]
-
- if "material" in search_criteria:
- # First check if we can solve our material not found problem by checking if we can find quality containers
- # that are assigned to the parents of this material profile.
- try:
- inherited_files = material_container.getInheritedFiles()
- except AttributeError: # Material_container does not support inheritance.
- inherited_files = []
-
- if inherited_files:
- for inherited_file in inherited_files:
- # Extract the ID from the path we used to load the file.
- search_criteria["material"] = os.path.basename(inherited_file).split(".")[0]
- containers = container_registry.findInstanceContainers(**search_criteria)
- if containers:
- return containers[0]
- # We still weren't able to find a quality for this specific material.
- # Try to find qualities for a generic version of the material.
- material_search_criteria = { "type": "material", "material": material_container.getMetaDataEntry("material"), "color_name": "Generic"}
- if definition.getMetaDataEntry("has_machine_quality"):
- if material_container:
- material_search_criteria["definition"] = material_container.getDefinition().id
-
- if definition.getMetaDataEntry("has_variants"):
- material_search_criteria["variant"] = material_container.getMetaDataEntry("variant")
- else:
- material_search_criteria["definition"] = self.getQualityDefinitionId(definition)
-
- if definition.getMetaDataEntry("has_variants") and variant_container:
- material_search_criteria["variant"] = self.getQualityVariantId(definition, variant_container)
- else:
- material_search_criteria["definition"] = "fdmprinter"
- material_containers = container_registry.findInstanceContainers(**material_search_criteria)
- # Try all materials to see if there is a quality profile available.
- for material_container in material_containers:
- search_criteria["material"] = material_container.getId()
-
- containers = container_registry.findInstanceContainers(**search_criteria)
- if containers:
- return containers[0]
-
- if "name" in search_criteria or "id" in search_criteria:
- # If a quality by this name can not be found, try a wider set of search criteria
- search_criteria.pop("name", None)
- search_criteria.pop("id", None)
-
- containers = container_registry.findInstanceContainers(**search_criteria)
- if containers:
- return containers[0]
-
- # Notify user that we were unable to find a matching quality
- message = Message(catalog.i18nc("@info:status", "Unable to find a quality profile for this combination. Default settings will be used instead."))
- message.show()
- return self._empty_quality_container
-
- ## Finds a quality-changes container to use if any other container
- # changes.
- #
- # \param quality_type The quality type to find a quality-changes for.
- # \param preferred_quality_changes_name The name of the quality-changes to
- # pick, if any such quality-changes profile is available.
- def _updateQualityChangesContainer(self, quality_type, preferred_quality_changes_name = None):
- container_registry = ContainerRegistry.getInstance() # Cache.
- search_criteria = { "type": "quality_changes" }
-
- search_criteria["quality"] = quality_type
- if preferred_quality_changes_name:
- search_criteria["name"] = preferred_quality_changes_name
-
- # Try to search with the name in the criteria first, since we prefer to have the correct name.
- containers = container_registry.findInstanceContainers(**search_criteria)
- if containers: # Found one!
- return containers[0]
-
- if "name" in search_criteria:
- del search_criteria["name"] # Not found, then drop the name requirement (if we had one) and search again.
- containers = container_registry.findInstanceContainers(**search_criteria)
- if containers:
- return containers[0]
-
- return self._empty_quality_changes_container # Didn't find anything with the required quality_type.
-
def _onMachineNameChanged(self):
self.globalContainerChanged.emit()
diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py
old mode 100644
new mode 100755
index a0ce679464..f6e407efb2
--- a/plugins/3MFReader/ThreeMFWorkspaceReader.py
+++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py
@@ -15,7 +15,10 @@ from .WorkspaceDialog import WorkspaceDialog
import xml.etree.ElementTree as ET
from cura.Settings.ExtruderManager import ExtruderManager
+from cura.Settings.ExtruderStack import ExtruderStack
+from cura.Settings.GlobalStack import GlobalStack
+from configparser import ConfigParser
import zipfile
import io
import configparser
@@ -31,10 +34,14 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
self._dialog = WorkspaceDialog()
self._3mf_mesh_reader = None
self._container_registry = ContainerRegistry.getInstance()
- self._definition_container_suffix = ContainerRegistry.getMimeTypeForContainer(DefinitionContainer).preferredSuffix
+
+ # suffixes registered with the MineTypes don't start with a dot '.'
+ self._definition_container_suffix = "." + ContainerRegistry.getMimeTypeForContainer(DefinitionContainer).preferredSuffix
self._material_container_suffix = None # We have to wait until all other plugins are loaded before we can set it
- self._instance_container_suffix = ContainerRegistry.getMimeTypeForContainer(InstanceContainer).preferredSuffix
- self._container_stack_suffix = ContainerRegistry.getMimeTypeForContainer(ContainerStack).preferredSuffix
+ self._instance_container_suffix = "." + ContainerRegistry.getMimeTypeForContainer(InstanceContainer).preferredSuffix
+ self._container_stack_suffix = "." + ContainerRegistry.getMimeTypeForContainer(ContainerStack).preferredSuffix
+ self._extruder_stack_suffix = "." + ContainerRegistry.getMimeTypeForContainer(ExtruderStack).preferredSuffix
+ self._global_stack_suffix = "." + ContainerRegistry.getMimeTypeForContainer(GlobalStack).preferredSuffix
self._resolve_strategies = {}
@@ -47,6 +54,49 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
self._id_mapping[old_id] = self._container_registry.uniqueName(old_id)
return self._id_mapping[old_id]
+ ## Separates the given file list into a list of GlobalStack files and a list of ExtruderStack files.
+ #
+ # In old versions, extruder stack files have the same suffix as container stack files ".stack.cfg".
+ #
+ def _determineGlobalAndExtruderStackFiles(self, project_file_name, file_list):
+ archive = zipfile.ZipFile(project_file_name, "r")
+
+ global_stack_file_list = [name for name in file_list if name.endswith(self._global_stack_suffix)]
+ extruder_stack_file_list = [name for name in file_list if name.endswith(self._extruder_stack_suffix)]
+
+ # separate container stack files and extruder stack files
+ files_to_determine = [name for name in file_list if name.endswith(self._container_stack_suffix)]
+ for file_name in files_to_determine:
+ # FIXME: HACK!
+ # We need to know the type of the stack file, but we can only know it if we deserialize it.
+ # The default ContainerStack.deserialize() will connect signals, which is not desired in this case.
+ # Since we know that the stack files are INI files, so we directly use the ConfigParser to parse them.
+ serialized = archive.open(file_name).read().decode("utf-8")
+ stack_config = ConfigParser()
+ stack_config.read_string(serialized)
+
+ # sanity check
+ if not stack_config.has_option("metadata", "type"):
+ Logger.log("e", "%s in %s doesn't seem to be valid stack file", file_name, project_file_name)
+ continue
+
+ stack_type = stack_config.get("metadata", "type")
+ if stack_type == "extruder_train":
+ extruder_stack_file_list.append(file_name)
+ elif stack_type == "machine":
+ global_stack_file_list.append(file_name)
+ else:
+ Logger.log("w", "Unknown container stack type '%s' from %s in %s",
+ stack_type, file_name, project_file_name)
+
+ if len(global_stack_file_list) != 1:
+ raise RuntimeError("More than one global stack file found: [%s]" % str(global_stack_file_list))
+
+ return global_stack_file_list[0], extruder_stack_file_list
+
+ ## read some info so we can make decisions
+ # \param file_name
+ # \param show_dialog In case we use preRead() to check if a file is a valid project file, we don't want to show a dialog.
def preRead(self, file_name, show_dialog=True, *args, **kwargs):
self._3mf_mesh_reader = Application.getInstance().getMeshFileHandler().getReaderForFile(file_name)
if self._3mf_mesh_reader and self._3mf_mesh_reader.preRead(file_name) == WorkspaceReader.PreReadResult.accepted:
@@ -59,51 +109,52 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
machine_type = ""
variant_type_name = i18n_catalog.i18nc("@label", "Nozzle")
- num_extruders = 0
# Check if there are any conflicts, so we can ask the user.
archive = zipfile.ZipFile(file_name, "r")
cura_file_names = [name for name in archive.namelist() if name.startswith("Cura/")]
- container_stack_files = [name for name in cura_file_names if name.endswith(self._container_stack_suffix)]
- self._resolve_strategies = {"machine": None, "quality_changes": None, "material": None}
- machine_conflict = False
- quality_changes_conflict = False
- for container_stack_file in container_stack_files:
- container_id = self._stripFileToId(container_stack_file)
- serialized = archive.open(container_stack_file).read().decode("utf-8")
- if machine_name == "":
- machine_name = self._getMachineNameFromSerializedStack(serialized)
- stacks = self._container_registry.findContainerStacks(id=container_id)
- if stacks:
- # Check if there are any changes at all in any of the container stacks.
- id_list = self._getContainerIdListFromSerialized(serialized)
- for index, container_id in enumerate(id_list):
- if stacks[0].getContainer(index).getId() != container_id:
- machine_conflict = True
- Job.yieldThread()
+ # A few lists of containers in this project files.
+ # When loading the global stack file, it may be associated with those containers, which may or may not be
+ # in Cura already, so we need to provide them as alternative search lists.
+ definition_container_list = []
+ instance_container_list = []
+ material_container_list = []
+
+ #
+ # Read definition containers
+ #
+ machine_definition_container_count = 0
+ extruder_definition_container_count = 0
definition_container_files = [name for name in cura_file_names if name.endswith(self._definition_container_suffix)]
- for definition_container_file in definition_container_files:
- container_id = self._stripFileToId(definition_container_file)
+ for each_definition_container_file in definition_container_files:
+ container_id = self._stripFileToId(each_definition_container_file)
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(each_definition_container_file).read().decode("utf-8"))
else:
definition_container = definitions[0]
+ definition_container_list.append(definition_container)
- if definition_container.getMetaDataEntry("type") != "extruder":
+ definition_container_type = definition_container.getMetaDataEntry("type")
+ if definition_container_type == "machine":
machine_type = definition_container.getName()
variant_type_name = definition_container.getMetaDataEntry("variants_name", variant_type_name)
+
+ machine_definition_container_count += 1
+ elif definition_container_type == "extruder":
+ extruder_definition_container_count += 1
else:
- num_extruders += 1
+ Logger.log("w", "Unknown definition container type %s for %s",
+ definition_container_type, each_definition_container_file)
Job.yieldThread()
-
- if num_extruders == 0:
- num_extruders = 1 # No extruder stacks found, which means there is one extruder
-
- extruders = num_extruders * [""]
+ # sanity check
+ if machine_definition_container_count != 1:
+ msg = "Expecting one machine definition container but got %s" % machine_definition_container_count
+ Logger.log("e", msg)
+ raise RuntimeError(msg)
material_labels = []
material_conflict = False
@@ -119,18 +170,24 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if materials and not materials[0].isReadOnly(): # Only non readonly materials can be in conflict
material_conflict = True
Job.yieldThread()
+
# Check if any quality_changes instance container is in conflict.
instance_container_files = [name for name in cura_file_names if name.endswith(self._instance_container_suffix)]
quality_name = ""
quality_type = ""
num_settings_overriden_by_quality_changes = 0 # How many settings are changed by the quality changes
+ num_settings_overriden_by_definition_changes = 0 # How many settings are changed by the definition changes
num_user_settings = 0
- for instance_container_file in instance_container_files:
- container_id = self._stripFileToId(instance_container_file)
+ 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)
# 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(archive.open(each_instance_container_file).read().decode("utf-8"))
+ instance_container_list.append(instance_container)
+
container_type = instance_container.getMetaDataEntry("type")
if container_type == "quality_changes":
quality_name = instance_container.getName()
@@ -141,6 +198,13 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# Check if there really is a conflict by comparing the values
if quality_changes[0] != instance_container:
quality_changes_conflict = True
+ elif container_type == "definition_changes":
+ definition_name = instance_container.getName()
+ num_settings_overriden_by_definition_changes += len(instance_container._instances)
+ definition_changes = self._container_registry.findDefinitionContainers(id = container_id)
+ 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")
@@ -151,6 +215,26 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
num_user_settings += len(instance_container._instances)
Job.yieldThread()
+
+ # Load ContainerStack files and ExtruderStack files
+ global_stack_file, extruder_stack_files = self._determineGlobalAndExtruderStackFiles(
+ file_name, cura_file_names)
+ self._resolve_strategies = {"machine": None, "quality_changes": None, "material": None}
+ machine_conflict = False
+ for container_stack_file in [global_stack_file] + extruder_stack_files:
+ container_id = self._stripFileToId(container_stack_file)
+ serialized = archive.open(container_stack_file).read().decode("utf-8")
+ if machine_name == "":
+ machine_name = self._getMachineNameFromSerializedStack(serialized)
+ stacks = self._container_registry.findContainerStacks(id = container_id)
+ if stacks:
+ # Check if there are any changes at all in any of the container stacks.
+ id_list = self._getContainerIdListFromSerialized(serialized)
+ for index, container_id in enumerate(id_list):
+ if stacks[0].getContainer(index).getId() != container_id:
+ machine_conflict = True
+ Job.yieldThread()
+
num_visible_settings = 0
try:
temp_preferences = Preferences()
@@ -171,9 +255,17 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if not show_dialog:
return WorkspaceReader.PreReadResult.accepted
+ # prepare data for the dialog
+ num_extruders = extruder_definition_container_count
+ if num_extruders == 0:
+ num_extruders = 1 # No extruder stacks found, which means there is one extruder
+
+ extruders = num_extruders * [""]
+
# Show the dialog, informing the user what is about to happen.
self._dialog.setMachineConflict(machine_conflict)
self._dialog.setQualityChangesConflict(quality_changes_conflict)
+ self._dialog.setDefinitionChangesConflict(definition_changes_conflict)
self._dialog.setMaterialConflict(material_conflict)
self._dialog.setNumVisibleSettings(num_visible_settings)
self._dialog.setQualityName(quality_name)
@@ -196,9 +288,28 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
return WorkspaceReader.PreReadResult.cancelled
self._resolve_strategies = self._dialog.getResult()
+ #
+ # There can be 3 resolve strategies coming from the dialog:
+ # - new: create a new container
+ # - override: override the existing container
+ # - None: There is no conflict, which means containers with the same IDs may or may not be there already.
+ # If they are there, there is no conflict between the them.
+ # In this case, you can either create a new one, or safely override the existing one.
+ #
+ # Default values
+ for k, v in self._resolve_strategies.items():
+ if v is None:
+ self._resolve_strategies[k] = "new"
return WorkspaceReader.PreReadResult.accepted
+ ## 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.
+ # It handles old style project files containing .stack.cfg as well as new style project files
+ # containing global.cfg / extruder.cfg
+ #
+ # \param file_name
def read(self, file_name):
archive = zipfile.ZipFile(file_name, "r")
@@ -232,6 +343,24 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# We do this so that if something goes wrong, it's easier to clean up.
containers_to_add = []
+ global_stack_file, extruder_stack_files = self._determineGlobalAndExtruderStackFiles(file_name, cura_file_names)
+
+ global_stack = None
+ extruder_stacks = []
+ extruder_stacks_added = []
+ container_stacks_added = []
+
+ containers_added = []
+
+ global_stack_id_original = self._stripFileToId(global_stack_file)
+ global_stack_id_new = global_stack_id_original
+ global_stack_need_rename = False
+ 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
+
# 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.
@@ -240,7 +369,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
definition_container_files = [name for name in cura_file_names if name.endswith(self._definition_container_suffix)]
for definition_container_file in definition_container_files:
container_id = self._stripFileToId(definition_container_file)
- definitions = self._container_registry.findDefinitionContainers(id=container_id)
+ 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"))
@@ -257,29 +386,32 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
material_container_files = [name for name in cura_file_names if name.endswith(self._material_container_suffix)]
for material_container_file in material_container_files:
container_id = self._stripFileToId(material_container_file)
- materials = self._container_registry.findInstanceContainers(id=container_id)
+ materials = self._container_registry.findInstanceContainers(id = container_id)
+
if not materials:
material_container = xml_material_profile(container_id)
material_container.deserialize(archive.open(material_container_file).read().decode("utf-8"))
containers_to_add.append(material_container)
else:
- if not materials[0].isReadOnly(): # Only create new materials if they are not read only.
+ 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":
- materials[0].deserialize(archive.open(material_container_file).read().decode("utf-8"))
+ material_container.deserialize(archive.open(material_container_file).read().decode("utf-8"))
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"))
containers_to_add.append(material_container)
- material_containers.append(material_container)
+
+ material_containers.append(material_container)
Job.yieldThread()
Logger.log("d", "Workspace loading is checking instance containers...")
# Get quality_changes and user profiles saved in the workspace
instance_container_files = [name for name in cura_file_names if name.endswith(self._instance_container_suffix)]
user_instance_containers = []
- quality_changes_instance_containers = []
+ quality_and_definition_changes_instance_containers = []
for instance_container_file in instance_container_files:
container_id = self._stripFileToId(instance_container_file)
instance_container = InstanceContainer(container_id)
@@ -290,189 +422,330 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
Job.yieldThread()
if container_type == "user":
# Check if quality changes already exists.
- user_containers = self._container_registry.findInstanceContainers(id=container_id)
+ user_containers = self._container_registry.findInstanceContainers(id = container_id)
if not user_containers:
containers_to_add.append(instance_container)
else:
if self._resolve_strategies["machine"] == "override" or self._resolve_strategies["machine"] is None:
- user_containers[0].deserialize(archive.open(instance_container_file).read().decode("utf-8"))
+ instance_container = user_containers[0]
+ instance_container.deserialize(archive.open(instance_container_file).read().decode("utf-8"))
+ 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_id = self.getNewId(extruder_id) + "_current_settings"
+ new_extruder_id = self.getNewId(extruder_id)
+ new_id = new_extruder_id + "_current_settings"
instance_container._id = new_id
instance_container.setName(new_id)
- instance_container.setMetaDataEntry("extruder", self.getNewId(extruder_id))
+ instance_container.setMetaDataEntry("extruder", new_extruder_id)
containers_to_add.append(instance_container)
machine_id = instance_container.getMetaDataEntry("machine", None)
if machine_id:
- new_id = self.getNewId(machine_id) + "_current_settings"
+ new_machine_id = self.getNewId(machine_id)
+ new_id = new_machine_id + "_current_settings"
instance_container._id = new_id
instance_container.setName(new_id)
- instance_container.setMetaDataEntry("machine", self.getNewId(machine_id))
+ instance_container.setMetaDataEntry("machine", new_machine_id)
containers_to_add.append(instance_container)
user_instance_containers.append(instance_container)
- elif container_type == "quality_changes":
+ elif container_type in ("quality_changes", "definition_changes"):
# Check if quality changes already exists.
- quality_changes = self._container_registry.findInstanceContainers(id = container_id)
- if not quality_changes:
+ changes_containers = self._container_registry.findInstanceContainers(id = container_id)
+ if not changes_containers:
containers_to_add.append(instance_container)
else:
- if self._resolve_strategies["quality_changes"] == "override":
- quality_changes[0].deserialize(archive.open(instance_container_file).read().decode("utf-8"))
- elif self._resolve_strategies["quality_changes"] is None:
+ 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?
+
+ 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)
+ instance_container.setMetaDataEntry("extruder", new_extruder_id)
+
+ machine_id = instance_container.getMetaDataEntry("machine", None)
+ if machine_id:
+ new_machine_id = self.getNewId(machine_id)
+ instance_container.setMetaDataEntry("machine", new_machine_id)
+
+ containers_to_add.append(instance_container)
+
+ elif self._resolve_strategies[container_type] is None:
# The ID already exists, but nothing in the values changed, so do nothing.
pass
- quality_changes_instance_containers.append(instance_container)
+ quality_and_definition_changes_instance_containers.append(instance_container)
else:
- continue
+ existing_container = self._container_registry.findInstanceContainers(id = container_id)
+ if not existing_container:
+ containers_to_add.append(instance_container)
+ if global_stack_need_rename:
+ if instance_container.getMetaDataEntry("machine"):
+ instance_container.setMetaDataEntry("machine", global_stack_id_new)
# Add all the containers right before we try to add / serialize the stack
for container in containers_to_add:
self._container_registry.addContainer(container)
container.setDirty(True)
+ containers_added.append(container)
# Get the stack(s) saved in the workspace.
Logger.log("d", "Workspace loading is checking stacks containers...")
- container_stack_files = [name for name in cura_file_names if name.endswith(self._container_stack_suffix)]
- global_stack = None
- extruder_stacks = []
- container_stacks_added = []
- try:
- for container_stack_file in container_stack_files:
- container_id = self._stripFileToId(container_stack_file)
- # Check if a stack by this ID already exists;
- container_stacks = self._container_registry.findContainerStacks(id=container_id)
+ # --
+ # load global stack file
+ try:
+ # Check if a stack by this ID already exists;
+ container_stacks = self._container_registry.findContainerStacks(id = global_stack_id_original)
+ if container_stacks:
+ stack = container_stacks[0]
+
+ if self._resolve_strategies["machine"] == "override":
+ # TODO: HACK
+ # 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"))
+ if network_authentication_id:
+ container_stacks[0].addMetaDataEntry("network_authentication_id", network_authentication_id)
+ if network_authentication_key:
+ container_stacks[0].addMetaDataEntry("network_authentication_key", network_authentication_key)
+ elif self._resolve_strategies["machine"] == "new":
+ stack = GlobalStack(global_stack_id_new)
+ stack.deserialize(archive.open(global_stack_file).read().decode("utf-8"))
+
+ # Ensure a unique ID and name
+ stack._id = global_stack_id_new
+
+ # Extruder stacks are "bound" to a machine. If we add the machine as a new one, the id of the
+ # bound machine also needs to change.
+ if stack.getMetaDataEntry("machine", None):
+ stack.setMetaDataEntry("machine", global_stack_id_new)
+
+ # Only machines need a new name, stacks may be non-unique
+ stack.setName(self._container_registry.uniqueName(stack.getName()))
+ container_stacks_added.append(stack)
+ self._container_registry.addContainer(stack)
+ else:
+ Logger.log("w", "Resolve strategy of %s for machine is not supported", self._resolve_strategies["machine"])
+ else:
+ # no existing container stack, so we create a new one
+ 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"))
+ container_stacks_added.append(stack)
+ self._container_registry.addContainer(stack)
+ containers_added.append(stack)
+
+ global_stack = stack
+ Job.yieldThread()
+ except:
+ Logger.logException("w", "We failed to serialize the stack. Trying to clean up.")
+ # Something went really wrong. Try to remove any data that we added.
+ for container in containers_added:
+ self._container_registry.removeContainer(container.getId())
+ return
+
+ # --
+ # load extruder stack files
+ try:
+ for index, extruder_stack_file in enumerate(extruder_stack_files):
+ container_id = self._stripFileToId(extruder_stack_file)
+
+ 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":
- # TODO: HACK
- # There is a machine, check if it has authenticationd 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(container_stack_file).read().decode("utf-8"))
- if network_authentication_id:
- container_stacks[0].addMetaDataEntry("network_authentication_id", network_authentication_id)
- if network_authentication_key:
- container_stacks[0].addMetaDataEntry("network_authentication_key", network_authentication_key)
+ pass # do nothing
elif self._resolve_strategies["machine"] == "new":
+ # create a new extruder stack from this one
new_id = self.getNewId(container_id)
- stack = ContainerStack(new_id)
- stack.deserialize(archive.open(container_stack_file).read().decode("utf-8"))
+ stack = ExtruderStack(new_id)
+ stack.deserialize(archive.open(extruder_stack_file).read().decode("utf-8"))
# Ensure a unique ID and name
stack._id = new_id
- # Extruder stacks are "bound" to a machine. If we add the machine as a new one, the id of the
- # bound machine also needs to change.
- if stack.getMetaDataEntry("machine", None):
- stack.setMetaDataEntry("machine", self.getNewId(stack.getMetaDataEntry("machine")))
-
- if stack.getMetaDataEntry("type") != "extruder_train":
- # Only machines need a new name, stacks may be non-unique
- stack.setName(self._container_registry.uniqueName(stack.getName()))
- container_stacks_added.append(stack)
self._container_registry.addContainer(stack)
- else:
- Logger.log("w", "Resolve strategy of %s for machine is not supported", self._resolve_strategies["machine"])
+ extruder_stacks_added.append(stack)
+ containers_added.append(stack)
else:
- stack = ContainerStack(container_id)
- # Deserialize stack by converting read data from bytes to string
- stack.deserialize(archive.open(container_stack_file).read().decode("utf-8"))
- container_stacks_added.append(stack)
- self._container_registry.addContainer(stack)
+ 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]
- if stack.getMetaDataEntry("type") == "extruder_train":
- extruder_stacks.append(stack)
- else:
- global_stack = stack
- Job.yieldThread()
+ 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"))
+ 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.")
# Something went really wrong. Try to remove any data that we added.
- for container in containers_to_add:
- self._container_registry.getInstance().removeContainer(container.getId())
-
- for container in container_stacks_added:
- self._container_registry.getInstance().removeContainer(container.getId())
-
- return None
+ for container in containers_added:
+ self._container_registry.removeContainer(container.getId())
+ return
+ #
+ # 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.
+ #
if self._resolve_strategies["machine"] == "new":
# A new machine was made, but it was serialized with the wrong user container. Fix that now.
for container in user_instance_containers:
+ # replacing the container ID for user instance containers for the extruders
extruder_id = container.getMetaDataEntry("extruder", None)
if extruder_id:
for extruder in extruder_stacks:
if extruder.getId() == extruder_id:
- extruder.replaceContainer(0, container)
+ extruder.userChanges = container
continue
+
+ # replacing the container ID for user instance containers for the machine
machine_id = container.getMetaDataEntry("machine", None)
if machine_id:
if global_stack.getId() == machine_id:
- global_stack.replaceContainer(0, container)
+ global_stack.userChanges = container
continue
- if self._resolve_strategies["quality_changes"] == "new":
- # Quality changes needs to get a new ID, added to registry and to the right stacks
- for container in quality_changes_instance_containers:
- old_id = container.getId()
- container.setName(self._container_registry.uniqueName(container.getName()))
- # We're not really supposed to change the ID in normal cases, but this is an exception.
- container._id = self.getNewId(container.getId())
+ for changes_container_type in ("quality_changes", "definition_changes"):
+ 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(container)
+ # 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)
- # Replace the quality changes container
- old_container = global_stack.findContainer({"type": "quality_changes"})
- if old_container.getId() == old_id:
- quality_changes_index = global_stack.getContainerIndex(old_container)
- global_stack.replaceContainer(quality_changes_index, container)
- continue
+ # Find the old (current) changes container in the global stack
+ if changes_container_type == "quality_changes":
+ old_container = global_stack.qualityChanges
+ elif changes_container_type == "definition_changes":
+ old_container = global_stack.definitionChanges
- for stack in extruder_stacks:
- old_container = stack.findContainer({"type": "quality_changes"})
+ # sanity checks
+ # NOTE: The following cases SHOULD NOT happen!!!!
+ if not old_container:
+ Logger.log("e", "We try to get [%s] from the global stack [%s] but we got None instead!",
+ changes_container_type, global_stack.getId())
+
+ # 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:
- quality_changes_index = stack.getContainerIndex(old_container)
- stack.replaceContainer(quality_changes_index, container)
+ if changes_container_type == "quality_changes":
+ global_stack.qualityChanges = each_changes_container
+ elif changes_container_type == "definition_changes":
+ global_stack.definitionChanges = each_changes_container
+ continue
+
+ # Replace the quality/definition changes container if it's in one of the ExtruderStacks
+ for each_extruder_stack in extruder_stacks:
+ changes_container = None
+ if changes_container_type == "quality_changes":
+ changes_container = each_extruder_stack.qualityChanges
+ elif changes_container_type == "definition_changes":
+ changes_container = each_extruder_stack.definitionChanges
+
+ # sanity checks
+ # NOTE: The following cases SHOULD NOT happen!!!!
+ if not changes_container:
+ Logger.log("e", "We try to get [%s] from the extruder stack [%s] but we got None instead!",
+ changes_container_type, each_extruder_stack.getId())
+
+ # 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 changes_container_type == "quality_changes":
+ each_extruder_stack.qualityChanges = each_changes_container
+ elif changes_container_type == "definition_changes":
+ each_extruder_stack.definitionChanges = each_changes_container
if self._resolve_strategies["material"] == "new":
- for material in material_containers:
- old_material = global_stack.findContainer({"type": "material"})
- if old_material.getId() in self._id_mapping:
- material_index = global_stack.getContainerIndex(old_material)
- global_stack.replaceContainer(material_index, material)
+ for each_material in material_containers:
+ old_material = global_stack.material
+
+ # check if the old material container has been renamed to this material container ID
+ # if the container hasn't been renamed, we do nothing.
+ new_id = self._id_mapping.get(old_material.getId())
+ if new_id is None or new_id != each_material.getId():
continue
- for stack in extruder_stacks:
- old_material = stack.findContainer({"type": "material"})
- if old_material.getId() in self._id_mapping:
- material_index = stack.getContainerIndex(old_material)
- stack.replaceContainer(material_index, material)
+ if old_material.getId() in self._id_mapping:
+ global_stack.material = each_material
+
+ for each_extruder_stack in extruder_stacks:
+ old_material = each_extruder_stack.material
+
+ # check if the old material container has been renamed to this material container ID
+ # if the container hasn't been renamed, we do nothing.
+ new_id = self._id_mapping.get(old_material.getId())
+ if new_id is None or new_id != each_material.getId():
continue
- for stack in extruder_stacks:
- ExtruderManager.getInstance().registerExtruder(stack, global_stack.getId())
+ if old_material.getId() in self._id_mapping:
+ each_extruder_stack.material = each_material
+
+ if extruder_stacks:
+ for stack in extruder_stacks:
+ ExtruderManager.getInstance().registerExtruder(stack, global_stack.getId())
else:
# Machine has no extruders, but it needs to be registered with the extruder manager.
ExtruderManager.getInstance().registerExtruder(None, global_stack.getId())
Logger.log("d", "Workspace loading is notifying rest of the code of changes...")
- # Notify everything/one that is to notify about changes.
- global_stack.containersChanged.emit(global_stack.getTop())
-
- for stack in extruder_stacks:
- stack.setNextStack(global_stack)
- stack.containersChanged.emit(stack.getTop())
+ if self._resolve_strategies["machine"] == "new":
+ for stack in extruder_stacks:
+ stack.setNextStack(global_stack)
+ stack.containersChanged.emit(stack.getTop())
# Actually change the active machine.
Application.getInstance().setGlobalContainerStack(global_stack)
+ # Notify everything/one that is to notify about changes.
+ global_stack.containersChanged.emit(global_stack.getTop())
+
# Load all the nodes / meshdata of the workspace
nodes = self._3mf_mesh_reader.read(file_name)
if nodes is None:
diff --git a/plugins/3MFReader/WorkspaceDialog.py b/plugins/3MFReader/WorkspaceDialog.py
index 1bae9575f2..9d6c70cf8b 100644
--- a/plugins/3MFReader/WorkspaceDialog.py
+++ b/plugins/3MFReader/WorkspaceDialog.py
@@ -1,7 +1,7 @@
# Copyright (c) 2016 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
-from PyQt5.QtCore import Qt, QUrl, pyqtSignal, QObject, pyqtProperty, QCoreApplication
+from PyQt5.QtCore import QUrl, pyqtSignal, QObject, pyqtProperty, QCoreApplication
from UM.FlameProfiler import pyqtSlot
from PyQt5.QtQml import QQmlComponent, QQmlContext
from UM.PluginRegistry import PluginRegistry
@@ -29,11 +29,13 @@ class WorkspaceDialog(QObject):
self._default_strategy = "override"
self._result = {"machine": self._default_strategy,
"quality_changes": self._default_strategy,
+ "definition_changes": self._default_strategy,
"material": self._default_strategy}
self._visible = False
self.showDialogSignal.connect(self.__show)
self._has_quality_changes_conflict = False
+ self._has_definition_changes_conflict = False
self._has_machine_conflict = False
self._has_material_conflict = False
self._num_visible_settings = 0
@@ -51,6 +53,7 @@ class WorkspaceDialog(QObject):
machineConflictChanged = pyqtSignal()
qualityChangesConflictChanged = pyqtSignal()
+ definitionChangesConflictChanged = pyqtSignal()
materialConflictChanged = pyqtSignal()
numVisibleSettingsChanged = pyqtSignal()
activeModeChanged = pyqtSignal()
@@ -185,6 +188,10 @@ class WorkspaceDialog(QObject):
def qualityChangesConflict(self):
return self._has_quality_changes_conflict
+ @pyqtProperty(bool, notify=definitionChangesConflictChanged)
+ def definitionChangesConflict(self):
+ return self._has_definition_changes_conflict
+
@pyqtProperty(bool, notify=materialConflictChanged)
def materialConflict(self):
return self._has_material_conflict
@@ -214,11 +221,18 @@ class WorkspaceDialog(QObject):
self._has_quality_changes_conflict = quality_changes_conflict
self.qualityChangesConflictChanged.emit()
+ def setDefinitionChangesConflict(self, definition_changes_conflict):
+ if self._has_definition_changes_conflict != definition_changes_conflict:
+ self._has_definition_changes_conflict = definition_changes_conflict
+ self.definitionChangesConflictChanged.emit()
+
def getResult(self):
if "machine" in self._result and not self._has_machine_conflict:
self._result["machine"] = None
if "quality_changes" in self._result and not self._has_quality_changes_conflict:
self._result["quality_changes"] = None
+ if "definition_changes" in self._result and not self._has_definition_changes_conflict:
+ self._result["definition_changes"] = None
if "material" in self._result and not self._has_material_conflict:
self._result["material"] = None
return self._result
@@ -240,6 +254,7 @@ class WorkspaceDialog(QObject):
# Reset the result
self._result = {"machine": self._default_strategy,
"quality_changes": self._default_strategy,
+ "definition_changes": self._default_strategy,
"material": self._default_strategy}
self._visible = True
self.showDialogSignal.emit()
diff --git a/plugins/CuraEngineBackend/Cura.proto b/plugins/CuraEngineBackend/Cura.proto
index 4eab500f0a..c2e4e5bb5f 100644
--- a/plugins/CuraEngineBackend/Cura.proto
+++ b/plugins/CuraEngineBackend/Cura.proto
@@ -90,9 +90,21 @@ message GCodeLayer {
}
-message PrintTimeMaterialEstimates { // The print time for the whole print and material estimates for the extruder
- float time = 1; // Total time estimate
- repeated MaterialEstimates materialEstimates = 2; // materialEstimates data
+message PrintTimeMaterialEstimates { // The print time for each feature and material estimates for the extruder
+ // Time estimate in each feature
+ float time_none = 1;
+ float time_inset_0 = 2;
+ float time_inset_x = 3;
+ float time_skin = 4;
+ float time_support = 5;
+ float time_skirt = 6;
+ float time_infill = 7;
+ float time_support_infill = 8;
+ float time_travel = 9;
+ float time_retract = 10;
+ float time_support_interface = 11;
+
+ repeated MaterialEstimates materialEstimates = 12; // materialEstimates data
}
message MaterialEstimates {
@@ -121,4 +133,4 @@ message GCodePrefix {
}
message SlicingFinished {
-}
\ No newline at end of file
+}
diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py
index d0f26f429e..9c9c9a1b90 100755
--- a/plugins/CuraEngineBackend/CuraEngineBackend.py
+++ b/plugins/CuraEngineBackend/CuraEngineBackend.py
@@ -187,7 +187,19 @@ class CuraEngineBackend(QObject, Backend):
Logger.log("w", "Slice unnecessary, nothing has changed that needs reslicing.")
return
- self.printDurationMessage.emit(0, [0])
+ self.printDurationMessage.emit({
+ "none": 0,
+ "inset_0": 0,
+ "inset_x": 0,
+ "skin": 0,
+ "support": 0,
+ "skirt": 0,
+ "infill": 0,
+ "support_infill": 0,
+ "travel": 0,
+ "retract": 0,
+ "support_interface": 0
+ }, [0])
self._stored_layer_data = []
self._stored_optimized_layer_data = []
@@ -481,13 +493,26 @@ class CuraEngineBackend(QObject, Backend):
## Called when a print time message is received from the engine.
#
- # \param message The protobuff message containing the print time and
+ # \param message The protobuf message containing the print time per feature and
# material amount per extruder
def _onPrintTimeMaterialEstimates(self, message):
material_amounts = []
for index in range(message.repeatedMessageCount("materialEstimates")):
material_amounts.append(message.getRepeatedMessage("materialEstimates", index).material_amount)
- self.printDurationMessage.emit(message.time, material_amounts)
+ feature_times = {
+ "none": message.time_none,
+ "inset_0": message.time_inset_0,
+ "inset_x": message.time_inset_x,
+ "skin": message.time_skin,
+ "support": message.time_support,
+ "skirt": message.time_skirt,
+ "infill": message.time_infill,
+ "support_infill": message.time_support_infill,
+ "travel": message.time_travel,
+ "retract": message.time_retract,
+ "support_interface": message.time_support_interface
+ }
+ self.printDurationMessage.emit(feature_times, material_amounts)
## Creates a new socket connection.
def _createSocket(self):
diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py
index 486ab25918..bfade90f2b 100755
--- a/plugins/MachineSettingsAction/MachineSettingsAction.py
+++ b/plugins/MachineSettingsAction/MachineSettingsAction.py
@@ -251,7 +251,7 @@ class MachineSettingsAction(MachineAction):
if definition.getProperty("machine_gcode_flavor", "value") == "UltiGCode" and not definition.getMetaDataEntry("has_materials", False):
has_materials = self._global_container_stack.getProperty("machine_gcode_flavor", "value") != "UltiGCode"
- material_container = self._global_container_stack.findContainer({"type": "material"})
+ material_container = self._global_container_stack.material
material_index = self._global_container_stack.getContainerIndex(material_container)
if has_materials:
@@ -272,7 +272,6 @@ class MachineSettingsAction(MachineAction):
if "has_materials" in self._global_container_stack.getMetaData():
self._global_container_stack.removeMetaDataEntry("has_materials")
- empty_material = self._container_registry.findInstanceContainers(id = "empty_material")[0]
- self._global_container_stack.replaceContainer(material_index, empty_material)
+ self._global_container_stack.material = ContainerRegistry.getInstance().getEmptyInstanceContainer()
Application.getInstance().globalContainerStackChanged.emit()
diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml
index 5a84642db5..654030b013 100644
--- a/plugins/MachineSettingsAction/MachineSettingsAction.qml
+++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml
@@ -16,23 +16,13 @@ Cura.MachineAction
property var extrudersModel: Cura.ExtrudersModel{}
property int extruderTabsCount: 0
- Component.onCompleted:
+ Connections
{
- // Populate extruder tabs after a short delay, because otherwise the tabs that are added when
- // the dialog is created are stuck.
- extruderTabsCountDelay.start();
- }
-
- Timer
- {
- id: extruderTabsCountDelay
- repeat: false
- interval: 1
-
- onTriggered:
+ target: base.extrudersModel
+ onModelChanged:
{
- var extruderCount = parseInt(machineExtruderCountProvider.properties.value);
- base.extruderTabsCount = (extruderCount > 1) ? extruderCount : 0;
+ var extruderCount = base.extrudersModel.rowCount();
+ base.extruderTabsCount = extruderCount > 1 ? extruderCount : 0;
}
}
@@ -46,7 +36,6 @@ Cura.MachineAction
onAccepted: manager.onFinishAction()
onRejected: manager.onFinishAction()
onClosing: manager.onFinishAction()
- onVisibilityChanged: extruderTabsCountDelay.start()
}
anchors.fill: parent;
@@ -383,7 +372,6 @@ Cura.MachineAction
onActivated:
{
manager.setMachineExtruderCount(index + 1);
- base.extruderTabsCount = (index > 0) ? index + 1 : 0;
}
}
diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py
index b283608cb0..65159888b0 100644
--- a/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py
+++ b/plugins/PerObjectSettingsTool/PerObjectSettingVisibilityHandler.py
@@ -63,17 +63,20 @@ class PerObjectSettingVisibilityHandler(UM.Settings.Models.SettingVisibilityHand
stack_nr = -1
stack = None
# Check from what stack we should copy the raw property of the setting from.
- if definition.limit_to_extruder != "-1" and self._stack.getProperty("machine_extruder_count", "value") > 1:
- # A limit to extruder function was set and it's a multi extrusion machine. Check what stack we do need to use.
- stack_nr = str(int(round(float(self._stack.getProperty(item, "limit_to_extruder")))))
+ if self._stack.getProperty("machine_extruder_count", "value") > 1:
+ if definition.limit_to_extruder != "-1":
+ # A limit to extruder function was set and it's a multi extrusion machine. Check what stack we do need to use.
+ stack_nr = str(int(round(float(self._stack.getProperty(item, "limit_to_extruder")))))
- # Check if the found stack_number is in the extruder list of extruders.
- if stack_nr not in ExtruderManager.getInstance().extruderIds and self._stack.getProperty("extruder_nr", "value") is not None:
- stack_nr = -1
+ # Check if the found stack_number is in the extruder list of extruders.
+ if stack_nr not in ExtruderManager.getInstance().extruderIds and self._stack.getProperty("extruder_nr", "value") is not None:
+ stack_nr = -1
- # Use the found stack number to get the right stack to copy the value from.
- if stack_nr in ExtruderManager.getInstance().extruderIds:
- stack = ContainerRegistry.getInstance().findContainerStacks(id = ExtruderManager.getInstance().extruderIds[stack_nr])[0]
+ # Use the found stack number to get the right stack to copy the value from.
+ if stack_nr in ExtruderManager.getInstance().extruderIds:
+ stack = ContainerRegistry.getInstance().findContainerStacks(id = ExtruderManager.getInstance().extruderIds[stack_nr])[0]
+ else:
+ stack = self._stack
# Use the raw property to set the value (so the inheritance doesn't break)
if stack is not None:
diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
index c3c7249155..3e78670e02 100644
--- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
+++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
@@ -141,14 +141,6 @@ Item {
storeIndex: 0
removeUnusedValue: false
}
-
- // If the extruder by which the object needs to be printed is changed, ensure that the
- // display is also notified of the fact.
- Connections
- {
- target: extruderSelector
- onActivated: provider.forcePropertiesChanged()
- }
}
}
}
diff --git a/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py b/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py
index 459de3248d..9b0eee7096 100755
--- a/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py
+++ b/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py
@@ -638,7 +638,7 @@ class NetworkPrinterOutputDevice(PrinterOutputDevice):
if self._json_printer_state["heads"][0]["extruders"][index]["hotend"]["id"] == "":
Logger.log("e", "No cartridge loaded in slot %s, unable to start print", index + 1)
self._error_message = Message(
- i18n_catalog.i18nc("@info:status", "Unable to start a new print job. No PrinterCore loaded in slot {0}".format(index + 1)))
+ i18n_catalog.i18nc("@info:status", "Unable to start a new print job. No Printcore loaded in slot {0}".format(index + 1)))
self._error_message.show()
return
if self._json_printer_state["heads"][0]["extruders"][index]["active_material"]["guid"] == "":
diff --git a/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml b/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml
index d59686e34e..5e0096c6b0 100644
--- a/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml
+++ b/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml
@@ -34,7 +34,7 @@ Cura.MachineAction
anchors.topMargin: UM.Theme.getSize("default_margin").height
width: parent.width
wrapMode: Text.WordWrap
- text: catalog.i18nc("@label","Please select any upgrades made to this Ultimaker 2");
+ text: catalog.i18nc("@label","Please select any upgrades made to this Ultimaker 2.");
}
CheckBox
diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py b/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py
index 7a9b102758..055d28b3ab 100644
--- a/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py
+++ b/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2016 Ultimaker B.V.
+# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
import configparser #To get version numbers from config files.
@@ -249,7 +249,9 @@ class VersionUpgrade21to22(VersionUpgrade):
def getCfgVersion(self, serialised):
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
- return int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
+ format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
+ setting_version = int(parser.get("metadata", "setting_version", fallback = 0))
+ return format_version * 1000000 + setting_version
## Gets the fallback quality to use for a specific machine-variant-material
# combination.
diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py b/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py
index f2803ca62f..74d74e61ae 100644
--- a/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py
+++ b/plugins/VersionUpgrade/VersionUpgrade21to22/__init__.py
@@ -18,10 +18,10 @@ def getMetaData():
"api": 3
},
"version_upgrade": {
- # From To Upgrade function
- ("profile", 1): ("quality", 2, upgrade.upgradeProfile),
- ("machine_instance", 1): ("machine_stack", 2, upgrade.upgradeMachineInstance),
- ("preferences", 2): ("preferences", 3, upgrade.upgradePreferences)
+ # From To Upgrade function
+ ("profile", 1000000): ("quality", 2000000, upgrade.upgradeProfile),
+ ("machine_instance", 1000000): ("machine_stack", 2000000, upgrade.upgradeMachineInstance),
+ ("preferences", 2000000): ("preferences", 3000000, upgrade.upgradePreferences)
},
"sources": {
"profile": {
diff --git a/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py b/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py
index b28124f16b..ab934210f6 100644
--- a/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py
+++ b/plugins/VersionUpgrade/VersionUpgrade22to24/VersionUpgrade.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2016 Ultimaker B.V.
+# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
import configparser #To get version numbers from config files.
@@ -77,6 +77,7 @@ class VersionUpgrade22to24(VersionUpgrade):
with open(variant_path, "r") as fhandle:
variant_config.read_file(fhandle)
+ config_name = "Unknown Variant"
if variant_config.has_section("general") and variant_config.has_option("general", "name"):
config_name = variant_config.get("general", "name")
if config_name.endswith("_variant"):
@@ -144,4 +145,6 @@ class VersionUpgrade22to24(VersionUpgrade):
def getCfgVersion(self, serialised):
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
- return int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
+ format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
+ setting_version = int(parser.get("metadata", "setting_version", fallback = 0))
+ return format_version * 1000000 + setting_version
diff --git a/plugins/VersionUpgrade/VersionUpgrade22to24/__init__.py b/plugins/VersionUpgrade/VersionUpgrade22to24/__init__.py
index e1114922d6..0df2c94b75 100644
--- a/plugins/VersionUpgrade/VersionUpgrade22to24/__init__.py
+++ b/plugins/VersionUpgrade/VersionUpgrade22to24/__init__.py
@@ -18,10 +18,10 @@ def getMetaData():
"api": 3
},
"version_upgrade": {
- # From To Upgrade function
- ("machine_instance", 2): ("machine_stack", 3, upgrade.upgradeMachineInstance),
- ("extruder_train", 2): ("extruder_train", 3, upgrade.upgradeExtruderTrain),
- ("preferences", 3): ("preferences", 4, upgrade.upgradePreferences)
+ # 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)
},
"sources": {
diff --git a/plugins/VersionUpgrade/VersionUpgrade24to25/VersionUpgrade24to25.py b/plugins/VersionUpgrade/VersionUpgrade25to26/VersionUpgrade25to26.py
similarity index 84%
rename from plugins/VersionUpgrade/VersionUpgrade24to25/VersionUpgrade24to25.py
rename to plugins/VersionUpgrade/VersionUpgrade25to26/VersionUpgrade25to26.py
index 1af2e7405a..c61962d276 100644
--- a/plugins/VersionUpgrade/VersionUpgrade24to25/VersionUpgrade24to25.py
+++ b/plugins/VersionUpgrade/VersionUpgrade25to26/VersionUpgrade25to26.py
@@ -7,7 +7,8 @@ import io #To serialise configparser output to a string.
from UM.VersionUpgrade import VersionUpgrade
_removed_settings = { #Settings that were removed in 2.5.
- "start_layers_at_same_position"
+ "start_layers_at_same_position",
+ "sub_div_rad_mult"
}
_split_settings = { #These settings should be copied to all settings it was split into.
@@ -15,13 +16,13 @@ _split_settings = { #These settings should be copied to all settings it was spli
}
## A collection of functions that convert the configuration of the user in Cura
-# 2.4 to a configuration for Cura 2.5.
+# 2.5 to a configuration for Cura 2.6.
#
# All of these methods are essentially stateless.
-class VersionUpgrade24to25(VersionUpgrade):
- ## Gets the version number from a CFG file in Uranium's 2.4 format.
+class VersionUpgrade25to26(VersionUpgrade):
+ ## Gets the version number from a CFG file in Uranium's 2.5 format.
#
- # Since the format may change, this is implemented for the 2.4 format only
+ # Since the format may change, this is implemented for the 2.5 format only
# and needs to be included in the version upgrade system rather than
# globally in Uranium.
#
@@ -33,9 +34,11 @@ class VersionUpgrade24to25(VersionUpgrade):
def getCfgVersion(self, serialised):
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialised)
- return int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
+ format_version = int(parser.get("general", "version")) #Explicitly give an exception when this fails. That means that the file format is not recognised.
+ setting_version = int(parser.get("metadata", "setting_version", fallback = 0))
+ return format_version * 1000000 + setting_version
- ## Upgrades the preferences file from version 2.4 to 2.5.
+ ## Upgrades the preferences file from version 2.5 to 2.6.
#
# \param serialised The serialised form of a preferences file.
# \param filename The name of the file to upgrade.
@@ -66,7 +69,7 @@ class VersionUpgrade24to25(VersionUpgrade):
parser.write(output)
return [filename], [output.getvalue()]
- ## Upgrades an instance container from version 2.4 to 2.5.
+ ## Upgrades an instance container from version 2.5 to 2.6.
#
# \param serialised The serialised form of a quality profile.
# \param filename The name of the file to upgrade.
@@ -85,7 +88,7 @@ class VersionUpgrade24to25(VersionUpgrade):
#Change the version number in the file.
if parser.has_section("general"):
- parser["general"]["version"] = "3"
+ parser["general"]["setting_version"] = "1"
#Re-serialise the file.
output = io.StringIO()
diff --git a/plugins/VersionUpgrade/VersionUpgrade24to25/__init__.py b/plugins/VersionUpgrade/VersionUpgrade25to26/__init__.py
similarity index 53%
rename from plugins/VersionUpgrade/VersionUpgrade24to25/__init__.py
rename to plugins/VersionUpgrade/VersionUpgrade25to26/__init__.py
index 701224787c..3aee161e3c 100644
--- a/plugins/VersionUpgrade/VersionUpgrade24to25/__init__.py
+++ b/plugins/VersionUpgrade/VersionUpgrade25to26/__init__.py
@@ -1,28 +1,28 @@
# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the AGPLv3 or higher.
-from . import VersionUpgrade24to25
+from . import VersionUpgrade25to26
from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
-upgrade = VersionUpgrade24to25.VersionUpgrade24to25()
+upgrade = VersionUpgrade25to26.VersionUpgrade25to26()
def getMetaData():
return {
"plugin": {
- "name": catalog.i18nc("@label", "Version Upgrade 2.4 to 2.5"),
+ "name": catalog.i18nc("@label", "Version Upgrade 2.5 to 2.6"),
"author": "Ultimaker",
"version": "1.0",
- "description": catalog.i18nc("@info:whatsthis", "Upgrades configurations from Cura 2.4 to Cura 2.5."),
+ "description": catalog.i18nc("@info:whatsthis", "Upgrades configurations from Cura 2.5 to Cura 2.6."),
"api": 3
},
"version_upgrade": {
- # From To Upgrade function
- ("preferences", 4): ("preferences", 5, upgrade.upgradePreferences),
- ("quality", 2): ("quality", 3, upgrade.upgradeInstanceContainer),
- ("variant", 2): ("variant", 3, upgrade.upgradeInstanceContainer), #We can re-use upgradeContainerStack since there is nothing specific to quality, variant or user profiles being changed.
- ("user", 2): ("user", 3, upgrade.upgradeInstanceContainer)
+ # 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)
},
"sources": {
"quality": {
@@ -41,5 +41,4 @@ def getMetaData():
}
def register(app):
- return {}
return { "version_upgrade": upgrade }
diff --git a/plugins/VersionUpgrade/VersionUpgrade24to25/tests/TestVersionUpgrade24to25.py b/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py
similarity index 85%
rename from plugins/VersionUpgrade/VersionUpgrade24to25/tests/TestVersionUpgrade24to25.py
rename to plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py
index cb7300ad87..78cd8a03c5 100644
--- a/plugins/VersionUpgrade/VersionUpgrade24to25/tests/TestVersionUpgrade24to25.py
+++ b/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py
@@ -4,12 +4,12 @@
import configparser #To check whether the appropriate exceptions are raised.
import pytest #To register tests with.
-import VersionUpgrade24to25 #The module we're testing.
+import VersionUpgrade25to26 #The module we're testing.
## Creates an instance of the upgrader to test with.
@pytest.fixture
def upgrader():
- return VersionUpgrade24to25.VersionUpgrade24to25()
+ return VersionUpgrade25to26.VersionUpgrade25to26()
test_cfg_version_good_data = [
{
@@ -17,7 +17,7 @@ test_cfg_version_good_data = [
"file_data": """[general]
version = 1
""",
- "version": 1
+ "version": 1000000
},
{
"test_name": "Other Data Around",
@@ -31,14 +31,32 @@ version = 3
layer_height = 0.12
infill_sparse_density = 42
""",
- "version": 3
+ "version": 3000000
},
{
"test_name": "Negative Version", #Why not?
"file_data": """[general]
version = -20
""",
- "version": -20
+ "version": -20000000
+ },
+ {
+ "test_name": "Setting Version",
+ "file_data": """[general]
+version = 1
+[metadata]
+setting_version = 1
+""",
+ "version": 1000001
+ },
+ {
+ "test_name": "Negative Setting Version",
+ "file_data": """[general]
+version = 1
+[metadata]
+setting_version = -3
+""",
+ "version": 999997
}
]
@@ -77,6 +95,22 @@ true = false
"test_name": "Not a Number",
"file_data": """[general]
version = not-a-text-version-number
+""",
+ "exception": ValueError
+ },
+ {
+ "test_name": "Setting Value NaN",
+ "file_data": """[general]
+version = 4
+[metadata]
+setting_version = latest_or_something
+""",
+ "exception": ValueError
+ },
+ {
+ "test_name": "Major-Minor",
+ "file_data": """[general]
+version = 1.2
""",
"exception": ValueError
}
@@ -121,7 +155,7 @@ foo = bar
}
]
-## Tests whether the settings that should be removed are removed for the 2.5
+## Tests whether the settings that should be removed are removed for the 2.6
# version of preferences.
@pytest.mark.parametrize("data", test_upgrade_preferences_removed_settings_data)
def test_upgradePreferencesRemovedSettings(data, upgrader):
@@ -137,7 +171,7 @@ def test_upgradePreferencesRemovedSettings(data, upgrader):
upgraded_preferences = upgraded_preferences[0]
#Find whether the removed setting is removed from the file now.
- settings -= VersionUpgrade24to25._removed_settings
+ settings -= VersionUpgrade25to26._removed_settings
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(upgraded_preferences)
assert (parser.has_section("general") and "visible_settings" in parser["general"]) == (len(settings) > 0) #If there are settings, there must also be a preference.
@@ -166,7 +200,7 @@ type = instance_container
}
]
-## Tests whether the settings that should be removed are removed for the 2.5
+## Tests whether the settings that should be removed are removed for the 2.6
# version of instance containers.
@pytest.mark.parametrize("data", test_upgrade_instance_container_removed_settings_data)
def test_upgradeInstanceContainerRemovedSettings(data, upgrader):
@@ -182,7 +216,7 @@ def test_upgradeInstanceContainerRemovedSettings(data, upgrader):
upgraded_container = upgraded_container[0]
#Find whether the forbidden setting is still in the container.
- settings -= VersionUpgrade24to25._removed_settings
+ settings -= VersionUpgrade25to26._removed_settings
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(upgraded_container)
assert parser.has_section("values") == (len(settings) > 0) #If there are settings, there must also be the values category.
diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py
index e813f6e686..197a7b778f 100644
--- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py
+++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py
@@ -21,6 +21,20 @@ class XmlMaterialProfile(InstanceContainer):
super().__init__(container_id, *args, **kwargs)
self._inherited_files = []
+ ## Translates the version number in the XML files to the setting_version
+ # metadata entry.
+ #
+ # Since the two may increment independently we need a way to say which
+ # versions of the XML specification are compatible with our setting data
+ # version numbers.
+ #
+ # \param xml_version: The version number found in an XML file.
+ # \return The corresponding setting_version.
+ def xmlVersionToSettingVersion(self, xml_version: str) -> int:
+ if xml_version == "1.3":
+ return 1
+ return 0 #Older than 1.3.
+
def getInheritedFiles(self):
return self._inherited_files
@@ -409,6 +423,10 @@ class XmlMaterialProfile(InstanceContainer):
inherited = self._resolveInheritance(inherits.text)
data = self._mergeXML(inherited, data)
+ if "version" in data.attrib:
+ meta_data["setting_version"] = self.xmlVersionToSettingVersion(data.attrib["version"])
+ else:
+ meta_data["setting_version"] = self.xmlVersionToSettingVersion("1.2") #1.2 and lower didn't have that version number there yet.
metadata = data.iterfind("./um:metadata/*", self.__namespaces)
for entry in metadata:
tag_name = _tag_without_namespace(entry)
@@ -441,8 +459,7 @@ class XmlMaterialProfile(InstanceContainer):
tag_name = _tag_without_namespace(entry)
property_values[tag_name] = entry.text
- diameter = float(property_values.get("diameter", 2.85)) # In mm
- density = float(property_values.get("density", 1.3)) # In g/cm3
+ meta_data["approximate_diameter"] = round(float(property_values.get("diameter", 2.85))) # In mm
meta_data["properties"] = property_values
self.setDefinition(ContainerRegistry.getInstance().findDefinitionContainers(id = "fdmprinter")[0])
@@ -461,7 +478,6 @@ class XmlMaterialProfile(InstanceContainer):
Logger.log("d", "Unsupported material setting %s", key)
self._cached_values = global_setting_values
- meta_data["approximate_diameter"] = round(diameter)
meta_data["compatible"] = global_compatibility
self.setMetaData(meta_data)
self._dirty = False
diff --git a/resources/definitions/alya3dp.def.json b/resources/definitions/alya3dp.def.json
index a0e9f03fbb..1ea16773d6 100644
--- a/resources/definitions/alya3dp.def.json
+++ b/resources/definitions/alya3dp.def.json
@@ -42,12 +42,6 @@
"machine_nozzle_gantry_distance": {
"default_value": 55
},
- "machine_nozzle_offset_x_1": {
- "default_value": 18
- },
- "machine_nozzle_offset_y_1": {
- "default_value": 0
- },
"machine_gcode_flavor": {
"default_value": "RepRap"
},
diff --git a/resources/definitions/fdmextruder.def.json b/resources/definitions/fdmextruder.def.json
index ff54582885..be006dfe59 100644
--- a/resources/definitions/fdmextruder.def.json
+++ b/resources/definitions/fdmextruder.def.json
@@ -7,6 +7,7 @@
"type": "extruder",
"author": "Ultimaker B.V.",
"manufacturer": "Ultimaker",
+ "setting_version": 1,
"visible": false
},
"settings":
diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json
index 3b25f44c10..bd34d8c7d8 100755
--- a/resources/definitions/fdmprinter.def.json
+++ b/resources/definitions/fdmprinter.def.json
@@ -8,6 +8,7 @@
"author": "Ultimaker B.V.",
"category": "Ultimaker",
"manufacturer": "Ultimaker",
+ "setting_version": 1,
"file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g",
"visible": false,
"has_materials": true,
@@ -1217,19 +1218,6 @@
"enabled": "infill_sparse_density > 0 and spaghetti_infill_enabled",
"settable_per_mesh": true
},
- "sub_div_rad_mult":
- {
- "label": "Cubic Subdivision Radius",
- "description": "A multiplier on the radius from the center of each cube to check for the boundary of the model, as to decide whether this cube should be subdivided. Larger values lead to more subdivisions, i.e. more small cubes.",
- "unit": "%",
- "type": "float",
- "default_value": 100,
- "minimum_value": "0",
- "minimum_value_warning": "100",
- "maximum_value_warning": "200",
- "enabled": "infill_sparse_density > 0 and infill_pattern == 'cubicsubdiv'",
- "settable_per_mesh": true
- },
"sub_div_rad_add":
{
"label": "Cubic Subdivision Shell",
@@ -1346,7 +1334,7 @@
"description": "The height of infill of a given density before switching to half the density.",
"unit": "mm",
"type": "float",
- "default_value": 5.0,
+ "default_value": 1.5,
"minimum_value": "0.0001",
"minimum_value_warning": "3 * resolveOrValue('layer_height')",
"maximum_value_warning": "100",
@@ -2989,7 +2977,7 @@
"description": "The extruder train to use for printing the support. This is used in multi-extrusion.",
"type": "extruder",
"default_value": "0",
- "enabled": "machine_extruder_count > 1",
+ "enabled": "support_enable and machine_extruder_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": false,
"children": {
@@ -3000,7 +2988,7 @@
"type": "extruder",
"default_value": "0",
"value": "support_extruder_nr",
- "enabled": "machine_extruder_count > 1",
+ "enabled": "support_enable and machine_extruder_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": false
},
@@ -3011,7 +2999,7 @@
"type": "extruder",
"default_value": "0",
"value": "support_extruder_nr",
- "enabled": "machine_extruder_count > 1",
+ "enabled": "support_enable and machine_extruder_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": false
},
@@ -3022,7 +3010,7 @@
"type": "extruder",
"default_value": "0",
"value": "support_extruder_nr",
- "enabled": "machine_extruder_count > 1",
+ "enabled": "support_enable and machine_extruder_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": false,
"children":
@@ -3034,7 +3022,7 @@
"type": "extruder",
"default_value": "0",
"value": "support_interface_extruder_nr",
- "enabled": "machine_extruder_count > 1",
+ "enabled": "support_enable and machine_extruder_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": false
},
@@ -3045,7 +3033,7 @@
"type": "extruder",
"default_value": "0",
"value": "support_interface_extruder_nr",
- "enabled": "machine_extruder_count > 1",
+ "enabled": "support_enable and machine_extruder_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": false
}
@@ -3098,7 +3086,7 @@
"zigzag": "Zig Zag"
},
"default_value": "zigzag",
- "enabled": true,
+ "enabled": "support_enable",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
@@ -3109,7 +3097,7 @@
"description": "Connect the ZigZags. This will increase the strength of the zig zag support structure.",
"type": "bool",
"default_value": true,
- "enabled": "support_pattern == 'zigzag'",
+ "enabled": "support_enable and (support_pattern == 'zigzag')",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true
@@ -3123,7 +3111,7 @@
"minimum_value": "0",
"maximum_value_warning": "100",
"default_value": 15,
- "enabled": true,
+ "enabled": "support_enable",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": true,
@@ -3138,7 +3126,7 @@
"minimum_value": "0",
"minimum_value_warning": "support_line_width",
"default_value": 2.66,
- "enabled": true,
+ "enabled": "support_enable",
"value": "(support_line_width * 100) / support_infill_rate * (2 if support_pattern == 'grid' else (3 if support_pattern == 'triangles' else 1))",
"limit_to_extruder": "support_infill_extruder_nr",
"settable_per_mesh": false,
@@ -3291,7 +3279,7 @@
"type": "bool",
"default_value": false,
"limit_to_extruder": "support_interface_extruder_nr",
- "enabled": true,
+ "enabled": "support_enable",
"settable_per_mesh": true,
"children":
{
@@ -3303,7 +3291,7 @@
"default_value": false,
"value": "support_interface_enable",
"limit_to_extruder": "support_roof_extruder_nr",
- "enabled": true,
+ "enabled": "support_enable",
"settable_per_mesh": true
},
"support_bottom_enable":
@@ -3314,7 +3302,7 @@
"default_value": false,
"value": "support_interface_enable",
"limit_to_extruder": "support_bottom_extruder_nr",
- "enabled": true,
+ "enabled": "support_enable",
"settable_per_mesh": true
}
}
@@ -3330,7 +3318,7 @@
"minimum_value_warning": "0.2 + resolveOrValue('layer_height')",
"maximum_value_warning": "10",
"limit_to_extruder": "support_interface_extruder_nr",
- "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable')",
+ "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
"settable_per_mesh": true,
"children":
{
@@ -3346,7 +3334,7 @@
"maximum_value_warning": "10",
"value": "extruderValue(support_roof_extruder_nr, 'support_interface_height')",
"limit_to_extruder": "support_roof_extruder_nr",
- "enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable')",
+ "enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
"settable_per_mesh": true
},
"support_bottom_height":
@@ -3361,7 +3349,7 @@
"minimum_value_warning": "min(0.2 + resolveOrValue('layer_height'), extruderValue(support_bottom_extruder_nr, 'support_bottom_stair_step_height'))",
"maximum_value_warning": "10",
"limit_to_extruder": "support_bottom_extruder_nr",
- "enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable')",
+ "enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
"settable_per_mesh": true
}
}
@@ -3375,7 +3363,7 @@
"minimum_value": "0",
"maximum_value_warning": "support_interface_height",
"limit_to_extruder": "support_interface_extruder_nr",
- "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable')",
+ "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
"settable_per_mesh": true
},
"support_interface_density":
@@ -3388,7 +3376,7 @@
"minimum_value": "0",
"maximum_value_warning": "100",
"limit_to_extruder": "support_interface_extruder_nr",
- "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable')",
+ "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
"settable_per_mesh": false,
"settable_per_extruder": true,
"children":
@@ -3403,7 +3391,7 @@
"minimum_value": "0",
"maximum_value": "100",
"limit_to_extruder": "support_roof_extruder_nr",
- "enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable')",
+ "enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
"settable_per_mesh": false,
"settable_per_extruder": true,
"children":
@@ -3419,7 +3407,7 @@
"minimum_value_warning": "support_roof_line_width - 0.0001",
"value": "0 if support_roof_density == 0 else (support_roof_line_width * 100) / support_roof_density * (2 if support_roof_pattern == 'grid' else (3 if support_roof_pattern == 'triangles' else 1))",
"limit_to_extruder": "support_roof_extruder_nr",
- "enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable')",
+ "enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
"settable_per_mesh": false,
"settable_per_extruder": true
}
@@ -3435,7 +3423,7 @@
"minimum_value": "0",
"maximum_value": "100",
"limit_to_extruder": "support_bottom_extruder_nr",
- "enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable')",
+ "enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
"settable_per_mesh": false,
"settable_per_extruder": true,
"children":
@@ -3451,7 +3439,7 @@
"minimum_value_warning": "support_bottom_line_width - 0.0001",
"value": "0 if support_bottom_density == 0 else (support_bottom_line_width * 100) / support_bottom_density * (2 if support_bottom_pattern == 'grid' else (3 if support_bottom_pattern == 'triangles' else 1))",
"limit_to_extruder": "support_bottom_extruder_nr",
- "enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable')",
+ "enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
"settable_per_mesh": false,
"settable_per_extruder": true
}
@@ -3475,7 +3463,7 @@
},
"default_value": "concentric",
"limit_to_extruder": "support_interface_extruder_nr",
- "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable')",
+ "enabled": "extruderValue(support_interface_extruder_nr, 'support_interface_enable') and support_enable",
"settable_per_mesh": false,
"settable_per_extruder": true,
"children":
@@ -3497,7 +3485,7 @@
"default_value": "concentric",
"value": "support_interface_pattern",
"limit_to_extruder": "support_roof_extruder_nr",
- "enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable')",
+ "enabled": "extruderValue(support_roof_extruder_nr, 'support_roof_enable') and support_enable",
"settable_per_mesh": false,
"settable_per_extruder": true
},
@@ -3518,7 +3506,7 @@
"default_value": "concentric",
"value": "support_interface_pattern",
"limit_to_extruder": "support_bottom_extruder_nr",
- "enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable')",
+ "enabled": "extruderValue(support_bottom_extruder_nr, 'support_bottom_enable') and support_enable",
"settable_per_mesh": false,
"settable_per_extruder": true
}
@@ -3594,7 +3582,8 @@
"resolve": "any(extruderValues('prime_blob_enable'))",
"default_value": true,
"settable_per_mesh": false,
- "settable_per_extruder": true
+ "settable_per_extruder": true,
+ "enabled": false
},
"extruder_prime_pos_x":
{
@@ -3635,7 +3624,7 @@
"none": "None"
},
"default_value": "brim",
- "resolve": "'raft' if 'raft' in extruderValues('adhesion_type') else ('brim' if 'brim' in extruderValues('adhesion_type') else 'skirt')",
+ "limit_to_extruder": "adhesion_extruder_nr",
"settable_per_mesh": false,
"settable_per_extruder": false
},
@@ -4215,7 +4204,7 @@
"type": "float",
"unit": "mm",
"enabled": "resolveOrValue('prime_tower_enable')",
- "default_value": 15,
+ "default_value": 20,
"resolve": "max(extruderValues('prime_tower_size'))",
"minimum_value": "0",
"maximum_value": "min(0.5 * machine_width, 0.5 * machine_depth)",
@@ -4472,6 +4461,31 @@
"settable_per_meshgroup": false,
"settable_globally": false
},
+ "infill_mesh_order":
+ {
+ "label": "Infill Mesh Order",
+ "description": "Determines which infill mesh is inside the infill of another infill mesh. An infill mesh with a higher order will modify the infill of infill meshes with lower order and normal meshes.",
+ "default_value": 0,
+ "value": "1 if infill_mesh else 0",
+ "minimum_value_warning": "1",
+ "maximum_value_warning": "50",
+ "type": "int",
+ "settable_per_mesh": true,
+ "settable_per_extruder": false,
+ "settable_per_meshgroup": false,
+ "settable_globally": false
+ },
+ "cutting_mesh":
+ {
+ "label": "Cutting Mesh",
+ "description": "Limit the volume of this mesh to within other meshes. You can use this to make certain areas of one mesh print with different settings and with a whole different extruder.",
+ "type": "bool",
+ "default_value": false,
+ "settable_per_mesh": true,
+ "settable_per_extruder": false,
+ "settable_per_meshgroup": false,
+ "settable_globally": false
+ },
"mold_enabled":
{
"label": "Mold",
@@ -4506,20 +4520,6 @@
"settable_per_mesh": true,
"enabled": "mold_enabled"
},
- "infill_mesh_order":
- {
- "label": "Infill Mesh Order",
- "description": "Determines which infill mesh is inside the infill of another infill mesh. An infill mesh with a higher order will modify the infill of infill meshes with lower order and normal meshes.",
- "default_value": 0,
- "value": "1 if infill_mesh else 0",
- "minimum_value_warning": "1",
- "maximum_value_warning": "50",
- "type": "int",
- "settable_per_mesh": true,
- "settable_per_extruder": false,
- "settable_per_meshgroup": false,
- "settable_globally": false
- },
"support_mesh":
{
"label": "Support Mesh",
@@ -4576,6 +4576,16 @@
"default_value": false,
"settable_per_mesh": false,
"settable_per_extruder": false
+ },
+ "smooth_spiralized_contours":
+ {
+ "label": "Smooth Spiralized Contours",
+ "description": "Smooth the spiralized contours to reduce the visibility of the Z seam (the Z-seam should be barely visible on the print but will still be visible in the layer view). Note that smoothing will tend to blur fine surface details.",
+ "type": "bool",
+ "default_value": true,
+ "enabled": "magic_spiralize",
+ "settable_per_mesh": false,
+ "settable_per_extruder": false
}
}
},
diff --git a/resources/definitions/innovo_inventor.def.json b/resources/definitions/innovo_inventor.def.json
index 40a2849979..4b169c5e31 100644
--- a/resources/definitions/innovo_inventor.def.json
+++ b/resources/definitions/innovo_inventor.def.json
@@ -44,12 +44,6 @@
"gantry_height": {
"default_value": 82.3
},
- "machine_nozzle_offset_x": {
- "default_value": 0
- },
- "machine_nozzle_offset_y": {
- "default_value": 15
- },
"machine_gcode_flavor": {
"default_value": "RepRap (Marlin/Sprinter)"
},
diff --git a/resources/definitions/maker_starter.def.json b/resources/definitions/maker_starter.def.json
index 74cdc694ee..305a35d0ca 100644
--- a/resources/definitions/maker_starter.def.json
+++ b/resources/definitions/maker_starter.def.json
@@ -4,6 +4,7 @@
"name": "3DMaker Starter",
"inherits": "fdmprinter",
"metadata": {
+ "visible": true,
"author": "tvlgiao",
"manufacturer": "3DMaker",
"category": "Other",
diff --git a/resources/definitions/ultimaker2_extended.def.json b/resources/definitions/ultimaker2_extended.def.json
index 803e9fe896..ac9d98c5eb 100644
--- a/resources/definitions/ultimaker2_extended.def.json
+++ b/resources/definitions/ultimaker2_extended.def.json
@@ -11,8 +11,7 @@
"file_formats": "text/x-gcode",
"icon": "icon_ultimaker2.png",
"platform": "ultimaker2_platform.obj",
- "platform_texture": "Ultimaker2Extendedbackplate.png",
- "supported_actions": ["UpgradeFirmware"]
+ "platform_texture": "Ultimaker2Extendedbackplate.png"
},
"overrides": {
diff --git a/resources/definitions/ultimaker2_go.def.json b/resources/definitions/ultimaker2_go.def.json
index 5d4c898ade..5873dfbc90 100644
--- a/resources/definitions/ultimaker2_go.def.json
+++ b/resources/definitions/ultimaker2_go.def.json
@@ -13,6 +13,7 @@
"platform": "ultimaker2go_platform.obj",
"platform_texture": "Ultimaker2Gobackplate.png",
"platform_offset": [0, 0, 0],
+ "first_start_actions": [],
"supported_actions":["UpgradeFirmware"]
},
diff --git a/resources/definitions/ultimaker3.def.json b/resources/definitions/ultimaker3.def.json
index e17316a80b..d1f8b19e36 100644
--- a/resources/definitions/ultimaker3.def.json
+++ b/resources/definitions/ultimaker3.def.json
@@ -73,6 +73,8 @@
"prime_tower_position_y": { "default_value": 178 },
"prime_tower_wipe_enabled": { "default_value": false },
+ "prime_blob_enable": { "enabled": true },
+
"acceleration_enabled": { "value": "True" },
"acceleration_layer_0": { "value": "acceleration_topbottom" },
"acceleration_prime_tower": { "value": "math.ceil(acceleration_print * 2000 / 4000)" },
@@ -111,7 +113,7 @@
"material_bed_temperature_layer_0": { "maximum_value": "115" },
"material_standby_temperature": { "value": "100" },
"multiple_mesh_overlap": { "value": "0" },
- "prime_tower_enable": { "value": "True" },
+ "prime_tower_enable": { "default_value": true },
"raft_airgap": { "value": "0" },
"raft_base_thickness": { "value": "0.3" },
"raft_interface_line_spacing": { "value": "0.5" },
diff --git a/resources/meshes/FT-5_build_plate.stl b/resources/meshes/FT-5_build_plate.stl
index 2891632d5f..009eebbfb5 100644
Binary files a/resources/meshes/FT-5_build_plate.stl and b/resources/meshes/FT-5_build_plate.stl differ
diff --git a/resources/meshes/kossel_pro_build_platform.stl b/resources/meshes/kossel_pro_build_platform.stl
index 8188f0408f..31dcea7dc8 100644
Binary files a/resources/meshes/kossel_pro_build_platform.stl and b/resources/meshes/kossel_pro_build_platform.stl differ
diff --git a/resources/meshes/makeR_prusa_tairona_i3_platform.stl b/resources/meshes/makeR_prusa_tairona_i3_platform.stl
index 2e4b650637..d6e2b92a8e 100644
Binary files a/resources/meshes/makeR_prusa_tairona_i3_platform.stl and b/resources/meshes/makeR_prusa_tairona_i3_platform.stl differ
diff --git a/resources/meshes/mendel90_platform.stl b/resources/meshes/mendel90_platform.stl
index 706c90539d..e9cccea41a 100644
Binary files a/resources/meshes/mendel90_platform.stl and b/resources/meshes/mendel90_platform.stl differ
diff --git a/resources/meshes/printrbot_simple_metal_upgrade.stl b/resources/meshes/printrbot_simple_metal_upgrade.stl
index 3ff934c478..4df4ee6217 100644
Binary files a/resources/meshes/printrbot_simple_metal_upgrade.stl and b/resources/meshes/printrbot_simple_metal_upgrade.stl differ
diff --git a/resources/meshes/prusai3_xl_platform.stl b/resources/meshes/prusai3_xl_platform.stl
index c4b8dd1c99..ad66835c06 100644
Binary files a/resources/meshes/prusai3_xl_platform.stl and b/resources/meshes/prusai3_xl_platform.stl differ
diff --git a/resources/qml/DiscardOrKeepProfileChangesDialog.qml b/resources/qml/DiscardOrKeepProfileChangesDialog.qml
index 4233bb9e18..f3c790e416 100644
--- a/resources/qml/DiscardOrKeepProfileChangesDialog.qml
+++ b/resources/qml/DiscardOrKeepProfileChangesDialog.qml
@@ -14,8 +14,8 @@ UM.Dialog
id: base
title: catalog.i18nc("@title:window", "Discard or Keep changes")
- width: 800 * Screen.devicePixelRatio
- height: 400 * Screen.devicePixelRatio
+ width: 800
+ height: 400
property var changesModel: Cura.UserChangesModel{ id: userChangesModel}
onVisibilityChanged:
{
@@ -36,9 +36,14 @@ UM.Dialog
}
}
- Column
+ Row
{
- anchors.fill: parent
+ id: infoTextRow
+ height: childrenRect.height
+ anchors.margins: UM.Theme.getSize("default_margin").width
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: parent.top
spacing: UM.Theme.getSize("default_margin").width
UM.I18nCatalog
@@ -47,29 +52,25 @@ UM.Dialog
name: "cura"
}
- Row
+ Label
{
- height: childrenRect.height
+ text: catalog.i18nc("@text:window", "You have customized some profile settings.\nWould you like to keep or discard those settings?")
anchors.margins: UM.Theme.getSize("default_margin").width
- anchors.left: parent.left
- anchors.right: parent.right
- spacing: UM.Theme.getSize("default_margin").width
-
- Label
- {
- text: catalog.i18nc("@text:window", "You have customized some profile settings.\nWould you like to keep or discard those settings?")
- anchors.margins: UM.Theme.getSize("default_margin").width
- font: UM.Theme.getFont("default")
- wrapMode: Text.WordWrap
- }
+ wrapMode: Text.WordWrap
}
+ }
+ Item
+ {
+ anchors.margins: UM.Theme.getSize("default_margin").width
+ anchors.top: infoTextRow.bottom
+ anchors.bottom: optionRow.top
+ anchors.left: parent.left
+ anchors.right: parent.right
TableView
{
- anchors.margins: UM.Theme.getSize("default_margin").width
- anchors.left: parent.left
- anchors.right: parent.right
- height: base.height - 150 * Screen.devicePixelRatio
+ anchors.fill: parent
+ height: base.height - 150
id: tableView
Component
{
@@ -132,92 +133,96 @@ UM.Dialog
model: base.changesModel
}
+ }
- Item
+ Item
+ {
+ id: optionRow
+ anchors.bottom: buttonsRow.top
+ anchors.right: parent.right
+ anchors.left: parent.left
+ anchors.margins: UM.Theme.getSize("default_margin").width
+ height: childrenRect.height
+
+ ComboBox
{
- anchors.right: parent.right
- anchors.left: parent.left
- anchors.margins: UM.Theme.getSize("default_margin").width
- height:childrenRect.height
+ id: discardOrKeepProfileChangesDropDownButton
+ width: 300
- ComboBox
+ model: ListModel
{
- id: discardOrKeepProfileChangesDropDownButton
- width: 300
+ id: discardOrKeepProfileListModel
- model: ListModel
- {
- id: discardOrKeepProfileListModel
-
- Component.onCompleted: {
- append({ text: catalog.i18nc("@option:discardOrKeep", "Always ask me this"), code: "always_ask" })
- append({ text: catalog.i18nc("@option:discardOrKeep", "Discard and never ask again"), code: "always_discard" })
- append({ text: catalog.i18nc("@option:discardOrKeep", "Keep and never ask again"), code: "always_keep" })
- }
- }
-
- onActivated:
- {
- var code = model.get(index).code;
- UM.Preferences.setValue("cura/choice_on_profile_override", code);
-
- if (code == "always_keep") {
- keepButton.enabled = true;
- discardButton.enabled = false;
- }
- else if (code == "always_discard") {
- keepButton.enabled = false;
- discardButton.enabled = true;
- }
- else {
- keepButton.enabled = true;
- discardButton.enabled = true;
- }
- }
- }
- }
-
- Item
- {
- anchors.right: parent.right
- anchors.left: parent.left
- anchors.margins: UM.Theme.getSize("default_margin").width
- height: childrenRect.height
-
- Button
- {
- id: discardButton
- text: catalog.i18nc("@action:button", "Discard");
- anchors.right: parent.right
- onClicked:
- {
- CuraApplication.discardOrKeepProfileChangesClosed("discard")
- base.hide()
- }
- isDefault: true
- }
-
- Button
- {
- id: keepButton
- text: catalog.i18nc("@action:button", "Keep");
- anchors.right: discardButton.left
- anchors.rightMargin: UM.Theme.getSize("default_margin").width
- onClicked:
- {
- CuraApplication.discardOrKeepProfileChangesClosed("keep")
- base.hide()
+ Component.onCompleted: {
+ append({ text: catalog.i18nc("@option:discardOrKeep", "Always ask me this"), code: "always_ask" })
+ append({ text: catalog.i18nc("@option:discardOrKeep", "Discard and never ask again"), code: "always_discard" })
+ append({ text: catalog.i18nc("@option:discardOrKeep", "Keep and never ask again"), code: "always_keep" })
}
}
- Button
+ onActivated:
{
- id: createNewProfileButton
- text: catalog.i18nc("@action:button", "Create New Profile");
- anchors.left: parent.left
- action: Cura.Actions.addProfile
- onClicked: base.hide()
+ var code = model.get(index).code;
+ UM.Preferences.setValue("cura/choice_on_profile_override", code);
+
+ if (code == "always_keep") {
+ keepButton.enabled = true;
+ discardButton.enabled = false;
+ }
+ else if (code == "always_discard") {
+ keepButton.enabled = false;
+ discardButton.enabled = true;
+ }
+ else {
+ keepButton.enabled = true;
+ discardButton.enabled = true;
+ }
}
}
}
+
+ Item
+ {
+ id: buttonsRow
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+ anchors.left: parent.left
+ anchors.margins: UM.Theme.getSize("default_margin").width
+ height: childrenRect.height
+
+ Button
+ {
+ id: discardButton
+ text: catalog.i18nc("@action:button", "Discard");
+ anchors.right: parent.right
+ onClicked:
+ {
+ CuraApplication.discardOrKeepProfileChangesClosed("discard")
+ base.hide()
+ }
+ isDefault: true
+ }
+
+ Button
+ {
+ id: keepButton
+ text: catalog.i18nc("@action:button", "Keep");
+ anchors.right: discardButton.left
+ anchors.rightMargin: UM.Theme.getSize("default_margin").width
+ onClicked:
+ {
+ CuraApplication.discardOrKeepProfileChangesClosed("keep")
+ base.hide()
+ }
+ }
+
+ Button
+ {
+ id: createNewProfileButton
+ text: catalog.i18nc("@action:button", "Create New Profile");
+ anchors.left: parent.left
+ action: Cura.Actions.addProfile
+ onClicked: base.hide()
+ }
+ }
}
\ No newline at end of file
diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml
index 6013117728..13d855d993 100644
--- a/resources/qml/JobSpecs.qml
+++ b/resources/qml/JobSpecs.qml
@@ -24,6 +24,7 @@ Item {
UM.I18nCatalog { id: catalog; name:"cura"}
property variant printDuration: PrintInformation.currentPrintTime
+ property variant printDurationPerFeature: PrintInformation.printTimesPerFeature
property variant printMaterialLengths: PrintInformation.materialLengths
property variant printMaterialWeights: PrintInformation.materialWeights
property variant printMaterialCosts: PrintInformation.materialCosts
@@ -159,7 +160,7 @@ Item {
UM.RecolorImage
{
id: timeIcon
- anchors.right: timeSpec.left
+ anchors.right: timeSpecPerFeatureTooltipArea.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width/2
anchors.verticalCenter: parent.verticalCenter
width: UM.Theme.getSize("save_button_specs_icons").width
@@ -169,15 +170,50 @@ Item {
color: UM.Theme.getColor("text_subtext")
source: UM.Theme.getIcon("print_time")
}
- Text
+ UM.TooltipArea
{
- id: timeSpec
+ id: timeSpecPerFeatureTooltipArea
+ text: {
+ var order = ["inset_0", "inset_x", "skin", "infill", "support_infill", "support_interface", "support", "travel", "retract", "none"];
+ var visible_names = {
+ "inset_0": catalog.i18nc("@tooltip", "Outer Wall"),
+ "inset_x": catalog.i18nc("@tooltip", "Inner Walls"),
+ "skin": catalog.i18nc("@tooltip", "Skin"),
+ "infill": catalog.i18nc("@tooltip", "Infill"),
+ "support_infill": catalog.i18nc("@tooltip", "Support Infill"),
+ "support_interface": catalog.i18nc("@tooltip", "Support Interface"),
+ "support": catalog.i18nc("@tooltip", "Support"),
+ "travel": catalog.i18nc("@tooltip", "Travel"),
+ "retract": catalog.i18nc("@tooltip", "Retractions"),
+ "none": catalog.i18nc("@tooltip", "Other")
+ };
+ var result = "";
+ for(var feature in order)
+ {
+ feature = order[feature];
+ if(base.printDurationPerFeature[feature] && base.printDurationPerFeature[feature].totalSeconds > 0)
+ {
+ result += "
" + visible_names[feature] + ": " + base.printDurationPerFeature[feature].getDisplayString(UM.DurationFormat.Short);
+ }
+ }
+ result = result.replace(/^\
/, ""); // remove newline before first item
+ return result;
+ }
+ width: childrenRect.width
+ height: childrenRect.height
anchors.right: lengthIcon.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width
anchors.verticalCenter: parent.verticalCenter
- font: UM.Theme.getFont("small")
- color: UM.Theme.getColor("text_subtext")
- text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short)
+
+ Text
+ {
+ id: timeSpec
+ anchors.left: parent.left
+ anchors.top: parent.top
+ font: UM.Theme.getFont("small")
+ color: UM.Theme.getColor("text_subtext")
+ text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short)
+ }
}
UM.RecolorImage
{
diff --git a/resources/qml/MultiplyObjectOptions.qml b/resources/qml/MultiplyObjectOptions.qml
deleted file mode 100644
index a079369d0d..0000000000
--- a/resources/qml/MultiplyObjectOptions.qml
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright (c) 2015 Ultimaker B.V.
-// Cura is released under the terms of the AGPLv3 or higher.
-
-import QtQuick 2.2
-import QtQuick.Controls 1.1
-import QtQuick.Window 2.1
-
-import UM 1.1 as UM
-
-UM.Dialog
-{
- id: base
-
- //: Dialog title
- title: catalog.i18nc("@title:window", "Multiply Model")
-
- minimumWidth: 400 * Screen.devicePixelRatio
- minimumHeight: 80 * Screen.devicePixelRatio
- width: minimumWidth
- height: minimumHeight
-
- property var objectId: 0;
- onAccepted: CuraApplication.multiplyObject(base.objectId, parseInt(copiesField.text))
-
- property variant catalog: UM.I18nCatalog { name: "cura" }
-
- signal reset()
- onReset: {
- copiesField.text = "1";
- copiesField.selectAll();
- copiesField.focus = true;
- }
-
- Row
- {
- spacing: UM.Theme.getSize("default_margin").width
-
- Label {
- text: "Number of copies:"
- anchors.verticalCenter: copiesField.verticalCenter
- }
-
- TextField {
- id: copiesField
- validator: RegExpValidator { regExp: /^\d{0,2}/ }
- maximumLength: 2
- }
- }
-
-
- rightButtons:
- [
- Button
- {
- text: catalog.i18nc("@action:button","OK")
- onClicked: base.accept()
- enabled: base.objectId != 0 && parseInt(copiesField.text) > 0
- },
- Button
- {
- text: catalog.i18nc("@action:button","Cancel")
- onClicked: base.reject()
- }
- ]
-}
-
diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml
index 689f7aafa9..f825cfc08c 100755
--- a/resources/qml/Preferences/GeneralPage.qml
+++ b/resources/qml/Preferences/GeneralPage.qml
@@ -322,7 +322,7 @@ UM.PreferencesPage
UM.TooltipArea {
width: childrenRect.width;
height: childrenRect.height;
- text: catalog.i18nc("@info:tooltip","Moves the camera so the model is in the center of the view when an model is selected")
+ text: catalog.i18nc("@info:tooltip","Moves the camera so the model is in the center of the view when a model is selected")
CheckBox
{
diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml
index 79314ca5cf..85d19b0cf0 100644
--- a/resources/qml/Settings/SettingView.qml
+++ b/resources/qml/Settings/SettingView.qml
@@ -154,7 +154,7 @@ Item
id: definitionsModel;
containerId: Cura.MachineManager.activeDefinitionId
visibilityHandler: UM.SettingPreferenceVisibilityHandler { }
- exclude: ["machine_settings", "command_line_settings", "infill_mesh", "infill_mesh_order", "support_mesh", "anti_overhang_mesh"] // TODO: infill_mesh settigns are excluded hardcoded, but should be based on the fact that settable_globally, settable_per_meshgroup and settable_per_extruder are false.
+ exclude: ["machine_settings", "command_line_settings", "infill_mesh", "infill_mesh_order", "cutting_mesh", "support_mesh", "anti_overhang_mesh"] // TODO: infill_mesh settigns are excluded hardcoded, but should be based on the fact that settable_globally, settable_per_meshgroup and settable_per_extruder are false.
expanded: CuraApplication.expandedCategories
onExpandedChanged:
{
diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml
index 86185727b2..1e4a715095 100644
--- a/resources/qml/SidebarSimple.qml
+++ b/resources/qml/SidebarSimple.qml
@@ -30,6 +30,7 @@ Item
id: infillCellLeft
anchors.top: parent.top
anchors.left: parent.left
+ anchors.topMargin: UM.Theme.getSize("default_margin").height
width: base.width * .45 - UM.Theme.getSize("default_margin").width
height: childrenRect.height
@@ -47,12 +48,13 @@ Item
}
}
- Flow
+ Row
{
id: infillCellRight
height: childrenRect.height;
- width: base.width * .55
+ width: base.width * .5
+
spacing: UM.Theme.getSize("default_margin").width
anchors.left: infillCellLeft.right
@@ -63,10 +65,11 @@ Item
id: infillListView
property int activeIndex:
{
- var density = parseInt(infillDensity.properties.value)
+ var density = parseInt(infillDensity.properties.value);
+ var steps = parseInt(infillSteps.properties.value);
for(var i = 0; i < infillModel.count; ++i)
{
- if(density > infillModel.get(i).percentageMin && density <= infillModel.get(i).percentageMax )
+ if(density > infillModel.get(i).percentageMin && density <= infillModel.get(i).percentageMax && steps > infillModel.get(i).stepsMin && steps <= infillModel.get(i).stepsMax)
{
return i;
}
@@ -85,7 +88,7 @@ Item
{
id: infillIconLining
- width: (infillCellRight.width - 3 * UM.Theme.getSize("default_margin").width) / 4;
+ width: (infillCellRight.width - ((infillModel.count - 1) * UM.Theme.getSize("default_margin").width)) / (infillModel.count);
height: width
border.color:
@@ -122,7 +125,7 @@ Item
{
id: infillIcon
anchors.fill: parent;
- anchors.margins: UM.Theme.getSize("infill_button_margin").width
+ anchors.margins: 2
sourceSize.width: width
sourceSize.height: width
@@ -150,6 +153,7 @@ Item
if (infillListView.activeIndex != index)
{
infillDensity.setPropertyValue("value", model.percentage)
+ infillSteps.setPropertyValue("value", model.steps)
}
}
onEntered:
@@ -181,37 +185,61 @@ Item
Component.onCompleted:
{
infillModel.append({
- name: catalog.i18nc("@label", "Hollow"),
+ name: catalog.i18nc("@label", "0%"),
percentage: 0,
+ steps: 0,
percentageMin: -1,
percentageMax: 0,
- text: catalog.i18nc("@label", "No (0%) infill will leave your model hollow at the cost of low strength"),
+ stepsMin: -1,
+ stepsMax: 0,
+ text: catalog.i18nc("@label", "Empty infill will leave your model hollow with low strength."),
icon: "hollow"
})
infillModel.append({
- name: catalog.i18nc("@label", "Light"),
+ name: catalog.i18nc("@label", "20%"),
percentage: 20,
+ steps: 0,
percentageMin: 0,
percentageMax: 30,
- text: catalog.i18nc("@label", "Light (20%) infill will give your model an average strength"),
+ stepsMin: -1,
+ stepsMax: 0,
+ text: catalog.i18nc("@label", "Light (20%) infill will give your model an average strength."),
icon: "sparse"
})
infillModel.append({
- name: catalog.i18nc("@label", "Dense"),
+ name: catalog.i18nc("@label", "50%"),
percentage: 50,
+ steps: 0,
percentageMin: 30,
percentageMax: 70,
- text: catalog.i18nc("@label", "Dense (50%) infill will give your model an above average strength"),
+ stepsMin: -1,
+ stepsMax: 0,
+ text: catalog.i18nc("@label", "Dense (50%) infill will give your model an above average strength."),
icon: "dense"
})
infillModel.append({
- name: catalog.i18nc("@label", "Solid"),
+ name: catalog.i18nc("@label", "100%"),
percentage: 100,
+ steps: 0,
percentageMin: 70,
- percentageMax: 100,
- text: catalog.i18nc("@label", "Solid (100%) infill will make your model completely solid"),
+ percentageMax: 9999999999,
+ stepsMin: -1,
+ stepsMax: 0,
+ text: catalog.i18nc("@label", "Solid (100%) infill will make your model completely solid."),
icon: "solid"
})
+ infillModel.append({
+ name: catalog.i18nc("@label", "Gradual"),
+ percentage: 90,
+ steps: 5,
+ percentageMin: 0,
+ percentageMax: 9999999999,
+ stepsMin: 0,
+ stepsMax: 9999999999,
+ infill_layer_height: 1.5,
+ text: catalog.i18nc("@label", "Gradual infill will gradually increase the amount of infill towards the top."),
+ icon: "gradual"
+ })
}
}
}
@@ -220,7 +248,7 @@ Item
{
id: helpersCell
anchors.top: infillCellRight.bottom
- anchors.topMargin: UM.Theme.getSize("default_margin").height
+ anchors.topMargin: UM.Theme.getSize("default_margin").height * 2
anchors.left: parent.left
anchors.right: parent.right
height: childrenRect.height
@@ -392,7 +420,7 @@ Item
property alias _hovered: adhesionMouseArea.containsMouse
anchors.top: supportExtruderCombobox.bottom
- anchors.topMargin: UM.Theme.getSize("default_margin").height
+ anchors.topMargin: UM.Theme.getSize("default_margin").height * 2
anchors.left: adhesionHelperLabel.right
anchors.leftMargin: UM.Theme.getSize("default_margin").width
@@ -467,7 +495,7 @@ Item
{
id: tipsCell
anchors.top: helpersCell.bottom
- anchors.topMargin: UM.Theme.getSize("default_margin").height
+ anchors.topMargin: UM.Theme.getSize("default_margin").height * 2
anchors.left: parent.left
width: parent.width
height: childrenRect.height
@@ -480,7 +508,7 @@ Item
anchors.rightMargin: UM.Theme.getSize("default_margin").width
wrapMode: Text.WordWrap
//: Tips label
- text: catalog.i18nc("@label", "Need help improving your prints? Read the Ultimaker Troubleshooting Guides").arg("https://ultimaker.com/en/troubleshooting");
+ text: catalog.i18nc("@label", "Need help improving your prints?
Read the Ultimaker Troubleshooting Guides").arg("https://ultimaker.com/en/troubleshooting");
font: UM.Theme.getFont("default");
color: UM.Theme.getColor("text");
linkColor: UM.Theme.getColor("text_link")
@@ -498,6 +526,16 @@ Item
storeIndex: 0
}
+ UM.SettingPropertyProvider
+ {
+ id: infillSteps
+
+ containerStackId: Cura.MachineManager.activeStackId
+ key: "gradual_infill_steps"
+ watchedProperties: [ "value" ]
+ storeIndex: 0
+ }
+
UM.SettingPropertyProvider
{
id: platformAdhesionType
diff --git a/resources/qml/WorkspaceSummaryDialog.qml b/resources/qml/WorkspaceSummaryDialog.qml
index 7da8495da0..3a66d04625 100644
--- a/resources/qml/WorkspaceSummaryDialog.qml
+++ b/resources/qml/WorkspaceSummaryDialog.qml
@@ -13,13 +13,10 @@ UM.Dialog
{
title: catalog.i18nc("@title:window", "Save Project")
- width: 550 * Screen.devicePixelRatio
- minimumWidth: 550 * Screen.devicePixelRatio
+ width: 500
+ height: 400
- height: 350 * Screen.devicePixelRatio
- minimumHeight: 350 * Screen.devicePixelRatio
-
- property int spacerHeight: 10 * Screen.devicePixelRatio
+ property int spacerHeight: 10
property bool dontShowAgain: true
@@ -42,7 +39,6 @@ UM.Dialog
Item
{
anchors.fill: parent
- anchors.margins: 20 * Screen.devicePixelRatio
UM.SettingDefinitionsModel
{
@@ -232,42 +228,43 @@ UM.Dialog
height: spacerHeight
width: height
}
-
- CheckBox
- {
- id: dontShowAgainCheckbox
- text: catalog.i18nc("@action:label", "Don't show project summary on save again")
- checked: dontShowAgain
- }
}
+ CheckBox
+ {
+ id: dontShowAgainCheckbox
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+
+ text: catalog.i18nc("@action:label", "Don't show project summary on save again")
+ checked: dontShowAgain
+ }
+
+ Button
+ {
+ id: cancel_button
+ anchors.bottom: parent.bottom
+ anchors.right: ok_button.left
+ anchors.rightMargin: 2
+
+ text: catalog.i18nc("@action:button","Cancel");
+ enabled: true
+ onClicked: close()
+ }
+
Button
{
id: ok_button
+ anchors.bottom: parent.bottom
+ anchors.right: parent.right
+
text: catalog.i18nc("@action:button","Save");
enabled: true
onClicked: {
close()
yes()
}
- anchors.bottomMargin: - 0.5 * height
- anchors.bottom: parent.bottom
- anchors.right: parent.right
- }
-
- Button
- {
- id: cancel_button
- text: catalog.i18nc("@action:button","Cancel");
- enabled: true
- onClicked: close()
-
- anchors.bottom: parent.bottom
- anchors.right: ok_button.left
- anchors.bottomMargin: - 0.5 * height
- anchors.rightMargin:2
-
}
}
}
\ No newline at end of file
diff --git a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg
index 7f3bf240ac..c803cd6196 100644
--- a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg
+++ b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg
@@ -1,4 +1,3 @@
-
[general]
version = 2
name = Normal Quality
@@ -9,6 +8,7 @@ type = quality
material = generic_pla
weight = 0
quality_type = normal
+setting_version = 1
[values]
layer_height = 0.2
diff --git a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg
index be93de160e..f22daa56a5 100644
--- a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg
+++ b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg
@@ -1,4 +1,3 @@
-
[general]
version = 2
name = High Quality
@@ -9,6 +8,7 @@ type = quality
material = generic_pla
weight = 1
quality_type = high
+setting_version = 1
[values]
layer_height = 0.1
diff --git a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg
index a116ff4485..198676d024 100644
--- a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg
+++ b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg
@@ -1,4 +1,3 @@
-
[general]
version = 2
name = Normal Quality
@@ -9,6 +8,7 @@ type = quality
material = generic_pla
weight = 0
quality_type = normal
+setting_version = 1
[values]
layer_height = 0.2
diff --git a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg
index 4bfb02fe77..8ef82f2f76 100644
--- a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg
+++ b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg
@@ -1,4 +1,3 @@
-
[general]
version = 2
name = Normal Quality
@@ -9,6 +8,7 @@ type = quality
material = generic_pla
weight = 0
quality_type = normal
+setting_version = 1
[values]
layer_height = 0.2
diff --git a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg
index 4c89f5cf28..79af56ff3d 100644
--- a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg
+++ b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg
@@ -1,4 +1,3 @@
-
[general]
version = 2
name = High Quality
@@ -9,6 +8,7 @@ type = quality
material = generic_pla
weight = 1
quality_type = high
+setting_version = 1
[values]
layer_height = 0.1
diff --git a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg
index fc11c5af19..50a01e9de1 100644
--- a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg
+++ b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg
@@ -1,4 +1,3 @@
-
[general]
version = 2
name = Normal Quality
@@ -9,6 +8,7 @@ type = quality
material = generic_pla
weight = 0
quality_type = normal
+setting_version = 1
[values]
layer_height = 0.2
diff --git a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg
index 63189c1ed1..f76df7c3c9 100644
--- a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg
+++ b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg
@@ -1,4 +1,3 @@
-
[general]
version = 2
name = Normal Quality
@@ -9,6 +8,7 @@ type = quality
material = generic_pla
weight = 0
quality_type = normal
+setting_version = 1
[values]
layer_height = 0.2
diff --git a/resources/quality/abax_titan/atitan_pla_high.inst.cfg b/resources/quality/abax_titan/atitan_pla_high.inst.cfg
index 7d6f8bb3d7..cb0b9fa238 100644
--- a/resources/quality/abax_titan/atitan_pla_high.inst.cfg
+++ b/resources/quality/abax_titan/atitan_pla_high.inst.cfg
@@ -1,4 +1,3 @@
-
[general]
version = 2
name = High Quality
@@ -8,6 +7,7 @@ type = quality
material = generic_pla
weight = 1
quality_type = high
+setting_version = 1
[values]
layer_height = 0.1
diff --git a/resources/quality/abax_titan/atitan_pla_normal.inst.cfg b/resources/quality/abax_titan/atitan_pla_normal.inst.cfg
index 6de6a1df32..5d9867db81 100644
--- a/resources/quality/abax_titan/atitan_pla_normal.inst.cfg
+++ b/resources/quality/abax_titan/atitan_pla_normal.inst.cfg
@@ -1,4 +1,3 @@
-
[general]
version = 2
name = Normal Quality
@@ -9,6 +8,7 @@ type = quality
material = generic_pla
weight = 0
quality_type = normal
+setting_version = 1
[values]
layer_height = 0.2
diff --git a/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg
index 6d7fe3b0eb..8359e17a9b 100644
--- a/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg
+++ b/resources/quality/cartesio/abs/cartesio_0.25_abs_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_abs_175_cartesio_0.25_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.3
diff --git a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg
index f59b39a94b..75338a4d83 100644
--- a/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg
+++ b/resources/quality/cartesio/abs/cartesio_0.25_abs_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_abs_175_cartesio_0.25_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.3
diff --git a/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg
index d34b6dfb3b..62a473ac02 100644
--- a/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg
+++ b/resources/quality/cartesio/abs/cartesio_0.4_abs_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_abs_175_cartesio_0.4_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg
index 2780eea101..19d08ae41b 100644
--- a/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg
+++ b/resources/quality/cartesio/abs/cartesio_0.4_abs_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_abs_175_cartesio_0.4_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg
index e22b61a456..8ab0733977 100644
--- a/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg
+++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = coarse
material = generic_abs_175_cartesio_0.8_mm
weight = 3
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg
index 602a11457f..097669c688 100644
--- a/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg
+++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_extra_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = extra coarse
material = generic_abs_175_cartesio_0.8_mm
weight = 4
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg
index 02e82c81e9..5ae8911ceb 100644
--- a/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg
+++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_abs_175_cartesio_0.8_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg
index b9b66fd4c0..ef2571113c 100644
--- a/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg
+++ b/resources/quality/cartesio/abs/cartesio_0.8_abs_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_abs_175_cartesio_0.8_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg
index 1d20414f7e..74390b0d82 100644
--- a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg
+++ b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = dsm_arnitel2045_175_cartesio_0.4_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg
index 2437f41b09..86309f2754 100644
--- a/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg
+++ b/resources/quality/cartesio/arnitel/cartesio_0.4_arnitel2045_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = dsm_arnitel2045_175_cartesio_0.4_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg
index 4ed6a3a28b..81f8f09c47 100644
--- a/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg
+++ b/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = coarse
global_quality = True
weight = 0
+setting_version = 1
[values]
layer_height = 0.4
diff --git a/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg
index a6b9aae464..07282666e3 100644
--- a/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg
+++ b/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = extra coarse
global_quality = True
weight = 0
+setting_version = 1
[values]
layer_height = 0.6
diff --git a/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg
index 17638b0e9b..c0b5895d7e 100644
--- a/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg
+++ b/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
global_quality = True
weight = 0
+setting_version = 1
[values]
layer_height = 0.1
diff --git a/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg
index 56c7db0f4a..ed3cb68326 100644
--- a/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg
+++ b/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
global_quality = True
weight = 0
+setting_version = 1
[values]
layer_height = 0.2
diff --git a/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg
index ed1d1ae00d..3c2b42bb1c 100644
--- a/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg
+++ b/resources/quality/cartesio/hips/cartesio_0.25_hips_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_hips_175_cartesio_0.25_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.3
diff --git a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg
index f259d31022..cf4ce231d5 100644
--- a/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg
+++ b/resources/quality/cartesio/hips/cartesio_0.25_hips_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_hips_175_cartesio_0.25_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.3
diff --git a/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg
index f3d3fb29c4..140655af2c 100644
--- a/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg
+++ b/resources/quality/cartesio/hips/cartesio_0.4_hips_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_hips_175_cartesio_0.4_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg
index 96217fa849..1e62e1ba8f 100644
--- a/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg
+++ b/resources/quality/cartesio/hips/cartesio_0.4_hips_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_hips_175_cartesio_0.4_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg
index 7e169f54bd..d15ffa60e1 100644
--- a/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg
+++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = coarse
material = generic_hips_175_cartesio_0.8_mm
weight = 3
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg
index 707932a7ed..00c2438197 100644
--- a/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg
+++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_extra_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = extra coarse
material = generic_hips_175_cartesio_0.8_mm
weight = 4
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg
index 3cc8f7dc25..e7fc711492 100644
--- a/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg
+++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_hips_175_cartesio_0.8_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg
index d9c10d815a..56b0ee0c2c 100644
--- a/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg
+++ b/resources/quality/cartesio/hips/cartesio_0.8_hips_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_hips_175_cartesio_0.8_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg
index 6cceba99c3..125699fe5f 100644
--- a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg
+++ b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_nylon_175_cartesio_0.25_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.3
diff --git a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg
index 07be2462f4..e039486f8a 100644
--- a/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg
+++ b/resources/quality/cartesio/nylon/cartesio_0.25_nylon_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_nylon_175_cartesio_0.25_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.3
diff --git a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg
index 271278143b..5c9fbc3b04 100644
--- a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg
+++ b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_nylon_175_cartesio_0.4_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg
index 32aaddf4cb..3fc80db1a4 100644
--- a/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg
+++ b/resources/quality/cartesio/nylon/cartesio_0.4_nylon_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_nylon_175_cartesio_0.4_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg
index f019fec205..62f6e4da1f 100644
--- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg
+++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = coarse
material = generic_nylon_175_cartesio_0.8_mm
weight = 3
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg
index b19df96222..813fde3915 100644
--- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg
+++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_extra_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = extra coarse
material = generic_nylon_175_cartesio_0.8_mm
weight = 4
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg
index adc278188d..cc18ceeda6 100644
--- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg
+++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_nylon_175_cartesio_0.8_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg
index 87e8515872..baaf108d6e 100644
--- a/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg
+++ b/resources/quality/cartesio/nylon/cartesio_0.8_nylon_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_nylon_175_cartesio_0.8_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg
index cb8b52cf12..531cfb3519 100644
--- a/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg
+++ b/resources/quality/cartesio/pc/cartesio_0.25_pc_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_pc_175_cartesio_0.25_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.3
diff --git a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg
index 8cb4ebc94b..ad07bcd2c7 100644
--- a/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg
+++ b/resources/quality/cartesio/pc/cartesio_0.25_pc_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_pc_175_cartesio_0.25_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.3
diff --git a/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg
index 3aa4211c0a..e03ebb8c95 100644
--- a/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg
+++ b/resources/quality/cartesio/pc/cartesio_0.4_pc_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_pc_175_cartesio_0.4_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg
index 42fc39d6f2..0acc0b5b2b 100644
--- a/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg
+++ b/resources/quality/cartesio/pc/cartesio_0.4_pc_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_pc_175_cartesio_0.4_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg
index ba2a33d4cf..2b760d6067 100644
--- a/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg
+++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = coarse
material = generic_pc_175_cartesio_0.8_mm
weight = 3
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg
index 443f009ba4..c2bb4d8df4 100644
--- a/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg
+++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_extra_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = extra coarse
material = generic_pc_175_cartesio_0.8_mm
weight = 4
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg
index 9dc821ad27..e0dd2cc81e 100644
--- a/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg
+++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_pc_175_cartesio_0.8_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg
index 893a8f0939..9d4169427f 100644
--- a/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg
+++ b/resources/quality/cartesio/pc/cartesio_0.8_pc_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_pc_175_cartesio_0.8_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg
index a197b70f1b..cc96f3f37f 100644
--- a/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg
+++ b/resources/quality/cartesio/petg/cartesio_0.25_petg_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_petg_175_cartesio_0.25_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.3
diff --git a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg
index c34c7f8eae..fe5bdb2e77 100644
--- a/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg
+++ b/resources/quality/cartesio/petg/cartesio_0.25_petg_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_petg_175_cartesio_0.25_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.3
diff --git a/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg
index 8130f8563e..0a019b60d6 100644
--- a/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg
+++ b/resources/quality/cartesio/petg/cartesio_0.4_petg_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_petg_175_cartesio_0.4_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg
index 84c7525b0b..8984f430f5 100644
--- a/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg
+++ b/resources/quality/cartesio/petg/cartesio_0.4_petg_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_petg_175_cartesio_0.4_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg
index a3a8d324fb..b8e06b8db6 100644
--- a/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg
+++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = coarse
material = generic_petg_175_cartesio_0.8_mm
weight = 3
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg
index 295b3c3e2c..cba49998f4 100644
--- a/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg
+++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_extra_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = extra coarse
material = generic_petg_175_cartesio_0.8_mm
weight = 4
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg
index df496e5e06..7b85c230b0 100644
--- a/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg
+++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_petg_175_cartesio_0.8_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg
index fa787830b2..d45d7a0d2c 100644
--- a/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg
+++ b/resources/quality/cartesio/petg/cartesio_0.8_petg_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_petg_175_cartesio_0.8_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg
index 633aeca2d2..7afd300aa2 100644
--- a/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg
+++ b/resources/quality/cartesio/pla/cartesio_0.25_pla_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_pla_175_cartesio_0.25_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.3
diff --git a/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg
index a212b65676..057215d70d 100644
--- a/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg
+++ b/resources/quality/cartesio/pla/cartesio_0.25_pla_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_pla_175_cartesio_0.25_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.3
diff --git a/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg
index 7a7f7f31a3..77d3008c1b 100644
--- a/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg
+++ b/resources/quality/cartesio/pla/cartesio_0.4_pla_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_pla_175_cartesio_0.4_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg
index 16ad34b9f0..3d08fd9514 100644
--- a/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg
+++ b/resources/quality/cartesio/pla/cartesio_0.4_pla_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_pla_175_cartesio_0.4_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg
index c6a680dfcc..1aca489096 100644
--- a/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg
+++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = coarse
material = generic_pla_175_cartesio_0.8_mm
weight = 3
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg
index a1ea49ba92..c4acfd0c8d 100644
--- a/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg
+++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_extra_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = extra coarse
material = generic_pla_175_cartesio_0.8_mm
weight = 4
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg
index 622cb124eb..ad4980d2e9 100644
--- a/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg
+++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_pla_175_cartesio_0.8_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg b/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg
index c24f46f30d..650431e0a9 100644
--- a/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg
+++ b/resources/quality/cartesio/pla/cartesio_0.8_pla_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_pla_175_cartesio_0.8_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg
index 34b7dcf0f1..580969fbaa 100644
--- a/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg
+++ b/resources/quality/cartesio/pva/cartesio_0.25_pva_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_pva_175_cartesio_0.25_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.3
diff --git a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg
index 5f6b8c846d..189ab1caec 100644
--- a/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg
+++ b/resources/quality/cartesio/pva/cartesio_0.25_pva_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_pva_175_cartesio_0.25_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.3
diff --git a/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg
index 26e476abb0..61a8b5f37c 100644
--- a/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg
+++ b/resources/quality/cartesio/pva/cartesio_0.4_pva_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_pva_175_cartesio_0.4_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg
index 14e6c6a956..e91cd56272 100644
--- a/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg
+++ b/resources/quality/cartesio/pva/cartesio_0.4_pva_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_pva_175_cartesio_0.4_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.5
diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg
index e009409d52..c109e8c20e 100644
--- a/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg
+++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = coarse
material = generic_pva_175_cartesio_0.8_mm
weight = 3
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg
index bc9dc55912..59c3530dba 100644
--- a/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg
+++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_extra_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = extra coarse
material = generic_pva_175_cartesio_0.8_mm
weight = 4
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg
index 9f5ea8a070..b651c5bd57 100644
--- a/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg
+++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_pva_175_cartesio_0.8_mm
weight = 1
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg
index 275ff906d2..9354602854 100644
--- a/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg
+++ b/resources/quality/cartesio/pva/cartesio_0.8_pva_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_pva_175_cartesio_0.8_mm
weight = 2
+setting_version = 1
[values]
infill_line_width = 0.9
diff --git a/resources/quality/coarse.inst.cfg b/resources/quality/coarse.inst.cfg
index 94612afcc0..7722e9d0ae 100644
--- a/resources/quality/coarse.inst.cfg
+++ b/resources/quality/coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = coarse
global_quality = True
weight = -3
+setting_version = 1
[values]
layer_height = 0.4
diff --git a/resources/quality/draft.inst.cfg b/resources/quality/draft.inst.cfg
index 134626365f..21a7c81d6c 100644
--- a/resources/quality/draft.inst.cfg
+++ b/resources/quality/draft.inst.cfg
@@ -9,6 +9,7 @@ type = quality
quality_type = draft
global_quality = True
weight = -2
+setting_version = 1
[values]
layer_height = 0.2
diff --git a/resources/quality/extra_coarse.inst.cfg b/resources/quality/extra_coarse.inst.cfg
index 1462464b59..4c2bced7d2 100644
--- a/resources/quality/extra_coarse.inst.cfg
+++ b/resources/quality/extra_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = Extra coarse
global_quality = True
weight = -4
+setting_version = 1
[values]
layer_height = 0.6
diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg
index 921dae9ae0..955b19dcf4 100644
--- a/resources/quality/high.inst.cfg
+++ b/resources/quality/high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
global_quality = True
weight = 1
+setting_version = 1
[values]
layer_height = 0.06
diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg
index cd1356cf3c..674ed17e44 100644
--- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg
+++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_petg_imade3d_jellybox_0.4_mm
weight = -1
quality_type = fast
+setting_version = 1
[values]
adhesion_type = skirt
diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg
index a0ad58711f..e98c0a38ee 100644
--- a/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg
+++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_coarse_2-fans.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_petg_imade3d_jellybox_0.4_mm_2-fans
weight = -1
quality_type = fast
+setting_version = 1
[values]
adhesion_type = skirt
diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg
index 5a51c3059f..2a947aceec 100644
--- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg
+++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_petg_imade3d_jellybox_0.4_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
adhesion_type = skirt
diff --git a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg
index c85b4f74d0..67078b9cde 100644
--- a/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg
+++ b/resources/quality/imade3d_jellybox/generic_petg_0.4_medium_2-fans.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_petg_imade3d_jellybox_0.4_mm_2-fans
weight = 0
quality_type = normal
+setting_version = 1
[values]
adhesion_type = skirt
diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg
index fb21ef1b9f..c82d42120d 100644
--- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg
+++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pla_imade3d_jellybox_0.4_mm
weight = -1
quality_type = fast
+setting_version = 1
[values]
adhesion_type = skirt
diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg
index a382d98b6e..634b1219f7 100644
--- a/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg
+++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_coarse_2-fans.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pla_imade3d_jellybox_0.4_mm_2-fans
weight = -1
quality_type = fast
+setting_version = 1
[values]
adhesion_type = skirt
diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg
index cba83980df..9d1ece2ea9 100644
--- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg
+++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pla_imade3d_jellybox_0.4_mm
weight = 1
quality_type = high
+setting_version = 1
[values]
adhesion_type = skirt
diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg
index e26c1406fb..2cc8a57a73 100644
--- a/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg
+++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_fine_2-fans.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pla_imade3d_jellybox_0.4_mm_2-fans
weight = 1
quality_type = high
+setting_version = 1
[values]
adhesion_type = skirt
diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg
index 59506db09a..c30943b4f2 100644
--- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg
+++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pla_imade3d_jellybox_0.4_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
adhesion_type = skirt
diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg
index 785941fbca..076d90334b 100644
--- a/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg
+++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_medium_2-fans.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pla_imade3d_jellybox_0.4_mm_2-fans
weight = 0
quality_type = normal
+setting_version = 1
[values]
adhesion_type = skirt
diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg
index 737d1acf59..c8db03506a 100644
--- a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg
+++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pla_imade3d_jellybox_0.4_mm
weight = 2
quality_type = ultrahigh
+setting_version = 1
[values]
adhesion_type = skirt
diff --git a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg
index 5a5a0c96dc..01d5d601dd 100644
--- a/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg
+++ b/resources/quality/imade3d_jellybox/generic_pla_0.4_ultrafine_2-fans.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pla_imade3d_jellybox_0.4_mm_2-fans
weight = 2
quality_type = ultrahigh
+setting_version = 1
[values]
adhesion_type = skirt
diff --git a/resources/quality/low.inst.cfg b/resources/quality/low.inst.cfg
index 82d4e0d327..8c8200395b 100644
--- a/resources/quality/low.inst.cfg
+++ b/resources/quality/low.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = low
global_quality = True
weight = -1
+setting_version = 1
[values]
infill_sparse_density = 10
diff --git a/resources/quality/normal.inst.cfg b/resources/quality/normal.inst.cfg
index 26da3b48da..47d47f97f1 100644
--- a/resources/quality/normal.inst.cfg
+++ b/resources/quality/normal.inst.cfg
@@ -8,5 +8,6 @@ type = quality
quality_type = normal
global_quality = True
weight = 0
+setting_version = 1
[values]
diff --git a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg
index 27848d4301..4c0cec96a7 100644
--- a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg
+++ b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg
@@ -7,6 +7,7 @@ definition = peopoly_moai
type = quality
weight = 1
quality_type = high
+setting_version = 1
[values]
infill_sparse_density = 70
diff --git a/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg
index 253070569f..720b98b1b0 100644
--- a/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg
+++ b/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg
@@ -7,6 +7,7 @@ definition = peopoly_moai
type = quality
weight = 2
quality_type = extra_high
+setting_version = 1
[values]
infill_sparse_density = 70
diff --git a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg
index c4ff8360fa..7d0053fc11 100644
--- a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg
+++ b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg
@@ -7,6 +7,7 @@ definition = peopoly_moai
type = quality
weight = 0
quality_type = normal
+setting_version = 1
[values]
infill_sparse_density = 70
diff --git a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg
index db2b48b3cc..e288ce3db5 100644
--- a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pla_ultimaker2_plus_0.25_mm
weight = 1
quality_type = high
+setting_version = 1
[values]
layer_height = 0.06
diff --git a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg
index d3f2740202..be01142816 100644
--- a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg
+++ b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pla_ultimaker2_plus_0.4_mm
weight = -1
quality_type = fast
+setting_version = 1
[values]
layer_height = 0.15
diff --git a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg
index d3347b4712..9d4469c1e4 100644
--- a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg
+++ b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pla_ultimaker2_plus_0.4_mm
weight = 1
quality_type = high
+setting_version = 1
[values]
layer_height = 0.06
diff --git a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg
index 758225535a..f9b27a3627 100644
--- a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pla_ultimaker2_plus_0.4_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
layer_height = 0.1
diff --git a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg
index 5eed5965e4..bcebb06221 100644
--- a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg
@@ -8,6 +8,7 @@ material = generic_pla_ultimaker2_plus_0.6_mm
type = quality
weight = 0
quality_type = normal
+setting_version = 1
[values]
layer_height = 0.15
diff --git a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg
index 96a81d874e..a090910641 100644
--- a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg
@@ -8,6 +8,7 @@ material = generic_pla_ultimaker2_plus_0.8_mm
type = quality
weight = -1
quality_type = fast
+setting_version = 1
[values]
layer_height = 0.2
diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg
index cd99fc0f8a..f93fcca48c 100644
--- a/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_abs_0.25_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_abs_ultimaker2_plus_0.25_mm
weight = 1
quality_type = high
+setting_version = 1
[values]
layer_height = 0.06
diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg
index e52a201789..8c7b34eeff 100644
--- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_fast.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_abs_ultimaker2_plus_0.4_mm
weight = -1
quality_type = fast
+setting_version = 1
[values]
layer_height = 0.15
diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg
index 4cbe9f4b88..7040a8ba38 100644
--- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_abs_ultimaker2_plus_0.4_mm
weight = 1
quality_type = high
+setting_version = 1
[values]
layer_height = 0.06
diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg
index 3cfa744787..740dadd493 100644
--- a/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_abs_0.4_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_abs_ultimaker2_plus_0.4_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
layer_height = 0.1
diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg
index 848441de61..d501703514 100644
--- a/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_abs_0.6_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_abs_ultimaker2_plus_0.6_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
layer_height = 0.15
diff --git a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg
index 20a35f157f..674f17958c 100644
--- a/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_abs_0.8_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_abs_ultimaker2_plus_0.8_mm
weight = -1
quality_type = fast
+setting_version = 1
[values]
layer_height = 0.2
diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg
index 29f1577d12..27d850162e 100644
--- a/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.25_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_cpe_ultimaker2_plus_0.25_mm
weight = -1
quality_type = high
+setting_version = 1
[values]
layer_height = 0.06
diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg
index edba5d2c79..6b882b1bbf 100644
--- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_fast.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_cpe_ultimaker2_plus_0.4_mm
weight = -1
quality_type = fast
+setting_version = 1
[values]
layer_height = 0.15
diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg
index a2442e6c96..6c4d24b195 100644
--- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_cpe_ultimaker2_plus_0.4_mm
weight = 1
quality_type = high
+setting_version = 1
[values]
layer_height = 0.06
diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg
index 4993e97bb0..d26cc8782c 100644
--- a/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.4_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_cpe_ultimaker2_plus_0.4_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
layer_height = 0.1
diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg
index ceaf31e153..10a4e5bd71 100644
--- a/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.6_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_cpe_ultimaker2_plus_0.6_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
layer_height = 0.15
diff --git a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg
index f81e931218..f4730bbd41 100644
--- a/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_cpe_0.8_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_cpe_ultimaker2_plus_0.8_mm
weight = -1
quality_type = fast
+setting_version = 1
[values]
layer_height = 0.2
diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg
index 294db7c10d..517d42ada2 100644
--- a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_draft.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_cpe_plus_ultimaker2_plus_0.4_mm
weight = -2
quality_type = draft
+setting_version = 1
[values]
speed_wall_x = 25
diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg
index 91059f94b3..6d77792901 100644
--- a/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.4_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_cpe_plus_ultimaker2_plus_0.4_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
speed_wall_x = 30
diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg
index 6d1cb47835..ed87b21b15 100644
--- a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_draft.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_cpe_plus_ultimaker2_plus_0.6_mm
weight = -2
quality_type = draft
+setting_version = 1
[values]
support_xy_distance = 0.6
diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg
index 1dbe3a56c8..7b20aa424d 100644
--- a/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.6_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_cpe_plus_ultimaker2_plus_0.6_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
support_xy_distance = 0.6
diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg
index 1b92686d50..d07e33e124 100644
--- a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_draft.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_cpe_plus_ultimaker2_plus_0.8_mm
weight = -2
quality_type = draft
+setting_version = 1
[values]
support_z_distance = 0.26
diff --git a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg
index 30746a1ac2..b2cd9478c6 100644
--- a/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_cpep_0.8_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_cpe_plus_ultimaker2_plus_0.8_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
support_z_distance = 0.26
diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg
index fea97a2621..94eac599b0 100644
--- a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_nylon_ultimaker2_plus_0.25_mm
weight = 1
quality_type = high
+setting_version = 1
[values]
support_xy_distance = 0.6
diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg
index 56be2489a5..663f67c56e 100644
--- a/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.25_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_nylon_ultimaker2_plus_0.25_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
support_xy_distance = 0.6
diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg
index 80948add53..f37365585e 100644
--- a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_fast.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_nylon_ultimaker2_plus_0.4_mm
weight = -1
quality_type = fast
+setting_version = 1
[values]
support_xy_distance = 0.6
diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg
index 8385b3f895..0bb3bcc12d 100644
--- a/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.4_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_nylon_ultimaker2_plus_0.4_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
support_xy_distance = 0.6
diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg
index d9e393b778..dfeb02991f 100644
--- a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_fast.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_nylon_ultimaker2_plus_0.6_mm
weight = -1
quality_type = fast
+setting_version = 1
[values]
support_xy_distance = 0.7
diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg
index e438dca035..259a581ccf 100644
--- a/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.6_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_nylon_ultimaker2_plus_0.6_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
support_xy_distance = 0.7
diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg
index 575109e588..1607d71d01 100644
--- a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_draft.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_nylon_ultimaker2_plus_0.8_mm
weight = -2
quality_type = draft
+setting_version = 1
[values]
support_xy_distance = 0.75
diff --git a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg
index abd8f499bc..8d3767e4c6 100644
--- a/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_nylon_0.8_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_nylon_ultimaker2_plus_0.8_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
support_xy_distance = 0.75
diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg
index 06f67b7298..33dc5551fd 100644
--- a/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_pc_0.25_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pc_ultimaker2_plus_0.25_mm
weight = 1
quality_type = high
+setting_version = 1
[values]
support_z_distance = 0.19
diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg
index be595385a4..2d26718f1b 100644
--- a/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_pc_0.25_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pc_ultimaker2_plus_0.25_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
support_z_distance = 0.19
diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg
index f20351cbb4..4c5dbf080b 100644
--- a/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_pc_0.4_fast.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pc_ultimaker2_plus_0.4_mm
weight = -1
quality_type = fast
+setting_version = 1
[values]
speed_wall_x = 30
diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg
index 469cab12cc..e49dcd52a7 100644
--- a/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_pc_0.4_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pc_ultimaker2_plus_0.4_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
speed_wall_x = 30
diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg
index bfd239e3cc..dc1d569ab9 100644
--- a/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_pc_0.6_fast.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pc_ultimaker2_plus_0.6_mm
weight = -1
quality_type = fast
+setting_version = 1
[values]
speed_travel = 150
diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg
index bf65d1b8aa..1c041e1567 100644
--- a/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_pc_0.6_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pc_ultimaker2_plus_0.6_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
speed_travel = 150
diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg
index 53fab6b028..782d44cdcc 100644
--- a/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_pc_0.8_draft.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pc_ultimaker2_plus_0.8_mm
weight = -2
quality_type = draft
+setting_version = 1
[values]
support_z_distance = 0.26
diff --git a/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg
index 9d79bf9faa..83c30e583d 100644
--- a/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_pc_0.8_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_pc_ultimaker2_plus_0.8_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
support_z_distance = 0.26
diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg
index 5c37a8432a..d1632b3482 100644
--- a/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.25_high.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_tpu_ultimaker2_plus_0.25_mm
weight = 1
quality_type = high
+setting_version = 1
[values]
support_xy_distance = 0.6
diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg
index 106476d57c..10a8cbded5 100644
--- a/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.4_normal.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_tpu_ultimaker2_plus_0.4_mm
weight = 0
quality_type = normal
+setting_version = 1
[values]
support_xy_distance = 0.65
diff --git a/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg
index e0a0388227..e96015c6bd 100644
--- a/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_tpu_0.6_fast.inst.cfg
@@ -8,6 +8,7 @@ type = quality
material = generic_tpu_ultimaker2_plus_0.6_mm
weight = -1
quality_type = fast
+setting_version = 1
[values]
support_xy_distance = 0.7
diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg
index 00d93f3575..4c7b194893 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Draft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = draft
material = generic_abs_ultimaker3_AA_0.4
weight = -2
+setting_version = 1
[values]
machine_nozzle_cool_down_speed = 0.85
@@ -15,7 +16,7 @@ machine_nozzle_heat_up_speed = 1.5
material_print_temperature = =default_material_print_temperature + 10
material_initial_print_temperature = =material_print_temperature - 5
material_final_print_temperature = =material_print_temperature - 10
-prime_tower_size = 16
+prime_tower_enable = False
skin_overlap = 20
speed_print = 60
speed_layer_0 = 20
diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg
index 066a044ee0..debb49caa8 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Fast_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = fast
material = generic_abs_ultimaker3_AA_0.4
weight = -1
+setting_version = 1
[values]
cool_min_speed = 7
@@ -17,7 +18,7 @@ material_print_temperature = =default_material_print_temperature + 5
material_initial_print_temperature = =material_print_temperature - 5
material_final_print_temperature = =material_print_temperature - 10
material_standby_temperature = 100
-prime_tower_size = 16
+prime_tower_enable = False
speed_print = 60
speed_layer_0 = 20
speed_topbottom = =math.ceil(speed_print * 30 / 60)
diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg
index 850af33c27..9e08d12b78 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_High_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_abs_ultimaker3_AA_0.4
weight = 1
+setting_version = 1
[values]
cool_min_speed = 12
@@ -17,7 +18,7 @@ material_standby_temperature = 100
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_tower_size = 16
+prime_tower_enable = False
speed_print = 50
speed_layer_0 = 20
speed_topbottom = =math.ceil(speed_print * 30 / 50)
diff --git a/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg
index 3793bf8b5e..344593be0e 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_ABS_Normal_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_abs_ultimaker3_AA_0.4
weight = 0
+setting_version = 1
[values]
machine_nozzle_cool_down_speed = 0.85
@@ -15,7 +16,7 @@ machine_nozzle_heat_up_speed = 1.5
material_initial_print_temperature = =material_print_temperature - 5
material_final_print_temperature = =material_print_temperature - 10
material_standby_temperature = 100
-prime_tower_size = 16
+prime_tower_enable = False
speed_print = 55
speed_layer_0 = 20
speed_topbottom = =math.ceil(speed_print * 30 / 55)
diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg
index ee03b6dbcf..7833e3756c 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Draft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = draft
material = generic_cpe_plus_ultimaker3_AA_0.4
weight = -2
+setting_version = 1
[values]
acceleration_enabled = True
@@ -29,7 +30,6 @@ material_print_temperature_layer_0 = =material_print_temperature
material_standby_temperature = 100
multiple_mesh_overlap = 0
prime_tower_enable = True
-prime_tower_size = 17
prime_tower_wipe_enabled = True
retraction_combing = off
retraction_extrusion_window = 1
diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg
index b61a7ee9de..ebe8646000 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Fast_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = fast
material = generic_cpe_plus_ultimaker3_AA_0.4
weight = -1
+setting_version = 1
[values]
acceleration_enabled = True
@@ -29,7 +30,6 @@ material_print_temperature_layer_0 = =material_print_temperature
material_standby_temperature = 100
multiple_mesh_overlap = 0
prime_tower_enable = True
-prime_tower_size = 17
prime_tower_wipe_enabled = True
retraction_combing = off
retraction_extrusion_window = 1
diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg
index 1507de5a6b..a9bd0db101 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_High_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_cpe_plus_ultimaker3_AA_0.4
weight = 1
+setting_version = 1
[values]
acceleration_enabled = True
@@ -31,7 +32,6 @@ material_print_temperature_layer_0 = =material_print_temperature
material_standby_temperature = 100
multiple_mesh_overlap = 0
prime_tower_enable = True
-prime_tower_size = 17
prime_tower_wipe_enabled = True
retraction_combing = off
retraction_extrusion_window = 1
diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg
index 88090b12cd..e9834620bb 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_CPEP_Normal_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_cpe_plus_ultimaker3_AA_0.4
weight = 0
+setting_version = 1
[values]
acceleration_enabled = True
@@ -30,7 +31,6 @@ material_print_temperature_layer_0 = =material_print_temperature
material_standby_temperature = 100
multiple_mesh_overlap = 0
prime_tower_enable = True
-prime_tower_size = 17
prime_tower_wipe_enabled = True
retraction_combing = off
retraction_extrusion_window = 1
diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg
index 7a536ce033..05e8a6540d 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Draft_Print.inst.cfg
@@ -8,13 +8,13 @@ type = quality
quality_type = draft
material = generic_cpe_ultimaker3_AA_0.4
weight = -2
+setting_version = 1
[values]
material_print_temperature = =default_material_print_temperature + 10
material_initial_print_temperature = =material_print_temperature - 5
material_final_print_temperature = =material_print_temperature - 10
material_standby_temperature = 100
-prime_tower_size = 17
skin_overlap = 20
speed_print = 60
speed_layer_0 = 20
diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg
index 96467fe36c..86ce49a964 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Fast_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = fast
material = generic_cpe_ultimaker3_AA_0.4
weight = -1
+setting_version = 1
[values]
cool_min_speed = 7
@@ -15,7 +16,6 @@ material_print_temperature = =default_material_print_temperature + 5
material_initial_print_temperature = =material_print_temperature - 5
material_final_print_temperature = =material_print_temperature - 10
material_standby_temperature = 100
-prime_tower_size = 17
speed_print = 60
speed_layer_0 = 20
speed_topbottom = =math.ceil(speed_print * 30 / 60)
diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg
index 1fd6167e67..3e7d5ab4b3 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_High_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_cpe_ultimaker3_AA_0.4
weight = 1
+setting_version = 1
[values]
cool_min_speed = 12
@@ -17,7 +18,6 @@ material_print_temperature = =default_material_print_temperature - 5
material_initial_print_temperature = =material_print_temperature - 5
material_final_print_temperature = =material_print_temperature - 10
material_standby_temperature = 100
-prime_tower_size = 17
speed_print = 50
speed_layer_0 = 20
speed_topbottom = =math.ceil(speed_print * 30 / 50)
diff --git a/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg
index 5ad1ef6b43..62fa68d862 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_CPE_Normal_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_cpe_ultimaker3_AA_0.4
weight = 0
+setting_version = 1
[values]
machine_nozzle_cool_down_speed = 0.85
@@ -15,7 +16,6 @@ machine_nozzle_heat_up_speed = 1.5
material_initial_print_temperature = =material_print_temperature - 5
material_final_print_temperature = =material_print_temperature - 10
material_standby_temperature = 100
-prime_tower_size = 17
speed_print = 55
speed_layer_0 = 20
speed_topbottom = =math.ceil(speed_print * 30 / 55)
diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg
index 6899989100..b7c2381840 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Draft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = draft
material = generic_nylon_ultimaker3_AA_0.4
weight = -2
+setting_version = 1
[values]
adhesion_type = brim
diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg
index 76a2491079..eb76b27f2a 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Fast_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = fast
material = generic_nylon_ultimaker3_AA_0.4
weight = -1
+setting_version = 1
[values]
adhesion_type = brim
diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg
index ba50bc4d31..74cd67af23 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_High_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_nylon_ultimaker3_AA_0.4
weight = 1
+setting_version = 1
[values]
adhesion_type = brim
diff --git a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg
index bebd9976f5..626629c746 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_Nylon_Normal_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_nylon_ultimaker3_AA_0.4
weight = 0
+setting_version = 1
[values]
adhesion_type = brim
diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg
index 94b40e427c..6cbb2ba357 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Draft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = draft
material = generic_pc_ultimaker3_AA_0.4
weight = -2
+setting_version = 1
[values]
acceleration_enabled = True
@@ -36,7 +37,6 @@ material_standby_temperature = 100
multiple_mesh_overlap = 0
ooze_shield_angle = 40
prime_tower_enable = True
-prime_tower_size = 16
prime_tower_wipe_enabled = True
raft_airgap = 0.25
retraction_count_max = 80
diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg
index 5d848d67dc..2402c8e7fa 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Fast_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = fast
material = generic_pc_ultimaker3_AA_0.4
weight = -1
+setting_version = 1
[values]
acceleration_enabled = True
@@ -35,7 +36,6 @@ material_standby_temperature = 100
multiple_mesh_overlap = 0
ooze_shield_angle = 40
prime_tower_enable = True
-prime_tower_size = 16
prime_tower_wipe_enabled = True
raft_airgap = 0.25
retraction_count_max = 80
diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg
index 451aa19f60..c54db7f99f 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_PC_High_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_pc_ultimaker3_AA_0.4
weight = 1
+setting_version = 1
[values]
acceleration_enabled = True
@@ -36,7 +37,6 @@ material_standby_temperature = 100
multiple_mesh_overlap = 0
ooze_shield_angle = 40
prime_tower_enable = True
-prime_tower_size = 16
prime_tower_wipe_enabled = True
raft_airgap = 0.25
retraction_count_max = 80
diff --git a/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg
index cc50189e8c..a7a1b6ba5c 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_PC_Normal_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_pc_ultimaker3_AA_0.4
weight = 0
+setting_version = 1
[values]
acceleration_enabled = True
@@ -33,7 +34,6 @@ material_standby_temperature = 100
multiple_mesh_overlap = 0
ooze_shield_angle = 40
prime_tower_enable = True
-prime_tower_size = 16
prime_tower_wipe_enabled = True
raft_airgap = 0.25
retraction_count_max = 80
diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg
index eb56b0aa4c..2ae33b91a9 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Draft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = draft
material = generic_pla_ultimaker3_AA_0.4
weight = -2
+setting_version = 1
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg
index c5faa17a2b..57faaacb65 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Fast_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = fast
material = generic_pla_ultimaker3_AA_0.4
weight = -1
+setting_version = 1
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg
index 1a6db5e3b5..7fda6c2e7d 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_High_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
material = generic_pla_ultimaker3_AA_0.4
weight = 1
+setting_version = 1
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
diff --git a/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg
index c7a7be37c0..3bd268a257 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_PLA_Normal_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_pla_ultimaker3_AA_0.4
weight = 0
+setting_version = 1
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
diff --git a/resources/quality/ultimaker3/um3_aa0.4_PVA_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PVA_Not_Supported_Quality.inst.cfg
index f4abd6f696..6d878cd4b7 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_PVA_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_PVA_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ type = quality
quality_type = normal
material = generic_pva_ultimaker3_AA_0.4
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg
index 1787b266e2..55170f8c79 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Draft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = draft
material = generic_tpu_ultimaker3_AA_0.4
weight = -2
+setting_version = 1
[values]
acceleration_enabled = True
@@ -38,7 +39,6 @@ material_print_temperature_layer_0 = =default_material_print_temperature + 2
material_standby_temperature = 100
multiple_mesh_overlap = 0
prime_tower_enable = True
-prime_tower_size = 16
prime_tower_wipe_enabled = True
retraction_count_max = 12
retraction_extra_prime_amount = 0.8
diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg
index f53d3fd285..89536c9308 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Fast_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = fast
material = generic_tpu_ultimaker3_AA_0.4
weight = -1
+setting_version = 1
[values]
acceleration_enabled = True
@@ -38,7 +39,6 @@ material_print_temperature_layer_0 = =default_material_print_temperature + 2
material_standby_temperature = 100
multiple_mesh_overlap = 0
prime_tower_enable = True
-prime_tower_size = 16
prime_tower_wipe_enabled = True
retraction_amount = 7
retraction_count_max = 12
diff --git a/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg
index 0b475eda92..51e77de9e7 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_TPU_Normal_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
material = generic_tpu_ultimaker3_AA_0.4
weight = 0
+setting_version = 1
[values]
acceleration_enabled = True
@@ -36,7 +37,6 @@ material_print_temperature_layer_0 = =default_material_print_temperature
material_standby_temperature = 100
multiple_mesh_overlap = 0
prime_tower_enable = True
-prime_tower_size = 16
prime_tower_wipe_enabled = True
retraction_count_max = 12
retraction_extra_prime_amount = 0.8
diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg
index 7fb96d0cea..06ec67d7ee 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Draft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = draft
material = generic_abs_ultimaker3_AA_0.8
weight = -2
+setting_version = 1
[values]
line_width = =machine_nozzle_size * 0.875
diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg
index 63f27c180d..3df0ce08ea 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Superdraft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = superdraft
material = generic_abs_ultimaker3_AA_0.8
weight = -4
+setting_version = 1
[values]
layer_height = 0.4
diff --git a/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg
index 1eeb95fcd2..4c99a7a286 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_ABS_Verydraft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = verydraft
material = generic_abs_ultimaker3_AA_0.8
weight = -3
+setting_version = 1
[values]
layer_height = 0.3
diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Not_Supported_Quality.inst.cfg
index 68b694b922..ddde16205e 100755
--- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = normal
material = generic_cpe_plus_ultimaker3_AA_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Not_Supported_Superdraft_Quality.inst.cfg
index 9cc2999ed2..8d65a8a653 100755
--- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = superdraft
material = generic_cpe_plus_ultimaker3_AA_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg
index dbee576a94..aae6e21061 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Draft_Print.inst.cfg
@@ -8,12 +8,14 @@ type = quality
quality_type = draft
material = generic_cpe_ultimaker3_AA_0.8
weight = -2
+setting_version = 1
[values]
brim_width = 15
line_width = =machine_nozzle_size * 0.875
material_print_temperature = =default_material_print_temperature + 15
material_standby_temperature = 100
+prime_tower_enable = True
speed_print = 40
speed_topbottom = =math.ceil(speed_print * 25 / 40)
speed_wall = =math.ceil(speed_print * 30 / 40)
diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg
index 9aa8b69381..af33717e7f 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Superdraft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = superdraft
material = generic_cpe_ultimaker3_AA_0.8
weight = -2
+setting_version = 1
[values]
brim_width = 15
@@ -15,6 +16,7 @@ layer_height = 0.4
line_width = =machine_nozzle_size * 0.875
material_print_temperature = =default_material_print_temperature + 20
material_standby_temperature = 100
+prime_tower_enable = True
speed_print = 45
speed_topbottom = =math.ceil(speed_print * 30 / 45)
speed_wall = =math.ceil(speed_print * 40 / 45)
diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg
index 3f897c91d3..cc87ac82cc 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_CPE_Verydraft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = verydraft
material = generic_cpe_ultimaker3_AA_0.8
weight = -2
+setting_version = 1
[values]
brim_width = 15
@@ -15,6 +16,7 @@ layer_height = 0.3
line_width = =machine_nozzle_size * 0.875
material_print_temperature = =default_material_print_temperature + 17
material_standby_temperature = 100
+prime_tower_enable = True
speed_print = 40
speed_topbottom = =math.ceil(speed_print * 25 / 40)
speed_wall = =math.ceil(speed_print * 30 / 40)
diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg
index 30d9dccb19..16dbd87bcd 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Draft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = draft
material = generic_nylon_ultimaker3_AA_0.8
weight = -2
+setting_version = 1
[values]
brim_width = 5.6
@@ -19,7 +20,6 @@ machine_nozzle_cool_down_speed = 0.9
machine_nozzle_heat_up_speed = 1.4
material_standby_temperature = 100
ooze_shield_angle = 40
-prime_tower_size = 15
raft_acceleration = =acceleration_layer_0
raft_airgap = =round(layer_height_0 * 0.85, 2)
raft_interface_thickness = =round(machine_nozzle_size * 0.3 / 0.4, 2)
diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg
index b2348c7a30..61a2c3add1 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Superdraft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = superdraft
material = generic_nylon_ultimaker3_AA_0.8
weight = -4
+setting_version = 1
[values]
brim_width = 5.6
@@ -20,7 +21,6 @@ machine_nozzle_cool_down_speed = 0.9
machine_nozzle_heat_up_speed = 1.4
material_standby_temperature = 100
ooze_shield_angle = 40
-prime_tower_size = 15
raft_acceleration = =acceleration_layer_0
raft_airgap = =round(layer_height_0 * 0.85, 2)
raft_interface_thickness = =round(machine_nozzle_size * 0.3 / 0.4, 2)
diff --git a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg
index 42b09bd272..73bf6a1fdf 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_Nylon_Verydraft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = verydraft
material = generic_nylon_ultimaker3_AA_0.8
weight = -3
+setting_version = 1
[values]
brim_width = 5.6
@@ -20,7 +21,6 @@ machine_nozzle_cool_down_speed = 0.9
machine_nozzle_heat_up_speed = 1.4
material_standby_temperature = 100
ooze_shield_angle = 40
-prime_tower_size = 15
raft_acceleration = =acceleration_layer_0
raft_airgap = =round(layer_height_0 * 0.85, 2)
raft_interface_thickness = =round(machine_nozzle_size * 0.3 / 0.4, 2)
diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Not_Supported_Quality.inst.cfg
index e47a866584..a047bc4496 100755
--- a/resources/quality/ultimaker3/um3_aa0.8_PC_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ type = quality
quality_type = normal
material = generic_pc_ultimaker3_AA_0.8
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Not_Supported_Superdraft_Quality.inst.cfg
index 14b08854b8..a73c5a121a 100755
--- a/resources/quality/ultimaker3/um3_aa0.8_PC_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ type = quality
quality_type = superdraft
material = generic_pc_ultimaker3_AA_0.8
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg
index b9222d6350..1b8026d963 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Draft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = draft
material = generic_pla_ultimaker3_AA_0.8
weight = -2
+setting_version = 1
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
@@ -25,7 +26,6 @@ material_final_print_temperature = =max(-273.15, material_print_temperature - 15
material_initial_print_temperature = =max(-273.15, material_print_temperature - 10)
material_print_temperature = =default_material_print_temperature + 10
material_standby_temperature = 100
-prime_tower_size = 15
support_angle = 70
support_line_width = =line_width * 0.75
support_pattern = ='triangles'
diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg
index e9f081ef4a..4b23cdbf5a 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Superdraft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = superdraft
material = generic_pla_ultimaker3_AA_0.8
weight = -4
+setting_version = 1
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
@@ -26,7 +27,6 @@ material_final_print_temperature = =max(-273.15, material_print_temperature - 15
material_initial_print_temperature = =max(-273.15, material_print_temperature - 10)
material_print_temperature = =default_material_print_temperature + 15
material_standby_temperature = 100
-prime_tower_size = 15
raft_margin = 10
support_angle = 70
support_line_width = =line_width * 0.75
diff --git a/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg
index af18a87a20..0f5a0eb102 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_PLA_Verydraft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = verydraft
material = generic_pla_ultimaker3_AA_0.8
weight = -3
+setting_version = 1
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
@@ -26,7 +27,6 @@ material_final_print_temperature = =max(-273.15, material_print_temperature - 15
material_initial_print_temperature = =max(-273.15, material_print_temperature - 10)
material_print_temperature = =default_material_print_temperature + 10
material_standby_temperature = 100
-prime_tower_size = 15
support_angle = 70
support_line_width = =line_width * 0.75
support_pattern = ='triangles'
diff --git a/resources/quality/ultimaker3/um3_aa0.8_PVA_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PVA_Not_Supported_Quality.inst.cfg
index ce306fad95..abbfe3f184 100755
--- a/resources/quality/ultimaker3/um3_aa0.8_PVA_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_PVA_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ type = quality
quality_type = normal
material = generic_pva_ultimaker3_AA_0.8
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_aa0.8_PVA_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PVA_Not_Supported_Superdraft_Quality.inst.cfg
index 5dbfab6341..ddd2dd6ca9 100755
--- a/resources/quality/ultimaker3/um3_aa0.8_PVA_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_PVA_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ type = quality
quality_type = superdraft
material = generic_pva_ultimaker3_AA_0.8
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Normal_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg
similarity index 99%
rename from resources/quality/ultimaker3/um3_aa0.8_TPU_Normal_Print.inst.cfg
rename to resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg
index 3f3eeb145e..678a12d5a8 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Normal_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = draft
material = generic_tpu_ultimaker3_AA_0.8
weight = -2
+setting_version = 1
[values]
brim_width = 8.75
diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Not_Supported_Quality.inst.cfg
index 7973ac08cc..b7ddab1a97 100755
--- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ type = quality
quality_type = normal
material = generic_tpu_ultimaker3_AA_0.8
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Not_Supported_Superdraft_Quality.inst.cfg
index ec04652763..0693986d1e 100755
--- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ type = quality
quality_type = superdraft
material = generic_tpu_ultimaker3_AA_0.8
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg
index 38930d1507..dfe159013b 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Superdraft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = superdraft
material = generic_tpu_ultimaker3_AA_0.8
weight = -4
+setting_version = 1
[values]
brim_width = 8.75
diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg
index edc9f61f0e..be41c23cdb 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Verydraft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = verydraft
material = generic_tpu_ultimaker3_AA_0.8
weight = -3
+setting_version = 1
[values]
brim_width = 8.75
diff --git a/resources/quality/ultimaker3/um3_bb0.4_ABS_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_ABS_Not_Supported_Quality.inst.cfg
index 7d2e7aa585..31d74c33a6 100644
--- a/resources/quality/ultimaker3/um3_bb0.4_ABS_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_ABS_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = normal
material = generic_abs_ultimaker3_BB_0.4
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.4_ABS_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_ABS_Not_Supported_Superdraft_Quality.inst.cfg
index a2d097ee09..16cc6c76b7 100755
--- a/resources/quality/ultimaker3/um3_bb0.4_ABS_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_ABS_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = superdraft
material = generic_abs_ultimaker3_BB_0.4
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.4_CPEP_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_CPEP_Not_Supported_Quality.inst.cfg
index d90ac7f126..ef3ae39c9a 100755
--- a/resources/quality/ultimaker3/um3_bb0.4_CPEP_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_CPEP_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = normal
material = generic_cpe_plus_ultimaker3_BB_0.4
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.4_CPEP_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_CPEP_Not_Supported_Superdraft_Quality.inst.cfg
index c7a19c3299..f6a5338f41 100755
--- a/resources/quality/ultimaker3/um3_bb0.4_CPEP_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_CPEP_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = superdraft
material = generic_cpe_plus_ultimaker3_BB_0.4
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.4_CPE_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_CPE_Not_Supported_Quality.inst.cfg
index 1d222bec93..4c05ed019e 100644
--- a/resources/quality/ultimaker3/um3_bb0.4_CPE_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_CPE_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = normal
material = generic_cpe_ultimaker3_BB_0.4
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.4_CPE_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_CPE_Not_Supported_Superdraft_Quality.inst.cfg
index 2c92677a40..9401ac061d 100755
--- a/resources/quality/ultimaker3/um3_bb0.4_CPE_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_CPE_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = superdraft
material = generic_cpe_ultimaker3_BB_0.4
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.4_Nylon_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_Nylon_Not_Supported_Quality.inst.cfg
index 4894ea3e79..b2db6334c0 100644
--- a/resources/quality/ultimaker3/um3_bb0.4_Nylon_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_Nylon_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = normal
material = generic_nylon_ultimaker3_BB_0.4
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.4_Nylon_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_Nylon_Not_Supported_Superdraft_Quality.inst.cfg
index d8c202efe8..ac99f78d04 100755
--- a/resources/quality/ultimaker3/um3_bb0.4_Nylon_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_Nylon_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = superdraft
material = generic_nylon_ultimaker3_BB_0.4
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.4_PC_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PC_Not_Supported_Quality.inst.cfg
index 919e3e952b..dfba41dfb6 100755
--- a/resources/quality/ultimaker3/um3_bb0.4_PC_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_PC_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = normal
material = generic_pc_ultimaker3_BB_0.4
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.4_PLA_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PLA_Not_Supported_Quality.inst.cfg
index 4dba9ea8c6..1b831fd1e2 100644
--- a/resources/quality/ultimaker3/um3_bb0.4_PLA_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_PLA_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = normal
material = generic_pla_ultimaker3_BB_0.4
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.4_PLA_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PLA_Not_Supported_Superdraft_Quality.inst.cfg
index f394ea40b4..153ae27d12 100755
--- a/resources/quality/ultimaker3/um3_bb0.4_PLA_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_PLA_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = superdraft
material = generic_pla_ultimaker3_BB_0.4
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg
index 83fd52a1fd..14d8a31c0a 100644
--- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Draft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = draft
weight = -2
material = generic_pva_ultimaker3_BB_0.4
+setting_version = 1
[values]
acceleration_support = =math.ceil(acceleration_print * 500 / 4000)
diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg
index 582d6e9c76..f7034e278e 100644
--- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Fast_Print.inst.cfg
@@ -8,6 +8,7 @@ weight = -1
type = quality
quality_type = fast
material = generic_pva_ultimaker3_BB_0.4
+setting_version = 1
[values]
acceleration_support = =math.ceil(acceleration_print * 500 / 4000)
diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg
index fc6be3ea3d..e929de3d78 100644
--- a/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_High_Quality.inst.cfg
@@ -8,6 +8,7 @@ weight = 0
type = quality
quality_type = high
material = generic_pva_ultimaker3_BB_0.4
+setting_version = 1
[values]
acceleration_support = =math.ceil(acceleration_print * 500 / 4000)
diff --git a/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg
index 5eb690fa99..92eebb1a0b 100644
--- a/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_PVA_Normal_Quality.inst.cfg
@@ -8,6 +8,7 @@ weight = 0
type = quality
quality_type = normal
material = generic_pva_ultimaker3_BB_0.4
+setting_version = 1
[values]
acceleration_support = =math.ceil(acceleration_print * 500 / 4000)
diff --git a/resources/quality/ultimaker3/um3_bb0.4_TPU_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_TPU_Not_Supported_Quality.inst.cfg
index 18bbdb6c12..106ef29f8e 100755
--- a/resources/quality/ultimaker3/um3_bb0.4_TPU_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_TPU_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = normal
material = generic_tpu_ultimaker3_BB_0.4
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.4_TPU_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.4_TPU_Not_Supported_Superdraft_Quality.inst.cfg
index 7d00e9e0df..95e0622c1a 100755
--- a/resources/quality/ultimaker3/um3_bb0.4_TPU_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.4_TPU_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = superdraft
material = generic_tpu_ultimaker3_BB_0.4
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.8_ABS_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_ABS_Not_Supported_Quality.inst.cfg
index 81b6ff8f4b..def07a3a80 100755
--- a/resources/quality/ultimaker3/um3_bb0.8_ABS_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_ABS_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = normal
material = generic_abs_ultimaker3_BB_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.8_ABS_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_ABS_Not_Supported_Superdraft_Quality.inst.cfg
index 2b65cf0aee..fe4ec5bbc6 100755
--- a/resources/quality/ultimaker3/um3_bb0.8_ABS_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_ABS_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = superdraft
material = generic_abs_ultimaker3_BB_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.8_CPEP_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_CPEP_Not_Supported_Quality.inst.cfg
index 7b60406d2b..279e1c9c89 100755
--- a/resources/quality/ultimaker3/um3_bb0.8_CPEP_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_CPEP_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = normal
material = generic_cpe_plus_ultimaker3_BB_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.8_CPEP_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_CPEP_Not_Supported_Superdraft_Quality.inst.cfg
index 6cec304241..3490da81a6 100755
--- a/resources/quality/ultimaker3/um3_bb0.8_CPEP_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_CPEP_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = superdraft
material = generic_cpe_plus_ultimaker3_BB_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.8_CPE_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_CPE_Not_Supported_Quality.inst.cfg
index dcb12e250f..b70fe13061 100755
--- a/resources/quality/ultimaker3/um3_bb0.8_CPE_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_CPE_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = normal
material = generic_cpe_ultimaker3_BB_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.8_CPE_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_CPE_Not_Supported_Superdraft_Quality.inst.cfg
index cc38d9956f..137a651ddd 100755
--- a/resources/quality/ultimaker3/um3_bb0.8_CPE_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_CPE_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = superdraft
material = generic_cpe_ultimaker3_BB_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.8_Nylon_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_Nylon_Not_Supported_Quality.inst.cfg
index 2bb282ad56..dfbf2754e2 100755
--- a/resources/quality/ultimaker3/um3_bb0.8_Nylon_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_Nylon_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = normal
material = generic_nylon_ultimaker3_BB_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.8_Nylon_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_Nylon_Not_Supported_Superdraft_Quality.inst.cfg
index 6f5099e267..9242228f50 100755
--- a/resources/quality/ultimaker3/um3_bb0.8_Nylon_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_Nylon_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = superdraft
material = generic_nylon_ultimaker3_BB_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.8_PC_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PC_Not_Supported_Quality.inst.cfg
index 7e3df6c22b..f206fd4368 100755
--- a/resources/quality/ultimaker3/um3_bb0.8_PC_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_PC_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = normal
material = generic_pc_ultimaker3_BB_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.8_PC_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PC_Not_Supported_Superdraft_Quality.inst.cfg
index f0c4723a42..cb18b565d7 100755
--- a/resources/quality/ultimaker3/um3_bb0.8_PC_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_PC_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = superdraft
material = generic_pc_ultimaker3_BB_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.8_PLA_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PLA_Not_Supported_Quality.inst.cfg
index 651b32be57..223b5a06fe 100755
--- a/resources/quality/ultimaker3/um3_bb0.8_PLA_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_PLA_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = normal
material = generic_pla_ultimaker3_BB_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.8_PLA_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PLA_Not_Supported_Superdraft_Quality.inst.cfg
index 2ec598e2df..a4f6a6dfeb 100755
--- a/resources/quality/ultimaker3/um3_bb0.8_PLA_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_PLA_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = superdraft
material = generic_pla_ultimaker3_BB_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg
index 17e406cdc8..83960d1491 100644
--- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Draft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = draft
weight = -2
material = generic_pva_ultimaker3_BB_0.8
+setting_version = 1
[values]
material_print_temperature = =default_material_print_temperature + 5
diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg
index 7e87761349..f907d0e492 100644
--- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Superdraft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = superdraft
weight = -4
material = generic_pva_ultimaker3_BB_0.8
+setting_version = 1
[values]
layer_height = 0.4
diff --git a/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg
index d79f0c6848..335d1f5c6d 100644
--- a/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_PVA_Verydraft_Print.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = verydraft
weight = -3
material = generic_pva_ultimaker3_BB_0.8
+setting_version = 1
[values]
layer_height = 0.3
diff --git a/resources/quality/ultimaker3/um3_bb0.8_TPU_Not_Supported_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_TPU_Not_Supported_Quality.inst.cfg
index 47652d807b..84e5c6d3d3 100755
--- a/resources/quality/ultimaker3/um3_bb0.8_TPU_Not_Supported_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_TPU_Not_Supported_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = normal
material = generic_tpu_ultimaker3_BB_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_bb0.8_TPU_Not_Supported_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_bb0.8_TPU_Not_Supported_Superdraft_Quality.inst.cfg
index eb37c60507..222a4935d5 100755
--- a/resources/quality/ultimaker3/um3_bb0.8_TPU_Not_Supported_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_bb0.8_TPU_Not_Supported_Superdraft_Quality.inst.cfg
@@ -9,5 +9,6 @@ quality_type = superdraft
material = generic_tpu_ultimaker3_BB_0.8
weight = 0
supported = False
+setting_version = 1
[values]
diff --git a/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg
index 96e25c6ad8..ee35746983 100644
--- a/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = draft
global_quality = True
weight = -2
+setting_version = 1
[values]
layer_height = 0.2
diff --git a/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg
index 6b1c3c4208..274533485e 100644
--- a/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = fast
global_quality = True
weight = -1
+setting_version = 1
[values]
layer_height = 0.15
diff --git a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg
index af0741ff88..a4f8b60fba 100644
--- a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = high
global_quality = True
weight = 0
+setting_version = 1
[values]
layer_height = 0.06
diff --git a/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg
index a875b0f1ce..e3400f2c5f 100644
--- a/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg
@@ -8,6 +8,7 @@ type = quality
quality_type = normal
global_quality = True
weight = 0
+setting_version = 1
[values]
layer_height = 0.1
diff --git a/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg
index fd3fd1f642..d9c8d00eee 100755
--- a/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg
@@ -7,7 +7,8 @@ definition = ultimaker3
type = quality
quality_type = superdraft
global_quality = True
-weight = -2
+weight = -4
+setting_version = 1
[values]
layer_height = 0.4
diff --git a/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg
index 83afa35e2e..35a62bd63e 100755
--- a/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg
@@ -7,7 +7,8 @@ definition = ultimaker3
type = quality
quality_type = verydraft
global_quality = True
-weight = -2
+weight = -3
+setting_version = 1
[values]
layer_height = 0.3
diff --git a/resources/themes/cura/icons/gradual.svg b/resources/themes/cura/icons/gradual.svg
new file mode 100644
index 0000000000..ed7f301e18
--- /dev/null
+++ b/resources/themes/cura/icons/gradual.svg
@@ -0,0 +1,102 @@
+
+
diff --git a/resources/variants/cartesio_0.25.inst.cfg b/resources/variants/cartesio_0.25.inst.cfg
index 2c7ecc7b03..b789eef732 100644
--- a/resources/variants/cartesio_0.25.inst.cfg
+++ b/resources/variants/cartesio_0.25.inst.cfg
@@ -6,6 +6,7 @@ definition = cartesio
[metadata]
author = Cartesio
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.25
diff --git a/resources/variants/cartesio_0.4.inst.cfg b/resources/variants/cartesio_0.4.inst.cfg
index 43bed9bfbd..46140ccc24 100644
--- a/resources/variants/cartesio_0.4.inst.cfg
+++ b/resources/variants/cartesio_0.4.inst.cfg
@@ -6,6 +6,7 @@ definition = cartesio
[metadata]
author = Cartesio
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.4
diff --git a/resources/variants/cartesio_0.8.inst.cfg b/resources/variants/cartesio_0.8.inst.cfg
index 0f6fda119a..118d79144a 100644
--- a/resources/variants/cartesio_0.8.inst.cfg
+++ b/resources/variants/cartesio_0.8.inst.cfg
@@ -6,6 +6,7 @@ definition = cartesio
[metadata]
author = Cartesio
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.8
diff --git a/resources/variants/imade3d_jellybox_0.4.inst.cfg b/resources/variants/imade3d_jellybox_0.4.inst.cfg
index b33fa0fea6..8bce86482b 100644
--- a/resources/variants/imade3d_jellybox_0.4.inst.cfg
+++ b/resources/variants/imade3d_jellybox_0.4.inst.cfg
@@ -6,6 +6,7 @@ definition = imade3d_jellybox
[metadata]
author = IMADE3D
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.4
diff --git a/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg b/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg
index 65c330e58b..e02c1fe29f 100644
--- a/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg
+++ b/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg
@@ -6,6 +6,7 @@ definition = imade3d_jellybox
[metadata]
author = IMADE3D
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.4
diff --git a/resources/variants/ultimaker2_0.25.inst.cfg b/resources/variants/ultimaker2_0.25.inst.cfg
index 9d59e47b89..1891124ce9 100644
--- a/resources/variants/ultimaker2_0.25.inst.cfg
+++ b/resources/variants/ultimaker2_0.25.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker2
[metadata]
author = Ultimaker
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.25
diff --git a/resources/variants/ultimaker2_0.4.inst.cfg b/resources/variants/ultimaker2_0.4.inst.cfg
index 7ebcbb69b7..622c97e6ff 100644
--- a/resources/variants/ultimaker2_0.4.inst.cfg
+++ b/resources/variants/ultimaker2_0.4.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker2
[metadata]
author = Ultimaker
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.4
diff --git a/resources/variants/ultimaker2_0.6.inst.cfg b/resources/variants/ultimaker2_0.6.inst.cfg
index accf507750..e64880932f 100644
--- a/resources/variants/ultimaker2_0.6.inst.cfg
+++ b/resources/variants/ultimaker2_0.6.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker2
[metadata]
author = Ultimaker
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.6
diff --git a/resources/variants/ultimaker2_0.8.inst.cfg b/resources/variants/ultimaker2_0.8.inst.cfg
index 97452046cb..f4b86e58ed 100644
--- a/resources/variants/ultimaker2_0.8.inst.cfg
+++ b/resources/variants/ultimaker2_0.8.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker2
[metadata]
author = Ultimaker
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.8
diff --git a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg
index b499db6163..044bec5731 100644
--- a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg
+++ b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker2_extended_plus
[metadata]
author = Ultimaker
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.25
diff --git a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg
index d2fb6f76b1..70cfbb81d1 100644
--- a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg
+++ b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker2_extended_plus
[metadata]
author = Ultimaker
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.4
diff --git a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg
index e4f9f0ce45..0bd4d181ac 100644
--- a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg
+++ b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker2_extended_plus
[metadata]
author = Ultimaker
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.6
diff --git a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg
index 18570ea75d..d83f23859f 100644
--- a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg
+++ b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker2_extended_plus
[metadata]
author = Ultimaker
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.8
diff --git a/resources/variants/ultimaker2_plus_0.25.inst.cfg b/resources/variants/ultimaker2_plus_0.25.inst.cfg
index 7cab771101..f493fecb71 100644
--- a/resources/variants/ultimaker2_plus_0.25.inst.cfg
+++ b/resources/variants/ultimaker2_plus_0.25.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker2_plus
[metadata]
author = Ultimaker
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.25
diff --git a/resources/variants/ultimaker2_plus_0.4.inst.cfg b/resources/variants/ultimaker2_plus_0.4.inst.cfg
index 748f367250..b7a7d8c7a7 100644
--- a/resources/variants/ultimaker2_plus_0.4.inst.cfg
+++ b/resources/variants/ultimaker2_plus_0.4.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker2_plus
[metadata]
author = Ultimaker
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.4
diff --git a/resources/variants/ultimaker2_plus_0.6.inst.cfg b/resources/variants/ultimaker2_plus_0.6.inst.cfg
index 34d0f7a5cf..9954359cc5 100644
--- a/resources/variants/ultimaker2_plus_0.6.inst.cfg
+++ b/resources/variants/ultimaker2_plus_0.6.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker2_plus
[metadata]
author = Ultimaker
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.6
diff --git a/resources/variants/ultimaker2_plus_0.8.inst.cfg b/resources/variants/ultimaker2_plus_0.8.inst.cfg
index e719409060..de21ac87ab 100644
--- a/resources/variants/ultimaker2_plus_0.8.inst.cfg
+++ b/resources/variants/ultimaker2_plus_0.8.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker2_plus
[metadata]
author = Ultimaker
type = variant
+setting_version = 1
[values]
machine_nozzle_size = 0.8
diff --git a/resources/variants/ultimaker3_aa0.8.inst.cfg b/resources/variants/ultimaker3_aa0.8.inst.cfg
index e7e1654c6e..e0486289a1 100644
--- a/resources/variants/ultimaker3_aa0.8.inst.cfg
+++ b/resources/variants/ultimaker3_aa0.8.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker3
[metadata]
author = ultimaker
type = variant
+setting_version = 1
[values]
acceleration_enabled = True
@@ -37,7 +38,6 @@ material_initial_print_temperature = =material_print_temperature - 5
material_standby_temperature = 100
multiple_mesh_overlap = 0
prime_tower_enable = False
-prime_tower_size = 16
prime_tower_wipe_enabled = True
retract_at_layer_change = True
retraction_amount = 6.5
diff --git a/resources/variants/ultimaker3_aa04.inst.cfg b/resources/variants/ultimaker3_aa04.inst.cfg
index dae256c990..4cf31caef0 100644
--- a/resources/variants/ultimaker3_aa04.inst.cfg
+++ b/resources/variants/ultimaker3_aa04.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker3
[metadata]
author = ultimaker
type = variant
+setting_version = 1
[values]
brim_width = 7
diff --git a/resources/variants/ultimaker3_bb0.8.inst.cfg b/resources/variants/ultimaker3_bb0.8.inst.cfg
index d0c2c9c661..72d4143370 100644
--- a/resources/variants/ultimaker3_bb0.8.inst.cfg
+++ b/resources/variants/ultimaker3_bb0.8.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker3
[metadata]
author = ultimaker
type = variant
+setting_version = 1
[values]
acceleration_enabled = True
diff --git a/resources/variants/ultimaker3_bb04.inst.cfg b/resources/variants/ultimaker3_bb04.inst.cfg
index b813e8474d..b72d849796 100644
--- a/resources/variants/ultimaker3_bb04.inst.cfg
+++ b/resources/variants/ultimaker3_bb04.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker3
[metadata]
author = ultimaker
type = variant
+setting_version = 1
[values]
cool_fan_speed_max = =cool_fan_speed
diff --git a/resources/variants/ultimaker3_extended_aa0.8.inst.cfg b/resources/variants/ultimaker3_extended_aa0.8.inst.cfg
index b89ce4406b..0fd110c76c 100644
--- a/resources/variants/ultimaker3_extended_aa0.8.inst.cfg
+++ b/resources/variants/ultimaker3_extended_aa0.8.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker3_extended
[metadata]
author = ultimaker
type = variant
+setting_version = 1
[values]
acceleration_enabled = True
@@ -37,7 +38,6 @@ material_initial_print_temperature = =material_print_temperature - 5
material_standby_temperature = 100
multiple_mesh_overlap = 0
prime_tower_enable = False
-prime_tower_size = 16
prime_tower_wipe_enabled = True
retract_at_layer_change = True
retraction_amount = 6.5
diff --git a/resources/variants/ultimaker3_extended_aa04.inst.cfg b/resources/variants/ultimaker3_extended_aa04.inst.cfg
index 6fa09c32ea..99daa082e4 100644
--- a/resources/variants/ultimaker3_extended_aa04.inst.cfg
+++ b/resources/variants/ultimaker3_extended_aa04.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker3_extended
[metadata]
author = ultimaker
type = variant
+setting_version = 1
[values]
brim_width = 7
diff --git a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg
index e4fb152ee0..f88dc818c8 100644
--- a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg
+++ b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker3_extended
[metadata]
author = ultimaker
type = variant
+setting_version = 1
[values]
acceleration_enabled = True
diff --git a/resources/variants/ultimaker3_extended_bb04.inst.cfg b/resources/variants/ultimaker3_extended_bb04.inst.cfg
index a7c43ea376..229bde1916 100644
--- a/resources/variants/ultimaker3_extended_bb04.inst.cfg
+++ b/resources/variants/ultimaker3_extended_bb04.inst.cfg
@@ -6,6 +6,7 @@ definition = ultimaker3_extended
[metadata]
author = ultimaker
type = variant
+setting_version = 1
[values]
cool_fan_speed_max = 100
diff --git a/tests/Settings/TestCuraContainerRegistry.py b/tests/Settings/TestCuraContainerRegistry.py
index 7b191a8376..ad79f74dd4 100644
--- a/tests/Settings/TestCuraContainerRegistry.py
+++ b/tests/Settings/TestCuraContainerRegistry.py
@@ -11,6 +11,7 @@ from cura.Settings.CuraContainerRegistry import CuraContainerRegistry #The class
from cura.Settings.ExtruderStack import ExtruderStack #Testing for returning the correct types of stacks.
from cura.Settings.GlobalStack import GlobalStack #Testing for returning the correct types of stacks.
from UM.Resources import Resources #Mocking some functions of this.
+import UM.Settings.InstanceContainer #Creating instance containers to register.
import UM.Settings.ContainerRegistry #Making empty container stacks.
import UM.Settings.ContainerStack #Setting the container registry here properly.
from UM.Settings.DefinitionContainer import DefinitionContainer
@@ -18,7 +19,15 @@ from UM.Settings.DefinitionContainer import DefinitionContainer
## Gives a fresh CuraContainerRegistry instance.
@pytest.fixture()
def container_registry():
- return CuraContainerRegistry()
+ registry = CuraContainerRegistry()
+ UM.Settings.InstanceContainer.setContainerRegistry(registry)
+ UM.Settings.ContainerStack.setContainerRegistry(registry)
+ return registry
+
+## Gives an arbitrary definition container.
+@pytest.fixture()
+def definition_container():
+ return DefinitionContainer(container_id = "Test Definition")
def teardown():
#If the temporary file for the legacy file rename test still exists, remove it.
@@ -26,6 +35,80 @@ def teardown():
if os.path.isfile(temporary_file):
os.remove(temporary_file)
+## Tests whether addContainer properly converts to ExtruderStack.
+def test_addContainerExtruderStack(container_registry, definition_container):
+ container_registry.addContainer(definition_container)
+
+ container_stack = UM.Settings.ContainerStack.ContainerStack(stack_id = "Test Container Stack") #A container we're going to convert.
+ container_stack.addMetaDataEntry("type", "extruder_train") #This is now an extruder train.
+ container_stack.insertContainer(0, definition_container) #Add a definition to it so it doesn't complain.
+
+ mock_super_add_container = unittest.mock.MagicMock() #Takes the role of the Uranium-ContainerRegistry where the resulting containers get registered.
+ with unittest.mock.patch("UM.Settings.ContainerRegistry.ContainerRegistry.addContainer", mock_super_add_container):
+ container_registry.addContainer(container_stack)
+
+ assert len(mock_super_add_container.call_args_list) == 1 #Called only once.
+ assert len(mock_super_add_container.call_args_list[0][0]) == 1 #Called with one parameter.
+ assert type(mock_super_add_container.call_args_list[0][0][0]) == ExtruderStack
+
+## Tests whether addContainer properly converts to GlobalStack.
+def test_addContainerGlobalStack(container_registry, definition_container):
+ container_registry.addContainer(definition_container)
+
+ container_stack = UM.Settings.ContainerStack.ContainerStack(stack_id = "Test Container Stack") #A container we're going to convert.
+ container_stack.addMetaDataEntry("type", "machine") #This is now a global stack.
+ container_stack.insertContainer(0, definition_container) #Must have a definition.
+
+ mock_super_add_container = unittest.mock.MagicMock() #Takes the role of the Uranium-ContainerRegistry where the resulting containers get registered.
+ with unittest.mock.patch("UM.Settings.ContainerRegistry.ContainerRegistry.addContainer", mock_super_add_container):
+ container_registry.addContainer(container_stack)
+
+ assert len(mock_super_add_container.call_args_list) == 1 #Called only once.
+ assert len(mock_super_add_container.call_args_list[0][0]) == 1 #Called with one parameter.
+ assert type(mock_super_add_container.call_args_list[0][0][0]) == GlobalStack
+
+def test_addContainerGoodSettingVersion(container_registry, definition_container):
+ definition_container.getMetaData()["setting_version"] = 3
+ container_registry.addContainer(definition_container)
+
+ instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance")
+ instance.addMetaDataEntry("setting_version", 3)
+ instance.setDefinition(definition_container)
+
+ mock_super_add_container = unittest.mock.MagicMock() #Take the role of the Uranium-ContainerRegistry where the resulting containers get registered.
+ with unittest.mock.patch("UM.Settings.ContainerRegistry.ContainerRegistry.addContainer", mock_super_add_container):
+ container_registry.addContainer(instance)
+
+ mock_super_add_container.assert_called_once_with(instance) #The instance must have been registered now.
+
+def test_addContainerNoSettingVersion(container_registry, definition_container):
+ definition_container.getMetaData()["setting_version"] = 3
+ container_registry.addContainer(definition_container)
+
+ instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance")
+ #Don't add setting_version metadata.
+ instance.setDefinition(definition_container)
+
+ mock_super_add_container = unittest.mock.MagicMock() #Take the role of the Uranium-ContainerRegistry where the resulting container should not get registered.
+ with unittest.mock.patch("UM.Settings.ContainerRegistry.ContainerRegistry.addContainer", mock_super_add_container):
+ container_registry.addContainer(instance)
+
+ mock_super_add_container.assert_not_called() #Should not get passed on to UM.Settings.ContainerRegistry.addContainer, because the setting_version is interpreted as 0!
+
+def test_addContainerBadSettingVersion(container_registry, definition_container):
+ definition_container.getMetaData()["setting_version"] = 3
+ container_registry.addContainer(definition_container)
+
+ instance = UM.Settings.InstanceContainer.InstanceContainer(container_id = "Test Instance")
+ instance.addMetaDataEntry("setting_version", 9001) #Wrong version!
+ instance.setDefinition(definition_container)
+
+ mock_super_add_container = unittest.mock.MagicMock() #Take the role of the Uranium-ContainerRegistry where the resulting container should not get registered.
+ with unittest.mock.patch("UM.Settings.ContainerRegistry.ContainerRegistry.addContainer", mock_super_add_container):
+ container_registry.addContainer(instance)
+
+ mock_super_add_container.assert_not_called() #Should not get passed on to UM.Settings.ContainerRegistry.addContainer, because the setting_version doesn't match its definition!
+
## Tests whether loading gives objects of the correct type.
@pytest.mark.parametrize("filename, output_class", [
("ExtruderLegacy.stack.cfg", ExtruderStack),
@@ -36,7 +119,6 @@ def teardown():
])
def test_loadTypes(filename, output_class, container_registry):
#Mock some dependencies.
- UM.Settings.ContainerStack.setContainerRegistry(container_registry)
Resources.getAllResourcesOfType = unittest.mock.MagicMock(return_value = [os.path.join(os.path.dirname(os.path.abspath(__file__)), "stacks", filename)]) #Return just this tested file.
def findContainers(container_type = 0, id = None):
diff --git a/tests/Settings/TestGlobalStack.py b/tests/Settings/TestGlobalStack.py
old mode 100644
new mode 100755
index 539de4929e..1eb3c43746
--- a/tests/Settings/TestGlobalStack.py
+++ b/tests/Settings/TestGlobalStack.py
@@ -78,9 +78,10 @@ def test_addExtruder(global_stack):
global_stack.addExtruder(second_extruder)
assert len(global_stack.extruders) == 2
assert global_stack.extruders[1] == second_extruder
- with unittest.mock.patch("cura.Settings.CuraContainerStack.DefinitionContainer", unittest.mock.MagicMock):
- with pytest.raises(TooManyExtrudersError): #Should be limited to 2 extruders because of machine_extruder_count.
- global_stack.addExtruder(unittest.mock.MagicMock())
+ # Disabled for now for Custom FDM Printer
+ # with unittest.mock.patch("cura.Settings.CuraContainerStack.DefinitionContainer", unittest.mock.MagicMock):
+ # with pytest.raises(TooManyExtrudersError): #Should be limited to 2 extruders because of machine_extruder_count.
+ # global_stack.addExtruder(unittest.mock.MagicMock())
assert len(global_stack.extruders) == 2 #Didn't add the faulty extruder.
#Tests setting user changes profiles to invalid containers.