diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000000..d25d71bcc9
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,4 @@
+.git
+.github
+resources/materials
+CuraEngine
\ No newline at end of file
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
index b78b9b91a2..c69cf91433 100644
--- a/.github/ISSUE_TEMPLATE.md
+++ b/.github/ISSUE_TEMPLATE.md
@@ -1,9 +1,12 @@
@@ -23,6 +26,9 @@ Thank you for using Cura!
**Display Driver**
+**Printer**
+
+
**Steps to Reproduce**
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000000..68255c56b9
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,45 @@
+FROM ultimaker/cura-build-environment:1
+
+# Environment vars for easy configuration
+ENV CURA_APP_DIR=/srv/cura
+
+# Ensure our sources dir exists
+RUN mkdir $CURA_APP_DIR
+
+# Setup CuraEngine
+ENV CURA_ENGINE_BRANCH=master
+WORKDIR $CURA_APP_DIR
+RUN git clone -b $CURA_ENGINE_BRANCH --depth 1 https://github.com/Ultimaker/CuraEngine
+WORKDIR $CURA_APP_DIR/CuraEngine
+RUN mkdir build
+WORKDIR $CURA_APP_DIR/CuraEngine/build
+RUN cmake3 ..
+RUN make
+RUN make install
+
+# TODO: setup libCharon
+
+# Setup Uranium
+ENV URANIUM_BRANCH=master
+WORKDIR $CURA_APP_DIR
+RUN git clone -b $URANIUM_BRANCH --depth 1 https://github.com/Ultimaker/Uranium
+
+# Setup materials
+ENV MATERIALS_BRANCH=master
+WORKDIR $CURA_APP_DIR
+RUN git clone -b $MATERIALS_BRANCH --depth 1 https://github.com/Ultimaker/fdm_materials materials
+
+# Setup Cura
+WORKDIR $CURA_APP_DIR/Cura
+ADD . .
+RUN mv $CURA_APP_DIR/materials resources/materials
+
+# Make sure Cura can find CuraEngine
+RUN ln -s /usr/local/bin/CuraEngine $CURA_APP_DIR/Cura
+
+# Run Cura
+WORKDIR $CURA_APP_DIR/Cura
+ENV PYTHONPATH=${PYTHONPATH}:$CURA_APP_DIR/Uranium
+RUN chmod +x ./CuraEngine
+RUN chmod +x ./run_in_docker.sh
+CMD "./run_in_docker.sh"
diff --git a/README.md b/README.md
index 366739e4be..70466e9c22 100644
--- a/README.md
+++ b/README.md
@@ -27,6 +27,10 @@ Build scripts
-------------
Please checkout [cura-build](https://github.com/Ultimaker/cura-build) for detailed building instructions.
+Running from Source
+-------------
+Please check our [Wiki page](https://github.com/Ultimaker/Cura/wiki/Running-Cura-from-Source) for details about running Cura from source.
+
Plugins
-------------
Please check our [Wiki page](https://github.com/Ultimaker/Cura/wiki/Plugin-Directory) for details about creating and using plugins.
diff --git a/cura.appdata.xml b/cura.appdata.xml
index 5c67814fae..2d8bff15ec 100644
--- a/cura.appdata.xml
+++ b/cura.appdata.xml
@@ -3,7 +3,7 @@
cura.desktop
CC0-1.0
- AGPL-3.0 and CC-BY-SA-4.0
+ LGPL-3.0 and CC-BY-SA-4.0
Cura
The world's most advanced 3d printer software
@@ -15,7 +15,7 @@
- Novices can start printing right away
- - Experts are able to customize 200 settings to achieve the best results
+ - Experts are able to customize 300 settings to achieve the best results
- Optimized profiles for Ultimaker materials
- Supported by a global network of Ultimaker certified service partners
- Print multiple objects at once with different settings for each object
@@ -26,6 +26,6 @@
http://software.ultimaker.com/Cura.png
- https://ultimaker.com/en/products/cura-software
+ https://ultimaker.com/en/products/cura-software?utm_source=cura&utm_medium=software&utm_campaign=resources
Cura
diff --git a/cura/BuildVolume.py b/cura/BuildVolume.py
index 922f23d30f..275fce6995 100755
--- a/cura/BuildVolume.py
+++ b/cura/BuildVolume.py
@@ -111,6 +111,9 @@ class BuildVolume(SceneNode):
# but it does not update the disallowed areas after material change
Application.getInstance().getMachineManager().activeStackChanged.connect(self._onStackChanged)
+ # Enable and disable extruder
+ Application.getInstance().getMachineManager().extruderChanged.connect(self.updateNodeBoundaryCheck)
+
# list of settings which were updated
self._changed_settings_since_last_rebuild = []
@@ -217,30 +220,26 @@ class BuildVolume(SceneNode):
group_nodes.append(node) # Keep list of affected group_nodes
if node.callDecoration("isSliceable") or node.callDecoration("isGroup"):
- node._outside_buildarea = False
- bbox = node.getBoundingBox()
-
- # Mark the node as outside the build volume if the bounding box test fails.
- if build_volume_bounding_box.intersectsBox(bbox) != AxisAlignedBox.IntersectionResult.FullIntersection:
- node._outside_buildarea = True
+ if node.collidesWithBbox(build_volume_bounding_box):
+ node.setOutsideBuildArea(True)
continue
- convex_hull = node.callDecoration("getConvexHull")
- if convex_hull:
- if not convex_hull.isValid():
- return
- # Check for collisions between disallowed areas and the object
- for area in self.getDisallowedAreas():
- overlap = convex_hull.intersectsPolygon(area)
- if overlap is None:
- continue
- node._outside_buildarea = True
- continue
+ if node.collidesWithArea(self.getDisallowedAreas()):
+ node.setOutsideBuildArea(True)
+ continue
+
+ # Mark the node as outside build volume if the set extruder is disabled
+ extruder_position = node.callDecoration("getActiveExtruderPosition")
+ if not self._global_container_stack.extruders[extruder_position].isEnabled:
+ node.setOutsideBuildArea(True)
+ continue
+
+ node.setOutsideBuildArea(False)
# Group nodes should override the _outside_buildarea property of their children.
for group_node in group_nodes:
for child_node in group_node.getAllChildren():
- child_node._outside_buildarea = group_node._outside_buildarea
+ child_node.setOutsideBuildArea(group_node.isOutsideBuildArea)
## Update the outsideBuildArea of a single node, given bounds or current build volume
def checkBoundsAndUpdate(self, node: CuraSceneNode, bounds: Optional[AxisAlignedBox] = None):
@@ -260,24 +259,20 @@ class BuildVolume(SceneNode):
build_volume_bounding_box = bounds
if node.callDecoration("isSliceable") or node.callDecoration("isGroup"):
- bbox = node.getBoundingBox()
-
- # Mark the node as outside the build volume if the bounding box test fails.
- if build_volume_bounding_box.intersectsBox(bbox) != AxisAlignedBox.IntersectionResult.FullIntersection:
+ if node.collidesWithBbox(build_volume_bounding_box):
+ node.setOutsideBuildArea(True)
+ return
+
+ if node.collidesWithArea(self.getDisallowedAreas()):
+ node.setOutsideBuildArea(True)
+ return
+
+ # Mark the node as outside build volume if the set extruder is disabled
+ extruder_position = node.callDecoration("getActiveExtruderPosition")
+ if not self._global_container_stack.extruders[extruder_position].isEnabled:
node.setOutsideBuildArea(True)
return
- convex_hull = self.callDecoration("getConvexHull")
- if convex_hull:
- if not convex_hull.isValid():
- return
- # Check for collisions between disallowed areas and the object
- for area in self.getDisallowedAreas():
- overlap = convex_hull.intersectsPolygon(area)
- if overlap is None:
- continue
- node.setOutsideBuildArea(True)
- return
node.setOutsideBuildArea(False)
## Recalculates the build volume & disallowed areas.
@@ -737,12 +732,17 @@ class BuildVolume(SceneNode):
prime_tower_x = prime_tower_x - machine_width / 2 #Offset by half machine_width and _depth to put the origin in the front-left.
prime_tower_y = prime_tower_y + machine_depth / 2
- prime_tower_area = Polygon([
- [prime_tower_x - prime_tower_size, prime_tower_y - prime_tower_size],
- [prime_tower_x, prime_tower_y - prime_tower_size],
- [prime_tower_x, prime_tower_y],
- [prime_tower_x - prime_tower_size, prime_tower_y],
- ])
+ if self._global_container_stack.getProperty("prime_tower_circular", "value"):
+ radius = prime_tower_size / 2
+ prime_tower_area = Polygon.approximatedCircle(radius)
+ prime_tower_area = prime_tower_area.translate(prime_tower_x - radius, prime_tower_y - radius)
+ else:
+ prime_tower_area = Polygon([
+ [prime_tower_x - prime_tower_size, prime_tower_y - prime_tower_size],
+ [prime_tower_x, prime_tower_y - prime_tower_size],
+ [prime_tower_x, prime_tower_y],
+ [prime_tower_x - prime_tower_size, prime_tower_y],
+ ])
prime_tower_area = prime_tower_area.getMinkowskiHull(Polygon.approximatedCircle(0))
for extruder in used_extruders:
result[extruder.getId()].append(prime_tower_area) #The prime tower location is the same for each extruder, regardless of offset.
@@ -821,6 +821,7 @@ class BuildVolume(SceneNode):
offset_y = extruder.getProperty("machine_nozzle_offset_y", "value")
if offset_y is None:
offset_y = 0
+ offset_y = -offset_y #Y direction of g-code is the inverse of Y direction of Cura's scene space.
result[extruder_id] = []
for polygon in machine_disallowed_polygons:
@@ -931,8 +932,8 @@ class BuildVolume(SceneNode):
# stack.
#
# \return A sequence of setting values, one for each extruder.
- def _getSettingFromAllExtruders(self, setting_key, property = "value"):
- all_values = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, property)
+ def _getSettingFromAllExtruders(self, setting_key):
+ all_values = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, "value")
all_types = ExtruderManager.getInstance().getAllExtruderSettings(setting_key, "type")
for i in range(len(all_values)):
if not all_values[i] and (all_types[i] == "int" or all_types[i] == "float"):
@@ -945,7 +946,7 @@ class BuildVolume(SceneNode):
# not part of the collision radius, such as bed adhesion (skirt/brim/raft)
# and travel avoid distance.
def _getEdgeDisallowedSize(self):
- if not self._global_container_stack:
+ if not self._global_container_stack or not self._global_container_stack.extruders:
return 0
container_stack = self._global_container_stack
@@ -1023,7 +1024,7 @@ class BuildVolume(SceneNode):
_raft_settings = ["adhesion_type", "raft_base_thickness", "raft_interface_thickness", "raft_surface_layers", "raft_surface_thickness", "raft_airgap", "layer_0_z_overlap"]
_extra_z_settings = ["retraction_hop_enabled", "retraction_hop"]
_prime_settings = ["extruder_prime_pos_x", "extruder_prime_pos_y", "extruder_prime_pos_z", "prime_blob_enable"]
- _tower_settings = ["prime_tower_enable", "prime_tower_size", "prime_tower_position_x", "prime_tower_position_y"]
+ _tower_settings = ["prime_tower_enable", "prime_tower_circular", "prime_tower_size", "prime_tower_position_x", "prime_tower_position_y"]
_ooze_shield_settings = ["ooze_shield_enabled", "ooze_shield_dist"]
_distance_settings = ["infill_wipe_dist", "travel_avoid_distance", "support_offset", "support_enable", "travel_avoid_other_parts"]
_extruder_settings = ["support_enable", "support_bottom_enable", "support_roof_enable", "support_infill_extruder_nr", "support_extruder_nr_layer_0", "support_bottom_extruder_nr", "support_roof_extruder_nr", "brim_line_count", "adhesion_extruder_nr", "adhesion_type"] #Settings that can affect which extruders are used.
diff --git a/cura/CrashHandler.py b/cura/CrashHandler.py
index fa09db3e50..c082578218 100644
--- a/cura/CrashHandler.py
+++ b/cura/CrashHandler.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2017 Ultimaker B.V.
+# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import platform
@@ -13,16 +13,18 @@ import ssl
import urllib.request
import urllib.error
import shutil
-import sys
-from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR
+from PyQt5.QtCore import QT_VERSION_STR, PYQT_VERSION_STR, Qt, QUrl
from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel, QTextEdit, QGroupBox, QCheckBox, QPushButton
+from PyQt5.QtGui import QDesktopServices
+from UM.Resources import Resources
from UM.Application import Application
from UM.Logger import Logger
from UM.View.GL.OpenGL import OpenGL
from UM.i18n import i18nCatalog
from UM.Platform import Platform
+from UM.Resources import Resources
catalog = i18nCatalog("cura")
@@ -91,6 +93,7 @@ class CrashHandler:
label = QLabel()
label.setText(catalog.i18nc("@label crash message", """A fatal error has occurred.
Unfortunately, Cura encountered an unrecoverable error during start up. It was possibly caused by some incorrect configuration files. We suggest to backup and reset your configuration.
+ Backups can be found in the configuration folder.
Please send us this Crash Report to fix the problem.
"""))
label.setWordWrap(True)
@@ -104,8 +107,13 @@ class CrashHandler:
show_details_button.setMaximumWidth(200)
show_details_button.clicked.connect(self._showDetailedReport)
+ show_configuration_folder_button = QPushButton(catalog.i18nc("@action:button", "Show configuration folder"), dialog)
+ show_configuration_folder_button.setMaximumWidth(200)
+ show_configuration_folder_button.clicked.connect(self._showConfigurationFolder)
+
layout.addWidget(self._send_report_checkbox)
layout.addWidget(show_details_button)
+ layout.addWidget(show_configuration_folder_button)
# "backup and start clean" and "close" buttons
buttons = QDialogButtonBox()
@@ -162,12 +170,15 @@ class CrashHandler:
file_name = base_name + "_" + date_now + "_" + idx
zip_file_path = os.path.join(root_dir, file_name + ".zip")
try:
- # remove the .zip extension because make_archive() adds it
- zip_file_path = zip_file_path[:-4]
- shutil.make_archive(zip_file_path, "zip", root_dir = root_dir, base_dir = base_name)
+ # only create the zip backup when the folder exists
+ if os.path.exists(folder):
+ # remove the .zip extension because make_archive() adds it
+ zip_file_path = zip_file_path[:-4]
+ shutil.make_archive(zip_file_path, "zip", root_dir = root_dir, base_dir = base_name)
+
+ # remove the folder only when the backup is successful
+ shutil.rmtree(folder, ignore_errors = True)
- # remove the folder only when the backup is successful
- shutil.rmtree(folder, ignore_errors = True)
# create an empty folder so Resources will not try to copy the old ones
os.makedirs(folder, 0o0755, exist_ok=True)
@@ -178,6 +189,10 @@ class CrashHandler:
self.early_crash_dialog.close()
+ def _showConfigurationFolder(self):
+ path = Resources.getConfigStoragePath();
+ QDesktopServices.openUrl(QUrl.fromLocalFile( path ))
+
def _showDetailedReport(self):
self.dialog.exec_()
@@ -244,7 +259,7 @@ class CrashHandler:
opengl_instance = OpenGL.getInstance()
if not opengl_instance:
self.data["opengl"] = {"version": "n/a", "vendor": "n/a", "type": "n/a"}
- return catalog.i18nc("@label", "not yet initialised
")
+ return catalog.i18nc("@label", "Not yet initialized
")
info = ""
info += catalog.i18nc("@label OpenGL version", "- OpenGL Version: {version}
").format(version = opengl_instance.getOpenGLVersion())
diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py
index 4ff39b84a4..f39c2ba554 100755
--- a/cura/CuraApplication.py
+++ b/cura/CuraApplication.py
@@ -1,7 +1,10 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
+
#Type hinting.
from typing import Dict
+
+from PyQt5.QtCore import QObject
from PyQt5.QtNetwork import QLocalServer
from PyQt5.QtNetwork import QLocalSocket
@@ -12,6 +15,7 @@ from UM.Math.Vector import Vector
from UM.Math.Quaternion import Quaternion
from UM.Math.AxisAlignedBox import AxisAlignedBox
from UM.Math.Matrix import Matrix
+from UM.Platform import Platform
from UM.Resources import Resources
from UM.Scene.ToolHandle import ToolHandle
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
@@ -51,13 +55,23 @@ from UM.Settings.SettingDefinition import SettingDefinition, DefinitionPropertyT
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.SettingFunction import SettingFunction
from cura.Settings.MachineNameValidator import MachineNameValidator
-from cura.Settings.ProfilesModel import ProfilesModel
-from cura.Settings.MaterialsModel import MaterialsModel
-from cura.Settings.QualityAndUserProfilesModel import QualityAndUserProfilesModel
+
+from cura.Machines.Models.BuildPlateModel import BuildPlateModel
+from cura.Machines.Models.NozzleModel import NozzleModel
+from cura.Machines.Models.QualityProfilesDropDownMenuModel import QualityProfilesDropDownMenuModel
+from cura.Machines.Models.CustomQualityProfilesDropDownMenuModel import CustomQualityProfilesDropDownMenuModel
+
+from cura.Machines.Models.MultiBuildPlateModel import MultiBuildPlateModel
+
+from cura.Machines.Models.MaterialManagementModel import MaterialManagementModel
+from cura.Machines.Models.GenericMaterialsModel import GenericMaterialsModel
+from cura.Machines.Models.BrandMaterialsModel import BrandMaterialsModel
+
from cura.Settings.SettingInheritanceManager import SettingInheritanceManager
-from cura.Settings.UserProfilesModel import UserProfilesModel
from cura.Settings.SimpleModeSettingsManager import SimpleModeSettingsManager
+from cura.Machines.VariantManager import VariantManager
+from cura.Machines.Models.QualityManagementModel import QualityManagementModel
from . import PlatformPhysics
from . import BuildVolume
@@ -70,17 +84,14 @@ from . import CameraImageProvider
from . import MachineActionManager
from cura.Settings.MachineManager import MachineManager
-from cura.Settings.MaterialManager import MaterialManager
from cura.Settings.ExtruderManager import ExtruderManager
from cura.Settings.UserChangesModel import UserChangesModel
from cura.Settings.ExtrudersModel import ExtrudersModel
-from cura.Settings.ContainerSettingsModel import ContainerSettingsModel
from cura.Settings.MaterialSettingsVisibilityHandler import MaterialSettingsVisibilityHandler
-from cura.Settings.QualitySettingsModel import QualitySettingsModel
+from cura.Machines.Models.QualitySettingsModel import QualitySettingsModel
from cura.Settings.ContainerManager import ContainerManager
from cura.ObjectsModel import ObjectsModel
-from cura.BuildPlateModel import BuildPlateModel
from PyQt5.QtCore import QUrl, pyqtSignal, pyqtProperty, QEvent, Q_ENUMS
from UM.FlameProfiler import pyqtSlot
@@ -198,10 +209,10 @@ class CuraApplication(QtApplication):
UM.VersionUpgradeManager.VersionUpgradeManager.getInstance().setCurrentVersions(
{
("quality_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.QualityInstanceContainer, "application/x-uranium-instancecontainer"),
- ("machine_stack", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.MachineStack, "application/x-cura-globalstack"),
- ("extruder_train", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.ExtruderStack, "application/x-cura-extruderstack"),
- ("preferences", Preferences.Version * 1000000 + self.SettingVersion): (Resources.Preferences, "application/x-uranium-preferences"),
- ("user", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer"),
+ ("machine_stack", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.MachineStack, "application/x-cura-globalstack"),
+ ("extruder_train", ContainerStack.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.ExtruderStack, "application/x-cura-extruderstack"),
+ ("preferences", Preferences.Version * 1000000 + self.SettingVersion): (Resources.Preferences, "application/x-uranium-preferences"),
+ ("user", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.UserInstanceContainer, "application/x-uranium-instancecontainer"),
("definition_changes", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.DefinitionChangesContainer, "application/x-uranium-instancecontainer"),
}
)
@@ -215,6 +226,7 @@ class CuraApplication(QtApplication):
self._material_manager = None
self._object_manager = None
self._build_plate_model = None
+ self._multi_build_plate_model = None
self._setting_inheritance_manager = None
self._simple_mode_settings_manager = None
self._cura_scene_controller = None
@@ -232,6 +244,8 @@ class CuraApplication(QtApplication):
if kwargs["parsed_command_line"].get("trigger_early_crash", False):
assert not "This crash is triggered by the trigger_early_crash command line argument."
+ self._variant_manager = None
+
self.default_theme = "cura-light"
self.setWindowIcon(QIcon(Resources.getPath(Resources.Images, "cura-icon.png")))
@@ -286,21 +300,25 @@ class CuraApplication(QtApplication):
# Since they are empty, they should never be serialized and instead just programmatically created.
# We need them to simplify the switching between materials.
empty_container = ContainerRegistry.getInstance().getEmptyInstanceContainer()
+ self.empty_container = empty_container
empty_definition_changes_container = copy.deepcopy(empty_container)
empty_definition_changes_container.setMetaDataEntry("id", "empty_definition_changes")
empty_definition_changes_container.addMetaDataEntry("type", "definition_changes")
ContainerRegistry.getInstance().addContainer(empty_definition_changes_container)
+ self.empty_definition_changes_container = empty_definition_changes_container
empty_variant_container = copy.deepcopy(empty_container)
empty_variant_container.setMetaDataEntry("id", "empty_variant")
empty_variant_container.addMetaDataEntry("type", "variant")
ContainerRegistry.getInstance().addContainer(empty_variant_container)
+ self.empty_variant_container = empty_variant_container
empty_material_container = copy.deepcopy(empty_container)
empty_material_container.setMetaDataEntry("id", "empty_material")
empty_material_container.addMetaDataEntry("type", "material")
ContainerRegistry.getInstance().addContainer(empty_material_container)
+ self.empty_material_container = empty_material_container
empty_quality_container = copy.deepcopy(empty_container)
empty_quality_container.setMetaDataEntry("id", "empty_quality")
@@ -309,12 +327,14 @@ class CuraApplication(QtApplication):
empty_quality_container.addMetaDataEntry("type", "quality")
empty_quality_container.addMetaDataEntry("supported", False)
ContainerRegistry.getInstance().addContainer(empty_quality_container)
+ self.empty_quality_container = empty_quality_container
empty_quality_changes_container = copy.deepcopy(empty_container)
empty_quality_changes_container.setMetaDataEntry("id", "empty_quality_changes")
empty_quality_changes_container.addMetaDataEntry("type", "quality_changes")
empty_quality_changes_container.addMetaDataEntry("quality_type", "not_supported")
ContainerRegistry.getInstance().addContainer(empty_quality_changes_container)
+ self.empty_quality_changes_container = empty_quality_changes_container
with ContainerRegistry.getInstance().lockFile():
ContainerRegistry.getInstance().loadAllMetadata()
@@ -380,6 +400,9 @@ class CuraApplication(QtApplication):
self.getCuraSceneController().setActiveBuildPlate(0) # Initialize
+ self._quality_profile_drop_down_menu_model = None
+ self._custom_quality_profile_drop_down_menu_model = None
+
CuraApplication.Created = True
@pyqtSlot(str, result = str)
@@ -522,8 +545,6 @@ class CuraApplication(QtApplication):
has_user_interaction = True
return has_user_interaction
- onDiscardOrKeepProfileChangesClosed = pyqtSignal() # Used to notify other managers that the dialog was closed
-
@pyqtSlot(str)
def discardOrKeepProfileChangesClosed(self, option):
if option == "discard":
@@ -546,7 +567,6 @@ class CuraApplication(QtApplication):
user_global_container.update()
# notify listeners that quality has changed (after user selected discard or keep)
- self.onDiscardOrKeepProfileChangesClosed.emit()
self.getMachineManager().activeQualityChanged.emit()
@pyqtSlot(int)
@@ -588,7 +608,13 @@ class CuraApplication(QtApplication):
def _loadPlugins(self):
self._plugin_registry.addType("profile_reader", self._addProfileReader)
self._plugin_registry.addType("profile_writer", self._addProfileWriter)
- self._plugin_registry.addPluginLocation(os.path.join(QtApplication.getInstallPrefix(), "lib", "cura"))
+
+ if Platform.isLinux():
+ lib_suffixes = {"", "64", "32", "x32"} #A few common ones on different distributions.
+ else:
+ lib_suffixes = {""}
+ for suffix in lib_suffixes:
+ self._plugin_registry.addPluginLocation(os.path.join(QtApplication.getInstallPrefix(), "lib" + suffix, "cura"))
if not hasattr(sys, "frozen"):
self._plugin_registry.addPluginLocation(os.path.join(os.path.abspath(os.path.dirname(__file__)), "..", "plugins"))
self._plugin_registry.loadPlugin("ConsoleLogger")
@@ -716,6 +742,20 @@ class CuraApplication(QtApplication):
def run(self):
self.preRun()
+ container_registry = ContainerRegistry.getInstance()
+ self._variant_manager = VariantManager(container_registry)
+ self._variant_manager.initialize()
+
+ from cura.Machines.MaterialManager import MaterialManager
+ self._material_manager = MaterialManager(container_registry, parent = self)
+ self._material_manager.initialize()
+
+ from cura.Machines.QualityManager import QualityManager
+ self._quality_manager = QualityManager(container_registry, parent = self)
+ self._quality_manager.initialize()
+
+ self._machine_manager = MachineManager(self)
+
# Check if we should run as single instance or not
self._setUpSingleInstanceServer()
@@ -809,7 +849,7 @@ class CuraApplication(QtApplication):
def getMachineManager(self, *args) -> MachineManager:
if self._machine_manager is None:
- self._machine_manager = MachineManager.createMachineManager()
+ self._machine_manager = MachineManager(self)
return self._machine_manager
def getExtruderManager(self, *args):
@@ -817,20 +857,32 @@ class CuraApplication(QtApplication):
self._extruder_manager = ExtruderManager.createExtruderManager()
return self._extruder_manager
+ def getVariantManager(self, *args):
+ return self._variant_manager
+
+ @pyqtSlot(result = QObject)
def getMaterialManager(self, *args):
- if self._material_manager is None:
- self._material_manager = MaterialManager.createMaterialManager()
return self._material_manager
+ @pyqtSlot(result = QObject)
+ def getQualityManager(self, *args):
+ return self._quality_manager
+
def getObjectsModel(self, *args):
if self._object_manager is None:
self._object_manager = ObjectsModel.createObjectsModel()
return self._object_manager
+ @pyqtSlot(result = QObject)
+ def getMultiBuildPlateModel(self, *args):
+ if self._multi_build_plate_model is None:
+ self._multi_build_plate_model = MultiBuildPlateModel(self)
+ return self._multi_build_plate_model
+
+ @pyqtSlot(result = QObject)
def getBuildPlateModel(self, *args):
if self._build_plate_model is None:
- self._build_plate_model = BuildPlateModel.createBuildPlateModel()
-
+ self._build_plate_model = BuildPlateModel(self)
return self._build_plate_model
def getCuraSceneController(self, *args):
@@ -868,6 +920,16 @@ class CuraApplication(QtApplication):
def getPrintInformation(self):
return self._print_information
+ def getQualityProfilesDropDownMenuModel(self, *args, **kwargs):
+ if self._quality_profile_drop_down_menu_model is None:
+ self._quality_profile_drop_down_menu_model = QualityProfilesDropDownMenuModel(self)
+ return self._quality_profile_drop_down_menu_model
+
+ def getCustomQualityProfilesDropDownMenuModel(self, *args, **kwargs):
+ if self._custom_quality_profile_drop_down_menu_model is None:
+ self._custom_quality_profile_drop_down_menu_model = CustomQualityProfilesDropDownMenuModel(self)
+ return self._custom_quality_profile_drop_down_menu_model
+
## Registers objects for the QML engine to use.
#
# \param engine The QML engine.
@@ -882,27 +944,34 @@ class CuraApplication(QtApplication):
qmlRegisterUncreatableType(CuraApplication, "Cura", 1, 0, "ResourceTypes", "Just an Enum type")
- qmlRegisterSingletonType(CuraSceneController, "Cura", 1, 2, "SceneController", self.getCuraSceneController)
+ qmlRegisterSingletonType(CuraSceneController, "Cura", 1, 0, "SceneController", self.getCuraSceneController)
qmlRegisterSingletonType(ExtruderManager, "Cura", 1, 0, "ExtruderManager", self.getExtruderManager)
qmlRegisterSingletonType(MachineManager, "Cura", 1, 0, "MachineManager", self.getMachineManager)
- qmlRegisterSingletonType(MaterialManager, "Cura", 1, 0, "MaterialManager", self.getMaterialManager)
qmlRegisterSingletonType(SettingInheritanceManager, "Cura", 1, 0, "SettingInheritanceManager", self.getSettingInheritanceManager)
- qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 2, "SimpleModeSettingsManager", self.getSimpleModeSettingsManager)
+ qmlRegisterSingletonType(SimpleModeSettingsManager, "Cura", 1, 0, "SimpleModeSettingsManager", self.getSimpleModeSettingsManager)
qmlRegisterSingletonType(MachineActionManager.MachineActionManager, "Cura", 1, 0, "MachineActionManager", self.getMachineActionManager)
- qmlRegisterSingletonType(ObjectsModel, "Cura", 1, 2, "ObjectsModel", self.getObjectsModel)
- qmlRegisterSingletonType(BuildPlateModel, "Cura", 1, 2, "BuildPlateModel", self.getBuildPlateModel)
+ qmlRegisterSingletonType(ObjectsModel, "Cura", 1, 0, "ObjectsModel", self.getObjectsModel)
+ qmlRegisterType(BuildPlateModel, "Cura", 1, 0, "BuildPlateModel")
+ qmlRegisterType(MultiBuildPlateModel, "Cura", 1, 0, "MultiBuildPlateModel")
qmlRegisterType(InstanceContainer, "Cura", 1, 0, "InstanceContainer")
qmlRegisterType(ExtrudersModel, "Cura", 1, 0, "ExtrudersModel")
- qmlRegisterType(ContainerSettingsModel, "Cura", 1, 0, "ContainerSettingsModel")
- qmlRegisterSingletonType(ProfilesModel, "Cura", 1, 0, "ProfilesModel", ProfilesModel.createProfilesModel)
- qmlRegisterType(MaterialsModel, "Cura", 1, 0, "MaterialsModel")
- qmlRegisterType(QualityAndUserProfilesModel, "Cura", 1, 0, "QualityAndUserProfilesModel")
- qmlRegisterType(UserProfilesModel, "Cura", 1, 0, "UserProfilesModel")
+
+ qmlRegisterType(GenericMaterialsModel, "Cura", 1, 0, "GenericMaterialsModel")
+ qmlRegisterType(BrandMaterialsModel, "Cura", 1, 0, "BrandMaterialsModel")
+ qmlRegisterType(MaterialManagementModel, "Cura", 1, 0, "MaterialManagementModel")
+ qmlRegisterType(QualityManagementModel, "Cura", 1, 0, "QualityManagementModel")
+
+ qmlRegisterSingletonType(QualityProfilesDropDownMenuModel, "Cura", 1, 0,
+ "QualityProfilesDropDownMenuModel", self.getQualityProfilesDropDownMenuModel)
+ qmlRegisterSingletonType(CustomQualityProfilesDropDownMenuModel, "Cura", 1, 0,
+ "CustomQualityProfilesDropDownMenuModel", self.getCustomQualityProfilesDropDownMenuModel)
+ qmlRegisterType(NozzleModel, "Cura", 1, 0, "NozzleModel")
+
qmlRegisterType(MaterialSettingsVisibilityHandler, "Cura", 1, 0, "MaterialSettingsVisibilityHandler")
qmlRegisterType(QualitySettingsModel, "Cura", 1, 0, "QualitySettingsModel")
qmlRegisterType(MachineNameValidator, "Cura", 1, 0, "MachineNameValidator")
- qmlRegisterType(UserChangesModel, "Cura", 1, 1, "UserChangesModel")
+ qmlRegisterType(UserChangesModel, "Cura", 1, 0, "UserChangesModel")
qmlRegisterSingletonType(ContainerManager, "Cura", 1, 0, "ContainerManager", ContainerManager.createContainerManager)
# As of Qt5.7, it is necessary to get rid of any ".." in the path for the singleton to work.
@@ -984,7 +1053,7 @@ class CuraApplication(QtApplication):
count = 0
scene_bounding_box = None
is_block_slicing_node = False
- active_build_plate = self.getBuildPlateModel().activeBuildPlate
+ active_build_plate = self.getMultiBuildPlateModel().activeBuildPlate
for node in DepthFirstIterator(self.getController().getScene().getRoot()):
if (
not issubclass(type(node), CuraSceneNode) or
@@ -1233,7 +1302,7 @@ class CuraApplication(QtApplication):
@pyqtSlot()
def arrangeAll(self):
nodes = []
- active_build_plate = self.getBuildPlateModel().activeBuildPlate
+ active_build_plate = self.getMultiBuildPlateModel().activeBuildPlate
for node in DepthFirstIterator(self.getController().getScene().getRoot()):
if not isinstance(node, SceneNode):
continue
@@ -1287,7 +1356,7 @@ class CuraApplication(QtApplication):
Logger.log("i", "Reloading all loaded mesh data.")
nodes = []
for node in DepthFirstIterator(self.getController().getScene().getRoot()):
- if not isinstance(node, SceneNode) or not node.getMeshData():
+ if not isinstance(node, CuraSceneNode) or not node.getMeshData():
continue
nodes.append(node)
@@ -1382,7 +1451,7 @@ class CuraApplication(QtApplication):
group_decorator = GroupDecorator()
group_node.addDecorator(group_decorator)
group_node.addDecorator(ConvexHullDecorator())
- group_node.addDecorator(BuildPlateDecorator(self.getBuildPlateModel().activeBuildPlate))
+ group_node.addDecorator(BuildPlateDecorator(self.getMultiBuildPlateModel().activeBuildPlate))
group_node.setParent(self.getController().getScene().getRoot())
group_node.setSelectable(True)
center = Selection.getSelectionCenter()
@@ -1527,7 +1596,7 @@ class CuraApplication(QtApplication):
arrange_objects_on_load = (
not Preferences.getInstance().getValue("cura/use_multi_build_plate") or
not Preferences.getInstance().getValue("cura/not_arrange_objects_on_load"))
- target_build_plate = self.getBuildPlateModel().activeBuildPlate if arrange_objects_on_load else -1
+ target_build_plate = self.getMultiBuildPlateModel().activeBuildPlate if arrange_objects_on_load else -1
root = self.getController().getScene().getRoot()
fixed_nodes = []
@@ -1536,12 +1605,22 @@ class CuraApplication(QtApplication):
fixed_nodes.append(node_)
arranger = Arrange.create(fixed_nodes = fixed_nodes)
min_offset = 8
+ default_extruder_position = self.getMachineManager().defaultExtruderPosition
+ default_extruder_id = self._global_container_stack.extruders[default_extruder_position].getId()
for original_node in nodes:
# Create a CuraSceneNode just if the original node is not that type
- node = original_node if isinstance(original_node, CuraSceneNode) else CuraSceneNode()
- node.setMeshData(original_node.getMeshData())
+ if isinstance(original_node, CuraSceneNode):
+ node = original_node
+ else:
+ node = CuraSceneNode()
+ node.setMeshData(original_node.getMeshData())
+
+ #Setting meshdata does not apply scaling.
+ if(original_node.getScale() != Vector(1.0, 1.0, 1.0)):
+ node.scale(original_node.getScale())
+
node.setSelectable(True)
node.setName(os.path.basename(filename))
@@ -1593,6 +1672,8 @@ class CuraApplication(QtApplication):
op = AddSceneNodeOperation(node, scene.getRoot())
op.push()
+
+ node.callDecoration("setActiveExtruder", default_extruder_id)
scene.sceneChanged.emit(node)
self.fileCompleted.emit(filename)
@@ -1613,7 +1694,7 @@ class CuraApplication(QtApplication):
result = workspace_reader.preRead(file_path, show_dialog=False)
return result == WorkspaceReader.PreReadResult.accepted
except Exception as e:
- Logger.log("e", "Could not check file %s: %s", file_url, e)
+ Logger.logException("e", "Could not check file %s: %s", file_url)
return False
def _onContextMenuRequested(self, x: float, y: float) -> None:
diff --git a/cura/Machines/ContainerNode.py b/cura/Machines/ContainerNode.py
new file mode 100644
index 0000000000..6a839fb921
--- /dev/null
+++ b/cura/Machines/ContainerNode.py
@@ -0,0 +1,49 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Optional
+
+from collections import OrderedDict
+
+from UM.Logger import Logger
+from UM.Settings.InstanceContainer import InstanceContainer
+
+
+##
+# A metadata / container combination. Use getContainer() to get the container corresponding to the metadata.
+#
+# ContainerNode is a multi-purpose class. It has two main purposes:
+# 1. It encapsulates an InstanceContainer. It contains that InstanceContainer's
+# - metadata (Always)
+# - container (lazy-loaded when needed)
+# 2. It also serves as a node in a hierarchical InstanceContainer lookup table/tree.
+# This is used in Variant, Material, and Quality Managers.
+#
+class ContainerNode:
+ __slots__ = ("metadata", "container", "children_map")
+
+ def __init__(self, metadata: Optional[dict] = None):
+ self.metadata = metadata
+ self.container = None
+ self.children_map = OrderedDict()
+
+ def getChildNode(self, child_key: str) -> Optional["ContainerNode"]:
+ return self.children_map.get(child_key)
+
+ def getContainer(self) -> "InstanceContainer":
+ if self.metadata is None:
+ raise RuntimeError("Cannot get container for a ContainerNode without metadata")
+
+ if self.container is None:
+ container_id = self.metadata["id"]
+ Logger.log("i", "Lazy-loading container [%s]", container_id)
+ from UM.Settings.ContainerRegistry import ContainerRegistry
+ container_list = ContainerRegistry.getInstance().findInstanceContainers(id = container_id)
+ if not container_list:
+ raise RuntimeError("Failed to lazy-load container [%s], cannot find it" % container_id)
+ self.container = container_list[0]
+
+ return self.container
+
+ def __str__(self) -> str:
+ return "%s[%s]" % (self.__class__.__name__, self.metadata.get("id"))
diff --git a/cura/Machines/MaterialGroup.py b/cura/Machines/MaterialGroup.py
new file mode 100644
index 0000000000..07b790c6bc
--- /dev/null
+++ b/cura/Machines/MaterialGroup.py
@@ -0,0 +1,27 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import List
+from cura.Machines.MaterialNode import MaterialNode #For type checking.
+
+## A MaterialGroup represents a group of material InstanceContainers that are derived from a single material profile.
+# The main InstanceContainer which has the ID of the material profile file name is called the "root_material". For
+# example: "generic_abs" is the root material (ID) of "generic_abs_ultimaker3" and "generic_abs_ultimaker3_AA_0.4",
+# and "generic_abs_ultimaker3" and "generic_abs_ultimaker3_AA_0.4" are derived materials of "generic_abs".
+#
+# Using "generic_abs" as an example, the MaterialGroup for "generic_abs" will contain the following information:
+# - name: "generic_abs", root_material_id
+# - root_material_node: MaterialNode of "generic_abs"
+# - derived_material_node_list: A list of MaterialNodes that are derived from "generic_abs",
+# so "generic_abs_ultimaker3", "generic_abs_ultimaker3_AA_0.4", etc.
+#
+class MaterialGroup:
+ __slots__ = ("name", "root_material_node", "derived_material_node_list")
+
+ def __init__(self, name: str, root_material_node: MaterialNode):
+ self.name = name
+ self.root_material_node = root_material_node
+ self.derived_material_node_list = [] #type: List[MaterialNode]
+
+ def __str__(self) -> str:
+ return "%s[%s]" % (self.__class__.__name__, self.name)
diff --git a/cura/Machines/MaterialManager.py b/cura/Machines/MaterialManager.py
new file mode 100644
index 0000000000..b01d360ab6
--- /dev/null
+++ b/cura/Machines/MaterialManager.py
@@ -0,0 +1,488 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from collections import defaultdict, OrderedDict
+import copy
+import uuid
+from typing import Optional, TYPE_CHECKING
+
+from PyQt5.Qt import QTimer, QObject, pyqtSignal, pyqtSlot
+
+from UM.Application import Application
+from UM.Logger import Logger
+from UM.Settings.ContainerRegistry import ContainerRegistry
+from UM.Settings.SettingFunction import SettingFunction
+from UM.Util import parseBool
+
+from .MaterialNode import MaterialNode
+from .MaterialGroup import MaterialGroup
+
+if TYPE_CHECKING:
+ from cura.Settings.GlobalStack import GlobalStack
+
+
+#
+# MaterialManager maintains a number of maps and trees for material lookup.
+# The models GUI and QML use are now only dependent on the MaterialManager. That means as long as the data in
+# MaterialManager gets updated correctly, the GUI models should be updated correctly too, and the same goes for GUI.
+#
+# For now, updating the lookup maps and trees here is very simple: we discard the old data completely and recreate them
+# again. This means the update is exactly the same as initialization. There are performance concerns about this approach
+# but so far the creation of the tables and maps is very fast and there is no noticeable slowness, we keep it like this
+# because it's simple.
+#
+class MaterialManager(QObject):
+
+ materialsUpdated = pyqtSignal() # Emitted whenever the material lookup tables are updated.
+
+ def __init__(self, container_registry, parent = None):
+ super().__init__(parent)
+ self._application = Application.getInstance()
+ self._container_registry = container_registry # type: ContainerRegistry
+
+ self._fallback_materials_map = dict() # material_type -> generic material metadata
+ self._material_group_map = dict() # root_material_id -> MaterialGroup
+ self._diameter_machine_variant_material_map = dict() # approximate diameter str -> dict(machine_definition_id -> MaterialNode)
+
+ # We're using these two maps to convert between the specific diameter material id and the generic material id
+ # because the generic material ids are used in qualities and definitions, while the specific diameter material is meant
+ # i.e. generic_pla -> generic_pla_175
+ self._material_diameter_map = defaultdict(dict) # root_material_id -> approximate diameter str -> root_material_id for that diameter
+ self._diameter_material_map = dict() # material id including diameter (generic_pla_175) -> material root id (generic_pla)
+
+ # This is used in Legacy UM3 send material function and the material management page.
+ self._guid_material_groups_map = defaultdict(list) # GUID -> a list of material_groups
+
+ # The machine definition ID for the non-machine-specific materials.
+ # This is used as the last fallback option if the given machine-specific material(s) cannot be found.
+ self._default_machine_definition_id = "fdmprinter"
+ self._default_approximate_diameter_for_quality_search = "3"
+
+ # When a material gets added/imported, there can be more than one InstanceContainers. In those cases, we don't
+ # want to react on every container/metadata changed signal. The timer here is to buffer it a bit so we don't
+ # react too many time.
+ self._update_timer = QTimer(self)
+ self._update_timer.setInterval(300)
+ self._update_timer.setSingleShot(True)
+ self._update_timer.timeout.connect(self._updateMaps)
+
+ self._container_registry.containerMetaDataChanged.connect(self._onContainerMetadataChanged)
+ self._container_registry.containerAdded.connect(self._onContainerMetadataChanged)
+ self._container_registry.containerRemoved.connect(self._onContainerMetadataChanged)
+
+ def initialize(self):
+ # Find all materials and put them in a matrix for quick search.
+ material_metadatas = {metadata["id"]: metadata for metadata in self._container_registry.findContainersMetadata(type = "material")}
+
+ self._material_group_map = dict()
+
+ # Map #1
+ # root_material_id -> MaterialGroup
+ for material_id, material_metadata in material_metadatas.items():
+ # We don't store empty material in the lookup tables
+ if material_id == "empty_material":
+ continue
+
+ root_material_id = material_metadata.get("base_file")
+ if root_material_id not in self._material_group_map:
+ self._material_group_map[root_material_id] = MaterialGroup(root_material_id, MaterialNode(material_metadatas[root_material_id]))
+ group = self._material_group_map[root_material_id]
+
+ #Store this material in the group of the appropriate root material.
+ if material_id != root_material_id:
+ new_node = MaterialNode(material_metadata)
+ group.derived_material_node_list.append(new_node)
+
+ # Order this map alphabetically so it's easier to navigate in a debugger
+ self._material_group_map = OrderedDict(sorted(self._material_group_map.items(), key = lambda x: x[0]))
+
+ # Map #1.5
+ # GUID -> material group list
+ self._guid_material_groups_map = defaultdict(list)
+ for root_material_id, material_group in self._material_group_map.items():
+ # This can happen when we are updating with incomplete data.
+ if material_group.root_material_node is None:
+ Logger.log("e", "Missing root material node for [%s]. Probably caused by update using incomplete data."
+ " Check all related signals for further debugging.",
+ material_group.name)
+ self._update_timer.start()
+ return
+ guid = material_group.root_material_node.metadata["GUID"]
+ self._guid_material_groups_map[guid].append(material_group)
+
+ # Map #2
+ # Lookup table for material type -> fallback material metadata, only for read-only materials
+ grouped_by_type_dict = dict()
+ for root_material_id, material_node in self._material_group_map.items():
+ if not self._container_registry.isReadOnly(root_material_id):
+ continue
+ material_type = material_node.root_material_node.metadata["material"]
+ if material_type not in grouped_by_type_dict:
+ grouped_by_type_dict[material_type] = {"generic": None,
+ "others": []}
+ brand = material_node.root_material_node.metadata["brand"]
+ if brand.lower() == "generic":
+ to_add = True
+ if material_type in grouped_by_type_dict:
+ diameter = material_node.root_material_node.metadata.get("approximate_diameter")
+ if diameter != self._default_approximate_diameter_for_quality_search:
+ to_add = False # don't add if it's not the default diameter
+ if to_add:
+ grouped_by_type_dict[material_type] = material_node.root_material_node.metadata
+ self._fallback_materials_map = grouped_by_type_dict
+
+ # Map #3
+ # There can be multiple material profiles for the same material with different diameters, such as "generic_pla"
+ # and "generic_pla_175". This is inconvenient when we do material-specific quality lookup because a quality can
+ # be for either "generic_pla" or "generic_pla_175", but not both. This map helps to get the correct material ID
+ # for quality search.
+ self._material_diameter_map = defaultdict(dict)
+ self._diameter_material_map = dict()
+
+ # Group the material IDs by the same name, material, brand, and color but with different diameters.
+ material_group_dict = dict()
+ keys_to_fetch = ("name", "material", "brand", "color")
+ for root_material_id, machine_node in self._material_group_map.items():
+ if not self._container_registry.isReadOnly(root_material_id):
+ continue
+
+ root_material_metadata = machine_node.root_material_node.metadata
+
+ key_data = []
+ for key in keys_to_fetch:
+ key_data.append(root_material_metadata.get(key))
+ key_data = tuple(key_data)
+
+ if key_data not in material_group_dict:
+ material_group_dict[key_data] = dict()
+ approximate_diameter = root_material_metadata.get("approximate_diameter")
+ material_group_dict[key_data][approximate_diameter] = root_material_metadata["id"]
+
+ # Map [root_material_id][diameter] -> root_material_id for this diameter
+ for data_dict in material_group_dict.values():
+ for root_material_id1 in data_dict.values():
+ if root_material_id1 in self._material_diameter_map:
+ continue
+ diameter_map = data_dict
+ for root_material_id2 in data_dict.values():
+ self._material_diameter_map[root_material_id2] = diameter_map
+
+ default_root_material_id = data_dict.get(self._default_approximate_diameter_for_quality_search)
+ if default_root_material_id is None:
+ default_root_material_id = list(data_dict.values())[0] # no default diameter present, just take "the" only one
+ for root_material_id in data_dict.values():
+ self._diameter_material_map[root_material_id] = default_root_material_id
+
+ # Map #4
+ # "machine" -> "variant_name" -> "root material ID" -> specific material InstanceContainer
+ # Construct the "machine" -> "variant" -> "root material ID" -> specific material InstanceContainer
+ self._diameter_machine_variant_material_map = dict()
+ for material_metadata in material_metadatas.values():
+ # We don't store empty material in the lookup tables
+ if material_metadata["id"] == "empty_material":
+ continue
+
+ root_material_id = material_metadata["base_file"]
+ definition = material_metadata["definition"]
+ approximate_diameter = material_metadata["approximate_diameter"]
+
+ if approximate_diameter not in self._diameter_machine_variant_material_map:
+ self._diameter_machine_variant_material_map[approximate_diameter] = {}
+
+ machine_variant_material_map = self._diameter_machine_variant_material_map[approximate_diameter]
+ if definition not in machine_variant_material_map:
+ machine_variant_material_map[definition] = MaterialNode()
+
+ machine_node = machine_variant_material_map[definition]
+ variant_name = material_metadata.get("variant_name")
+ if not variant_name:
+ # if there is no variant, this material is for the machine, so put its metadata in the machine node.
+ machine_node.material_map[root_material_id] = MaterialNode(material_metadata)
+ else:
+ # this material is variant-specific, so we save it in a variant-specific node under the
+ # machine-specific node
+ if variant_name not in machine_node.children_map:
+ machine_node.children_map[variant_name] = MaterialNode()
+
+ variant_node = machine_node.children_map[variant_name]
+ if root_material_id not in variant_node.material_map:
+ variant_node.material_map[root_material_id] = MaterialNode(material_metadata)
+ else:
+ # Sanity check: make sure we don't have duplicated variant-specific materials for the same machine
+ raise RuntimeError("Found duplicate variant name [%s] for machine [%s] in material [%s]" %
+ (variant_name, definition, material_metadata["id"]))
+
+ self.materialsUpdated.emit()
+
+ def _updateMaps(self):
+ Logger.log("i", "Updating material lookup data ...")
+ self.initialize()
+
+ def _onContainerMetadataChanged(self, container):
+ self._onContainerChanged(container)
+
+ def _onContainerChanged(self, container):
+ container_type = container.getMetaDataEntry("type")
+ if container_type != "material":
+ return
+
+ # update the maps
+ self._update_timer.start()
+
+ def getMaterialGroup(self, root_material_id: str) -> Optional[MaterialGroup]:
+ return self._material_group_map.get(root_material_id)
+
+ def getRootMaterialIDForDiameter(self, root_material_id: str, approximate_diameter: str) -> str:
+ return self._material_diameter_map.get(root_material_id).get(approximate_diameter, root_material_id)
+
+ def getRootMaterialIDWithoutDiameter(self, root_material_id: str) -> str:
+ return self._diameter_material_map.get(root_material_id)
+
+ def getMaterialGroupListByGUID(self, guid: str) -> Optional[list]:
+ return self._guid_material_groups_map.get(guid)
+
+ #
+ # Return a dict with all root material IDs (k) and ContainerNodes (v) that's suitable for the given setup.
+ #
+ def getAvailableMaterials(self, machine_definition_id: str, extruder_variant_name: Optional[str],
+ diameter: float) -> dict:
+ # round the diameter to get the approximate diameter
+ rounded_diameter = str(round(diameter))
+ if rounded_diameter not in self._diameter_machine_variant_material_map:
+ Logger.log("i", "Cannot find materials with diameter [%s] (rounded to [%s])", diameter, rounded_diameter)
+ return dict()
+
+ # If there are variant materials, get the variant material
+ machine_variant_material_map = self._diameter_machine_variant_material_map[rounded_diameter]
+ machine_node = machine_variant_material_map.get(machine_definition_id)
+ default_machine_node = machine_variant_material_map.get(self._default_machine_definition_id)
+ variant_node = None
+ if extruder_variant_name is not None and machine_node is not None:
+ variant_node = machine_node.getChildNode(extruder_variant_name)
+
+ nodes_to_check = [variant_node, machine_node, default_machine_node]
+
+ # Fallback mechanism of finding materials:
+ # 1. variant-specific material
+ # 2. machine-specific material
+ # 3. generic material (for fdmprinter)
+ material_id_metadata_dict = dict()
+ for node in nodes_to_check:
+ if node is not None:
+ for material_id, node in node.material_map.items():
+ if material_id not in material_id_metadata_dict:
+ material_id_metadata_dict[material_id] = node
+
+ return material_id_metadata_dict
+
+ #
+ # A convenience function to get available materials for the given machine with the extruder position.
+ #
+ def getAvailableMaterialsForMachineExtruder(self, machine: "GlobalStack",
+ extruder_stack: "ExtruderStack") -> Optional[dict]:
+ machine_definition_id = machine.definition.getId()
+ variant_name = None
+ if extruder_stack.variant.getId() != "empty_variant":
+ variant_name = extruder_stack.variant.getName()
+ diameter = extruder_stack.approximateMaterialDiameter
+
+ # Fetch the available materials (ContainerNode) for the current active machine and extruder setup.
+ return self.getAvailableMaterials(machine_definition_id, variant_name, diameter)
+
+ #
+ # Gets MaterialNode for the given extruder and machine with the given material name.
+ # Returns None if:
+ # 1. the given machine doesn't have materials;
+ # 2. cannot find any material InstanceContainers with the given settings.
+ #
+ def getMaterialNode(self, machine_definition_id: str, extruder_variant_name: Optional[str],
+ diameter: float, root_material_id: str) -> Optional["InstanceContainer"]:
+ # round the diameter to get the approximate diameter
+ rounded_diameter = str(round(diameter))
+ if rounded_diameter not in self._diameter_machine_variant_material_map:
+ Logger.log("i", "Cannot find materials with diameter [%s] (rounded to [%s]) for root material id [%s]",
+ diameter, rounded_diameter, root_material_id)
+ return None
+
+ # If there are variant materials, get the variant material
+ machine_variant_material_map = self._diameter_machine_variant_material_map[rounded_diameter]
+ machine_node = machine_variant_material_map.get(machine_definition_id)
+ variant_node = None
+
+ # Fallback for "fdmprinter" if the machine-specific materials cannot be found
+ if machine_node is None:
+ machine_node = machine_variant_material_map.get(self._default_machine_definition_id)
+ if machine_node is not None and extruder_variant_name is not None:
+ variant_node = machine_node.getChildNode(extruder_variant_name)
+
+ # Fallback mechanism of finding materials:
+ # 1. variant-specific material
+ # 2. machine-specific material
+ # 3. generic material (for fdmprinter)
+ nodes_to_check = [variant_node, machine_node,
+ machine_variant_material_map.get(self._default_machine_definition_id)]
+
+ material_node = None
+ for node in nodes_to_check:
+ if node is not None:
+ material_node = node.material_map.get(root_material_id)
+ if material_node:
+ break
+
+ return material_node
+
+ #
+ # Used by QualityManager. Built-in quality profiles may be based on generic material IDs such as "generic_pla".
+ # For materials such as ultimaker_pla_orange, no quality profiles may be found, so we should fall back to use
+ # the generic material IDs to search for qualities.
+ #
+ # An example would be, suppose we have machine with preferred material set to "filo3d_pla" (1.75mm), but its
+ # extruders only use 2.85mm materials, then we won't be able to find the preferred material for this machine.
+ # A fallback would be to fetch a generic material of the same type "PLA" as "filo3d_pla", and in this case it will
+ # be "generic_pla". This function is intended to get a generic fallback material for the given material type.
+ #
+ # This function returns the generic root material ID for the given material type, where material types are "PLA",
+ # "ABS", etc.
+ #
+ def getFallbackMaterialIdByMaterialType(self, material_type: str) -> Optional[str]:
+ # For safety
+ if material_type not in self._fallback_materials_map:
+ Logger.log("w", "The material type [%s] does not have a fallback material" % material_type)
+ return None
+ fallback_material = self._fallback_materials_map[material_type]
+ if fallback_material:
+ return self.getRootMaterialIDWithoutDiameter(fallback_material["id"])
+ else:
+ return None
+
+ def getDefaultMaterial(self, global_stack: "GlobalStack", extruder_variant_name: Optional[str]) -> Optional["MaterialNode"]:
+ node = None
+ machine_definition = global_stack.definition
+ if parseBool(global_stack.getMetaDataEntry("has_materials", False)):
+ material_diameter = machine_definition.getProperty("material_diameter", "value")
+ if isinstance(material_diameter, SettingFunction):
+ material_diameter = material_diameter(global_stack)
+ approximate_material_diameter = str(round(material_diameter))
+ root_material_id = machine_definition.getMetaDataEntry("preferred_material")
+ root_material_id = self.getRootMaterialIDForDiameter(root_material_id, approximate_material_diameter)
+ node = self.getMaterialNode(machine_definition.getId(), extruder_variant_name,
+ material_diameter, root_material_id)
+ return node
+
+ def removeMaterialByRootId(self, root_material_id: str):
+ material_group = self.getMaterialGroup(root_material_id)
+ if not material_group:
+ Logger.log("i", "Unable to remove the material with id %s, because it doesn't exist.", root_material_id)
+ return
+
+ nodes_to_remove = [material_group.root_material_node] + material_group.derived_material_node_list
+ for node in nodes_to_remove:
+ self._container_registry.removeContainer(node.metadata["id"])
+
+ #
+ # Methods for GUI
+ #
+
+ #
+ # Sets the new name for the given material.
+ #
+ @pyqtSlot("QVariant", str)
+ def setMaterialName(self, material_node: "MaterialNode", name: str):
+ root_material_id = material_node.metadata["base_file"]
+ if self._container_registry.isReadOnly(root_material_id):
+ Logger.log("w", "Cannot set name of read-only container %s.", root_material_id)
+ return
+
+ material_group = self.getMaterialGroup(root_material_id)
+ material_group.root_material_node.getContainer().setName(name)
+
+ #
+ # Removes the given material.
+ #
+ @pyqtSlot("QVariant")
+ def removeMaterial(self, material_node: "MaterialNode"):
+ root_material_id = material_node.metadata["base_file"]
+ self.removeMaterialByRootId(root_material_id)
+
+ #
+ # Creates a duplicate of a material, which has the same GUID and base_file metadata.
+ # Returns the root material ID of the duplicated material if successful.
+ #
+ @pyqtSlot("QVariant", result = str)
+ def duplicateMaterial(self, material_node, new_base_id = None, new_metadata = None) -> Optional[str]:
+ root_material_id = material_node.metadata["base_file"]
+
+ material_group = self.getMaterialGroup(root_material_id)
+ if not material_group:
+ Logger.log("i", "Unable to duplicate the material with id %s, because it doesn't exist.", root_material_id)
+ return None
+
+ base_container = material_group.root_material_node.getContainer()
+
+ # Ensure all settings are saved.
+ self._application.saveSettings()
+
+ # Create a new ID & container to hold the data.
+ new_containers = []
+ if new_base_id is None:
+ new_base_id = self._container_registry.uniqueName(base_container.getId())
+ new_base_container = copy.deepcopy(base_container)
+ new_base_container.getMetaData()["id"] = new_base_id
+ new_base_container.getMetaData()["base_file"] = new_base_id
+ if new_metadata is not None:
+ for key, value in new_metadata.items():
+ new_base_container.getMetaData()[key] = value
+ new_containers.append(new_base_container)
+
+ # Clone all of them.
+ for node in material_group.derived_material_node_list:
+ container_to_copy = node.getContainer()
+ # Create unique IDs for every clone.
+ new_id = new_base_id
+ if container_to_copy.getMetaDataEntry("definition") != "fdmprinter":
+ new_id += "_" + container_to_copy.getMetaDataEntry("definition")
+ if container_to_copy.getMetaDataEntry("variant_name"):
+ variant_name = container_to_copy.getMetaDataEntry("variant_name")
+ new_id += "_" + variant_name.replace(" ", "_")
+
+ new_container = copy.deepcopy(container_to_copy)
+ new_container.getMetaData()["id"] = new_id
+ new_container.getMetaData()["base_file"] = new_base_id
+ if new_metadata is not None:
+ for key, value in new_metadata.items():
+ new_container.getMetaData()[key] = value
+
+ new_containers.append(new_container)
+
+ for container_to_add in new_containers:
+ container_to_add.setDirty(True)
+ self._container_registry.addContainer(container_to_add)
+ return new_base_id
+
+ #
+ # Create a new material by cloning Generic PLA for the current material diameter and generate a new GUID.
+ #
+ @pyqtSlot(result = str)
+ def createMaterial(self) -> str:
+ from UM.i18n import i18nCatalog
+ catalog = i18nCatalog("cura")
+ # Ensure all settings are saved.
+ self._application.saveSettings()
+
+ global_stack = self._application.getGlobalContainerStack()
+ approximate_diameter = str(round(global_stack.getProperty("material_diameter", "value")))
+ root_material_id = "generic_pla"
+ root_material_id = self.getRootMaterialIDForDiameter(root_material_id, approximate_diameter)
+ material_group = self.getMaterialGroup(root_material_id)
+
+ # Create a new ID & container to hold the data.
+ new_id = self._container_registry.uniqueName("custom_material")
+ new_metadata = {"name": catalog.i18nc("@label", "Custom Material"),
+ "brand": catalog.i18nc("@label", "Custom"),
+ "GUID": str(uuid.uuid4()),
+ }
+
+ self.duplicateMaterial(material_group.root_material_node,
+ new_base_id = new_id,
+ new_metadata = new_metadata)
+ return new_id
diff --git a/cura/Machines/MaterialNode.py b/cura/Machines/MaterialNode.py
new file mode 100644
index 0000000000..fde11186c2
--- /dev/null
+++ b/cura/Machines/MaterialNode.py
@@ -0,0 +1,21 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Optional
+
+from .ContainerNode import ContainerNode
+
+
+#
+# A MaterialNode is a node in the material lookup tree/map/table. It contains 2 (extra) fields:
+# - material_map: a one-to-one map of "material_root_id" to material_node.
+# - children_map: the key-value map for child nodes of this node. This is used in a lookup tree.
+#
+#
+class MaterialNode(ContainerNode):
+ __slots__ = ("material_map", "children_map")
+
+ def __init__(self, metadata: Optional[dict] = None):
+ super().__init__(metadata = metadata)
+ self.material_map = {} # material_root_id -> material_node
+ self.children_map = {} # mapping for the child nodes
diff --git a/cura/Machines/Models/BaseMaterialsModel.py b/cura/Machines/Models/BaseMaterialsModel.py
new file mode 100644
index 0000000000..0a1337feeb
--- /dev/null
+++ b/cura/Machines/Models/BaseMaterialsModel.py
@@ -0,0 +1,68 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty
+
+from UM.Application import Application
+from UM.Qt.ListModel import ListModel
+
+
+#
+# This is the base model class for GenericMaterialsModel and BrandMaterialsModel
+# Those 2 models are used by the material drop down menu to show generic materials and branded materials separately.
+# The extruder position defined here is being used to bound a menu to the correct extruder. This is used in the top
+# bar menu "Settings" -> "Extruder nr" -> "Material" -> this menu
+#
+class BaseMaterialsModel(ListModel):
+ RootMaterialIdRole = Qt.UserRole + 1
+ IdRole = Qt.UserRole + 2
+ NameRole = Qt.UserRole + 3
+ BrandRole = Qt.UserRole + 4
+ MaterialRole = Qt.UserRole + 5
+ ColorRole = Qt.UserRole + 6
+ ContainerNodeRole = Qt.UserRole + 7
+
+ extruderPositionChanged = pyqtSignal()
+
+ def __init__(self, parent = None):
+ super().__init__(parent)
+ self._application = Application.getInstance()
+ self._machine_manager = self._application.getMachineManager()
+
+ self.addRoleName(self.RootMaterialIdRole, "root_material_id")
+ self.addRoleName(self.IdRole, "id")
+ self.addRoleName(self.NameRole, "name")
+ self.addRoleName(self.BrandRole, "brand")
+ self.addRoleName(self.MaterialRole, "material")
+ self.addRoleName(self.ColorRole, "color_name")
+ self.addRoleName(self.ContainerNodeRole, "container_node")
+
+ self._extruder_position = 0
+ self._extruder_stack = None
+
+ def _updateExtruderStack(self):
+ global_stack = self._machine_manager.activeMachine
+ if global_stack is None:
+ return
+
+ if self._extruder_stack is not None:
+ self._extruder_stack.pyqtContainersChanged.disconnect(self._update)
+ self._extruder_stack = global_stack.extruders.get(str(self._extruder_position))
+ if self._extruder_stack is not None:
+ self._extruder_stack.pyqtContainersChanged.connect(self._update)
+
+ def setExtruderPosition(self, position: int):
+ if self._extruder_position != position:
+ self._extruder_position = position
+ self._updateExtruderStack()
+ self.extruderPositionChanged.emit()
+
+ @pyqtProperty(int, fset = setExtruderPosition, notify = extruderPositionChanged)
+ def extruderPosition(self) -> int:
+ return self._extruder_position
+
+ #
+ # This is an abstract method that needs to be implemented by
+ #
+ def _update(self):
+ pass
diff --git a/cura/Machines/Models/BrandMaterialsModel.py b/cura/Machines/Models/BrandMaterialsModel.py
new file mode 100644
index 0000000000..e36c6448d3
--- /dev/null
+++ b/cura/Machines/Models/BrandMaterialsModel.py
@@ -0,0 +1,137 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty
+
+from UM.Qt.ListModel import ListModel
+from UM.Logger import Logger
+from cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel
+
+
+#
+# This is an intermediate model to group materials with different colours for a same brand and type.
+#
+class MaterialsModelGroupedByType(ListModel):
+ NameRole = Qt.UserRole + 1
+ ColorsRole = Qt.UserRole + 2
+
+ def __init__(self, parent = None):
+ super().__init__(parent)
+
+ self.addRoleName(self.NameRole, "name")
+ self.addRoleName(self.ColorsRole, "colors")
+
+
+#
+# This model is used to show branded materials in the material drop down menu.
+# The structure of the menu looks like this:
+# Brand -> Material Type -> list of materials
+#
+# To illustrate, a branded material menu may look like this:
+# Ultimaker -> PLA -> Yellow PLA
+# -> Black PLA
+# -> ...
+# -> ABS -> White ABS
+# ...
+#
+class BrandMaterialsModel(ListModel):
+ NameRole = Qt.UserRole + 1
+ MaterialsRole = Qt.UserRole + 2
+
+ extruderPositionChanged = pyqtSignal()
+
+ def __init__(self, parent = None):
+ super().__init__(parent)
+
+ self.addRoleName(self.NameRole, "name")
+ self.addRoleName(self.MaterialsRole, "materials")
+
+ self._extruder_position = 0
+
+ from cura.CuraApplication import CuraApplication
+ self._machine_manager = CuraApplication.getInstance().getMachineManager()
+ self._extruder_manager = CuraApplication.getInstance().getExtruderManager()
+ self._material_manager = CuraApplication.getInstance().getMaterialManager()
+
+ self._machine_manager.globalContainerChanged.connect(self._update)
+ self._material_manager.materialsUpdated.connect(self._update)
+ self._update()
+
+ def setExtruderPosition(self, position: int):
+ if self._extruder_position != position:
+ self._extruder_position = position
+ self.extruderPositionChanged.emit()
+
+ @pyqtProperty(int, fset = setExtruderPosition, notify = extruderPositionChanged)
+ def extruderPosition(self) -> int:
+ return self._extruder_position
+
+ def _update(self):
+ Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
+ global_stack = self._machine_manager.activeMachine
+ if global_stack is None:
+ self.setItems([])
+ return
+ extruder_position = str(self._extruder_position)
+ if extruder_position not in global_stack.extruders:
+ self.setItems([])
+ return
+ extruder_stack = global_stack.extruders[str(self._extruder_position)]
+
+ available_material_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack,
+ extruder_stack)
+ if available_material_dict is None:
+ self.setItems([])
+ return
+
+ brand_item_list = []
+ brand_group_dict = {}
+ for root_material_id, container_node in available_material_dict.items():
+ metadata = container_node.metadata
+ brand = metadata["brand"]
+ # Only add results for generic materials
+ if brand.lower() == "generic":
+ continue
+
+ if brand not in brand_group_dict:
+ brand_group_dict[brand] = {}
+
+ material_type = metadata["material"]
+ if material_type not in brand_group_dict[brand]:
+ brand_group_dict[brand][material_type] = []
+
+ item = {"root_material_id": root_material_id,
+ "id": metadata["id"],
+ "name": metadata["name"],
+ "brand": metadata["brand"],
+ "material": metadata["material"],
+ "color_name": metadata["color_name"],
+ "container_node": container_node
+ }
+ brand_group_dict[brand][material_type].append(item)
+
+ for brand, material_dict in brand_group_dict.items():
+ brand_item = {"name": brand,
+ "materials": MaterialsModelGroupedByType(self)}
+
+ material_type_item_list = []
+ for material_type, material_list in material_dict.items():
+ material_type_item = {"name": material_type,
+ "colors": BaseMaterialsModel(self)}
+ material_type_item["colors"].clear()
+
+ # Sort materials by name
+ material_list = sorted(material_list, key = lambda x: x["name"].upper())
+ material_type_item["colors"].setItems(material_list)
+
+ material_type_item_list.append(material_type_item)
+
+ # Sort material type by name
+ material_type_item_list = sorted(material_type_item_list, key = lambda x: x["name"].upper())
+ brand_item["materials"].setItems(material_type_item_list)
+
+ brand_item_list.append(brand_item)
+
+ # Sort brand by name
+ brand_item_list = sorted(brand_item_list, key = lambda x: x["name"].upper())
+ self.setItems(brand_item_list)
diff --git a/cura/Machines/Models/BuildPlateModel.py b/cura/Machines/Models/BuildPlateModel.py
new file mode 100644
index 0000000000..e1b4f40d8e
--- /dev/null
+++ b/cura/Machines/Models/BuildPlateModel.py
@@ -0,0 +1,51 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from PyQt5.QtCore import Qt
+
+from UM.Application import Application
+from UM.Logger import Logger
+from UM.Qt.ListModel import ListModel
+from UM.Util import parseBool
+
+from cura.Machines.VariantManager import VariantType
+
+
+class BuildPlateModel(ListModel):
+ NameRole = Qt.UserRole + 1
+ ContainerNodeRole = Qt.UserRole + 2
+
+ def __init__(self, parent = None):
+ super().__init__(parent)
+
+ self.addRoleName(self.NameRole, "name")
+ self.addRoleName(self.ContainerNodeRole, "container_node")
+
+ self._application = Application.getInstance()
+ self._variant_manager = self._application._variant_manager
+ self._machine_manager = self._application.getMachineManager()
+
+ self._machine_manager.globalContainerChanged.connect(self._update)
+
+ self._update()
+
+ def _update(self):
+ Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
+ global_stack = self._machine_manager._global_container_stack
+ if not global_stack:
+ self.setItems([])
+ return
+
+ has_variants = parseBool(global_stack.getMetaDataEntry("has_variant_buildplates", False))
+ if not has_variants:
+ self.setItems([])
+ return
+
+ variant_dict = self._variant_manager.getVariantNodes(global_stack, variant_type = VariantType.BUILD_PLATE)
+
+ item_list = []
+ for name, variant_node in variant_dict.items():
+ item = {"name": name,
+ "container_node": variant_node}
+ item_list.append(item)
+ self.setItems(item_list)
diff --git a/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py b/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py
new file mode 100644
index 0000000000..dcade8cb0d
--- /dev/null
+++ b/cura/Machines/Models/CustomQualityProfilesDropDownMenuModel.py
@@ -0,0 +1,37 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from UM.Logger import Logger
+
+from cura.Machines.Models.QualityProfilesDropDownMenuModel import QualityProfilesDropDownMenuModel
+
+
+#
+# This model is used for the custom profile items in the profile drop down menu.
+#
+class CustomQualityProfilesDropDownMenuModel(QualityProfilesDropDownMenuModel):
+
+ def _update(self):
+ Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
+
+ active_global_stack = self._machine_manager.activeMachine
+ if active_global_stack is None:
+ self.setItems([])
+ Logger.log("d", "No active GlobalStack, set %s as empty.", self.__class__.__name__)
+ return
+
+ quality_changes_group_dict = self._quality_manager.getQualityChangesGroups(active_global_stack)
+
+ item_list = []
+ for key in sorted(quality_changes_group_dict, key = lambda name: name.upper()):
+ quality_changes_group = quality_changes_group_dict[key]
+
+ item = {"name": quality_changes_group.name,
+ "layer_height": "",
+ "layer_height_without_unit": "",
+ "available": quality_changes_group.is_available,
+ "quality_changes_group": quality_changes_group}
+
+ item_list.append(item)
+
+ self.setItems(item_list)
diff --git a/cura/Machines/Models/GenericMaterialsModel.py b/cura/Machines/Models/GenericMaterialsModel.py
new file mode 100644
index 0000000000..6b149448ea
--- /dev/null
+++ b/cura/Machines/Models/GenericMaterialsModel.py
@@ -0,0 +1,61 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from UM.Logger import Logger
+from cura.Machines.Models.BaseMaterialsModel import BaseMaterialsModel
+
+
+class GenericMaterialsModel(BaseMaterialsModel):
+
+ def __init__(self, parent = None):
+ super().__init__(parent)
+
+ from cura.CuraApplication import CuraApplication
+ self._machine_manager = CuraApplication.getInstance().getMachineManager()
+ self._extruder_manager = CuraApplication.getInstance().getExtruderManager()
+ self._material_manager = CuraApplication.getInstance().getMaterialManager()
+
+ self._machine_manager.globalContainerChanged.connect(self._update)
+ self._material_manager.materialsUpdated.connect(self._update)
+ self._update()
+
+ def _update(self):
+ Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
+
+ global_stack = self._machine_manager.activeMachine
+ if global_stack is None:
+ self.setItems([])
+ return
+ extruder_position = str(self._extruder_position)
+ if extruder_position not in global_stack.extruders:
+ self.setItems([])
+ return
+ extruder_stack = global_stack.extruders[extruder_position]
+
+ available_material_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack,
+ extruder_stack)
+ if available_material_dict is None:
+ self.setItems([])
+ return
+
+ item_list = []
+ for root_material_id, container_node in available_material_dict.items():
+ metadata = container_node.metadata
+ # Only add results for generic materials
+ if metadata["brand"].lower() != "generic":
+ continue
+
+ item = {"root_material_id": root_material_id,
+ "id": metadata["id"],
+ "name": metadata["name"],
+ "brand": metadata["brand"],
+ "material": metadata["material"],
+ "color_name": metadata["color_name"],
+ "container_node": container_node
+ }
+ item_list.append(item)
+
+ # Sort the item list by material name alphabetically
+ item_list = sorted(item_list, key = lambda d: d["name"].upper())
+
+ self.setItems(item_list)
diff --git a/cura/Machines/Models/MaterialManagementModel.py b/cura/Machines/Models/MaterialManagementModel.py
new file mode 100644
index 0000000000..46e9cb887a
--- /dev/null
+++ b/cura/Machines/Models/MaterialManagementModel.py
@@ -0,0 +1,104 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from PyQt5.QtCore import Qt
+
+from UM.Logger import Logger
+from UM.Qt.ListModel import ListModel
+
+
+#
+# This model is for the Material management page.
+#
+class MaterialManagementModel(ListModel):
+ RootMaterialIdRole = Qt.UserRole + 1
+ DisplayNameRole = Qt.UserRole + 2
+ BrandRole = Qt.UserRole + 3
+ MaterialTypeRole = Qt.UserRole + 4
+ ColorNameRole = Qt.UserRole + 5
+ ColorCodeRole = Qt.UserRole + 6
+ ContainerNodeRole = Qt.UserRole + 7
+ ContainerIdRole = Qt.UserRole + 8
+
+ DescriptionRole = Qt.UserRole + 9
+ AdhesionInfoRole = Qt.UserRole + 10
+ ApproximateDiameterRole = Qt.UserRole + 11
+ GuidRole = Qt.UserRole + 12
+ DensityRole = Qt.UserRole + 13
+ DiameterRole = Qt.UserRole + 14
+ IsReadOnlyRole = Qt.UserRole + 15
+
+ def __init__(self, parent = None):
+ super().__init__(parent)
+
+ self.addRoleName(self.RootMaterialIdRole, "root_material_id")
+ self.addRoleName(self.DisplayNameRole, "name")
+ self.addRoleName(self.BrandRole, "brand")
+ self.addRoleName(self.MaterialTypeRole, "material")
+ self.addRoleName(self.ColorNameRole, "color_name")
+ self.addRoleName(self.ColorCodeRole, "color_code")
+ self.addRoleName(self.ContainerNodeRole, "container_node")
+ self.addRoleName(self.ContainerIdRole, "container_id")
+
+ self.addRoleName(self.DescriptionRole, "description")
+ self.addRoleName(self.AdhesionInfoRole, "adhesion_info")
+ self.addRoleName(self.ApproximateDiameterRole, "approximate_diameter")
+ self.addRoleName(self.GuidRole, "guid")
+ self.addRoleName(self.DensityRole, "density")
+ self.addRoleName(self.DiameterRole, "diameter")
+ self.addRoleName(self.IsReadOnlyRole, "is_read_only")
+
+ from cura.CuraApplication import CuraApplication
+ self._container_registry = CuraApplication.getInstance().getContainerRegistry()
+ self._machine_manager = CuraApplication.getInstance().getMachineManager()
+ self._extruder_manager = CuraApplication.getInstance().getExtruderManager()
+ self._material_manager = CuraApplication.getInstance().getMaterialManager()
+
+ self._machine_manager.globalContainerChanged.connect(self._update)
+ self._extruder_manager.activeExtruderChanged.connect(self._update)
+ self._material_manager.materialsUpdated.connect(self._update)
+
+ self._update()
+
+ def _update(self):
+ Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
+
+ global_stack = self._machine_manager.activeMachine
+ if global_stack is None:
+ self.setItems([])
+ return
+ active_extruder_stack = self._machine_manager.activeStack
+
+ available_material_dict = self._material_manager.getAvailableMaterialsForMachineExtruder(global_stack,
+ active_extruder_stack)
+ if available_material_dict is None:
+ self.setItems([])
+ return
+
+ material_list = []
+ for root_material_id, container_node in available_material_dict.items():
+ keys_to_fetch = ("name",
+ "brand",
+ "material",
+ "color_name",
+ "color_code",
+ "description",
+ "adhesion_info",
+ "approximate_diameter",)
+
+ item = {"root_material_id": container_node.metadata["base_file"],
+ "container_node": container_node,
+ "guid": container_node.metadata["GUID"],
+ "container_id": container_node.metadata["id"],
+ "density": container_node.metadata.get("properties", {}).get("density", ""),
+ "diameter": container_node.metadata.get("properties", {}).get("diameter", ""),
+ "is_read_only": self._container_registry.isReadOnly(container_node.metadata["id"]),
+ }
+
+ for key in keys_to_fetch:
+ item[key] = container_node.metadata.get(key, "")
+
+ material_list.append(item)
+
+ material_list = sorted(material_list, key = lambda k: (k["brand"].upper(), k["name"].upper()))
+ self.setItems(material_list)
diff --git a/cura/BuildPlateModel.py b/cura/Machines/Models/MultiBuildPlateModel.py
similarity index 70%
rename from cura/BuildPlateModel.py
rename to cura/Machines/Models/MultiBuildPlateModel.py
index 73f61202c6..f0f4997014 100644
--- a/cura/BuildPlateModel.py
+++ b/cura/Machines/Models/MultiBuildPlateModel.py
@@ -1,24 +1,32 @@
-from PyQt5.QtCore import pyqtSignal, pyqtProperty, pyqtSlot
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from PyQt5.QtCore import pyqtSignal, pyqtProperty
-from UM.Qt.ListModel import ListModel
-from UM.Scene.Selection import Selection
-from UM.Logger import Logger
from UM.Application import Application
+from UM.Scene.Selection import Selection
+from UM.Qt.ListModel import ListModel
-class BuildPlateModel(ListModel):
+#
+# This is the model for multi build plate feature.
+# This has nothing to do with the build plate types you can choose on the sidebar for a machine.
+#
+class MultiBuildPlateModel(ListModel):
+
maxBuildPlateChanged = pyqtSignal()
activeBuildPlateChanged = pyqtSignal()
selectionChanged = pyqtSignal()
- def __init__(self):
- super().__init__()
- Application.getInstance().getController().getScene().sceneChanged.connect(self._updateSelectedObjectBuildPlateNumbers)
+ def __init__(self, parent = None):
+ super().__init__(parent)
+
+ self._application = Application.getInstance()
+ self._application.getController().getScene().sceneChanged.connect(self._updateSelectedObjectBuildPlateNumbers)
Selection.selectionChanged.connect(self._updateSelectedObjectBuildPlateNumbers)
self._max_build_plate = 1 # default
self._active_build_plate = -1
- self._selection_build_plates = []
def setMaxBuildPlate(self, max_build_plate):
self._max_build_plate = max_build_plate
@@ -37,10 +45,6 @@ class BuildPlateModel(ListModel):
def activeBuildPlate(self):
return self._active_build_plate
- @staticmethod
- def createBuildPlateModel():
- return BuildPlateModel()
-
def _updateSelectedObjectBuildPlateNumbers(self, *args):
result = set()
for node in Selection.getAllSelectedObjects():
diff --git a/cura/Machines/Models/NozzleModel.py b/cura/Machines/Models/NozzleModel.py
new file mode 100644
index 0000000000..0879998b7d
--- /dev/null
+++ b/cura/Machines/Models/NozzleModel.py
@@ -0,0 +1,61 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from PyQt5.QtCore import Qt
+
+from UM.Application import Application
+from UM.Logger import Logger
+from UM.Qt.ListModel import ListModel
+from UM.Util import parseBool
+
+
+class NozzleModel(ListModel):
+ IdRole = Qt.UserRole + 1
+ HotendNameRole = Qt.UserRole + 2
+ ContainerNodeRole = Qt.UserRole + 3
+
+ def __init__(self, parent = None):
+ super().__init__(parent)
+
+ self.addRoleName(self.IdRole, "id")
+ self.addRoleName(self.HotendNameRole, "hotend_name")
+ self.addRoleName(self.ContainerNodeRole, "container_node")
+
+ self._application = Application.getInstance()
+ self._machine_manager = self._application.getMachineManager()
+ self._variant_manager = self._application.getVariantManager()
+
+ self._machine_manager.globalContainerChanged.connect(self._update)
+ self._update()
+
+ def _update(self):
+ Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
+
+ self.items.clear()
+
+ global_stack = self._machine_manager.activeMachine
+ if global_stack is None:
+ self.setItems([])
+ return
+
+ has_variants = parseBool(global_stack.getMetaDataEntry("has_variants", False))
+ if not has_variants:
+ self.setItems([])
+ return
+
+ from cura.Machines.VariantManager import VariantType
+ variant_node_dict = self._variant_manager.getVariantNodes(global_stack, VariantType.NOZZLE)
+ if not variant_node_dict:
+ self.setItems([])
+ return
+
+ item_list = []
+ for hotend_name, container_node in sorted(variant_node_dict.items(), key = lambda i: i[0].upper()):
+ item = {"id": hotend_name,
+ "hotend_name": hotend_name,
+ "container_node": container_node
+ }
+
+ item_list.append(item)
+
+ self.setItems(item_list)
diff --git a/cura/Machines/Models/QualityManagementModel.py b/cura/Machines/Models/QualityManagementModel.py
new file mode 100644
index 0000000000..4d2b551805
--- /dev/null
+++ b/cura/Machines/Models/QualityManagementModel.py
@@ -0,0 +1,124 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from PyQt5.QtCore import Qt, pyqtSlot
+
+from UM.Qt.ListModel import ListModel
+from UM.Logger import Logger
+
+#
+# This the QML model for the quality management page.
+#
+class QualityManagementModel(ListModel):
+ NameRole = Qt.UserRole + 1
+ IsReadOnlyRole = Qt.UserRole + 2
+ QualityGroupRole = Qt.UserRole + 3
+ QualityChangesGroupRole = Qt.UserRole + 4
+
+ def __init__(self, parent = None):
+ super().__init__(parent)
+
+ self.addRoleName(self.NameRole, "name")
+ self.addRoleName(self.IsReadOnlyRole, "is_read_only")
+ self.addRoleName(self.QualityGroupRole, "quality_group")
+ self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group")
+
+ from cura.CuraApplication import CuraApplication
+ self._container_registry = CuraApplication.getInstance().getContainerRegistry()
+ self._machine_manager = CuraApplication.getInstance().getMachineManager()
+ self._extruder_manager = CuraApplication.getInstance().getExtruderManager()
+ self._quality_manager = CuraApplication.getInstance().getQualityManager()
+
+ self._machine_manager.globalContainerChanged.connect(self._update)
+ self._quality_manager.qualitiesUpdated.connect(self._update)
+
+ self._update()
+
+ def _update(self):
+ Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
+
+ global_stack = self._machine_manager.activeMachine
+
+ quality_group_dict = self._quality_manager.getQualityGroups(global_stack)
+ quality_changes_group_dict = self._quality_manager.getQualityChangesGroups(global_stack)
+
+ available_quality_types = set(quality_type for quality_type, quality_group in quality_group_dict.items()
+ if quality_group.is_available)
+ if not available_quality_types and not quality_changes_group_dict:
+ # Nothing to show
+ self.setItems([])
+ return
+
+ item_list = []
+ # Create quality group items
+ for quality_group in quality_group_dict.values():
+ if not quality_group.is_available:
+ continue
+
+ item = {"name": quality_group.name,
+ "is_read_only": True,
+ "quality_group": quality_group,
+ "quality_changes_group": None}
+ item_list.append(item)
+ # Sort by quality names
+ item_list = sorted(item_list, key = lambda x: x["name"].upper())
+
+ # Create quality_changes group items
+ quality_changes_item_list = []
+ for quality_changes_group in quality_changes_group_dict.values():
+ if quality_changes_group.quality_type not in available_quality_types:
+ continue
+ quality_group = quality_group_dict[quality_changes_group.quality_type]
+ item = {"name": quality_changes_group.name,
+ "is_read_only": False,
+ "quality_group": quality_group,
+ "quality_changes_group": quality_changes_group}
+ quality_changes_item_list.append(item)
+
+ # Sort quality_changes items by names and append to the item list
+ quality_changes_item_list = sorted(quality_changes_item_list, key = lambda x: x["name"].upper())
+ item_list += quality_changes_item_list
+
+ self.setItems(item_list)
+
+ # TODO: Duplicated code here from InstanceContainersModel. Refactor and remove this later.
+ #
+ ## Gets a list of the possible file filters that the plugins have
+ # registered they can read or write. The convenience meta-filters
+ # "All Supported Types" and "All Files" are added when listing
+ # readers, but not when listing writers.
+ #
+ # \param io_type \type{str} name of the needed IO type
+ # \return A list of strings indicating file name filters for a file
+ # dialog.
+ @pyqtSlot(str, result = "QVariantList")
+ def getFileNameFilters(self, io_type):
+ from UM.i18n import i18nCatalog
+ catalog = i18nCatalog("uranium")
+ #TODO: This function should be in UM.Resources!
+ filters = []
+ all_types = []
+ for plugin_id, meta_data in self._getIOPlugins(io_type):
+ for io_plugin in meta_data[io_type]:
+ filters.append(io_plugin["description"] + " (*." + io_plugin["extension"] + ")")
+ all_types.append("*.{0}".format(io_plugin["extension"]))
+
+ if "_reader" in io_type:
+ # if we're listing readers, add the option to show all supported files as the default option
+ filters.insert(0, catalog.i18nc("@item:inlistbox", "All Supported Types ({0})", " ".join(all_types)))
+ filters.append(catalog.i18nc("@item:inlistbox", "All Files (*)")) # Also allow arbitrary files, if the user so prefers.
+ return filters
+
+ ## Gets a list of profile reader or writer plugins
+ # \return List of tuples of (plugin_id, meta_data).
+ def _getIOPlugins(self, io_type):
+ from UM.PluginRegistry import PluginRegistry
+ pr = PluginRegistry.getInstance()
+ active_plugin_ids = pr.getActivePlugins()
+
+ result = []
+ for plugin_id in active_plugin_ids:
+ meta_data = pr.getMetaData(plugin_id)
+ if io_type in meta_data:
+ result.append( (plugin_id, meta_data) )
+ return result
diff --git a/cura/Machines/Models/QualityProfilesDropDownMenuModel.py b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py
new file mode 100644
index 0000000000..d8c4b668cf
--- /dev/null
+++ b/cura/Machines/Models/QualityProfilesDropDownMenuModel.py
@@ -0,0 +1,107 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from PyQt5.QtCore import Qt
+
+from UM.Application import Application
+from UM.Logger import Logger
+from UM.Qt.ListModel import ListModel
+
+from cura.Machines.QualityManager import QualityGroup
+
+
+#
+# QML Model for all built-in quality profiles. This model is used for the drop-down quality menu.
+#
+class QualityProfilesDropDownMenuModel(ListModel):
+ NameRole = Qt.UserRole + 1
+ QualityTypeRole = Qt.UserRole + 2
+ LayerHeightRole = Qt.UserRole + 3
+ LayerHeightUnitRole = Qt.UserRole + 4
+ AvailableRole = Qt.UserRole + 5
+ QualityGroupRole = Qt.UserRole + 6
+ QualityChangesGroupRole = Qt.UserRole + 7
+
+ def __init__(self, parent = None):
+ super().__init__(parent)
+
+ self.addRoleName(self.NameRole, "name")
+ self.addRoleName(self.QualityTypeRole, "quality_type")
+ self.addRoleName(self.LayerHeightRole, "layer_height")
+ self.addRoleName(self.LayerHeightUnitRole, "layer_height_unit")
+ self.addRoleName(self.AvailableRole, "available") #Whether the quality profile is available in our current nozzle + material.
+ self.addRoleName(self.QualityGroupRole, "quality_group")
+ self.addRoleName(self.QualityChangesGroupRole, "quality_changes_group")
+
+ self._application = Application.getInstance()
+ self._machine_manager = self._application.getMachineManager()
+ self._quality_manager = Application.getInstance().getQualityManager()
+
+ self._application.globalContainerStackChanged.connect(self._update)
+ self._machine_manager.activeQualityGroupChanged.connect(self._update)
+ self._machine_manager.extruderChanged.connect(self._update)
+ self._quality_manager.qualitiesUpdated.connect(self._update)
+
+ self._layer_height_unit = "" # This is cached
+
+ self._update()
+
+ def _update(self):
+ Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
+
+ global_stack = self._machine_manager.activeMachine
+ if global_stack is None:
+ self.setItems([])
+ Logger.log("d", "No active GlobalStack, set quality profile model as empty.")
+ return
+
+ # Check for material compatibility
+ if not self._machine_manager.activeMaterialsCompatible():
+ Logger.log("d", "No active material compatibility, set quality profile model as empty.")
+ self.setItems([])
+ return
+
+ quality_group_dict = self._quality_manager.getQualityGroups(global_stack)
+
+ item_list = []
+ for key in sorted(quality_group_dict):
+ quality_group = quality_group_dict[key]
+
+ layer_height = self._fetchLayerHeight(quality_group)
+
+ item = {"name": quality_group.name,
+ "quality_type": quality_group.quality_type,
+ "layer_height": layer_height,
+ "layer_height_unit": self._layer_height_unit,
+ "available": quality_group.is_available,
+ "quality_group": quality_group}
+
+ item_list.append(item)
+
+ # Sort items based on layer_height
+ item_list = sorted(item_list, key = lambda x: x["layer_height"])
+
+ self.setItems(item_list)
+
+ def _fetchLayerHeight(self, quality_group: "QualityGroup"):
+ global_stack = self._machine_manager.activeMachine
+ if not self._layer_height_unit:
+ unit = global_stack.definition.getProperty("layer_height", "unit")
+ if not unit:
+ unit = ""
+ self._layer_height_unit = unit
+
+ default_layer_height = global_stack.definition.getProperty("layer_height", "value")
+
+ # Get layer_height from the quality profile for the GlobalStack
+ container = quality_group.node_for_global.getContainer()
+
+ layer_height = default_layer_height
+ if container.hasProperty("layer_height", "value"):
+ layer_height = container.getProperty("layer_height", "value")
+ else:
+ # Look for layer_height in the GlobalStack from material -> definition
+ container = global_stack.definition
+ if container.hasProperty("layer_height", "value"):
+ layer_height = container.getProperty("layer_height", "value")
+ return float(layer_height)
diff --git a/cura/Machines/Models/QualitySettingsModel.py b/cura/Machines/Models/QualitySettingsModel.py
new file mode 100644
index 0000000000..4470ffc80e
--- /dev/null
+++ b/cura/Machines/Models/QualitySettingsModel.py
@@ -0,0 +1,162 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
+
+from UM.Application import Application
+from UM.Logger import Logger
+from UM.Qt.ListModel import ListModel
+from UM.Settings.ContainerRegistry import ContainerRegistry
+
+
+#
+# This model is used to show details settings of the selected quality in the quality management page.
+#
+class QualitySettingsModel(ListModel):
+ KeyRole = Qt.UserRole + 1
+ LabelRole = Qt.UserRole + 2
+ UnitRole = Qt.UserRole + 3
+ ProfileValueRole = Qt.UserRole + 4
+ ProfileValueSourceRole = Qt.UserRole + 5
+ UserValueRole = Qt.UserRole + 6
+ CategoryRole = Qt.UserRole + 7
+
+ GLOBAL_STACK_POSITION = -1
+
+ def __init__(self, parent = None):
+ super().__init__(parent = parent)
+
+ self.addRoleName(self.KeyRole, "key")
+ self.addRoleName(self.LabelRole, "label")
+ self.addRoleName(self.UnitRole, "unit")
+ self.addRoleName(self.ProfileValueRole, "profile_value")
+ self.addRoleName(self.ProfileValueSourceRole, "profile_value_source")
+ self.addRoleName(self.UserValueRole, "user_value")
+ self.addRoleName(self.CategoryRole, "category")
+
+ self._container_registry = ContainerRegistry.getInstance()
+ self._application = Application.getInstance()
+ self._quality_manager = self._application.getQualityManager()
+
+ self._selected_position = self.GLOBAL_STACK_POSITION #Must be either GLOBAL_STACK_POSITION or an extruder position (0, 1, etc.)
+ self._selected_quality_item = None # The selected quality in the quality management page
+ self._i18n_catalog = None
+
+ self._quality_manager.qualitiesUpdated.connect(self._update)
+
+ self._update()
+
+ selectedPositionChanged = pyqtSignal()
+ selectedQualityItemChanged = pyqtSignal()
+
+ def setSelectedPosition(self, selected_position):
+ if selected_position != self._selected_position:
+ self._selected_position = selected_position
+ self.selectedPositionChanged.emit()
+ self._update()
+
+ @pyqtProperty(int, fset = setSelectedPosition, notify = selectedPositionChanged)
+ def selectedPosition(self):
+ return self._selected_position
+
+ def setSelectedQualityItem(self, selected_quality_item):
+ if selected_quality_item != self._selected_quality_item:
+ self._selected_quality_item = selected_quality_item
+ self.selectedQualityItemChanged.emit()
+ self._update()
+
+ @pyqtProperty("QVariantMap", fset = setSelectedQualityItem, notify = selectedQualityItemChanged)
+ def selectedQualityItem(self):
+ return self._selected_quality_item
+
+ def _update(self):
+ Logger.log("d", "Updating {model_class_name}.".format(model_class_name = self.__class__.__name__))
+
+ if not self._selected_quality_item:
+ self.setItems([])
+ return
+
+ items = []
+
+ global_container_stack = self._application.getGlobalContainerStack()
+ definition_container = global_container_stack.definition
+
+ quality_group = self._selected_quality_item["quality_group"]
+ quality_changes_group = self._selected_quality_item["quality_changes_group"]
+
+ if self._selected_position == self.GLOBAL_STACK_POSITION:
+ quality_node = quality_group.node_for_global
+ else:
+ quality_node = quality_group.nodes_for_extruders.get(self._selected_position)
+ settings_keys = quality_group.getAllKeys()
+ quality_containers = [quality_node.getContainer()]
+
+ # Here, if the user has selected a quality changes, then "quality_changes_group" will not be None, and we fetch
+ # the settings in that quality_changes_group.
+ if quality_changes_group is not None:
+ if self._selected_position == self.GLOBAL_STACK_POSITION:
+ quality_changes_node = quality_changes_group.node_for_global
+ else:
+ quality_changes_node = quality_changes_group.nodes_for_extruders.get(self._selected_position)
+ if quality_changes_node is not None: # it can be None if number of extruders are changed during runtime
+ try:
+ quality_containers.insert(0, quality_changes_node.getContainer())
+ except RuntimeError:
+ # FIXME: This is to prevent incomplete update of QualityManager
+ Logger.logException("d", "Failed to get container for quality changes node %s", quality_changes_node)
+ return
+ settings_keys.update(quality_changes_group.getAllKeys())
+
+ # We iterate over all definitions instead of settings in a quality/qualtiy_changes group is because in the GUI,
+ # the settings are grouped together by categories, and we had to go over all the definitions to figure out
+ # which setting belongs in which category.
+ current_category = ""
+ for definition in definition_container.findDefinitions():
+ if definition.type == "category":
+ current_category = definition.label
+ if self._i18n_catalog:
+ current_category = self._i18n_catalog.i18nc(definition.key + " label", definition.label)
+ continue
+
+ profile_value = None
+ profile_value_source = ""
+ for quality_container in quality_containers:
+ new_value = quality_container.getProperty(definition.key, "value")
+
+ if new_value is not None:
+ profile_value_source = quality_container.getMetaDataEntry("type")
+ profile_value = new_value
+
+ # Global tab should use resolve (if there is one)
+ if self._selected_position == self.GLOBAL_STACK_POSITION:
+ resolve_value = global_container_stack.getProperty(definition.key, "resolve")
+ if resolve_value is not None and definition.key in settings_keys:
+ profile_value = resolve_value
+
+ if profile_value is not None:
+ break
+
+ if self._selected_position == self.GLOBAL_STACK_POSITION:
+ user_value = global_container_stack.userChanges.getProperty(definition.key, "value")
+ else:
+ extruder_stack = global_container_stack.extruders[str(self._selected_position)]
+ user_value = extruder_stack.userChanges.getProperty(definition.key, "value")
+
+ if profile_value is None and user_value is None:
+ continue
+
+ label = definition.label
+ if self._i18n_catalog:
+ label = self._i18n_catalog.i18nc(definition.key + " label", label)
+
+ items.append({
+ "key": definition.key,
+ "label": label,
+ "unit": definition.unit,
+ "profile_value": "" if profile_value is None else str(profile_value), # it is for display only
+ "profile_value_source": profile_value_source,
+ "user_value": "" if user_value is None else str(user_value),
+ "category": current_category
+ })
+
+ self.setItems(items)
diff --git a/cura/Machines/Models/__init__.py b/cura/Machines/Models/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cura/Machines/QualityChangesGroup.py b/cura/Machines/QualityChangesGroup.py
new file mode 100644
index 0000000000..ad320a7006
--- /dev/null
+++ b/cura/Machines/QualityChangesGroup.py
@@ -0,0 +1,27 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from UM.Application import Application
+
+from .QualityGroup import QualityGroup
+
+
+class QualityChangesGroup(QualityGroup):
+ def __init__(self, name: str, quality_type: str, parent = None):
+ super().__init__(name, quality_type, parent)
+ self._container_registry = Application.getInstance().getContainerRegistry()
+
+ def addNode(self, node: "QualityNode"):
+ extruder_position = node.metadata.get("position")
+ if extruder_position is None: #Then we're a global quality changes profile.
+ if self.node_for_global is not None:
+ raise RuntimeError("{group} tries to overwrite the existing node_for_global {original_global} with {new_global}".format(group = self, original_global = self.node_for_global, new_global = node))
+ self.node_for_global = node
+ else: #This is an extruder's quality changes profile.
+ if extruder_position in self.nodes_for_extruders:
+ raise RuntimeError("%s tries to overwrite the existing nodes_for_extruders position [%s] %s with %s" %
+ (self, extruder_position, self.node_for_global, node))
+ self.nodes_for_extruders[extruder_position] = node
+
+ def __str__(self) -> str:
+ return "%s[<%s>, available = %s]" % (self.__class__.__name__, self.name, self.is_available)
diff --git a/cura/Machines/QualityGroup.py b/cura/Machines/QualityGroup.py
new file mode 100644
index 0000000000..02096cfb36
--- /dev/null
+++ b/cura/Machines/QualityGroup.py
@@ -0,0 +1,50 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Dict, Optional, List
+
+from PyQt5.QtCore import QObject, pyqtSlot
+
+
+#
+# A QualityGroup represents a group of containers that must be applied to each ContainerStack when it's used.
+# Some concrete examples are Quality and QualityChanges: when we select quality type "normal", this quality type
+# must be applied to all stacks in a machine, although each stack can have different containers. Use an Ultimaker 3
+# as an example, suppose we choose quality type "normal", the actual InstanceContainers on each stack may look
+# as below:
+# GlobalStack ExtruderStack 1 ExtruderStack 2
+# quality container: um3_global_normal um3_aa04_pla_normal um3_aa04_abs_normal
+#
+# This QualityGroup is mainly used in quality and quality_changes to group the containers that can be applied to
+# a machine, so when a quality/custom quality is selected, the container can be directly applied to each stack instead
+# of looking them up again.
+#
+class QualityGroup(QObject):
+
+ def __init__(self, name: str, quality_type: str, parent = None):
+ super().__init__(parent)
+ self.name = name
+ self.node_for_global = None # type: Optional["QualityGroup"]
+ self.nodes_for_extruders = {} # type: Dict[int, "QualityGroup"]
+ self.quality_type = quality_type
+ self.is_available = False
+
+ @pyqtSlot(result = str)
+ def getName(self) -> str:
+ return self.name
+
+ def getAllKeys(self) -> set:
+ result = set()
+ for node in [self.node_for_global] + list(self.nodes_for_extruders.values()):
+ if node is None:
+ continue
+ result.update(node.getContainer().getAllKeys())
+ return result
+
+ def getAllNodes(self) -> List["QualityGroup"]:
+ result = []
+ if self.node_for_global is not None:
+ result.append(self.node_for_global)
+ for extruder_node in self.nodes_for_extruders.values():
+ result.append(extruder_node)
+ return result
diff --git a/cura/Machines/QualityManager.py b/cura/Machines/QualityManager.py
new file mode 100644
index 0000000000..efb940b857
--- /dev/null
+++ b/cura/Machines/QualityManager.py
@@ -0,0 +1,491 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import TYPE_CHECKING, Optional
+
+from PyQt5.QtCore import QObject, QTimer, pyqtSignal, pyqtSlot
+
+from UM.Application import Application
+from UM.Logger import Logger
+from UM.Util import parseBool
+from UM.Settings.InstanceContainer import InstanceContainer
+
+from cura.Settings.ExtruderStack import ExtruderStack
+
+from .QualityGroup import QualityGroup
+from .QualityNode import QualityNode
+
+if TYPE_CHECKING:
+ from cura.Settings.GlobalStack import GlobalStack
+ from .QualityChangesGroup import QualityChangesGroup
+
+
+#
+# Similar to MaterialManager, QualityManager maintains a number of maps and trees for quality profile lookup.
+# The models GUI and QML use are now only dependent on the QualityManager. That means as long as the data in
+# QualityManager gets updated correctly, the GUI models should be updated correctly too, and the same goes for GUI.
+#
+# For now, updating the lookup maps and trees here is very simple: we discard the old data completely and recreate them
+# again. This means the update is exactly the same as initialization. There are performance concerns about this approach
+# but so far the creation of the tables and maps is very fast and there is no noticeable slowness, we keep it like this
+# because it's simple.
+#
+class QualityManager(QObject):
+
+ qualitiesUpdated = pyqtSignal()
+
+ def __init__(self, container_registry, parent = None):
+ super().__init__(parent)
+ self._application = Application.getInstance()
+ self._material_manager = self._application.getMaterialManager()
+ self._container_registry = container_registry
+
+ self._empty_quality_container = self._application.empty_quality_container
+ self._empty_quality_changes_container = self._application.empty_quality_changes_container
+
+ self._machine_variant_material_quality_type_to_quality_dict = {} # for quality lookup
+ self._machine_quality_type_to_quality_changes_dict = {} # for quality_changes lookup
+
+ self._default_machine_definition_id = "fdmprinter"
+
+ self._container_registry.containerMetaDataChanged.connect(self._onContainerMetadataChanged)
+ self._container_registry.containerAdded.connect(self._onContainerMetadataChanged)
+ self._container_registry.containerRemoved.connect(self._onContainerMetadataChanged)
+
+ # When a custom quality gets added/imported, there can be more than one InstanceContainers. In those cases,
+ # we don't want to react on every container/metadata changed signal. The timer here is to buffer it a bit so
+ # we don't react too many time.
+ self._update_timer = QTimer(self)
+ self._update_timer.setInterval(300)
+ self._update_timer.setSingleShot(True)
+ self._update_timer.timeout.connect(self._updateMaps)
+
+ def initialize(self):
+ # Initialize the lookup tree for quality profiles with following structure:
+ # -> ->
+ # ->
+
+ self._machine_variant_material_quality_type_to_quality_dict = {} # for quality lookup
+ self._machine_quality_type_to_quality_changes_dict = {} # for quality_changes lookup
+
+ quality_metadata_list = self._container_registry.findContainersMetadata(type = "quality")
+ for metadata in quality_metadata_list:
+ if metadata["id"] == "empty_quality":
+ continue
+
+ definition_id = metadata["definition"]
+ quality_type = metadata["quality_type"]
+
+ root_material_id = metadata.get("material")
+ variant_name = metadata.get("variant")
+ is_global_quality = metadata.get("global_quality", False)
+ is_global_quality = is_global_quality or (root_material_id is None and variant_name is None)
+
+ # Sanity check: material+variant and is_global_quality cannot be present at the same time
+ if is_global_quality and (root_material_id or variant_name):
+ raise RuntimeError("Quality profile [%s] contains invalid data: it is a global quality but contains 'material' and 'nozzle' info." % metadata["id"])
+
+ if definition_id not in self._machine_variant_material_quality_type_to_quality_dict:
+ self._machine_variant_material_quality_type_to_quality_dict[definition_id] = QualityNode()
+ machine_node = self._machine_variant_material_quality_type_to_quality_dict[definition_id]
+
+ if is_global_quality:
+ # For global qualities, save data in the machine node
+ machine_node.addQualityMetadata(quality_type, metadata)
+ continue
+
+ if variant_name is not None:
+ # If variant_name is specified in the quality/quality_changes profile, check if material is specified,
+ # too.
+ if variant_name not in machine_node.children_map:
+ machine_node.children_map[variant_name] = QualityNode()
+ variant_node = machine_node.children_map[variant_name]
+
+ if root_material_id is None:
+ # If only variant_name is specified but material is not, add the quality/quality_changes metadata
+ # into the current variant node.
+ variant_node.addQualityMetadata(quality_type, metadata)
+ else:
+ # If only variant_name and material are both specified, go one level deeper: create a material node
+ # under the current variant node, and then add the quality/quality_changes metadata into the
+ # material node.
+ if root_material_id not in variant_node.children_map:
+ variant_node.children_map[root_material_id] = QualityNode()
+ material_node = variant_node.children_map[root_material_id]
+
+ material_node.addQualityMetadata(quality_type, metadata)
+
+ else:
+ # If variant_name is not specified, check if material is specified.
+ if root_material_id is not None:
+ if root_material_id not in machine_node.children_map:
+ machine_node.children_map[root_material_id] = QualityNode()
+ material_node = machine_node.children_map[root_material_id]
+
+ material_node.addQualityMetadata(quality_type, metadata)
+
+ # Initialize the lookup tree for quality_changes profiles with following structure:
+ # -> ->
+ quality_changes_metadata_list = self._container_registry.findContainersMetadata(type = "quality_changes")
+ for metadata in quality_changes_metadata_list:
+ if metadata["id"] == "empty_quality_changes":
+ continue
+
+ machine_definition_id = metadata["definition"]
+ quality_type = metadata["quality_type"]
+
+ if machine_definition_id not in self._machine_quality_type_to_quality_changes_dict:
+ self._machine_quality_type_to_quality_changes_dict[machine_definition_id] = QualityNode()
+ machine_node = self._machine_quality_type_to_quality_changes_dict[machine_definition_id]
+ machine_node.addQualityChangesMetadata(quality_type, metadata)
+
+ Logger.log("d", "Lookup tables updated.")
+ self.qualitiesUpdated.emit()
+
+ def _updateMaps(self):
+ self.initialize()
+
+ def _onContainerMetadataChanged(self, container):
+ self._onContainerChanged(container)
+
+ def _onContainerChanged(self, container):
+ container_type = container.getMetaDataEntry("type")
+ if container_type not in ("quality", "quality_changes"):
+ return
+
+ # update the cache table
+ self._update_timer.start()
+
+ # Updates the given quality groups' availabilities according to which extruders are being used/ enabled.
+ def _updateQualityGroupsAvailability(self, machine: "GlobalStack", quality_group_list):
+ used_extruders = set()
+ for i in range(machine.getProperty("machine_extruder_count", "value")):
+ if machine.extruders[str(i)].isEnabled:
+ used_extruders.add(str(i))
+
+ # Update the "is_available" flag for each quality group.
+ for quality_group in quality_group_list:
+ is_available = True
+ if quality_group.node_for_global is None:
+ is_available = False
+ if is_available:
+ for position in used_extruders:
+ if position not in quality_group.nodes_for_extruders:
+ is_available = False
+ break
+
+ quality_group.is_available = is_available
+
+ # Returns a dict of "custom profile name" -> QualityChangesGroup
+ def getQualityChangesGroups(self, machine: "GlobalStack") -> dict:
+ machine_definition_id = getMachineDefinitionIDForQualitySearch(machine)
+
+ machine_node = self._machine_quality_type_to_quality_changes_dict.get(machine_definition_id)
+ if not machine_node:
+ Logger.log("i", "Cannot find node for machine def [%s] in QualityChanges lookup table", machine_definition_id)
+ return dict()
+
+ # Update availability for each QualityChangesGroup:
+ # A custom profile is always available as long as the quality_type it's based on is available
+ quality_group_dict = self.getQualityGroups(machine)
+ available_quality_type_list = [qt for qt, qg in quality_group_dict.items() if qg.is_available]
+
+ # Iterate over all quality_types in the machine node
+ quality_changes_group_dict = dict()
+ for quality_type, quality_changes_node in machine_node.quality_type_map.items():
+ for quality_changes_name, quality_changes_group in quality_changes_node.children_map.items():
+ quality_changes_group_dict[quality_changes_name] = quality_changes_group
+ quality_changes_group.is_available = quality_type in available_quality_type_list
+
+ return quality_changes_group_dict
+
+ #
+ # Gets all quality groups for the given machine. Both available and none available ones will be included.
+ # It returns a dictionary with "quality_type"s as keys and "QualityGroup"s as values.
+ # Whether a QualityGroup is available can be unknown via the field QualityGroup.is_available.
+ # For more details, see QualityGroup.
+ #
+ def getQualityGroups(self, machine: "GlobalStack") -> dict:
+ machine_definition_id = getMachineDefinitionIDForQualitySearch(machine)
+
+ # This determines if we should only get the global qualities for the global stack and skip the global qualities for the extruder stacks
+ has_variant_materials = parseBool(machine.getMetaDataEntry("has_variant_materials", False))
+
+ # To find the quality container for the GlobalStack, check in the following fall-back manner:
+ # (1) the machine-specific node
+ # (2) the generic node
+ machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(machine_definition_id)
+ default_machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(self._default_machine_definition_id)
+ nodes_to_check = [machine_node, default_machine_node]
+
+ # Iterate over all quality_types in the machine node
+ quality_group_dict = {}
+ for node in nodes_to_check:
+ if node and node.quality_type_map:
+ # Only include global qualities
+ if has_variant_materials:
+ quality_node = list(node.quality_type_map.values())[0]
+ is_global_quality = parseBool(quality_node.metadata.get("global_quality", False))
+ if not is_global_quality:
+ continue
+
+ for quality_type, quality_node in node.quality_type_map.items():
+ quality_group = QualityGroup(quality_node.metadata["name"], quality_type)
+ quality_group.node_for_global = quality_node
+ quality_group_dict[quality_type] = quality_group
+ break
+
+ # Iterate over all extruders to find quality containers for each extruder
+ for position, extruder in machine.extruders.items():
+ variant_name = None
+ if extruder.variant.getId() != "empty_variant":
+ variant_name = extruder.variant.getName()
+
+ # This is a list of root material IDs to use for searching for suitable quality profiles.
+ # The root material IDs in this list are in prioritized order.
+ root_material_id_list = []
+ has_material = False # flag indicating whether this extruder has a material assigned
+ if extruder.material.getId() != "empty_material":
+ has_material = True
+ root_material_id = extruder.material.getMetaDataEntry("base_file")
+ # Convert possible generic_pla_175 -> generic_pla
+ root_material_id = self._material_manager.getRootMaterialIDWithoutDiameter(root_material_id)
+ root_material_id_list.append(root_material_id)
+
+ # Also try to get the fallback material
+ material_type = extruder.material.getMetaDataEntry("material")
+ fallback_root_material_id = self._material_manager.getFallbackMaterialIdByMaterialType(material_type)
+ if fallback_root_material_id:
+ root_material_id_list.append(fallback_root_material_id)
+
+ # Here we construct a list of nodes we want to look for qualities with the highest priority first.
+ # The use case is that, when we look for qualities for a machine, we first want to search in the following
+ # order:
+ # 1. machine-variant-and-material-specific qualities if exist
+ # 2. machine-variant-specific qualities if exist
+ # 3. machine-material-specific qualities if exist
+ # 4. machine-specific qualities if exist
+ # 5. generic qualities if exist
+ # Each points above can be represented as a node in the lookup tree, so here we simply put those nodes into
+ # the list with priorities as the order. Later, we just need to loop over each node in this list and fetch
+ # qualities from there.
+ nodes_to_check = []
+
+ if variant_name:
+ # In this case, we have both a specific variant and a specific material
+ variant_node = machine_node.getChildNode(variant_name)
+ if variant_node and has_material:
+ for root_material_id in root_material_id_list:
+ material_node = variant_node.getChildNode(root_material_id)
+ if material_node:
+ nodes_to_check.append(material_node)
+ break
+ nodes_to_check.append(variant_node)
+
+ # In this case, we only have a specific material but NOT a variant
+ if has_material:
+ for root_material_id in root_material_id_list:
+ material_node = machine_node.getChildNode(root_material_id)
+ if material_node:
+ nodes_to_check.append(material_node)
+ break
+
+ nodes_to_check += [machine_node, default_machine_node]
+ for node in nodes_to_check:
+ if node and node.quality_type_map:
+ if has_variant_materials:
+ # Only include variant qualities; skip non global qualities
+ quality_node = list(node.quality_type_map.values())[0]
+ is_global_quality = parseBool(quality_node.metadata.get("global_quality", False))
+ if is_global_quality:
+ continue
+
+ for quality_type, quality_node in node.quality_type_map.items():
+ if quality_type not in quality_group_dict:
+ quality_group = QualityGroup(quality_node.metadata["name"], quality_type)
+ quality_group_dict[quality_type] = quality_group
+
+ quality_group = quality_group_dict[quality_type]
+ quality_group.nodes_for_extruders[position] = quality_node
+ break
+
+ # Update availabilities for each quality group
+ self._updateQualityGroupsAvailability(machine, quality_group_dict.values())
+
+ return quality_group_dict
+
+ def getQualityGroupsForMachineDefinition(self, machine: "GlobalStack") -> dict:
+ machine_definition_id = getMachineDefinitionIDForQualitySearch(machine)
+
+ # To find the quality container for the GlobalStack, check in the following fall-back manner:
+ # (1) the machine-specific node
+ # (2) the generic node
+ machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(machine_definition_id)
+ default_machine_node = self._machine_variant_material_quality_type_to_quality_dict.get(
+ self._default_machine_definition_id)
+ nodes_to_check = [machine_node, default_machine_node]
+
+ # Iterate over all quality_types in the machine node
+ quality_group_dict = dict()
+ for node in nodes_to_check:
+ if node and node.quality_type_map:
+ for quality_type, quality_node in node.quality_type_map.items():
+ quality_group = QualityGroup(quality_node.metadata["name"], quality_type)
+ quality_group.node_for_global = quality_node
+ quality_group_dict[quality_type] = quality_group
+ break
+
+ return quality_group_dict
+
+ #
+ # Methods for GUI
+ #
+
+ #
+ # Remove the given quality changes group.
+ #
+ @pyqtSlot(QObject)
+ def removeQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup"):
+ Logger.log("i", "Removing quality changes group [%s]", quality_changes_group.name)
+ for node in quality_changes_group.getAllNodes():
+ self._container_registry.removeContainer(node.metadata["id"])
+
+ #
+ # Rename a set of quality changes containers. Returns the new name.
+ #
+ @pyqtSlot(QObject, str, result = str)
+ def renameQualityChangesGroup(self, quality_changes_group: "QualityChangesGroup", new_name: str) -> str:
+ Logger.log("i", "Renaming QualityChangesGroup[%s] to [%s]", quality_changes_group.name, new_name)
+ if new_name == quality_changes_group.name:
+ Logger.log("i", "QualityChangesGroup name [%s] unchanged.", quality_changes_group.name)
+ return new_name
+
+ new_name = self._container_registry.uniqueName(new_name)
+ for node in quality_changes_group.getAllNodes():
+ node.getContainer().setName(new_name)
+
+ quality_changes_group.name = new_name
+
+ self._application.getMachineManager().activeQualityChanged.emit()
+ self._application.getMachineManager().activeQualityGroupChanged.emit()
+
+ return new_name
+
+ #
+ # Duplicates the given quality.
+ #
+ @pyqtSlot(str, "QVariantMap")
+ def duplicateQualityChanges(self, quality_changes_name, quality_model_item):
+ global_stack = self._application.getGlobalContainerStack()
+ if not global_stack:
+ Logger.log("i", "No active global stack, cannot duplicate quality changes.")
+ return
+
+ quality_group = quality_model_item["quality_group"]
+ quality_changes_group = quality_model_item["quality_changes_group"]
+ if quality_changes_group is None:
+ # create global quality changes only
+ new_quality_changes = self._createQualityChanges(quality_group.quality_type, quality_changes_name,
+ global_stack, None)
+ self._container_registry.addContainer(new_quality_changes)
+ else:
+ new_name = self._container_registry.uniqueName(quality_changes_name)
+ for node in quality_changes_group.getAllNodes():
+ container = node.getContainer()
+ new_id = self._container_registry.uniqueName(container.getId())
+ self._container_registry.addContainer(container.duplicate(new_id, new_name))
+
+ ## Create quality changes containers from the user containers in the active stacks.
+ #
+ # This will go through the global and extruder stacks and create quality_changes containers from
+ # the user containers in each stack. These then replace the quality_changes containers in the
+ # stack and clear the user settings.
+ @pyqtSlot(str)
+ def createQualityChanges(self, base_name):
+ machine_manager = Application.getInstance().getMachineManager()
+
+ global_stack = machine_manager.activeMachine
+ if not global_stack:
+ return
+
+ active_quality_name = machine_manager.activeQualityOrQualityChangesName
+ if active_quality_name == "":
+ Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId())
+ return
+
+ machine_manager.blurSettings.emit()
+ if base_name is None or base_name == "":
+ base_name = active_quality_name
+ unique_name = self._container_registry.uniqueName(base_name)
+
+ # Go through the active stacks and create quality_changes containers from the user containers.
+ stack_list = [global_stack] + list(global_stack.extruders.values())
+ for stack in stack_list:
+ user_container = stack.userChanges
+ quality_container = stack.quality
+ quality_changes_container = stack.qualityChanges
+ if not quality_container or not quality_changes_container:
+ Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId())
+ continue
+
+ quality_type = quality_container.getMetaDataEntry("quality_type")
+ extruder_stack = None
+ if isinstance(stack, ExtruderStack):
+ extruder_stack = stack
+ new_changes = self._createQualityChanges(quality_type, unique_name, global_stack, extruder_stack)
+ from cura.Settings.ContainerManager import ContainerManager
+ ContainerManager.getInstance()._performMerge(new_changes, quality_changes_container, clear_settings = False)
+ ContainerManager.getInstance()._performMerge(new_changes, user_container)
+
+ self._container_registry.addContainer(new_changes)
+
+ #
+ # Create a quality changes container with the given setup.
+ #
+ def _createQualityChanges(self, quality_type: str, new_name: str, machine: "GlobalStack",
+ extruder_stack: Optional["ExtruderStack"]) -> "InstanceContainer":
+ base_id = machine.definition.getId() if extruder_stack is None else extruder_stack.getId()
+ new_id = base_id + "_" + new_name
+ new_id = new_id.lower().replace(" ", "_")
+ new_id = self._container_registry.uniqueName(new_id)
+
+ # Create a new quality_changes container for the quality.
+ quality_changes = InstanceContainer(new_id)
+ quality_changes.setName(new_name)
+ quality_changes.addMetaDataEntry("type", "quality_changes")
+ quality_changes.addMetaDataEntry("quality_type", quality_type)
+
+ # If we are creating a container for an extruder, ensure we add that to the container
+ if extruder_stack is not None:
+ quality_changes.addMetaDataEntry("position", extruder_stack.getMetaDataEntry("position"))
+
+ # If the machine specifies qualities should be filtered, ensure we match the current criteria.
+ machine_definition_id = getMachineDefinitionIDForQualitySearch(machine)
+ quality_changes.setDefinition(machine_definition_id)
+
+ quality_changes.addMetaDataEntry("setting_version", self._application.SettingVersion)
+ return quality_changes
+
+
+#
+# Gets the machine definition ID that can be used to search for Quality containers that are suitable for the given
+# machine. The rule is as follows:
+# 1. By default, the machine definition ID for quality container search will be "fdmprinter", which is the generic
+# machine.
+# 2. If a machine has its own machine quality (with "has_machine_quality = True"), we should use the given machine's
+# own machine definition ID for quality search.
+# Example: for an Ultimaker 3, the definition ID should be "ultimaker3".
+# 3. When condition (2) is met, AND the machine has "quality_definition" defined in its definition file, then the
+# definition ID specified in "quality_definition" should be used.
+# Example: for an Ultimaker 3 Extended, it has "quality_definition = ultimaker3". This means Ultimaker 3 Extended
+# shares the same set of qualities profiles as Ultimaker 3.
+#
+def getMachineDefinitionIDForQualitySearch(machine: "GlobalStack", default_definition_id: str = "fdmprinter") -> str:
+ machine_definition_id = default_definition_id
+ if parseBool(machine.getMetaDataEntry("has_machine_quality", False)):
+ # Only use the machine's own quality definition ID if this machine has machine quality.
+ machine_definition_id = machine.getMetaDataEntry("quality_definition")
+ if machine_definition_id is None:
+ machine_definition_id = machine.definition.getId()
+
+ return machine_definition_id
diff --git a/cura/Machines/QualityNode.py b/cura/Machines/QualityNode.py
new file mode 100644
index 0000000000..a30e219da3
--- /dev/null
+++ b/cura/Machines/QualityNode.py
@@ -0,0 +1,35 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import Optional
+
+from .ContainerNode import ContainerNode
+from .QualityChangesGroup import QualityChangesGroup
+
+
+#
+# QualityNode is used for BOTH quality and quality_changes containers.
+#
+class QualityNode(ContainerNode):
+
+ def __init__(self, metadata: Optional[dict] = None):
+ super().__init__(metadata = metadata)
+ self.quality_type_map = {} # quality_type -> QualityNode for InstanceContainer
+
+ def addQualityMetadata(self, quality_type: str, metadata: dict):
+ if quality_type not in self.quality_type_map:
+ self.quality_type_map[quality_type] = QualityNode(metadata)
+
+ def getQualityNode(self, quality_type: str) -> Optional["QualityNode"]:
+ return self.quality_type_map.get(quality_type)
+
+ def addQualityChangesMetadata(self, quality_type: str, metadata: dict):
+ if quality_type not in self.quality_type_map:
+ self.quality_type_map[quality_type] = QualityNode()
+ quality_type_node = self.quality_type_map[quality_type]
+
+ name = metadata["name"]
+ if name not in quality_type_node.children_map:
+ quality_type_node.children_map[name] = QualityChangesGroup(name, quality_type)
+ quality_changes_group = quality_type_node.children_map[name]
+ quality_changes_group.addNode(QualityNode(metadata))
diff --git a/cura/Machines/VariantManager.py b/cura/Machines/VariantManager.py
new file mode 100644
index 0000000000..1e6dcfe838
--- /dev/null
+++ b/cura/Machines/VariantManager.py
@@ -0,0 +1,119 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from enum import Enum
+from collections import OrderedDict
+from typing import Optional, TYPE_CHECKING
+
+from UM.Logger import Logger
+from UM.Settings.ContainerRegistry import ContainerRegistry
+from UM.Util import parseBool
+
+from cura.Machines.ContainerNode import ContainerNode
+from cura.Settings.GlobalStack import GlobalStack
+
+if TYPE_CHECKING:
+ from UM.Settings.DefinitionContainer import DefinitionContainer
+
+
+class VariantType(Enum):
+ BUILD_PLATE = "buildplate"
+ NOZZLE = "nozzle"
+
+
+ALL_VARIANT_TYPES = (VariantType.BUILD_PLATE, VariantType.NOZZLE)
+
+
+#
+# VariantManager is THE place to look for a specific variant. It maintains a variant lookup table with the following
+# structure:
+#
+# [machine_definition_id] -> [variant_type] -> [variant_name] -> ContainerNode(metadata / container)
+# Example: "ultimaker3" -> "buildplate" -> "Glass" (if present) -> ContainerNode
+# -> ...
+# -> "nozzle" -> "AA 0.4"
+# -> "BB 0.8"
+# -> ...
+#
+# Note that the "container" field is not loaded in the beginning because it would defeat the purpose of lazy-loading.
+# A container is loaded when getVariant() is called to load a variant InstanceContainer.
+#
+class VariantManager:
+
+ def __init__(self, container_registry):
+ self._container_registry = container_registry # type: ContainerRegistry
+
+ self._machine_to_variant_dict_map = dict() # ->
+
+ self._exclude_variant_id_list = ["empty_variant"]
+
+ #
+ # Initializes the VariantManager including:
+ # - initializing the variant lookup table based on the metadata in ContainerRegistry.
+ #
+ def initialize(self):
+ self._machine_to_variant_dict_map = OrderedDict()
+
+ # Cache all variants from the container registry to a variant map for better searching and organization.
+ variant_metadata_list = self._container_registry.findContainersMetadata(type = "variant")
+ for variant_metadata in variant_metadata_list:
+ if variant_metadata["id"] in self._exclude_variant_id_list:
+ Logger.log("d", "Exclude variant [%s]", variant_metadata["id"])
+ continue
+
+ variant_name = variant_metadata["name"]
+ variant_definition = variant_metadata["definition"]
+ if variant_definition not in self._machine_to_variant_dict_map:
+ self._machine_to_variant_dict_map[variant_definition] = OrderedDict()
+ for variant_type in ALL_VARIANT_TYPES:
+ self._machine_to_variant_dict_map[variant_definition][variant_type] = dict()
+
+ variant_type = variant_metadata["hardware_type"]
+ variant_type = VariantType(variant_type)
+ variant_dict = self._machine_to_variant_dict_map[variant_definition][variant_type]
+ if variant_name in variant_dict:
+ # ERROR: duplicated variant name.
+ raise RuntimeError("Found duplicated variant name [%s], type [%s] for machine [%s]" %
+ (variant_name, variant_type, variant_definition))
+
+ variant_dict[variant_name] = ContainerNode(metadata = variant_metadata)
+
+ #
+ # Gets the variant InstanceContainer with the given information.
+ # Almost the same as getVariantMetadata() except that this returns an InstanceContainer if present.
+ #
+ def getVariantNode(self, machine_definition_id: str, variant_name: str,
+ variant_type: Optional["VariantType"] = None) -> Optional["ContainerNode"]:
+ if variant_type is None:
+ variant_node = None
+ variant_type_dict = self._machine_to_variant_dict_map[machine_definition_id]
+ for variant_dict in variant_type_dict.values():
+ if variant_name in variant_dict:
+ variant_node = variant_dict[variant_name]
+ break
+ return variant_node
+ return self._machine_to_variant_dict_map[machine_definition_id].get(variant_type, {}).get(variant_name)
+
+ def getVariantNodes(self, machine: "GlobalStack",
+ variant_type: Optional["VariantType"] = None) -> dict:
+ machine_definition_id = machine.definition.getId()
+ return self._machine_to_variant_dict_map.get(machine_definition_id, {}).get(variant_type, {})
+
+ #
+ # Gets the default variant for the given machine definition.
+ #
+ def getDefaultVariantNode(self, machine_definition: "DefinitionContainer",
+ variant_type: VariantType) -> Optional["ContainerNode"]:
+ machine_definition_id = machine_definition.getId()
+ preferred_variant_name = None
+ if variant_type == VariantType.BUILD_PLATE:
+ if parseBool(machine_definition.getMetaDataEntry("has_variant_buildplates", False)):
+ preferred_variant_name = machine_definition.getMetaDataEntry("preferred_variant_buildplate_name")
+ else:
+ if parseBool(machine_definition.getMetaDataEntry("has_variants", False)):
+ preferred_variant_name = machine_definition.getMetaDataEntry("preferred_variant_name")
+
+ node = None
+ if preferred_variant_name:
+ node = self.getVariantNode(machine_definition_id, preferred_variant_name, variant_type)
+ return node
diff --git a/cura/Machines/__init__.py b/cura/Machines/__init__.py
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/cura/PreviewPass.py b/cura/PreviewPass.py
index af42b59b78..de21a5dc86 100644
--- a/cura/PreviewPass.py
+++ b/cura/PreviewPass.py
@@ -17,6 +17,18 @@ MYPY = False
if MYPY:
from UM.Scene.Camera import Camera
+
+# Make color brighter by normalizing it (maximum factor 2.5 brighter)
+# color_list is a list of 4 elements: [r, g, b, a], each element is a float 0..1
+def prettier_color(color_list):
+ maximum = max(color_list[:3])
+ if maximum > 0:
+ factor = min(1 / maximum, 2.5)
+ else:
+ factor = 1.0
+ return [min(i * factor, 1.0) for i in color_list]
+
+
## A render pass subclass that renders slicable objects with default parameters.
# It uses the active camera by default, but it can be overridden to use a different camera.
#
@@ -41,6 +53,9 @@ class PreviewPass(RenderPass):
if not self._shader:
self._shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "overhang.shader"))
self._shader.setUniformValue("u_overhangAngle", 1.0)
+ self._shader.setUniformValue("u_ambientColor", [0.1, 0.1, 0.1, 1.0])
+ self._shader.setUniformValue("u_specularColor", [0.6, 0.6, 0.6, 1.0])
+ self._shader.setUniformValue("u_shininess", 20.0)
self._gl.glClearColor(0.0, 0.0, 0.0, 0.0)
self._gl.glClear(self._gl.GL_COLOR_BUFFER_BIT | self._gl.GL_DEPTH_BUFFER_BIT)
@@ -52,7 +67,7 @@ class PreviewPass(RenderPass):
for node in DepthFirstIterator(self._scene.getRoot()):
if node.callDecoration("isSliceable") and node.getMeshData() and node.isVisible():
uniforms = {}
- uniforms["diffuse_color"] = node.getDiffuseColor()
+ uniforms["diffuse_color"] = prettier_color(node.getDiffuseColor())
batch.addItem(node.getWorldTransformation(), node.getMeshData(), uniforms = uniforms)
self.bind()
diff --git a/cura/PrintInformation.py b/cura/PrintInformation.py
index 7b4b43eb14..05b740637d 100644
--- a/cura/PrintInformation.py
+++ b/cura/PrintInformation.py
@@ -1,27 +1,22 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty
-from UM.FlameProfiler import pyqtSlot
+from typing import Dict
+import math
+import os.path
+import unicodedata
+import json
+import re # To create abbreviations for printer names.
+
+from PyQt5.QtCore import QObject, pyqtSignal, pyqtProperty, pyqtSlot
from UM.Application import Application
from UM.Logger import Logger
from UM.Qt.Duration import Duration
from UM.Preferences import Preferences
from UM.Scene.SceneNode import SceneNode
-from UM.Settings.ContainerRegistry import ContainerRegistry
-from cura.Scene.CuraSceneNode import CuraSceneNode
-
-from cura.Settings.ExtruderManager import ExtruderManager
-from typing import Dict
-
-import math
-import os.path
-import unicodedata
-import json
-import re #To create abbreviations for printer names.
-
from UM.i18n import i18nCatalog
+
catalog = i18nCatalog("cura")
## A class for processing and calculating minimum, current and maximum print time as well as managing the job name
@@ -76,16 +71,19 @@ class PrintInformation(QObject):
self._active_build_plate = 0
self._initVariablesWithBuildPlate(self._active_build_plate)
- Application.getInstance().globalContainerStackChanged.connect(self._updateJobName)
- Application.getInstance().fileLoaded.connect(self.setBaseName)
- Application.getInstance().getBuildPlateModel().activeBuildPlateChanged.connect(self._onActiveBuildPlateChanged)
- Application.getInstance().workspaceLoaded.connect(self.setProjectName)
+ self._application = Application.getInstance()
+ self._multi_build_plate_model = self._application.getMultiBuildPlateModel()
+
+ self._application.globalContainerStackChanged.connect(self._updateJobName)
+ self._application.globalContainerStackChanged.connect(self.setToZeroPrintInformation)
+ self._application.fileLoaded.connect(self.setBaseName)
+ self._application.workspaceLoaded.connect(self.setProjectName)
+ self._multi_build_plate_model.activeBuildPlateChanged.connect(self._onActiveBuildPlateChanged)
Preferences.getInstance().preferenceChanged.connect(self._onPreferencesChanged)
- self._active_material_container = None
- Application.getInstance().getMachineManager().activeMaterialChanged.connect(self._onActiveMaterialChanged)
- self._onActiveMaterialChanged()
+ self._application.getMachineManager().rootMaterialChanged.connect(self._onActiveMaterialsChanged)
+ self._onActiveMaterialsChanged()
self._material_amounts = []
@@ -200,11 +198,10 @@ class PrintInformation(QObject):
self._current_print_time[build_plate_number].setDuration(total_estimated_time)
def _calculateInformation(self, build_plate_number):
- if Application.getInstance().getGlobalContainerStack() is None:
+ global_stack = Application.getInstance().getGlobalContainerStack()
+ if global_stack is None:
return
- # Material amount is sent as an amount of mm^3, so calculate length from that
- radius = Application.getInstance().getGlobalContainerStack().getProperty("material_diameter", "value") / 2
self._material_lengths[build_plate_number] = []
self._material_weights[build_plate_number] = []
self._material_costs[build_plate_number] = []
@@ -212,18 +209,17 @@ class PrintInformation(QObject):
material_preference_values = json.loads(Preferences.getInstance().getValue("cura/material_settings"))
- extruder_stacks = list(ExtruderManager.getInstance().getMachineExtruders(Application.getInstance().getGlobalContainerStack().getId()))
- for index, amount in enumerate(self._material_amounts):
+ extruder_stacks = global_stack.extruders
+ for position, extruder_stack in extruder_stacks.items():
+ index = int(position)
+ if index >= len(self._material_amounts):
+ continue
+ amount = self._material_amounts[index]
## Find the right extruder stack. As the list isn't sorted because it's a annoying generator, we do some
# list comprehension filtering to solve this for us.
- material = None
- if extruder_stacks: # Multi extrusion machine
- extruder_stack = [extruder for extruder in extruder_stacks if extruder.getMetaDataEntry("position") == str(index)][0]
- density = extruder_stack.getMetaDataEntry("properties", {}).get("density", 0)
- material = extruder_stack.findContainer({"type": "material"})
- else: # Machine with no extruder stacks
- density = Application.getInstance().getGlobalContainerStack().getMetaDataEntry("properties", {}).get("density", 0)
- material = Application.getInstance().getGlobalContainerStack().findContainer({"type": "material"})
+ density = extruder_stack.getMetaDataEntry("properties", {}).get("density", 0)
+ material = extruder_stack.findContainer({"type": "material"})
+ radius = extruder_stack.getProperty("material_diameter", "value") / 2
weight = float(amount) * float(density) / 1000
cost = 0
@@ -242,6 +238,7 @@ class PrintInformation(QObject):
else:
cost = 0
+ # Material amount is sent as an amount of mm^3, so calculate length from that
if radius != 0:
length = round((amount / (math.pi * radius ** 2)) / 1000, 2)
else:
@@ -260,25 +257,11 @@ class PrintInformation(QObject):
if preference != "cura/material_settings":
return
- for build_plate_number in range(Application.getInstance().getBuildPlateModel().maxBuildPlate + 1):
+ for build_plate_number in range(self._multi_build_plate_model.maxBuildPlate + 1):
self._calculateInformation(build_plate_number)
- def _onActiveMaterialChanged(self):
- if self._active_material_container:
- try:
- self._active_material_container.metaDataChanged.disconnect(self._onMaterialMetaDataChanged)
- except TypeError: #pyQtSignal gives a TypeError when disconnecting from something that is already disconnected.
- pass
-
- active_material_id = Application.getInstance().getMachineManager().activeMaterialId
- active_material_containers = ContainerRegistry.getInstance().findInstanceContainers(id = active_material_id)
-
- if active_material_containers:
- self._active_material_container = active_material_containers[0]
- self._active_material_container.metaDataChanged.connect(self._onMaterialMetaDataChanged)
-
def _onActiveBuildPlateChanged(self):
- new_active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate
+ new_active_build_plate = self._multi_build_plate_model.activeBuildPlate
if new_active_build_plate != self._active_build_plate:
self._active_build_plate = new_active_build_plate
@@ -290,8 +273,8 @@ class PrintInformation(QObject):
self.materialNamesChanged.emit()
self.currentPrintTimeChanged.emit()
- def _onMaterialMetaDataChanged(self, *args, **kwargs):
- for build_plate_number in range(Application.getInstance().getBuildPlateModel().maxBuildPlate + 1):
+ def _onActiveMaterialsChanged(self, *args, **kwargs):
+ for build_plate_number in range(self._multi_build_plate_model.maxBuildPlate + 1):
self._calculateInformation(build_plate_number)
@pyqtSlot(str)
@@ -361,10 +344,10 @@ class PrintInformation(QObject):
if not global_container_stack:
self._abbr_machine = ""
return
- active_machine_type_id = global_container_stack.definition.getId()
+ active_machine_type_name = global_container_stack.definition.getName()
abbr_machine = ""
- for word in re.findall(r"[\w']+", active_machine_type_id):
+ for word in re.findall(r"[\w']+", active_machine_type_name):
if word.lower() == "ultimaker":
abbr_machine += "UM"
elif word.isdigit():
@@ -396,7 +379,9 @@ class PrintInformation(QObject):
return result
# Simulate message with zero time duration
- def setToZeroPrintInformation(self, build_plate):
+ def setToZeroPrintInformation(self, build_plate = None):
+ if build_plate is None:
+ build_plate = self._active_build_plate
# Construct the 0-time message
temp_message = {}
diff --git a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py
index a7b7edc636..315b195e2a 100644
--- a/cura/PrinterOutput/NetworkedPrinterOutputDevice.py
+++ b/cura/PrinterOutput/NetworkedPrinterOutputDevice.py
@@ -219,6 +219,9 @@ class NetworkedPrinterOutputDevice(PrinterOutputDevice):
reply.uploadProgress.connect(onProgress)
self._registerOnFinishedCallback(reply, onFinished)
+
+ return reply
+
def postForm(self, target: str, header_data: str, body_data: bytes, onFinished: Optional[Callable[[Any, QNetworkReply], None]], onProgress: Callable = None) -> None:
post_part = QHttpPart()
post_part.setHeader(QNetworkRequest.ContentDispositionHeader, header_data)
diff --git a/cura/PrinterOutput/PrinterOutputModel.py b/cura/PrinterOutput/PrinterOutputModel.py
index 8234989519..1c23d0e18e 100644
--- a/cura/PrinterOutput/PrinterOutputModel.py
+++ b/cura/PrinterOutput/PrinterOutputModel.py
@@ -103,32 +103,32 @@ class PrinterOutputModel(QObject):
self._head_position = Vector(x, y, z)
self.headPositionChanged.emit()
- @pyqtProperty("long", "long", "long")
- @pyqtProperty("long", "long", "long", "long")
+ @pyqtProperty(float, float, float)
+ @pyqtProperty(float, float, float, float)
def setHeadPosition(self, x, y, z, speed = 3000):
self.updateHeadPosition(x, y, z)
self._controller.setHeadPosition(self, x, y, z, speed)
- @pyqtProperty("long")
- @pyqtProperty("long", "long")
+ @pyqtProperty(float)
+ @pyqtProperty(float, float)
def setHeadX(self, x, speed = 3000):
self.updateHeadPosition(x, self._head_position.y, self._head_position.z)
self._controller.setHeadPosition(self, x, self._head_position.y, self._head_position.z, speed)
- @pyqtProperty("long")
- @pyqtProperty("long", "long")
+ @pyqtProperty(float)
+ @pyqtProperty(float, float)
def setHeadY(self, y, speed = 3000):
self.updateHeadPosition(self._head_position.x, y, self._head_position.z)
self._controller.setHeadPosition(self, self._head_position.x, y, self._head_position.z, speed)
- @pyqtProperty("long")
- @pyqtProperty("long", "long")
+ @pyqtProperty(float)
+ @pyqtProperty(float, float)
def setHeadZ(self, z, speed = 3000):
self.updateHeadPosition(self._head_position.x, self._head_position.y, z)
self._controller.setHeadPosition(self, self._head_position.x, self._head_position.y, z, speed)
- @pyqtSlot("long", "long", "long")
- @pyqtSlot("long", "long", "long", "long")
+ @pyqtSlot(float, float, float)
+ @pyqtSlot(float, float, float, float)
def moveHead(self, x = 0, y = 0, z = 0, speed = 3000):
self._controller.moveHead(self, x, y, z, speed)
diff --git a/cura/ProfileReader.py b/cura/ProfileReader.py
index d4600ed99f..460fce823e 100644
--- a/cura/ProfileReader.py
+++ b/cura/ProfileReader.py
@@ -3,6 +3,13 @@
from UM.PluginObject import PluginObject
+
+# Exception when there is no profile to import from a given files.
+# Note that this should not be treated as an exception but as an information instead.
+class NoProfileException(Exception):
+ pass
+
+
## A type of plug-ins that reads profiles from a file.
#
# The profile is then stored as instance container of the type user profile.
@@ -14,4 +21,4 @@ class ProfileReader(PluginObject):
#
# \return \type{Profile|Profile[]} The profile that was obtained from the file or a list of Profiles.
def read(self, file_name):
- raise NotImplementedError("Profile reader plug-in was not correctly implemented. The read function was not implemented.")
\ No newline at end of file
+ raise NotImplementedError("Profile reader plug-in was not correctly implemented. The read function was not implemented.")
diff --git a/cura/QualityManager.py b/cura/QualityManager.py
deleted file mode 100644
index 76a0c86a5f..0000000000
--- a/cura/QualityManager.py
+++ /dev/null
@@ -1,332 +0,0 @@
-# Copyright (c) 2017 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-# This collects a lot of quality and quality changes related code which was split between ContainerManager
-# and the MachineManager and really needs to usable from both.
-from typing import Any, Dict, List, Optional, TYPE_CHECKING
-
-from UM.Application import Application
-from UM.Settings.ContainerRegistry import ContainerRegistry
-from UM.Settings.InstanceContainer import InstanceContainer
-from cura.Settings.ExtruderManager import ExtruderManager
-
-if TYPE_CHECKING:
- from cura.Settings.GlobalStack import GlobalStack
- from cura.Settings.ExtruderStack import ExtruderStack
- from UM.Settings.DefinitionContainer import DefinitionContainerInterface
-
-class QualityManager:
-
- ## Get the singleton instance for this class.
- @classmethod
- def getInstance(cls) -> "QualityManager":
- # Note: Explicit use of class name to prevent issues with inheritance.
- if not QualityManager.__instance:
- QualityManager.__instance = cls()
- return QualityManager.__instance
-
- __instance = None # type: "QualityManager"
-
- ## Find a quality by name for a specific machine definition and materials.
- #
- # \param quality_name
- # \param machine_definition (Optional) \type{DefinitionContainerInterface} If nothing is
- # specified then the currently selected machine definition is used.
- # \param material_containers_metadata If nothing is specified then the
- # current set of selected materials is used.
- # \return the matching quality container \type{InstanceContainer}
- def findQualityByName(self, quality_name: str, machine_definition: Optional["DefinitionContainerInterface"] = None, material_containers_metadata: Optional[List[Dict[str, Any]]] = None) -> Optional[InstanceContainer]:
- criteria = {"type": "quality", "name": quality_name}
- result = self._getFilteredContainersForStack(machine_definition, material_containers_metadata, **criteria)
-
- # Fall back to using generic materials and qualities if nothing could be found.
- if not result and material_containers_metadata and len(material_containers_metadata) == 1:
- basic_materials = self._getBasicMaterialMetadatas(material_containers_metadata[0])
- result = self._getFilteredContainersForStack(machine_definition, basic_materials, **criteria)
-
- return result[0] if result else None
-
- ## Find a quality changes container by name.
- #
- # \param quality_changes_name \type{str} the name of the quality changes container.
- # \param machine_definition (Optional) \type{DefinitionContainer} If nothing is
- # specified then the currently selected machine definition is used..
- # \return the matching quality changes containers \type{List[InstanceContainer]}
- def findQualityChangesByName(self, quality_changes_name: str, machine_definition: Optional["DefinitionContainerInterface"] = None):
- if not machine_definition:
- global_stack = Application.getGlobalContainerStack()
- if not global_stack:
- return [] #No stack, so no current definition could be found, so there are no quality changes either.
- machine_definition = global_stack.definition
-
- result = self.findAllQualityChangesForMachine(machine_definition)
- result = [quality_change for quality_change in result if quality_change.getName() == quality_changes_name]
- return result
-
- ## Fetch the list of available quality types for this combination of machine definition and materials.
- #
- # \param machine_definition \type{DefinitionContainer}
- # \param material_containers \type{List[InstanceContainer]}
- # \return \type{List[str]}
- def findAllQualityTypesForMachineAndMaterials(self, machine_definition: "DefinitionContainerInterface", material_containers: List[InstanceContainer]) -> List[str]:
- # Determine the common set of quality types which can be
- # applied to all of the materials for this machine.
- quality_type_dict = self.__fetchQualityTypeDictForMaterial(machine_definition, material_containers[0])
- common_quality_types = set(quality_type_dict.keys())
- for material_container in material_containers[1:]:
- next_quality_type_dict = self.__fetchQualityTypeDictForMaterial(machine_definition, material_container)
- common_quality_types.intersection_update(set(next_quality_type_dict.keys()))
-
- return list(common_quality_types)
-
- def findAllQualitiesForMachineAndMaterials(self, machine_definition: "DefinitionContainerInterface", material_containers: List[InstanceContainer]) -> List[InstanceContainer]:
- # Determine the common set of quality types which can be
- # applied to all of the materials for this machine.
- quality_type_dict = self.__fetchQualityTypeDictForMaterial(machine_definition, material_containers[0])
- qualities = set(quality_type_dict.values())
- for material_container in material_containers[1:]:
- next_quality_type_dict = self.__fetchQualityTypeDictForMaterial(machine_definition, material_container)
- qualities.intersection_update(set(next_quality_type_dict.values()))
-
- return list(qualities)
-
- ## Fetches a dict of quality types names to quality profiles for a combination of machine and material.
- #
- # \param machine_definition \type{DefinitionContainer} the machine definition.
- # \param material \type{InstanceContainer} the material.
- # \return \type{Dict[str, InstanceContainer]} the dict of suitable quality type names mapping to qualities.
- def __fetchQualityTypeDictForMaterial(self, machine_definition: "DefinitionContainerInterface", material: InstanceContainer) -> Dict[str, InstanceContainer]:
- qualities = self.findAllQualitiesForMachineMaterial(machine_definition, material)
- quality_type_dict = {}
- for quality in qualities:
- quality_type_dict[quality.getMetaDataEntry("quality_type")] = quality
- return quality_type_dict
-
- ## Find a quality container by quality type.
- #
- # \param quality_type \type{str} the name of the quality type to search for.
- # \param machine_definition (Optional) \type{InstanceContainer} If nothing is
- # specified then the currently selected machine definition is used.
- # \param material_containers_metadata If nothing is specified then the
- # current set of selected materials is used.
- # \return the matching quality container \type{InstanceContainer}
- def findQualityByQualityType(self, quality_type: str, machine_definition: Optional["DefinitionContainerInterface"] = None, material_containers_metadata: Optional[List[Dict[str, Any]]] = None, **kwargs) -> InstanceContainer:
- criteria = kwargs
- criteria["type"] = "quality"
- if quality_type:
- criteria["quality_type"] = quality_type
- result = self._getFilteredContainersForStack(machine_definition, material_containers_metadata, **criteria)
- # Fall back to using generic materials and qualities if nothing could be found.
- if not result and material_containers_metadata and len(material_containers_metadata) == 1:
- basic_materials = self._getBasicMaterialMetadatas(material_containers_metadata[0])
- if basic_materials:
- result = self._getFilteredContainersForStack(machine_definition, basic_materials, **criteria)
- return result[0] if result else None
-
- ## Find all suitable qualities for a combination of machine and material.
- #
- # \param machine_definition \type{DefinitionContainer} the machine definition.
- # \param material_container \type{InstanceContainer} the material.
- # \return \type{List[InstanceContainer]} the list of suitable qualities.
- def findAllQualitiesForMachineMaterial(self, machine_definition: "DefinitionContainerInterface", material_container: InstanceContainer) -> List[InstanceContainer]:
- criteria = {"type": "quality"}
- result = self._getFilteredContainersForStack(machine_definition, [material_container.getMetaData()], **criteria)
- if not result:
- basic_materials = self._getBasicMaterialMetadatas(material_container.getMetaData())
- if basic_materials:
- result = self._getFilteredContainersForStack(machine_definition, basic_materials, **criteria)
-
- return result
-
- ## Find all quality changes for a machine.
- #
- # \param machine_definition \type{DefinitionContainer} the machine definition.
- # \return \type{List[InstanceContainer]} the list of quality changes
- def findAllQualityChangesForMachine(self, machine_definition: "DefinitionContainerInterface") -> List[InstanceContainer]:
- if machine_definition.getMetaDataEntry("has_machine_quality"):
- definition_id = machine_definition.getId()
- else:
- definition_id = "fdmprinter"
-
- filter_dict = { "type": "quality_changes", "definition": definition_id }
- quality_changes_list = ContainerRegistry.getInstance().findInstanceContainers(**filter_dict)
- return quality_changes_list
-
- def findAllExtruderDefinitionsForMachine(self, machine_definition: "DefinitionContainerInterface") -> List["DefinitionContainerInterface"]:
- filter_dict = { "machine": machine_definition.getId() }
- return ContainerRegistry.getInstance().findDefinitionContainers(**filter_dict)
-
- ## Find all quality changes for a given extruder.
- #
- # \param extruder_definition The extruder to find the quality changes for.
- # \return The list of quality changes for the given extruder.
- def findAllQualityChangesForExtruder(self, extruder_definition: "DefinitionContainerInterface") -> List[InstanceContainer]:
- filter_dict = {"type": "quality_changes", "extruder": extruder_definition.getId()}
- return ContainerRegistry.getInstance().findInstanceContainers(**filter_dict)
-
- ## Find all usable qualities for a machine and extruders.
- #
- # Finds all of the qualities for this combination of machine and extruders.
- # Only one quality per quality type is returned. i.e. if there are 2 qualities with quality_type=normal
- # then only one of then is returned (at random).
- #
- # \param global_container_stack \type{GlobalStack} the global machine definition
- # \param extruder_stacks \type{List[ExtruderStack]} the list of extruder stacks
- # \return \type{List[InstanceContainer]} the list of the matching qualities. The quality profiles
- # return come from the first extruder in the given list of extruders.
- def findAllUsableQualitiesForMachineAndExtruders(self, global_container_stack: "GlobalStack", extruder_stacks: List["ExtruderStack"]) -> List[InstanceContainer]:
- global_machine_definition = global_container_stack.getBottom()
-
- machine_manager = Application.getInstance().getMachineManager()
- active_stack_id = machine_manager.activeStackId
-
- materials = []
-
- for stack in extruder_stacks:
- if stack.getId() == active_stack_id and machine_manager.newMaterial:
- materials.append(machine_manager.newMaterial)
- else:
- materials.append(stack.material)
-
- quality_types = self.findAllQualityTypesForMachineAndMaterials(global_machine_definition, materials)
-
- # Map the list of quality_types to InstanceContainers
- qualities = self.findAllQualitiesForMachineMaterial(global_machine_definition, materials[0])
- quality_type_dict = {}
- for quality in qualities:
- quality_type_dict[quality.getMetaDataEntry("quality_type")] = quality
-
- return [quality_type_dict[quality_type] for quality_type in quality_types]
-
- ## Fetch more basic versions of a material.
- #
- # This tries to find a generic or basic version of the given material.
- # \param material_container \type{Dict[str, Any]} The metadata of a
- # material to find the basic versions of.
- # \return \type{List[Dict[str, Any]]} A list of the metadata of basic
- # materials, or an empty list if none could be found.
- def _getBasicMaterialMetadatas(self, material_container: Dict[str, Any]) -> List[Dict[str, Any]]:
- if "definition" not in material_container:
- definition_id = "fdmprinter"
- else:
- material_container_definition = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = material_container["definition"])
- if not material_container_definition:
- definition_id = "fdmprinter"
- else:
- material_container_definition = material_container_definition[0]
- if "has_machine_quality" not in material_container_definition:
- definition_id = "fdmprinter"
- else:
- definition_id = material_container_definition.get("quality_definition", material_container_definition["id"])
-
- base_material = material_container.get("material")
- if base_material:
- # There is a basic material specified
- criteria = {
- "type": "material",
- "name": base_material,
- "definition": definition_id,
- "variant": material_container.get("variant")
- }
- containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(**criteria)
- return containers
-
- return []
-
- def _getFilteredContainers(self, **kwargs):
- return self._getFilteredContainersForStack(None, None, **kwargs)
-
- def _getFilteredContainersForStack(self, machine_definition: "DefinitionContainerInterface" = None, material_metadata: Optional[List[Dict[str, Any]]] = None, **kwargs):
- # Fill in any default values.
- if machine_definition is None:
- machine_definition = Application.getInstance().getGlobalContainerStack().getBottom()
- quality_definition_id = machine_definition.getMetaDataEntry("quality_definition")
- if quality_definition_id is not None:
- machine_definition = ContainerRegistry.getInstance().findDefinitionContainers(id = quality_definition_id)[0]
-
- if not material_metadata:
- active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
- if active_stacks:
- material_metadata = [stack.material.getMetaData() for stack in active_stacks]
-
- criteria = kwargs
- filter_by_material = False
-
- machine_definition = self.getParentMachineDefinition(machine_definition)
- criteria["definition"] = machine_definition.getId()
- found_containers_with_machine_definition = ContainerRegistry.getInstance().findInstanceContainersMetadata(**criteria)
- whole_machine_definition = self.getWholeMachineDefinition(machine_definition)
- if whole_machine_definition.getMetaDataEntry("has_machine_quality"):
- definition_id = machine_definition.getMetaDataEntry("quality_definition", whole_machine_definition.getId())
- criteria["definition"] = definition_id
-
- filter_by_material = whole_machine_definition.getMetaDataEntry("has_materials")
- # only fall back to "fdmprinter" when there is no container for this machine
- elif not found_containers_with_machine_definition:
- criteria["definition"] = "fdmprinter"
-
- # Stick the material IDs in a set
- material_ids = set()
-
- for material_instance in material_metadata:
- if material_instance is not None:
- # Add the parent material too.
- for basic_material in self._getBasicMaterialMetadatas(material_instance):
- material_ids.add(basic_material["id"])
- material_ids.add(material_instance["id"])
- containers = ContainerRegistry.getInstance().findInstanceContainers(**criteria)
-
- result = []
- for container in containers:
- # If the machine specifies we should filter by material, exclude containers that do not match any active material.
- if filter_by_material and container.getMetaDataEntry("material") not in material_ids and "global_quality" not in kwargs:
- continue
- result.append(container)
-
- return result
-
- ## Get the parent machine definition of a machine definition.
- #
- # \param machine_definition \type{DefinitionContainer} This may be a normal machine definition or
- # an extruder definition.
- # \return \type{DefinitionContainer} the parent machine definition. If the given machine
- # definition doesn't have a parent then it is simply returned.
- def getParentMachineDefinition(self, machine_definition: "DefinitionContainerInterface") -> "DefinitionContainerInterface":
- container_registry = ContainerRegistry.getInstance()
-
- machine_entry = machine_definition.getMetaDataEntry("machine")
- if machine_entry is None:
- # We have a normal (whole) machine defintion
- quality_definition = machine_definition.getMetaDataEntry("quality_definition")
- if quality_definition is not None:
- parent_machine_definition = container_registry.findDefinitionContainers(id = quality_definition)[0]
- return self.getParentMachineDefinition(parent_machine_definition)
- else:
- return machine_definition
- else:
- # This looks like an extruder. Find the rest of the machine.
- whole_machine = container_registry.findDefinitionContainers(id = machine_entry)[0]
- parent_machine = self.getParentMachineDefinition(whole_machine)
- if whole_machine is parent_machine:
- # This extruder already belongs to a 'parent' machine def.
- return machine_definition
- else:
- # Look up the corresponding extruder definition in the parent machine definition.
- extruder_position = machine_definition.getMetaDataEntry("position")
- parent_extruder_id = parent_machine.getMetaDataEntry("machine_extruder_trains")[extruder_position]
- return container_registry.findDefinitionContainers(id = parent_extruder_id)[0]
-
- ## Get the whole/global machine definition from an extruder definition.
- #
- # \param machine_definition \type{DefinitionContainer} This may be a normal machine definition or
- # an extruder definition.
- # \return \type{DefinitionContainerInterface}
- def getWholeMachineDefinition(self, machine_definition: "DefinitionContainerInterface") -> "DefinitionContainerInterface":
- machine_entry = machine_definition.getMetaDataEntry("machine")
- if machine_entry is None:
- # This already is a 'global' machine definition.
- return machine_definition
- else:
- container_registry = ContainerRegistry.getInstance()
- whole_machine = container_registry.findDefinitionContainers(id = machine_entry)[0]
- return whole_machine
diff --git a/cura/Scene/ConvexHullNode.py b/cura/Scene/ConvexHullNode.py
index 6c8c201498..1131958627 100644
--- a/cura/Scene/ConvexHullNode.py
+++ b/cura/Scene/ConvexHullNode.py
@@ -68,7 +68,7 @@ class ConvexHullNode(SceneNode):
ConvexHullNode.shader.setUniformValue("u_opacity", 0.6)
if self.getParent():
- if self.getMeshData() and isinstance(self._node, SceneNode) and self._node.callDecoration("getBuildPlateNumber") == Application.getInstance().getBuildPlateModel().activeBuildPlate:
+ if self.getMeshData() and isinstance(self._node, SceneNode) and self._node.callDecoration("getBuildPlateNumber") == Application.getInstance().getMultiBuildPlateModel().activeBuildPlate:
renderer.queueNode(self, transparent = True, shader = ConvexHullNode.shader, backface_cull = True, sort = -8)
if self._convex_hull_head_mesh:
renderer.queueNode(self, shader = ConvexHullNode.shader, transparent = True, mesh = self._convex_hull_head_mesh, backface_cull = True, sort = -8)
diff --git a/cura/Scene/CuraSceneController.py b/cura/Scene/CuraSceneController.py
index 1c008d1893..749c5257a2 100644
--- a/cura/Scene/CuraSceneController.py
+++ b/cura/Scene/CuraSceneController.py
@@ -4,7 +4,7 @@ from PyQt5.QtCore import Qt, pyqtSlot, QObject
from PyQt5.QtWidgets import QApplication
from cura.ObjectsModel import ObjectsModel
-from cura.BuildPlateModel import BuildPlateModel
+from cura.Machines.Models.MultiBuildPlateModel import MultiBuildPlateModel
from UM.Application import Application
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
@@ -16,11 +16,11 @@ from UM.Signal import Signal
class CuraSceneController(QObject):
activeBuildPlateChanged = Signal()
- def __init__(self, objects_model: ObjectsModel, build_plate_model: BuildPlateModel):
+ def __init__(self, objects_model: ObjectsModel, multi_build_plate_model: MultiBuildPlateModel):
super().__init__()
self._objects_model = objects_model
- self._build_plate_model = build_plate_model
+ self._multi_build_plate_model = multi_build_plate_model
self._active_build_plate = -1
self._last_selected_index = 0
@@ -41,9 +41,9 @@ class CuraSceneController(QObject):
self._max_build_plate = max_build_plate
changed = True
if changed:
- self._build_plate_model.setMaxBuildPlate(self._max_build_plate)
+ self._multi_build_plate_model.setMaxBuildPlate(self._max_build_plate)
build_plates = [{"name": "Build Plate %d" % (i + 1), "buildPlateNumber": i} for i in range(self._max_build_plate + 1)]
- self._build_plate_model.setItems(build_plates)
+ self._multi_build_plate_model.setItems(build_plates)
if self._active_build_plate > self._max_build_plate:
build_plate_number = 0
if self._last_selected_index >= 0: # go to the buildplate of the item you last selected
@@ -104,12 +104,12 @@ class CuraSceneController(QObject):
self._active_build_plate = nr
Selection.clear()
- self._build_plate_model.setActiveBuildPlate(nr)
+ self._multi_build_plate_model.setActiveBuildPlate(nr)
self._objects_model.setActiveBuildPlate(nr)
self.activeBuildPlateChanged.emit()
@staticmethod
def createCuraSceneController():
objects_model = Application.getInstance().getObjectsModel()
- build_plate_model = Application.getInstance().getBuildPlateModel()
- return CuraSceneController(objects_model = objects_model, build_plate_model = build_plate_model)
+ multi_build_plate_model = Application.getInstance().getMultiBuildPlateModel()
+ return CuraSceneController(objects_model = objects_model, multi_build_plate_model = multi_build_plate_model)
diff --git a/cura/Scene/CuraSceneNode.py b/cura/Scene/CuraSceneNode.py
index 969d491f49..b29108d636 100644
--- a/cura/Scene/CuraSceneNode.py
+++ b/cura/Scene/CuraSceneNode.py
@@ -1,9 +1,13 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+from copy import deepcopy
from typing import List
from UM.Application import Application
+from UM.Math.AxisAlignedBox import AxisAlignedBox
from UM.Scene.SceneNode import SceneNode
-from copy import deepcopy
-from cura.Settings.ExtrudersModel import ExtrudersModel
+
+from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator
## Scene nodes that are models are only seen when selecting the corresponding build plate
@@ -11,6 +15,8 @@ from cura.Settings.ExtrudersModel import ExtrudersModel
class CuraSceneNode(SceneNode):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
+ if "no_setting_override" not in kwargs:
+ self.addDecorator(SettingOverrideDecorator()) # now we always have a getActiveExtruderPosition, unless explicitly disabled
self._outside_buildarea = False
def setOutsideBuildArea(self, new_value):
@@ -20,10 +26,10 @@ class CuraSceneNode(SceneNode):
return self._outside_buildarea or self.callDecoration("getBuildPlateNumber") < 0
def isVisible(self):
- return super().isVisible() and self.callDecoration("getBuildPlateNumber") == Application.getInstance().getBuildPlateModel().activeBuildPlate
+ return super().isVisible() and self.callDecoration("getBuildPlateNumber") == Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
def isSelectable(self) -> bool:
- return super().isSelectable() and self.callDecoration("getBuildPlateNumber") == Application.getInstance().getBuildPlateModel().activeBuildPlate
+ return super().isSelectable() and self.callDecoration("getBuildPlateNumber") == Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
## Get the extruder used to print this node. If there is no active node, then the extruder in position zero is returned
# TODO The best way to do it is by adding the setActiveExtruder decorator to every node when is loaded
@@ -72,9 +78,34 @@ class CuraSceneNode(SceneNode):
1.0
]
+ ## Return if the provided bbox collides with the bbox of this scene node
+ def collidesWithBbox(self, check_bbox):
+ bbox = self.getBoundingBox()
+
+ # Mark the node as outside the build volume if the bounding box test fails.
+ if check_bbox.intersectsBox(bbox) != AxisAlignedBox.IntersectionResult.FullIntersection:
+ return True
+
+ return False
+
+ ## Return if any area collides with the convex hull of this scene node
+ def collidesWithArea(self, areas):
+ convex_hull = self.callDecoration("getConvexHull")
+ if convex_hull:
+ if not convex_hull.isValid():
+ return False
+
+ # Check for collisions between disallowed areas and the object
+ for area in areas:
+ overlap = convex_hull.intersectsPolygon(area)
+ if overlap is None:
+ continue
+ return True
+ return False
+
## Taken from SceneNode, but replaced SceneNode with CuraSceneNode
def __deepcopy__(self, memo):
- copy = CuraSceneNode()
+ copy = CuraSceneNode(no_setting_override = True) # Setting override will be added later
copy.setTransformation(self.getLocalTransformation())
copy.setMeshData(self._mesh_data)
copy.setVisible(deepcopy(self._visible, memo))
diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py
index d2e8410dde..7161169b22 100644
--- a/cura/Settings/ContainerManager.py
+++ b/cura/Settings/ContainerManager.py
@@ -1,16 +1,14 @@
# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-import copy
import os.path
import urllib.parse
import uuid
-from typing import Any, Dict, List, Union
+from typing import Dict, Union
from PyQt5.QtCore import QObject, QUrl, QVariant
from UM.FlameProfiler import pyqtSlot
from PyQt5.QtWidgets import QMessageBox
-from UM.Util import parseBool
from UM.PluginRegistry import PluginRegistry
from UM.SaveFile import SaveFile
@@ -22,7 +20,6 @@ from UM.Application import Application
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.DefinitionContainer import DefinitionContainer
from UM.Settings.InstanceContainer import InstanceContainer
-from cura.QualityManager import QualityManager
from UM.MimeTypeDatabase import MimeTypeNotFoundError
from UM.Settings.ContainerRegistry import ContainerRegistry
@@ -30,9 +27,11 @@ from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.i18n import i18nCatalog
from cura.Settings.ExtruderManager import ExtruderManager
+from cura.Settings.ExtruderStack import ExtruderStack
catalog = i18nCatalog("cura")
+
## Manager class that contains common actions to deal with containers in Cura.
#
# This is primarily intended as a class to be able to perform certain actions
@@ -42,154 +41,12 @@ class ContainerManager(QObject):
def __init__(self, parent = None):
super().__init__(parent)
+ self._application = Application.getInstance()
self._container_registry = ContainerRegistry.getInstance()
- self._machine_manager = Application.getInstance().getMachineManager()
+ self._machine_manager = self._application.getMachineManager()
+ self._material_manager = self._application.getMaterialManager()
self._container_name_filters = {}
- ## Create a duplicate of the specified container
- #
- # This will create and add a duplicate of the container corresponding
- # to the container ID.
- #
- # \param container_id \type{str} The ID of the container to duplicate.
- #
- # \return The ID of the new container, or an empty string if duplication failed.
- @pyqtSlot(str, result = str)
- def duplicateContainer(self, container_id):
- #TODO: It should be able to duplicate a container of which only the metadata is known.
- containers = self._container_registry.findContainers(id = container_id)
- if not containers:
- Logger.log("w", "Could duplicate container %s because it was not found.", container_id)
- return ""
-
- container = containers[0]
- new_container = self.duplicateContainerInstance(container)
- return new_container.getId()
-
- ## Create a duplicate of the given container instance
- #
- # This will create and add a duplicate of the container that was passed.
- #
- # \param container \type{ContainerInterface} The container to duplicate.
- #
- # \return The duplicated container, or None if duplication failed.
- def duplicateContainerInstance(self, container):
- new_container = None
- new_name = self._container_registry.uniqueName(container.getName())
- # Only InstanceContainer has a duplicate method at the moment.
- # So fall back to serialize/deserialize when no duplicate method exists.
- if hasattr(container, "duplicate"):
- new_container = container.duplicate(new_name)
- else:
- new_container = container.__class__(new_name)
- new_container.deserialize(container.serialize())
- new_container.setName(new_name)
-
- # TODO: we probably don't want to add it to the registry here!
- if new_container:
- self._container_registry.addContainer(new_container)
-
- return new_container
-
- ## Change the name of a specified container to a new name.
- #
- # \param container_id \type{str} The ID of the container to change the name of.
- # \param new_id \type{str} The new ID of the container.
- # \param new_name \type{str} The new name of the specified container.
- #
- # \return True if successful, False if not.
- @pyqtSlot(str, str, str, result = bool)
- def renameContainer(self, container_id, new_id, new_name):
- containers = self._container_registry.findContainers(id = container_id)
- if not containers:
- Logger.log("w", "Could rename container %s because it was not found.", container_id)
- return False
-
- container = containers[0]
- # First, remove the container from the registry. This will clean up any files related to the container.
- self._container_registry.removeContainer(container_id)
-
- # Ensure we have a unique name for the container
- new_name = self._container_registry.uniqueName(new_name)
-
- # Then, update the name and ID of the container
- container.setName(new_name)
- container._id = new_id # TODO: Find a nicer way to set a new, unique ID
-
- # Finally, re-add the container so it will be properly serialized again.
- self._container_registry.addContainer(container)
-
- return True
-
- ## Remove the specified container.
- #
- # \param container_id \type{str} The ID of the container to remove.
- #
- # \return True if the container was successfully removed, False if not.
- @pyqtSlot(str, result = bool)
- def removeContainer(self, container_id):
- containers = self._container_registry.findContainers(id = container_id)
- if not containers:
- Logger.log("w", "Could not remove container %s because it was not found.", container_id)
- return False
-
- self._container_registry.removeContainer(containers[0].getId())
-
- return True
-
- ## Merge a container with another.
- #
- # This will try to merge one container into the other, by going through the container
- # and setting the right properties on the other container.
- #
- # \param merge_into_id \type{str} The ID of the container to merge into.
- # \param merge_id \type{str} The ID of the container to merge.
- #
- # \return True if successfully merged, False if not.
- @pyqtSlot(str, result = bool)
- def mergeContainers(self, merge_into_id, merge_id):
- containers = self._container_registry.findContainers(id = merge_into_id)
- if not containers:
- Logger.log("w", "Could merge into container %s because it was not found.", merge_into_id)
- return False
-
- merge_into = containers[0]
-
- containers = self._container_registry.findContainers(id = merge_id)
- if not containers:
- Logger.log("w", "Could not merge container %s because it was not found", merge_id)
- return False
-
- merge = containers[0]
-
- if not isinstance(merge, type(merge_into)):
- Logger.log("w", "Cannot merge two containers of different types")
- return False
-
- self._performMerge(merge_into, merge)
-
- return True
-
- ## Clear the contents of a container.
- #
- # \param container_id \type{str} The ID of the container to clear.
- #
- # \return True if successful, False if not.
- @pyqtSlot(str, result = bool)
- def clearContainer(self, container_id):
- if self._container_registry.isReadOnly(container_id):
- Logger.log("w", "Cannot clear read-only container %s", container_id)
- return False
-
- containers = self._container_registry.findContainers(id = container_id)
- if not containers:
- Logger.log("w", "Could clear container %s because it was not found.", container_id)
- return False
-
- containers[0].clear()
-
- return True
-
@pyqtSlot(str, str, result=str)
def getContainerMetaDataEntry(self, container_id, entry_name):
metadatas = self._container_registry.findContainersMetadata(id = container_id)
@@ -211,18 +68,15 @@ class ContainerManager(QObject):
# \param entry_value The new value of the entry.
#
# \return True if successful, False if not.
- @pyqtSlot(str, str, str, result = bool)
- def setContainerMetaDataEntry(self, container_id, entry_name, entry_value):
- if self._container_registry.isReadOnly(container_id):
- Logger.log("w", "Cannot set metadata of read-only container %s.", container_id)
+ # TODO: This is ONLY used by MaterialView for material containers. Maybe refactor this.
+ @pyqtSlot("QVariant", str, str)
+ def setContainerMetaDataEntry(self, container_node, entry_name, entry_value):
+ root_material_id = container_node.metadata["base_file"]
+ if self._container_registry.isReadOnly(root_material_id):
+ Logger.log("w", "Cannot set metadata of read-only container %s.", root_material_id)
return False
- containers = self._container_registry.findContainers(id = container_id) #We need the complete container, since we need to know whether the container is read-only or not.
- if not containers:
- Logger.log("w", "Could not set metadata of container %s because it was not found.", container_id)
- return False
-
- container = containers[0]
+ material_group = self._material_manager.getMaterialGroup(root_material_id)
entries = entry_name.split("/")
entry_name = entries.pop()
@@ -230,7 +84,7 @@ class ContainerManager(QObject):
sub_item_changed = False
if entries:
root_name = entries.pop(0)
- root = container.getMetaDataEntry(root_name)
+ root = material_group.root_material_node.metadata.get(root_name)
item = root
for _ in range(len(entries)):
@@ -243,12 +97,11 @@ class ContainerManager(QObject):
entry_name = root_name
entry_value = root
+ container = material_group.root_material_node.getContainer()
container.setMetaDataEntry(entry_name, entry_value)
if sub_item_changed: #If it was only a sub-item that has changed then the setMetaDataEntry won't correctly notice that something changed, and we must manually signal that the metadata changed.
container.metaDataChanged.emit(container)
- return True
-
## Set a setting property of the specified container.
#
# This will set the specified property of the specified setting of the container
@@ -306,60 +159,6 @@ class ContainerManager(QObject):
return container.getProperty(setting_key, property_name)
- ## Set the name of the specified container.
- @pyqtSlot(str, str, result = bool)
- def setContainerName(self, container_id, new_name):
- if self._container_registry.isReadOnly(container_id):
- Logger.log("w", "Cannot set name of read-only container %s.", container_id)
- return False
-
- containers = self._container_registry.findContainers(id = container_id) #We need to get the full container, not just metadata, since we need to know whether it's read-only.
- if not containers:
- Logger.log("w", "Could not set name of container %s because it was not found.", container_id)
- return False
-
- containers[0].setName(new_name)
-
- return True
-
- ## Find instance containers matching certain criteria.
- #
- # This effectively forwards to
- # ContainerRegistry::findInstanceContainersMetadata.
- #
- # \param criteria A dict of key - value pairs to search for.
- #
- # \return A list of container IDs that match the given criteria.
- @pyqtSlot("QVariantMap", result = "QVariantList")
- def findInstanceContainers(self, criteria):
- return [entry["id"] for entry in self._container_registry.findInstanceContainersMetadata(**criteria)]
-
- @pyqtSlot(str, result = bool)
- def isContainerUsed(self, container_id):
- Logger.log("d", "Checking if container %s is currently used", container_id)
- # check if this is a material container. If so, check if any material with the same base is being used by any
- # stacks.
- container_ids_to_check = [container_id]
- container_results = self._container_registry.findInstanceContainersMetadata(id = container_id, type = "material")
- if container_results:
- this_container = container_results[0]
- material_base_file = this_container["id"]
- if "base_file" in this_container:
- material_base_file = this_container["base_file"]
- # check all material container IDs with the same base
- material_containers = self._container_registry.findInstanceContainersMetadata(base_file = material_base_file,
- type = "material")
- if material_containers:
- container_ids_to_check = [container["id"] for container in material_containers]
-
- all_stacks = self._container_registry.findContainerStacks()
- for stack in all_stacks:
- for used_container_id in container_ids_to_check:
- if used_container_id in [child.getId() for child in stack.getContainers()]:
- Logger.log("d", "The container is in use by %s", stack.getId())
- return True
- return False
-
@pyqtSlot(str, result = str)
def makeUniqueName(self, original_name):
return self._container_registry.uniqueName(original_name)
@@ -399,7 +198,7 @@ class ContainerManager(QObject):
@pyqtSlot(str, str, QUrl, result = "QVariantMap")
def exportContainer(self, container_id: str, file_type: str, file_url_or_string: Union[QUrl, str]) -> Dict[str, str]:
if not container_id or not file_type or not file_url_or_string:
- return { "status": "error", "message": "Invalid arguments"}
+ return {"status": "error", "message": "Invalid arguments"}
if isinstance(file_url_or_string, QUrl):
file_url = file_url_or_string.toLocalFile()
@@ -407,20 +206,20 @@ class ContainerManager(QObject):
file_url = file_url_or_string
if not file_url:
- return { "status": "error", "message": "Invalid path"}
+ return {"status": "error", "message": "Invalid path"}
mime_type = None
- if not file_type in self._container_name_filters:
+ if file_type not in self._container_name_filters:
try:
mime_type = MimeTypeDatabase.getMimeTypeForFile(file_url)
except MimeTypeNotFoundError:
- return { "status": "error", "message": "Unknown File Type" }
+ return {"status": "error", "message": "Unknown File Type"}
else:
mime_type = self._container_name_filters[file_type]["mime"]
containers = self._container_registry.findContainers(id = container_id)
if not containers:
- return { "status": "error", "message": "Container not found"}
+ return {"status": "error", "message": "Container not found"}
container = containers[0]
if Platform.isOSX() and "." in file_url:
@@ -437,12 +236,12 @@ class ContainerManager(QObject):
result = QMessageBox.question(None, catalog.i18nc("@title:window", "File Already Exists"),
catalog.i18nc("@label Don't translate the XML tag !", "The file {0} already exists. Are you sure you want to overwrite it?").format(file_url))
if result == QMessageBox.No:
- return { "status": "cancelled", "message": "User cancelled"}
+ return {"status": "cancelled", "message": "User cancelled"}
try:
contents = container.serialize()
except NotImplementedError:
- return { "status": "error", "message": "Unable to serialize container"}
+ return {"status": "error", "message": "Unable to serialize container"}
if contents is None:
return {"status": "error", "message": "Serialization returned None. Unable to write to file"}
@@ -450,7 +249,7 @@ class ContainerManager(QObject):
with SaveFile(file_url, "w") as f:
f.write(contents)
- return { "status": "success", "message": "Succesfully exported container", "path": file_url}
+ return {"status": "success", "message": "Successfully exported container", "path": file_url}
## Imports a profile from a file
#
@@ -461,7 +260,7 @@ class ContainerManager(QObject):
@pyqtSlot(QUrl, result = "QVariantMap")
def importMaterialContainer(self, file_url_or_string: Union[QUrl, str]) -> Dict[str, str]:
if not file_url_or_string:
- return { "status": "error", "message": "Invalid path"}
+ return {"status": "error", "message": "Invalid path"}
if isinstance(file_url_or_string, QUrl):
file_url = file_url_or_string.toLocalFile()
@@ -469,16 +268,16 @@ class ContainerManager(QObject):
file_url = file_url_or_string
if not file_url or not os.path.exists(file_url):
- return { "status": "error", "message": "Invalid path" }
+ return {"status": "error", "message": "Invalid path"}
try:
mime_type = MimeTypeDatabase.getMimeTypeForFile(file_url)
except MimeTypeNotFoundError:
- return { "status": "error", "message": "Could not determine mime type of file" }
+ return {"status": "error", "message": "Could not determine mime type of file"}
container_type = self._container_registry.getContainerForMimeType(mime_type)
if not container_type:
- return { "status": "error", "message": "Could not find a container to handle the specified file."}
+ return {"status": "error", "message": "Could not find a container to handle the specified file."}
container_id = urllib.parse.unquote_plus(mime_type.stripExtension(os.path.basename(file_url)))
container_id = self._container_registry.uniqueName(container_id)
@@ -489,7 +288,7 @@ class ContainerManager(QObject):
with open(file_url, "rt", encoding = "utf-8") as f:
container.deserialize(f.read())
except PermissionError:
- return { "status": "error", "message": "Permission denied when trying to read the file"}
+ return {"status": "error", "message": "Permission denied when trying to read the file"}
except Exception as ex:
return {"status": "error", "message": str(ex)}
@@ -497,7 +296,7 @@ class ContainerManager(QObject):
self._container_registry.addContainer(container)
- return { "status": "success", "message": "Successfully imported container {0}".format(container.getName()) }
+ return {"status": "success", "message": "Successfully imported container {0}".format(container.getName())}
## Update the current active quality changes container with the settings from the user container.
#
@@ -522,7 +321,7 @@ class ContainerManager(QObject):
self._performMerge(quality_changes, stack.getTop())
- self._machine_manager.activeQualityChanged.emit()
+ self._machine_manager.activeQualityChangesGroupChanged.emit()
return True
@@ -535,414 +334,47 @@ class ContainerManager(QObject):
# Go through global and extruder stacks and clear their topmost container (the user settings).
for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
- container = stack.getTop()
+ container = stack.userChanges
container.clear()
send_emits_containers.append(container)
+ # user changes are possibly added to make the current setup match the current enabled extruders
+ Application.getInstance().getMachineManager().correctExtruderSettings()
+
for container in send_emits_containers:
container.sendPostponedEmits()
- ## Create quality changes containers from the user containers in the active stacks.
- #
- # This will go through the global and extruder stacks and create quality_changes containers from
- # the user containers in each stack. These then replace the quality_changes containers in the
- # stack and clear the user settings.
- #
- # \return \type{bool} True if the operation was successfully, False if not.
- @pyqtSlot(str, result = bool)
- def createQualityChanges(self, base_name):
- global_stack = Application.getInstance().getGlobalContainerStack()
- if not global_stack:
- return False
-
- active_quality_name = self._machine_manager.activeQualityName
- if active_quality_name == "":
- Logger.log("w", "No quality container found in stack %s, cannot create profile", global_stack.getId())
- return False
-
- self._machine_manager.blurSettings.emit()
- if base_name is None or base_name == "":
- base_name = active_quality_name
- unique_name = self._container_registry.uniqueName(base_name)
-
- # Go through the active stacks and create quality_changes containers from the user containers.
- for stack in ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks():
- user_container = stack.getTop()
- quality_container = stack.quality
- quality_changes_container = stack.qualityChanges
- if not quality_container or not quality_changes_container:
- Logger.log("w", "No quality or quality changes container found in stack %s, ignoring it", stack.getId())
- continue
-
- extruder_id = None if stack is global_stack else QualityManager.getInstance().getParentMachineDefinition(stack.getBottom()).getId()
- new_changes = self._createQualityChanges(quality_container, unique_name,
- Application.getInstance().getGlobalContainerStack().getBottom(),
- extruder_id)
- self._performMerge(new_changes, quality_changes_container, clear_settings = False)
- self._performMerge(new_changes, user_container)
-
- self._container_registry.addContainer(new_changes)
- stack.replaceContainer(stack.getContainerIndex(quality_changes_container), new_changes)
-
- self._machine_manager.activeQualityChanged.emit()
- return True
-
- ## Remove all quality changes containers matching a specified name.
- #
- # This will search for quality_changes containers matching the supplied name and remove them.
- # Note that if the machine specifies that qualities should be filtered by machine and/or material
- # only the containers related to the active machine/material are removed.
- #
- # \param quality_name The name of the quality changes to remove.
- #
- # \return \type{bool} True if successful, False if not.
- @pyqtSlot(str, result = bool)
- def removeQualityChanges(self, quality_name):
- Logger.log("d", "Attempting to remove the quality change containers with name %s", quality_name)
- containers_found = False
-
- if not quality_name:
- return containers_found # Without a name we will never find a container to remove.
-
- # If the container that is being removed is the currently active quality, set another quality as the active quality
- activate_quality = quality_name == self._machine_manager.activeQualityName
- activate_quality_type = None
-
- global_stack = Application.getInstance().getGlobalContainerStack()
- if not global_stack or not quality_name:
- return ""
- machine_definition = QualityManager.getInstance().getParentMachineDefinition(global_stack.getBottom())
-
- for container in QualityManager.getInstance().findQualityChangesByName(quality_name, machine_definition):
- containers_found = True
- if activate_quality and not activate_quality_type:
- activate_quality_type = container.getMetaDataEntry("quality")
- self._container_registry.removeContainer(container.getId())
-
- if not containers_found:
- Logger.log("d", "Unable to remove quality containers, as we did not find any by the name of %s", quality_name)
-
- elif activate_quality:
- definition_id = "fdmprinter" if not self._machine_manager.filterQualityByMachine else self._machine_manager.activeDefinitionId
- containers = self._container_registry.findInstanceContainersMetadata(type = "quality", definition = definition_id, quality_type = activate_quality_type)
- if containers:
- self._machine_manager.setActiveQuality(containers[0]["id"])
- self._machine_manager.activeQualityChanged.emit()
-
- return containers_found
-
- ## Rename a set of quality changes containers.
- #
- # This will search for quality_changes containers matching the supplied name and rename them.
- # Note that if the machine specifies that qualities should be filtered by machine and/or material
- # only the containers related to the active machine/material are renamed.
- #
- # \param quality_name The name of the quality changes containers to rename.
- # \param new_name The new name of the quality changes.
- #
- # \return True if successful, False if not.
- @pyqtSlot(str, str, result = bool)
- def renameQualityChanges(self, quality_name, new_name):
- Logger.log("d", "User requested QualityChanges container rename of %s to %s", quality_name, new_name)
- if not quality_name or not new_name:
- return False
-
- if quality_name == new_name:
- Logger.log("w", "Unable to rename %s to %s, because they are the same.", quality_name, new_name)
- return True
-
- global_stack = Application.getInstance().getGlobalContainerStack()
- if not global_stack:
- return False
-
- self._machine_manager.blurSettings.emit()
-
- new_name = self._container_registry.uniqueName(new_name)
-
- container_registry = self._container_registry
-
- containers_to_rename = self._container_registry.findInstanceContainersMetadata(type = "quality_changes", name = quality_name)
-
- for container in containers_to_rename:
- stack_id = global_stack.getId()
- if "extruder" in container:
- stack_id = container["extruder"]
- container_registry.renameContainer(container["id"], new_name, self._createUniqueId(stack_id, new_name))
-
- if not containers_to_rename:
- Logger.log("e", "Unable to rename %s, because we could not find the profile", quality_name)
-
- self._machine_manager.activeQualityChanged.emit()
- return True
-
- ## Duplicate a specified set of quality or quality_changes containers.
- #
- # This will search for containers matching the specified name. If the container is a "quality" type container, a new
- # quality_changes container will be created with the specified quality as base. If the container is a "quality_changes"
- # container, it is simply duplicated and renamed.
- #
- # \param quality_name The name of the quality to duplicate.
- #
- # \return A string containing the name of the duplicated containers, or an empty string if it failed.
- @pyqtSlot(str, str, result = str)
- def duplicateQualityOrQualityChanges(self, quality_name, base_name):
- global_stack = Application.getInstance().getGlobalContainerStack()
- if not global_stack or not quality_name:
- return ""
- machine_definition = global_stack.definition
-
- active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
- if active_stacks is None:
- return ""
- material_metadatas = [stack.material.getMetaData() for stack in active_stacks]
-
- result = self._duplicateQualityOrQualityChangesForMachineType(quality_name, base_name,
- QualityManager.getInstance().getParentMachineDefinition(machine_definition),
- material_metadatas)
- return result[0].getName() if result else ""
-
- ## Duplicate a quality or quality changes profile specific to a machine type
- #
- # \param quality_name The name of the quality or quality changes container to duplicate.
- # \param base_name The desired name for the new container.
- # \param machine_definition The machine with the specific machine type.
- # \param material_metadatas Metadata of materials
- # \return List of duplicated quality profiles.
- def _duplicateQualityOrQualityChangesForMachineType(self, quality_name: str, base_name: str, machine_definition: DefinitionContainer, material_metadatas: List[Dict[str, Any]]) -> List[InstanceContainer]:
- Logger.log("d", "Attempting to duplicate the quality %s", quality_name)
-
- if base_name is None:
- base_name = quality_name
- # Try to find a Quality with the name.
- container = QualityManager.getInstance().findQualityByName(quality_name, machine_definition, material_metadatas)
- if container:
- Logger.log("d", "We found a quality to duplicate.")
- return self._duplicateQualityForMachineType(container, base_name, machine_definition)
- Logger.log("d", "We found a quality_changes to duplicate.")
- # Assume it is a quality changes.
- return self._duplicateQualityChangesForMachineType(quality_name, base_name, machine_definition)
-
- # Duplicate a quality profile
- def _duplicateQualityForMachineType(self, quality_container, base_name, machine_definition) -> List[InstanceContainer]:
- if base_name is None:
- base_name = quality_container.getName()
- new_name = self._container_registry.uniqueName(base_name)
-
- new_change_instances = []
-
- # Handle the global stack first.
- global_changes = self._createQualityChanges(quality_container, new_name, machine_definition, None)
- new_change_instances.append(global_changes)
- self._container_registry.addContainer(global_changes)
-
- # Handle the extruders if present.
- extruders = machine_definition.getMetaDataEntry("machine_extruder_trains")
- if extruders:
- for extruder_id in extruders:
- extruder = extruders[extruder_id]
- new_changes = self._createQualityChanges(quality_container, new_name, machine_definition, extruder)
- new_change_instances.append(new_changes)
- self._container_registry.addContainer(new_changes)
-
- return new_change_instances
-
- # Duplicate a quality changes container
- def _duplicateQualityChangesForMachineType(self, quality_changes_name, base_name, machine_definition) -> List[InstanceContainer]:
- new_change_instances = []
- for container in QualityManager.getInstance().findQualityChangesByName(quality_changes_name,
- machine_definition):
- base_id = container.getMetaDataEntry("extruder")
- if not base_id:
- base_id = container.getDefinition().getId()
- new_unique_id = self._createUniqueId(base_id, base_name)
- new_container = container.duplicate(new_unique_id, base_name)
- new_change_instances.append(new_container)
- self._container_registry.addContainer(new_container)
-
- return new_change_instances
-
- ## Create a duplicate of a material, which has the same GUID and base_file metadata
- #
- # \return \type{str} the id of the newly created container.
- @pyqtSlot(str, result = str)
- def duplicateMaterial(self, material_id: str) -> str:
- original = self._container_registry.findContainersMetadata(id = material_id)
- if not original:
- Logger.log("d", "Unable to duplicate the material with id %s, because it doesn't exist.", material_id)
- return ""
- original = original[0]
-
- base_container_id = original.get("base_file")
- base_container = self._container_registry.findContainers(id = base_container_id)
- if not base_container:
- Logger.log("d", "Unable to duplicate the material with id {material_id}, because base_file {base_container_id} doesn't exist.".format(material_id = material_id, base_container_id = base_container_id))
- return ""
- base_container = base_container[0]
-
- #We'll copy all containers with the same base.
- #This way the correct variant and machine still gets assigned when loading the copy of the material.
- containers_to_copy = self._container_registry.findInstanceContainers(base_file = base_container_id)
-
- # Ensure all settings are saved.
- Application.getInstance().saveSettings()
-
- # Create a new ID & container to hold the data.
- new_containers = []
- new_base_id = self._container_registry.uniqueName(base_container.getId())
- new_base_container = copy.deepcopy(base_container)
- new_base_container.getMetaData()["id"] = new_base_id
- new_base_container.getMetaData()["base_file"] = new_base_id
- new_containers.append(new_base_container)
-
- #Clone all of them.
- clone_of_original = None #Keeping track of which one is the clone of the original material, since we need to return that.
- for container_to_copy in containers_to_copy:
- #Create unique IDs for every clone.
- current_id = container_to_copy.getId()
- new_id = new_base_id
- if container_to_copy.getMetaDataEntry("definition") != "fdmprinter":
- new_id += "_" + container_to_copy.getMetaDataEntry("definition")
- if container_to_copy.getMetaDataEntry("variant"):
- variant = self._container_registry.findContainers(id = container_to_copy.getMetaDataEntry("variant"))[0]
- new_id += "_" + variant.getName().replace(" ", "_")
- if current_id == material_id:
- clone_of_original = new_id
-
- new_container = copy.deepcopy(container_to_copy)
- new_container.getMetaData()["id"] = new_id
- new_container.getMetaData()["base_file"] = new_base_id
- new_containers.append(new_container)
-
- for container_to_add in new_containers:
- container_to_add.setDirty(True)
- ContainerRegistry.getInstance().addContainer(container_to_add)
- return self._getMaterialContainerIdForActiveMachine(clone_of_original)
-
- ## Create a duplicate of a material or it's original entry
- #
- # \return \type{str} the id of the newly created container.
- @pyqtSlot(str, result = str)
- def duplicateOriginalMaterial(self, material_id):
-
- # check if the given material has a base file (i.e. was shipped by default)
- base_file = self.getContainerMetaDataEntry(material_id, "base_file")
-
- if base_file == "":
- # there is no base file, so duplicate by ID
- return self.duplicateMaterial(material_id)
- else:
- # there is a base file, so duplicate the original material
- return self.duplicateMaterial(base_file)
-
- ## Create a new material by cloning Generic PLA for the current material diameter and setting the GUID to something unqiue
- #
- # \return \type{str} the id of the newly created container.
- @pyqtSlot(result = str)
- def createMaterial(self) -> str:
- # Ensure all settings are saved.
- Application.getInstance().saveSettings()
-
- global_stack = Application.getInstance().getGlobalContainerStack()
- if not global_stack:
- return ""
-
- approximate_diameter = str(round(global_stack.getProperty("material_diameter", "value")))
- containers = self._container_registry.findInstanceContainersMetadata(id = "generic_pla*", approximate_diameter = approximate_diameter)
- if not containers:
- Logger.log("d", "Unable to create a new material by cloning Generic PLA, because it cannot be found for the material diameter for this machine.")
- return ""
-
- base_file = containers[0].get("base_file")
- containers = self._container_registry.findInstanceContainers(id = base_file)
- if not containers:
- Logger.log("d", "Unable to create a new material by cloning Generic PLA, because the base file for Generic PLA for this machine can not be found.")
- return ""
-
- # Create a new ID & container to hold the data.
- new_id = self._container_registry.uniqueName("custom_material")
- container_type = type(containers[0]) # Always XMLMaterialProfile, since we specifically clone the base_file
- duplicated_container = container_type(new_id)
-
- # Instead of duplicating we load the data from the basefile again.
- # This ensures that the inheritance goes well and all "cut up" subclasses of the xmlMaterial profile
- # are also correctly created.
- with open(containers[0].getPath(), encoding="utf-8") as f:
- duplicated_container.deserialize(f.read())
-
- duplicated_container.setMetaDataEntry("GUID", str(uuid.uuid4()))
- duplicated_container.setMetaDataEntry("brand", catalog.i18nc("@label", "Custom"))
- # We're defaulting to PLA, as machines with material profiles don't like material types they don't know.
- # TODO: This is a hack, the only reason this is in now is to bandaid the problem as we're close to a release!
- duplicated_container.setMetaDataEntry("material", "PLA")
- duplicated_container.setName(catalog.i18nc("@label", "Custom Material"))
-
- self._container_registry.addContainer(duplicated_container)
- return self._getMaterialContainerIdForActiveMachine(new_id)
-
- ## Find the id of a material container based on the new material
- # Utilty function that is shared between duplicateMaterial and createMaterial
- #
- # \param base_file \type{str} the id of the created container.
- def _getMaterialContainerIdForActiveMachine(self, base_file):
- global_stack = Application.getInstance().getGlobalContainerStack()
- if not global_stack:
- return base_file
-
- has_machine_materials = parseBool(global_stack.getMetaDataEntry("has_machine_materials", default = False))
- has_variant_materials = parseBool(global_stack.getMetaDataEntry("has_variant_materials", default = False))
- has_variants = parseBool(global_stack.getMetaDataEntry("has_variants", default = False))
- if has_machine_materials or has_variant_materials:
- if has_variants:
- materials = self._container_registry.findInstanceContainersMetadata(type = "material", base_file = base_file, definition = global_stack.getBottom().getId(), variant = self._machine_manager.activeVariantId)
- else:
- materials = self._container_registry.findInstanceContainersMetadata(type = "material", base_file = base_file, definition = global_stack.getBottom().getId())
-
- if materials:
- return materials[0]["id"]
-
- Logger.log("w", "Unable to find a suitable container based on %s for the current machine.", base_file)
- return "" # do not activate a new material if a container can not be found
-
- return base_file
-
## Get a list of materials that have the same GUID as the reference material
#
# \param material_id \type{str} the id of the material for which to get the linked materials.
# \return \type{list} a list of names of materials with the same GUID
- @pyqtSlot(str, result = "QStringList")
- def getLinkedMaterials(self, material_id: str):
- containers = self._container_registry.findInstanceContainersMetadata(id = material_id)
- if not containers:
- Logger.log("d", "Unable to find materials linked to material with id %s, because it doesn't exist.", material_id)
- return []
+ @pyqtSlot("QVariant", result = "QStringList")
+ def getLinkedMaterials(self, material_node):
+ guid = material_node.metadata["GUID"]
- material_container = containers[0]
- material_base_file = material_container.get("base_file", "")
- material_guid = material_container.get("GUID", "")
- if not material_guid:
- Logger.log("d", "Unable to find materials linked to material with id %s, because it doesn't have a GUID.", material_id)
- return []
+ material_group_list = self._material_manager.getMaterialGroupListByGUID(guid)
- containers = self._container_registry.findInstanceContainersMetadata(type = "material", GUID = material_guid)
linked_material_names = []
- for container in containers:
- if container["id"] in [material_id, material_base_file] or container.get("base_file") != container["id"]:
- continue
-
- linked_material_names.append(container["name"])
+ if material_group_list:
+ for material_group in material_group_list:
+ linked_material_names.append(material_group.root_material_node.metadata["name"])
return linked_material_names
## Unlink a material from all other materials by creating a new GUID
# \param material_id \type{str} the id of the material to create a new GUID for.
- @pyqtSlot(str)
- def unlinkMaterial(self, material_id: str):
- containers = self._container_registry.findInstanceContainers(id=material_id)
- if not containers:
- Logger.log("d", "Unable to make the material with id %s unique, because it doesn't exist.", material_id)
- return ""
+ @pyqtSlot("QVariant")
+ def unlinkMaterial(self, material_node):
+ # Get the material group
+ material_group = self._material_manager.getMaterialGroup(material_node.metadata["base_file"])
- containers[0].setMetaDataEntry("GUID", str(uuid.uuid4()))
+ # Generate a new GUID
+ new_guid = str(uuid.uuid4())
+ # Update the GUID
+ # NOTE: We only need to set the root material container because XmlMaterialProfile.setMetaDataEntry() will
+ # take care of the derived containers too
+ container = material_group.root_material_node.getContainer()
+ container.setMetaDataEntry("GUID", new_guid)
## Get the singleton instance for this class.
@classmethod
@@ -960,8 +392,6 @@ class ContainerManager(QObject):
return ContainerManager.getInstance()
def _performMerge(self, merge_into, merge, clear_settings = True):
- assert isinstance(merge, type(merge_into))
-
if merge == merge_into:
return
@@ -1015,81 +445,6 @@ class ContainerManager(QObject):
name_filter = "{0} ({1})".format(mime_type.comment, suffix_list)
self._container_name_filters[name_filter] = entry
- ## Creates a unique ID for a container by prefixing the name with the stack ID.
- #
- # This method creates a unique ID for a container by prefixing it with a specified stack ID.
- # This is done to ensure we have an easily identified ID for quality changes, which have the
- # same name across several stacks.
- #
- # \param stack_id The ID of the stack to prepend.
- # \param container_name The name of the container that we are creating a unique ID for.
- #
- # \return Container name prefixed with stack ID, in lower case with spaces replaced by underscores.
- def _createUniqueId(self, stack_id, container_name):
- result = stack_id + "_" + container_name
- result = result.lower()
- result.replace(" ", "_")
- return result
-
- ## Create a quality changes container for a specified quality container.
- #
- # \param quality_container The quality container to create a changes container for.
- # \param new_name The name of the new quality_changes container.
- # \param machine_definition The machine definition this quality changes container is specific to.
- # \param extruder_id
- #
- # \return A new quality_changes container with the specified container as base.
- def _createQualityChanges(self, quality_container, new_name, machine_definition, extruder_id):
- base_id = machine_definition.getId() if extruder_id is None else extruder_id
-
- # Create a new quality_changes container for the quality.
- quality_changes = InstanceContainer(self._createUniqueId(base_id, new_name))
- quality_changes.setName(new_name)
- quality_changes.addMetaDataEntry("type", "quality_changes")
- quality_changes.addMetaDataEntry("quality_type", quality_container.getMetaDataEntry("quality_type"))
-
- # If we are creating a container for an extruder, ensure we add that to the container
- if extruder_id is not None:
- quality_changes.addMetaDataEntry("extruder", extruder_id)
-
- # If the machine specifies qualities should be filtered, ensure we match the current criteria.
- if not machine_definition.getMetaDataEntry("has_machine_quality"):
- quality_changes.setDefinition("fdmprinter")
- else:
- quality_changes.setDefinition(QualityManager.getInstance().getParentMachineDefinition(machine_definition).getId())
-
- from cura.CuraApplication import CuraApplication
- quality_changes.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
- return quality_changes
-
-
- ## Import profiles from a list of file_urls.
- # Each QUrl item must end with .curaprofile, or it will not be imported.
- #
- # \param QVariant, essentially a list with QUrl objects.
- # \return Dict with keys status, text
- @pyqtSlot("QVariantList", result="QVariantMap")
- def importProfiles(self, file_urls):
- status = "ok"
- results = {"ok": [], "error": []}
- for file_url in file_urls:
- if not file_url.isValid():
- continue
- path = file_url.toLocalFile()
- if not path:
- continue
- if not path.endswith(".curaprofile"):
- continue
-
- single_result = self._container_registry.importProfile(path)
- if single_result["status"] == "error":
- status = "error"
- results[single_result["status"]].append(single_result["message"])
-
- return {
- "status": status,
- "message": "\n".join(results["ok"] + results["error"])}
-
## Import single profile, file_url does not have to end with curaprofile
@pyqtSlot(QUrl, result="QVariantMap")
def importProfile(self, file_url):
@@ -1100,11 +455,13 @@ class ContainerManager(QObject):
return
return self._container_registry.importProfile(path)
- @pyqtSlot("QVariantList", QUrl, str)
- def exportProfile(self, instance_id: str, file_url: QUrl, file_type: str) -> None:
+ @pyqtSlot(QObject, QUrl, str)
+ def exportQualityChangesGroup(self, quality_changes_group, file_url: QUrl, file_type: str):
if not file_url.isValid():
return
path = file_url.toLocalFile()
if not path:
return
- self._container_registry.exportProfile(instance_id, path, file_type)
+
+ container_list = [n.getContainer() for n in quality_changes_group.getAllNodes()]
+ self._container_registry.exportQualityProfile(container_list, path, file_type)
diff --git a/cura/Settings/ContainerSettingsModel.py b/cura/Settings/ContainerSettingsModel.py
deleted file mode 100644
index 2c4bef6464..0000000000
--- a/cura/Settings/ContainerSettingsModel.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright (c) 2016 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from UM.Application import Application
-from UM.Qt.ListModel import ListModel
-
-from PyQt5.QtCore import pyqtProperty, Qt, pyqtSignal, pyqtSlot, QUrl
-
-from UM.Settings.ContainerRegistry import ContainerRegistry
-from UM.Settings.InstanceContainer import InstanceContainer
-from UM.Settings.SettingFunction import SettingFunction
-
-class ContainerSettingsModel(ListModel):
- LabelRole = Qt.UserRole + 1
- CategoryRole = Qt.UserRole + 2
- UnitRole = Qt.UserRole + 3
- ValuesRole = Qt.UserRole + 4
-
- def __init__(self, parent = None):
- super().__init__(parent)
- self.addRoleName(self.LabelRole, "label")
- self.addRoleName(self.CategoryRole, "category")
- self.addRoleName(self.UnitRole, "unit")
- self.addRoleName(self.ValuesRole, "values")
-
- self._container_ids = []
- self._containers = []
-
- def _onPropertyChanged(self, key, property_name):
- if property_name == "value":
- self._update()
-
- def _update(self):
- items = []
-
- if len(self._container_ids) == 0:
- return
-
- keys = []
- for container in self._containers:
- keys = keys + list(container.getAllKeys())
-
- keys = list(set(keys)) # remove duplicate keys
-
- for key in keys:
- definition = None
- category = None
- values = []
- for container in self._containers:
- instance = container.getInstance(key)
- if instance:
- definition = instance.definition
-
- # Traverse up to find the category
- category = definition
- while category.type != "category":
- category = category.parent
-
- value = container.getProperty(key, "value")
- if type(value) == SettingFunction:
- values.append("=\u0192")
- else:
- values.append(container.getProperty(key, "value"))
- else:
- values.append("")
-
- items.append({
- "key": key,
- "values": values,
- "label": definition.label,
- "unit": definition.unit,
- "category": category.label
- })
- items.sort(key = lambda k: (k["category"], k["key"]))
- self.setItems(items)
-
- ## Set the ids of the containers which have the settings this model should list.
- # Also makes sure the model updates when the containers have property changes
- def setContainers(self, container_ids):
- for container in self._containers:
- container.propertyChanged.disconnect(self._onPropertyChanged)
-
- self._container_ids = container_ids
- self._containers = []
-
- for container_id in self._container_ids:
- containers = ContainerRegistry.getInstance().findContainers(id = container_id)
- if containers:
- containers[0].propertyChanged.connect(self._onPropertyChanged)
- self._containers.append(containers[0])
-
- self._update()
-
- containersChanged = pyqtSignal()
- @pyqtProperty("QVariantList", fset = setContainers, notify = containersChanged)
- def containers(self):
- return self.container_ids
diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py
index 148ed6fe59..828897b4dd 100644
--- a/cura/Settings/CuraContainerRegistry.py
+++ b/cura/Settings/CuraContainerRegistry.py
@@ -25,14 +25,16 @@ from UM.Resources import Resources
from . import ExtruderStack
from . import GlobalStack
-from .ContainerManager import ContainerManager
from .ExtruderManager import ExtruderManager
from cura.CuraApplication import CuraApplication
+from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
+from cura.ProfileReader import NoProfileException
from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
+
class CuraContainerRegistry(ContainerRegistry):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -102,7 +104,7 @@ class CuraContainerRegistry(ContainerRegistry):
# \param instance_ids \type{list} the IDs of the profiles to export.
# \param file_name \type{str} the full path and filename to export to.
# \param file_type \type{str} the file type with the format " (*.)"
- def exportProfile(self, instance_ids, file_name, file_type):
+ def exportQualityProfile(self, container_list, file_name, file_type):
# Parse the fileType to deduce what plugin can save the file format.
# fileType has the format " (*.)"
split = file_type.rfind(" (*.") # Find where the description ends and the extension starts.
@@ -121,31 +123,10 @@ class CuraContainerRegistry(ContainerRegistry):
catalog.i18nc("@label Don't translate the XML tag !", "The file {0} already exists. Are you sure you want to overwrite it?").format(file_name))
if result == QMessageBox.No:
return
- found_containers = []
- extruder_positions = []
- for instance_id in instance_ids:
- containers = ContainerRegistry.getInstance().findInstanceContainers(id = instance_id)
- if containers:
- found_containers.append(containers[0])
-
- # Determine the position of the extruder of this container
- extruder_id = containers[0].getMetaDataEntry("extruder", "")
- if extruder_id == "":
- # Global stack
- extruder_positions.append(-1)
- else:
- extruder_containers = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = extruder_id)
- if extruder_containers:
- extruder_positions.append(int(extruder_containers[0].get("position", 0)))
- else:
- extruder_positions.append(0)
- # Ensure the profiles are always exported in order (global, extruder 0, extruder 1, ...)
- found_containers = [containers for (positions, containers) in sorted(zip(extruder_positions, found_containers))]
profile_writer = self._findProfileWriter(extension, description)
-
try:
- success = profile_writer.write(file_name, found_containers)
+ success = profile_writer.write(file_name, container_list)
except Exception as e:
Logger.log("e", "Failed to export profile to %s: %s", file_name, str(e))
m = Message(catalog.i18nc("@info:status Don't translate the XML tags or !", "Failed to export profile to {0}: {1}", file_name, str(e)),
@@ -205,6 +186,8 @@ class CuraContainerRegistry(ContainerRegistry):
profile_reader = plugin_registry.getPluginObject(plugin_id)
try:
profile_or_list = profile_reader.read(file_name) # Try to open the file with the profile reader.
+ except NoProfileException:
+ return { "status": "ok", "message": catalog.i18nc("@info:status Don't translate the XML tags or !", "No custom profile to import in file {0}", file_name)}
except Exception as e:
# Note that this will fail quickly. That is, if any profile reader throws an exception, it will stop reading. It will only continue reading if the reader returned None.
Logger.log("e", "Failed to import profile from %s: %s while using profile reader. Got exception %s", file_name,profile_reader.getPluginId(), str(e))
@@ -235,9 +218,9 @@ class CuraContainerRegistry(ContainerRegistry):
if not expected_machine_definition:
expected_machine_definition = global_container_stack.definition.getId()
if expected_machine_definition is not None and profile_definition is not None and profile_definition != expected_machine_definition:
- Logger.log("e", "Profile [%s] is for machine [%s] but the current active machine is [%s]. Will not import the profile", file_name)
+ Logger.log("e", "Profile [%s] is for machine [%s] but the current active machine is [%s]. Will not import the profile", file_name, profile_definition, expected_machine_definition)
return { "status": "error",
- "message": catalog.i18nc("@info:status Don't translate the XML tags or !", "The machine defined in profile {0} doesn't match with your current machine, could not import it.", file_name)}
+ "message": catalog.i18nc("@info:status Don't translate the XML tags or !", "The machine defined in profile {0} ({1}) doesn't match with your current machine ({2}), could not import it.", file_name, profile_definition, expected_machine_definition)}
name_seed = os.path.splitext(os.path.basename(file_name))[0]
new_name = self.uniqueName(name_seed)
@@ -258,7 +241,7 @@ class CuraContainerRegistry(ContainerRegistry):
profile.addMetaDataEntry("type", "quality_changes")
profile.addMetaDataEntry("definition", global_profile.getMetaDataEntry("definition"))
profile.addMetaDataEntry("quality_type", global_profile.getMetaDataEntry("quality_type"))
- profile.addMetaDataEntry("extruder", extruder.getId())
+ profile.addMetaDataEntry("position", "0")
profile.setDirty(True)
if idx == 0:
# move all per-extruder settings to the first extruder's quality_changes
@@ -289,11 +272,12 @@ class CuraContainerRegistry(ContainerRegistry):
elif profile_index < len(machine_extruders) + 1:
# This is assumed to be an extruder profile
- extruder_id = Application.getInstance().getMachineManager().getQualityDefinitionId(machine_extruders[profile_index - 1].getBottom())
- if not profile.getMetaDataEntry("extruder"):
- profile.addMetaDataEntry("extruder", extruder_id)
+ extruder_id = machine_extruders[profile_index - 1].definition.getId()
+ extuder_position = str(profile_index - 1)
+ if not profile.getMetaDataEntry("position"):
+ profile.addMetaDataEntry("position", extuder_position)
else:
- profile.setMetaDataEntry("extruder", extruder_id)
+ profile.setMetaDataEntry("position", extuder_position)
profile_id = (extruder_id + "_" + name_seed).lower().replace(" ", "_")
else: #More extruders in the imported file than in the machine.
@@ -348,39 +332,16 @@ class CuraContainerRegistry(ContainerRegistry):
return catalog.i18nc("@info:status", "Profile is missing a quality type.")
quality_type_criteria = {"quality_type": quality_type}
- if self._machineHasOwnQualities():
- profile.setDefinition(self._activeQualityDefinition().getId())
- if self._machineHasOwnMaterials():
- active_material_id = self._activeMaterialId()
- if active_material_id and active_material_id != "empty": # only update if there is an active material
- profile.addMetaDataEntry("material", active_material_id)
- quality_type_criteria["material"] = active_material_id
-
- quality_type_criteria["definition"] = profile.getDefinition().getId()
-
- else:
- profile.setDefinition("fdmprinter")
- quality_type_criteria["definition"] = "fdmprinter"
-
- machine_definition = Application.getInstance().getGlobalContainerStack().getBottom()
- del quality_type_criteria["definition"]
-
- # materials = None
-
- if "material" in quality_type_criteria:
- # materials = ContainerRegistry.getInstance().findInstanceContainers(id = quality_type_criteria["material"])
- del quality_type_criteria["material"]
-
- # Do not filter quality containers here with materials because we are trying to import a profile, so it should
- # NOT be restricted by the active materials on the current machine.
- materials = None
+ global_stack = Application.getInstance().getGlobalContainerStack()
+ definition_id = getMachineDefinitionIDForQualitySearch(global_stack)
+ profile.setDefinition(definition_id)
# Check to make sure the imported profile actually makes sense in context of the current configuration.
# This prevents issues where importing a "draft" profile for a machine without "draft" qualities would report as
# successfully imported but then fail to show up.
- from cura.QualityManager import QualityManager
- qualities = QualityManager.getInstance()._getFilteredContainersForStack(machine_definition, materials, **quality_type_criteria)
- if not qualities:
+ quality_manager = CuraApplication.getInstance()._quality_manager
+ quality_group_dict = quality_manager.getQualityGroupsForMachineDefinition(global_stack)
+ if quality_type not in quality_group_dict:
return catalog.i18nc("@info:status", "Could not find a quality type {0} for the current configuration.", quality_type)
ContainerRegistry.getInstance().addContainer(profile)
@@ -400,18 +361,6 @@ class CuraContainerRegistry(ContainerRegistry):
result.append( (plugin_id, meta_data) )
return result
- ## Get the definition to use to select quality profiles for the active machine
- # \return the active quality definition object or None if there is no quality definition
- def _activeQualityDefinition(self):
- global_container_stack = Application.getInstance().getGlobalContainerStack()
- if global_container_stack:
- definition_id = Application.getInstance().getMachineManager().getQualityDefinitionId(global_container_stack.getBottom())
- definition = self.findDefinitionContainers(id = definition_id)[0]
-
- if definition:
- return definition
- return None
-
## Returns true if the current machine requires its own materials
# \return True if the current machine requires its own materials
def _machineHasOwnMaterials(self):
@@ -507,8 +456,6 @@ class CuraContainerRegistry(ContainerRegistry):
extruder_stack.setDefinition(extruder_definition)
extruder_stack.addMetaDataEntry("position", extruder_definition.getMetaDataEntry("position"))
- from cura.CuraApplication import CuraApplication
-
# create a new definition_changes container for the extruder stack
definition_changes_id = self.uniqueName(extruder_stack.getId() + "_settings") if create_new_ids else extruder_stack.getId() + "_settings"
definition_changes_name = definition_changes_id
@@ -567,26 +514,28 @@ class CuraContainerRegistry(ContainerRegistry):
self.addContainer(user_container)
extruder_stack.setUserChanges(user_container)
- variant_id = "default"
+ application = CuraApplication.getInstance()
+ empty_variant = application.empty_variant_container
+ empty_material = application.empty_material_container
+ empty_quality = application.empty_quality_container
+
if machine.variant.getId() not in ("empty", "empty_variant"):
- variant_id = machine.variant.getId()
+ variant = machine.variant
else:
- variant_id = "empty_variant"
- extruder_stack.setVariantById(variant_id)
+ variant = empty_variant
+ extruder_stack.variant = variant
- material_id = "default"
if machine.material.getId() not in ("empty", "empty_material"):
- material_id = machine.material.getId()
+ material = machine.material
else:
- material_id = "empty_material"
- extruder_stack.setMaterialById(material_id)
+ material = empty_material
+ extruder_stack.material = material
- quality_id = "default"
if machine.quality.getId() not in ("empty", "empty_quality"):
- quality_id = machine.quality.getId()
+ quality = machine.quality
else:
- quality_id = "empty_quality"
- extruder_stack.setQualityById(quality_id)
+ quality = empty_quality
+ extruder_stack.quality = quality
machine_quality_changes = machine.qualityChanges
if new_global_quality_changes is not None:
@@ -598,7 +547,7 @@ class CuraContainerRegistry(ContainerRegistry):
extruder_quality_changes_container = extruder_quality_changes_container[0]
quality_changes_id = extruder_quality_changes_container.getId()
- extruder_stack.setQualityChangesById(quality_changes_id)
+ extruder_stack.qualityChanges = self.findInstanceContainers(id = quality_changes_id)[0]
else:
# Some extruder quality_changes containers can be created at runtime as files in the qualities
# folder. Those files won't be loaded in the registry immediately. So we also need to search
@@ -607,7 +556,7 @@ class CuraContainerRegistry(ContainerRegistry):
if extruder_quality_changes_container:
quality_changes_id = extruder_quality_changes_container.getId()
extruder_quality_changes_container.addMetaDataEntry("extruder", extruder_stack.definition.getId())
- extruder_stack.setQualityChangesById(quality_changes_id)
+ extruder_stack.qualityChanges = self.findInstanceContainers(id = quality_changes_id)[0]
else:
# if we still cannot find a quality changes container for the extruder, create a new one
container_name = machine_quality_changes.getName()
@@ -642,7 +591,7 @@ class CuraContainerRegistry(ContainerRegistry):
machine_quality_changes.removeInstance(qc_setting_key, postpone_emit=True)
else:
- extruder_stack.setQualityChangesById("empty_quality_changes")
+ extruder_stack.qualityChanges = self.findInstanceContainers(id = "empty_quality_changes")[0]
self.addContainer(extruder_stack)
diff --git a/cura/Settings/CuraContainerStack.py b/cura/Settings/CuraContainerStack.py
index b97bb3314e..00db4f57c7 100755
--- a/cura/Settings/CuraContainerStack.py
+++ b/cura/Settings/CuraContainerStack.py
@@ -83,20 +83,6 @@ class CuraContainerStack(ContainerStack):
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.
- #
- # This will search for the specified container and set it. If no container was found, an error will be raised.
- #
- # \param new_quality_changes_id The ID of the new quality changes container.
- #
- # \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
- def setQualityChangesById(self, new_quality_changes_id: str) -> None:
- quality_changes = ContainerRegistry.getInstance().findInstanceContainers(id = new_quality_changes_id)
- if quality_changes:
- self.setQualityChanges(quality_changes[0])
- else:
- raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_quality_changes_id))
-
## Get the quality changes container.
#
# \return The quality changes container. Should always be a valid container, but can be equal to the empty InstanceContainer.
@@ -110,31 +96,6 @@ class CuraContainerStack(ContainerStack):
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.
- #
- # This will search for the specified container and set it. If no container was found, an error will be raised.
- # There is a special value for ID, which is "default". The "default" value indicates the quality should be set
- # to whatever the machine definition specifies as "preferred" container, or a fallback value. See findDefaultQuality
- # for details.
- #
- # \param new_quality_id The ID of the new quality container.
- #
- # \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
- def setQualityById(self, new_quality_id: str) -> None:
- quality = self._empty_quality
- if new_quality_id == "default":
- new_quality = self.findDefaultQuality()
- if new_quality:
- quality = new_quality
- else:
- qualities = ContainerRegistry.getInstance().findInstanceContainers(id = new_quality_id)
- if qualities:
- quality = qualities[0]
- else:
- raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_quality_id))
-
- self.setQuality(quality)
-
## Get the quality container.
#
# \return The quality container. Should always be a valid container, but can be equal to the empty InstanceContainer.
@@ -148,31 +109,6 @@ class CuraContainerStack(ContainerStack):
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.
- #
- # This will search for the specified container and set it. If no container was found, an error will be raised.
- # There is a special value for ID, which is "default". The "default" value indicates the quality should be set
- # to whatever the machine definition specifies as "preferred" container, or a fallback value. See findDefaultMaterial
- # for details.
- #
- # \param new_material_id The ID of the new material container.
- #
- # \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
- def setMaterialById(self, new_material_id: str) -> None:
- material = self._empty_material
- if new_material_id == "default":
- new_material = self.findDefaultMaterial()
- if new_material:
- material = new_material
- else:
- materials = ContainerRegistry.getInstance().findInstanceContainers(id = new_material_id)
- if materials:
- material = materials[0]
- else:
- raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_material_id))
-
- self.setMaterial(material)
-
## Get the material container.
#
# \return The material container. Should always be a valid container, but can be equal to the empty InstanceContainer.
@@ -186,31 +122,6 @@ class CuraContainerStack(ContainerStack):
def setVariant(self, new_variant: InstanceContainer) -> None:
self.replaceContainer(_ContainerIndexes.Variant, new_variant)
- ## Set the variant container by an ID.
- #
- # This will search for the specified container and set it. If no container was found, an error will be raised.
- # There is a special value for ID, which is "default". The "default" value indicates the quality should be set
- # to whatever the machine definition specifies as "preferred" container, or a fallback value. See findDefaultVariant
- # for details.
- #
- # \param new_variant_id The ID of the new variant container.
- #
- # \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
- def setVariantById(self, new_variant_id: str) -> None:
- variant = self._empty_variant
- if new_variant_id == "default":
- new_variant = self.findDefaultVariantBuildplate() if self.getMetaDataEntry("type") == "machine" else self.findDefaultVariant()
- if new_variant:
- variant = new_variant
- else:
- variants = ContainerRegistry.getInstance().findInstanceContainers(id = new_variant_id)
- if variants:
- variant = variants[0]
- else:
- raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_variant_id))
-
- self.setVariant(variant)
-
## Get the variant container.
#
# \return The variant container. Should always be a valid container, but can be equal to the empty InstanceContainer.
@@ -224,18 +135,6 @@ class CuraContainerStack(ContainerStack):
def setDefinitionChanges(self, new_definition_changes: InstanceContainer) -> None:
self.replaceContainer(_ContainerIndexes.DefinitionChanges, new_definition_changes)
- ## Set the definition changes container by an ID.
- #
- # \param new_definition_changes_id The ID of the new definition changes container.
- #
- # \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
- def setDefinitionChangesById(self, new_definition_changes_id: str) -> None:
- new_definition_changes = ContainerRegistry.getInstance().findInstanceContainers(id = new_definition_changes_id)
- if new_definition_changes:
- self.setDefinitionChanges(new_definition_changes[0])
- else:
- raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_definition_changes_id))
-
## Get the definition changes container.
#
# \return The definition changes container. Should always be a valid container, but can be equal to the empty InstanceContainer.
@@ -249,18 +148,6 @@ class CuraContainerStack(ContainerStack):
def setDefinition(self, new_definition: DefinitionContainerInterface) -> None:
self.replaceContainer(_ContainerIndexes.Definition, new_definition)
- ## Set the definition container by an ID.
- #
- # \param new_definition_id The ID of the new definition container.
- #
- # \throws Exceptions.InvalidContainerError Raised when no container could be found with the specified ID.
- def setDefinitionById(self, new_definition_id: str) -> None:
- new_definition = ContainerRegistry.getInstance().findDefinitionContainers(id = new_definition_id)
- if new_definition:
- self.setDefinition(new_definition[0])
- else:
- raise Exceptions.InvalidContainerError("Could not find container with id {id}".format(id = new_definition_id))
-
## Get the definition container.
#
# \return The definition container. Should always be a valid container, but can be equal to the empty InstanceContainer.
@@ -348,6 +235,10 @@ class CuraContainerStack(ContainerStack):
elif container != self._empty_instance_container and container.getMetaDataEntry("type") != expected_type:
raise Exceptions.InvalidContainerError("Cannot replace container at index {index} with a container that is not of {type} type, but {actual_type} type.".format(index = index, type = expected_type, actual_type = container.getMetaDataEntry("type")))
+ current_container = self._containers[index]
+ if current_container.getId() == container.getId():
+ return
+
super().replaceContainer(index, container, postpone_emit)
## Overridden from ContainerStack
@@ -391,243 +282,6 @@ class CuraContainerStack(ContainerStack):
self._containers = new_containers
- ## Find the variant that should be used as "default" variant.
- #
- # This will search for variants that match the current definition and pick the preferred one,
- # if specified by the machine definition.
- #
- # The following criteria are used to find the default variant:
- # - If the machine definition does not have a metadata entry "has_variants" set to True, return None
- # - The definition of the variant should be the same as the machine definition for this stack.
- # - The container should have a metadata entry "type" with value "variant".
- # - If the machine definition has a metadata entry "preferred_variant", filter the variant IDs based on that.
- #
- # \return The container that should be used as default, or None if nothing was found or the machine does not use variants.
- #
- # \note This method assumes the stack has a valid machine definition.
- def findDefaultVariant(self) -> Optional[ContainerInterface]:
- definition = self._getMachineDefinition()
- # has_variants can be overridden in other containers and stacks.
- # In the case of UM2, it is overridden in the GlobalStack
- if not self.getMetaDataEntry("has_variants"):
- # If the machine does not use variants, we should never set a variant.
- return None
-
- # First add any variant. Later, overwrite with preference if the preference is valid.
- variant = None
- definition_id = self._findInstanceContainerDefinitionId(definition)
- variants = ContainerRegistry.getInstance().findInstanceContainers(definition = definition_id, type = "variant")
- if variants:
- variant = variants[0]
-
- preferred_variant_id = definition.getMetaDataEntry("preferred_variant")
- if preferred_variant_id:
- preferred_variants = ContainerRegistry.getInstance().findInstanceContainers(id = preferred_variant_id, definition = definition_id, type = "variant")
- if preferred_variants:
- variant = preferred_variants[0]
- else:
- Logger.log("w", "The preferred variant \"{variant}\" of stack {stack} does not exist or is not a variant.", variant = preferred_variant_id, stack = self.id)
- # And leave it at the default variant.
-
- if variant:
- return variant
-
- Logger.log("w", "Could not find a valid default variant for stack {stack}", stack = self.id)
- return None
-
- ## Find the global variant that should be used as "default". This is used for the buildplates.
- #
- # This will search for variants that match the current definition and pick the preferred one,
- # if specified by the machine definition.
- #
- # The following criteria are used to find the default global variant:
- # - If the machine definition does not have a metadata entry "has_variant_buildplates" set to True, return None
- # - The definition of the variant should be the same as the machine definition for this stack.
- # - The container should have a metadata entry "type" with value "variant" and "hardware_type" with value "buildplate".
- # - If the machine definition has a metadata entry "preferred_variant_buildplate", filter the variant IDs based on that.
- #
- # \return The container that should be used as default, or None if nothing was found or the machine does not use variants.
- #
- # \note This method assumes the stack has a valid machine definition.
- def findDefaultVariantBuildplate(self) -> Optional[ContainerInterface]:
- definition = self._getMachineDefinition()
- # has_variant_buildplates can be overridden in other containers and stacks.
- # In the case of UM2, it is overridden in the GlobalStack
- if not self.getMetaDataEntry("has_variant_buildplates"):
- # If the machine does not use variants, we should never set a variant.
- return None
-
- # First add any variant. Later, overwrite with preference if the preference is valid.
- variant = None
- definition_id = self._findInstanceContainerDefinitionId(definition)
- variants = ContainerRegistry.getInstance().findInstanceContainers(definition = definition_id, type = "variant", hardware_type = "buildplate")
- if variants:
- variant = variants[0]
-
- preferred_variant_buildplate_id = definition.getMetaDataEntry("preferred_variant_buildplate")
- if preferred_variant_buildplate_id:
- preferred_variant_buildplates = ContainerRegistry.getInstance().findInstanceContainers(id = preferred_variant_buildplate_id, definition = definition_id, type = "variant")
- if preferred_variant_buildplates:
- variant = preferred_variant_buildplates[0]
- else:
- Logger.log("w", "The preferred variant buildplate \"{variant}\" of stack {stack} does not exist or is not a variant.",
- variant = preferred_variant_buildplate_id, stack = self.id)
- # And leave it at the default variant.
-
- if variant:
- return variant
-
- Logger.log("w", "Could not find a valid default buildplate variant for stack {stack}", stack = self.id)
- return None
-
- ## Find the material that should be used as "default" material.
- #
- # This will search for materials that match the current definition and pick the preferred one,
- # if specified by the machine definition.
- #
- # The following criteria are used to find the default material:
- # - If the machine definition does not have a metadata entry "has_materials" set to True, return None
- # - If the machine definition has a metadata entry "has_machine_materials", the definition of the material should
- # be the same as the machine definition for this stack. Otherwise, the definition should be "fdmprinter".
- # - The container should have a metadata entry "type" with value "material".
- # - The material should have an approximate diameter that matches the machine
- # - If the machine definition has a metadata entry "has_variants" and set to True, the "variant" metadata entry of
- # the material should be the same as the ID of the variant in the stack. Only applies if "has_machine_materials" is also True.
- # - If the stack currently has a material set, try to find a material that matches the current material by name.
- # - Otherwise, if the machine definition has a metadata entry "preferred_material", try to find a material that matches the specified ID.
- #
- # \return The container that should be used as default, or None if nothing was found or the machine does not use materials.
- def findDefaultMaterial(self) -> Optional[ContainerInterface]:
- definition = self._getMachineDefinition()
- if not definition.getMetaDataEntry("has_materials"):
- # Machine does not use materials, never try to set it.
- return None
-
- search_criteria = {"type": "material"}
- if definition.getMetaDataEntry("has_machine_materials"):
- search_criteria["definition"] = self._findInstanceContainerDefinitionId(definition)
-
- if definition.getMetaDataEntry("has_variants"):
- search_criteria["variant"] = self.variant.id
- else:
- search_criteria["definition"] = "fdmprinter"
-
- if self.material != self._empty_material:
- search_criteria["name"] = self.material.name
- else:
- preferred_material = definition.getMetaDataEntry("preferred_material")
- if preferred_material:
- search_criteria["id"] = preferred_material
-
- approximate_material_diameter = str(round(self.getProperty("material_diameter", "value")))
- search_criteria["approximate_diameter"] = approximate_material_diameter
-
- materials = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
- if not materials:
- Logger.log("w", "The preferred material \"{material}\" could not be found for stack {stack}", material = preferred_material, stack = self.id)
- # We failed to find any materials matching the specified criteria, drop some specific criteria and try to find
- # a material that sort-of matches what we want.
- search_criteria.pop("variant", None)
- search_criteria.pop("id", None)
- search_criteria.pop("name", None)
- materials = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
-
- if not materials:
- Logger.log("w", "Could not find a valid material for stack {stack}", stack = self.id)
- return None
-
- for material in materials:
- # Prefer a read-only material
- if ContainerRegistry.getInstance().isReadOnly(material.getId()):
- return material
-
- return materials[0]
-
-
- ## Find the quality that should be used as "default" quality.
- #
- # This will search for qualities that match the current definition and pick the preferred one,
- # if specified by the machine definition.
- #
- # \return The container that should be used as default, or None if nothing was found.
- def findDefaultQuality(self) -> Optional[ContainerInterface]:
- definition = self._getMachineDefinition()
- registry = ContainerRegistry.getInstance()
- material_container = self.material if self.material.getId() not in (self._empty_material.getId(), self._empty_instance_container.getId()) else None
-
- search_criteria = {"type": "quality"}
-
- if definition.getMetaDataEntry("has_machine_quality"):
- search_criteria["definition"] = self._findInstanceContainerDefinitionId(definition)
-
- if definition.getMetaDataEntry("has_materials") and material_container:
- search_criteria["material"] = material_container.id
- else:
- search_criteria["definition"] = "fdmprinter"
-
- if self.quality != self._empty_quality:
- search_criteria["name"] = self.quality.name
- else:
- preferred_quality = definition.getMetaDataEntry("preferred_quality")
- if preferred_quality:
- search_criteria["id"] = preferred_quality
-
- containers = 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 = 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 self.material != self._empty_instance_container:
- material_search_criteria["definition"] = material_container.getMetaDataEntry("definition")
-
- if definition.getMetaDataEntry("has_variants"):
- material_search_criteria["variant"] = material_container.getMetaDataEntry("variant")
- else:
- material_search_criteria["definition"] = self._findInstanceContainerDefinitionId(definition)
-
- if definition.getMetaDataEntry("has_variants") and self.variant != self._empty_instance_container:
- material_search_criteria["variant"] = self.variant.id
- else:
- material_search_criteria["definition"] = "fdmprinter"
- material_containers = registry.findInstanceContainersMetadata(**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["id"]
-
- containers = 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 = registry.findInstanceContainers(**search_criteria)
- if containers:
- return containers[0]
-
- return None
-
## protected:
# Helper to make sure we emit a PyQt signal on container changes.
diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py
index 608a13c600..a8234b9de9 100644
--- a/cura/Settings/CuraStackBuilder.py
+++ b/cura/Settings/CuraStackBuilder.py
@@ -1,15 +1,18 @@
-# Copyright (c) 2017 Ultimaker B.V.
+# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from UM.Logger import Logger
+from typing import Optional
+from UM.Logger import Logger
from UM.Settings.Interfaces import DefinitionContainerInterface
from UM.Settings.InstanceContainer import InstanceContainer
from UM.Settings.ContainerRegistry import ContainerRegistry
+from UM.Settings.SettingFunction import SettingFunction
+from UM.Util import parseBool
+from cura.Machines.VariantManager import VariantType
from .GlobalStack import GlobalStack
from .ExtruderStack import ExtruderStack
-from typing import Optional
## Contains helper functions to create new machines.
@@ -22,7 +25,13 @@ class CuraStackBuilder:
# \return The new global stack or None if an error occurred.
@classmethod
def createMachine(cls, name: str, definition_id: str) -> Optional[GlobalStack]:
+ from cura.CuraApplication import CuraApplication
+ application = CuraApplication.getInstance()
+ variant_manager = application.getVariantManager()
+ material_manager = application.getMaterialManager()
+ quality_manager = application.getQualityManager()
registry = ContainerRegistry.getInstance()
+
definitions = registry.findDefinitionContainers(id = definition_id)
if not definitions:
Logger.log("w", "Definition {definition} was not found!", definition = definition_id)
@@ -30,7 +39,21 @@ class CuraStackBuilder:
machine_definition = definitions[0]
- generated_name = registry.createUniqueName("machine", "", name, machine_definition.name)
+ # get variant container for the global stack
+ global_variant_container = application.empty_variant_container
+ global_variant_node = variant_manager.getDefaultVariantNode(machine_definition, VariantType.BUILD_PLATE)
+ if global_variant_node:
+ global_variant_container = global_variant_node.getContainer()
+
+ # get variant container for extruders
+ extruder_variant_container = application.empty_variant_container
+ extruder_variant_node = variant_manager.getDefaultVariantNode(machine_definition, VariantType.NOZZLE)
+ extruder_variant_name = None
+ if extruder_variant_node:
+ extruder_variant_container = extruder_variant_node.getContainer()
+ extruder_variant_name = extruder_variant_container.getName()
+
+ generated_name = registry.createUniqueName("machine", "", name, machine_definition.getName())
# Make sure the new name does not collide with any definition or (quality) profile
# createUniqueName() only looks at other stacks, but not at definitions or quality profiles
# Note that we don't go for uniqueName() immediately because that function matches with ignore_case set to true
@@ -40,49 +63,55 @@ class CuraStackBuilder:
new_global_stack = cls.createGlobalStack(
new_stack_id = generated_name,
definition = machine_definition,
- quality = "default",
- material = "default",
- variant = "default",
+ variant_container = global_variant_container,
+ material_container = application.empty_material_container,
+ quality_container = application.empty_quality_container,
)
-
new_global_stack.setName(generated_name)
- extruder_definition = registry.findDefinitionContainers(machine = machine_definition.getId())
+ # get material container for extruders
+ material_container = application.empty_material_container
+ material_node = material_manager.getDefaultMaterial(new_global_stack, extruder_variant_name)
+ if material_node:
+ material_container = material_node.getContainer()
- if not extruder_definition:
- # create extruder stack for single extrusion machines that have no separate extruder definition files
- extruder_definition = registry.findDefinitionContainers(id = "fdmextruder")[0]
- new_extruder_id = registry.uniqueName(machine_definition.getName() + " " + extruder_definition.id)
+ # Create ExtruderStacks
+ extruder_dict = machine_definition.getMetaDataEntry("machine_extruder_trains")
+
+ for position, extruder_definition_id in extruder_dict.items():
+ # Sanity check: make sure that the positions in the extruder definitions are same as in the machine
+ # definition
+ extruder_definition = registry.findDefinitionContainers(id = extruder_definition_id)[0]
+ position_in_extruder_def = extruder_definition.getMetaDataEntry("position")
+ if position_in_extruder_def != position:
+ raise RuntimeError("Extruder position [%s] defined in extruder definition [%s] is not the same as in machine definition [%s] position [%s]" %
+ (position_in_extruder_def, extruder_definition_id, definition_id, position))
+
+ new_extruder_id = registry.uniqueName(extruder_definition_id)
new_extruder = cls.createExtruderStack(
new_extruder_id,
- definition = extruder_definition,
- machine_definition_id = machine_definition.getId(),
- quality = "default",
- material = "default",
- variant = "default",
- next_stack = new_global_stack
+ extruder_definition = extruder_definition,
+ machine_definition_id = definition_id,
+ position = position,
+ variant_container = extruder_variant_container,
+ material_container = material_container,
+ quality_container = application.empty_quality_container,
+ global_stack = new_global_stack,
)
+ new_extruder.setNextStack(new_global_stack)
new_global_stack.addExtruder(new_extruder)
registry.addContainer(new_extruder)
- else:
- # create extruder stack for each found extruder definition
- for extruder_definition in registry.findDefinitionContainers(machine = machine_definition.id):
- position = extruder_definition.getMetaDataEntry("position", None)
- if not position:
- Logger.log("w", "Extruder definition %s specifies no position metadata entry.", extruder_definition.id)
- new_extruder_id = registry.uniqueName(extruder_definition.id)
- new_extruder = cls.createExtruderStack(
- new_extruder_id,
- definition = extruder_definition,
- machine_definition_id = machine_definition.getId(),
- quality = "default",
- material = "default",
- variant = "default",
- next_stack = new_global_stack
- )
- new_global_stack.addExtruder(new_extruder)
- registry.addContainer(new_extruder)
+ preferred_quality_type = machine_definition.getMetaDataEntry("preferred_quality_type")
+ quality_group_dict = quality_manager.getQualityGroups(new_global_stack)
+ quality_group = quality_group_dict.get(preferred_quality_type)
+
+ new_global_stack.quality = quality_group.node_for_global.getContainer()
+ for position, extruder_stack in new_global_stack.extruders.items():
+ if position in quality_group.nodes_for_extruders:
+ extruder_stack.quality = quality_group.nodes_for_extruders[position].getContainer()
+ else:
+ extruder_stack.quality = application.empty_quality_container
# Register the global stack after the extruder stacks are created. This prevents the registry from adding another
# extruder stack because the global stack didn't have one yet (which is enforced since Cura 3.1).
@@ -100,43 +129,27 @@ class CuraStackBuilder:
#
# \return A new Global stack instance with the specified parameters.
@classmethod
- def createExtruderStack(cls, new_stack_id: str, definition: DefinitionContainerInterface, machine_definition_id: str, **kwargs) -> ExtruderStack:
- stack = ExtruderStack(new_stack_id)
- stack.setName(definition.getName())
- stack.setDefinition(definition)
- stack.addMetaDataEntry("position", definition.getMetaDataEntry("position"))
-
- if "next_stack" in kwargs:
- # Add stacks before containers are added, since they may trigger a setting update.
- stack.setNextStack(kwargs["next_stack"])
-
- user_container = InstanceContainer(new_stack_id + "_user")
- user_container.addMetaDataEntry("type", "user")
- user_container.addMetaDataEntry("extruder", new_stack_id)
+ def createExtruderStack(cls, new_stack_id: str, extruder_definition: DefinitionContainerInterface, machine_definition_id: str,
+ position: int,
+ variant_container, material_container, quality_container, global_stack) -> ExtruderStack:
from cura.CuraApplication import CuraApplication
- user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
- user_container.setDefinition(machine_definition_id)
+ application = CuraApplication.getInstance()
- stack.setUserChanges(user_container)
+ stack = ExtruderStack(new_stack_id, parent = global_stack)
+ stack.setName(extruder_definition.getName())
+ stack.setDefinition(extruder_definition)
- # Important! The order here matters, because that allows the stack to
- # assume the material and variant have already been set.
- if "definition_changes" in kwargs:
- stack.setDefinitionChangesById(kwargs["definition_changes"])
- else:
- stack.setDefinitionChanges(cls.createDefinitionChangesContainer(stack, new_stack_id + "_settings"))
+ stack.addMetaDataEntry("position", position)
- if "variant" in kwargs:
- stack.setVariantById(kwargs["variant"])
+ user_container = cls.createUserChangesContainer(new_stack_id + "_user", machine_definition_id, new_stack_id,
+ is_global_stack = False)
- if "material" in kwargs:
- stack.setMaterialById(kwargs["material"])
-
- if "quality" in kwargs:
- stack.setQualityById(kwargs["quality"])
-
- if "quality_changes" in kwargs:
- stack.setQualityChangesById(kwargs["quality_changes"])
+ stack.definitionChanges = cls.createDefinitionChangesContainer(stack, new_stack_id + "_settings")
+ stack.variant = variant_container
+ stack.material = material_container
+ stack.quality = quality_container
+ stack.qualityChanges = application.empty_quality_changes_container
+ stack.userChanges = user_container
# Only add the created containers to the registry after we have set all the other
# properties. This makes the create operation more transactional, since any problems
@@ -153,44 +166,48 @@ class CuraStackBuilder:
#
# \return A new Global stack instance with the specified parameters.
@classmethod
- def createGlobalStack(cls, new_stack_id: str, definition: DefinitionContainerInterface, **kwargs) -> GlobalStack:
+ def createGlobalStack(cls, new_stack_id: str, definition: DefinitionContainerInterface,
+ variant_container, material_container, quality_container) -> GlobalStack:
+ from cura.CuraApplication import CuraApplication
+ application = CuraApplication.getInstance()
+
stack = GlobalStack(new_stack_id)
stack.setDefinition(definition)
- user_container = InstanceContainer(new_stack_id + "_user")
- user_container.addMetaDataEntry("type", "user")
- user_container.addMetaDataEntry("machine", new_stack_id)
- from cura.CuraApplication import CuraApplication
- user_container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
- user_container.setDefinition(definition.getId())
+ # Create user container
+ user_container = cls.createUserChangesContainer(new_stack_id + "_user", definition.getId(), new_stack_id,
+ is_global_stack = True)
- stack.setUserChanges(user_container)
-
- # Important! The order here matters, because that allows the stack to
- # assume the material and variant have already been set.
- if "definition_changes" in kwargs:
- stack.setDefinitionChangesById(kwargs["definition_changes"])
- else:
- stack.setDefinitionChanges(cls.createDefinitionChangesContainer(stack, new_stack_id + "_settings"))
-
- if "variant" in kwargs:
- stack.setVariantById(kwargs["variant"])
-
- if "material" in kwargs:
- stack.setMaterialById(kwargs["material"])
-
- if "quality" in kwargs:
- stack.setQualityById(kwargs["quality"])
-
- if "quality_changes" in kwargs:
- stack.setQualityChangesById(kwargs["quality_changes"])
+ stack.definitionChanges = cls.createDefinitionChangesContainer(stack, new_stack_id + "_settings")
+ stack.variant = variant_container
+ stack.material = material_container
+ stack.quality = quality_container
+ stack.qualityChanges = application.empty_quality_changes_container
+ stack.userChanges = user_container
ContainerRegistry.getInstance().addContainer(user_container)
return stack
@classmethod
- def createDefinitionChangesContainer(cls, container_stack, container_name, container_index = None):
+ def createUserChangesContainer(cls, container_name: str, definition_id: str, stack_id: str,
+ is_global_stack: bool) -> "InstanceContainer":
+ from cura.CuraApplication import CuraApplication
+
+ unique_container_name = ContainerRegistry.getInstance().uniqueName(container_name)
+
+ container = InstanceContainer(unique_container_name)
+ container.setDefinition(definition_id)
+ container.addMetaDataEntry("type", "user")
+ container.addMetaDataEntry("setting_version", CuraApplication.SettingVersion)
+
+ metadata_key_to_add = "machine" if is_global_stack else "extruder"
+ container.addMetaDataEntry(metadata_key_to_add, stack_id)
+
+ return container
+
+ @classmethod
+ def createDefinitionChangesContainer(cls, container_stack, container_name):
from cura.CuraApplication import CuraApplication
unique_container_name = ContainerRegistry.getInstance().uniqueName(container_name)
diff --git a/cura/Settings/ExtruderManager.py b/cura/Settings/ExtruderManager.py
index 35b5b1320b..0ac3e4bd66 100755
--- a/cura/Settings/ExtruderManager.py
+++ b/cura/Settings/ExtruderManager.py
@@ -12,6 +12,7 @@ from UM.Scene.Selection import Selection
from UM.Scene.Iterator.BreadthFirstIterator import BreadthFirstIterator
from UM.Settings.ContainerRegistry import ContainerRegistry # Finding containers by ID.
from UM.Settings.SettingFunction import SettingFunction
+from UM.Settings.SettingInstance import SettingInstance
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.PropertyEvaluationContext import PropertyEvaluationContext
from typing import Optional, List, TYPE_CHECKING, Union
@@ -30,28 +31,22 @@ class ExtruderManager(QObject):
def __init__(self, parent = None):
super().__init__(parent)
+ self._application = Application.getInstance()
+
self._extruder_trains = {} # Per machine, a dictionary of extruder container stack IDs. Only for separately defined extruders.
self._active_extruder_index = -1 # Indicates the index of the active extruder stack. -1 means no active extruder stack
self._selected_object_extruders = []
- self._global_container_stack_definition_id = None
self._addCurrentMachineExtruders()
- Application.getInstance().globalContainerStackChanged.connect(self.__globalContainerStackChanged)
+ #Application.getInstance().globalContainerStackChanged.connect(self._globalContainerStackChanged)
Selection.selectionChanged.connect(self.resetSelectedObjectExtruders)
## Signal to notify other components when the list of extruders for a machine definition changes.
extrudersChanged = pyqtSignal(QVariant)
- ## Signal to notify other components when the global container stack is switched to a definition
- # that has different extruders than the previous global container stack
- globalContainerStackDefinitionChanged = pyqtSignal()
-
## Notify when the user switches the currently active extruder.
activeExtruderChanged = pyqtSignal()
- ## The signal notifies subscribers if extruders are added
- extrudersAdded = pyqtSignal()
-
## Gets the unique identifier of the currently active extruder stack.
#
# The currently active extruder stack is the stack that is currently being
@@ -184,6 +179,7 @@ class ExtruderManager(QObject):
self._selected_object_extruders = []
self.selectedObjectExtrudersChanged.emit()
+ @pyqtSlot(result = QObject)
def getActiveExtruderStack(self) -> Optional["ExtruderStack"]:
global_container_stack = Application.getInstance().getGlobalContainerStack()
@@ -245,6 +241,13 @@ class ExtruderManager(QObject):
result.append(extruder_stack.getProperty(setting_key, prop))
return result
+ def extruderValueWithDefault(self, value):
+ machine_manager = self._application.getMachineManager()
+ if value == "-1":
+ return machine_manager.defaultExtruderPosition
+ else:
+ return value
+
## Gets the extruder stacks that are actually being used at the moment.
#
# An extruder stack is being used if it is the extruder to print any mesh
@@ -256,7 +259,7 @@ class ExtruderManager(QObject):
#
# \return A list of extruder stacks.
def getUsedExtruderStacks(self) -> List["ContainerStack"]:
- global_stack = Application.getInstance().getGlobalContainerStack()
+ global_stack = self._application.getGlobalContainerStack()
container_registry = ContainerRegistry.getInstance()
used_extruder_stack_ids = set()
@@ -306,16 +309,19 @@ class ExtruderManager(QObject):
# Check support extruders
if support_enabled:
- used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("support_infill_extruder_nr", "value"))])
- used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("support_extruder_nr_layer_0", "value"))])
+ used_extruder_stack_ids.add(self.extruderIds[self.extruderValueWithDefault(str(global_stack.getProperty("support_infill_extruder_nr", "value")))])
+ used_extruder_stack_ids.add(self.extruderIds[self.extruderValueWithDefault(str(global_stack.getProperty("support_extruder_nr_layer_0", "value")))])
if support_bottom_enabled:
- used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("support_bottom_extruder_nr", "value"))])
+ used_extruder_stack_ids.add(self.extruderIds[self.extruderValueWithDefault(str(global_stack.getProperty("support_bottom_extruder_nr", "value")))])
if support_roof_enabled:
- used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("support_roof_extruder_nr", "value"))])
+ used_extruder_stack_ids.add(self.extruderIds[self.extruderValueWithDefault(str(global_stack.getProperty("support_roof_extruder_nr", "value")))])
# The platform adhesion extruder. Not used if using none.
if global_stack.getProperty("adhesion_type", "value") != "none":
- used_extruder_stack_ids.add(self.extruderIds[str(global_stack.getProperty("adhesion_extruder_nr", "value"))])
+ extruder_nr = str(global_stack.getProperty("adhesion_extruder_nr", "value"))
+ if extruder_nr == "-1":
+ extruder_nr = Application.getInstance().getMachineManager().defaultExtruderPosition
+ used_extruder_stack_ids.add(self.extruderIds[extruder_nr])
try:
return [container_registry.findContainerStacks(id = stack_id)[0] for stack_id in used_extruder_stack_ids]
@@ -371,12 +377,7 @@ class ExtruderManager(QObject):
return result[:machine_extruder_count]
- def __globalContainerStackChanged(self) -> None:
- global_container_stack = Application.getInstance().getGlobalContainerStack()
- if global_container_stack and global_container_stack.getBottom() and global_container_stack.getBottom().getId() != self._global_container_stack_definition_id:
- self._global_container_stack_definition_id = global_container_stack.getBottom().getId()
- self.globalContainerStackDefinitionChanged.emit()
-
+ def _globalContainerStackChanged(self) -> None:
# If the global container changed, the machine changed and might have extruders that were not registered yet
self._addCurrentMachineExtruders()
@@ -384,7 +385,7 @@ class ExtruderManager(QObject):
## Adds the extruders of the currently active machine.
def _addCurrentMachineExtruders(self) -> None:
- global_stack = Application.getInstance().getGlobalContainerStack()
+ global_stack = self._application.getGlobalContainerStack()
extruders_changed = False
if global_stack:
@@ -404,20 +405,82 @@ class ExtruderManager(QObject):
self._extruder_trains[global_stack_id][extruder_train.getMetaDataEntry("position")] = extruder_train
# regardless of what the next stack is, we have to set it again, because of signal routing. ???
+ extruder_train.setParent(global_stack)
extruder_train.setNextStack(global_stack)
extruders_changed = True
- # FIX: We have to remove those settings here because we know that those values have been copied to all
- # the extruders at this point.
- for key in ("material_diameter", "machine_nozzle_size"):
- if global_stack.definitionChanges.hasProperty(key, "value"):
- global_stack.definitionChanges.removeInstance(key, postpone_emit = True)
-
+ self._fixMaterialDiameterAndNozzleSize(global_stack, extruder_trains)
if extruders_changed:
self.extrudersChanged.emit(global_stack_id)
- self.extrudersAdded.emit()
self.setActiveExtruderIndex(0)
+ #
+ # This function tries to fix the problem with per-extruder-settable nozzle size and material diameter problems
+ # in early versions (3.0 - 3.2.1).
+ #
+ # In earlier versions, "nozzle size" and "material diameter" are only applicable to the complete machine, so all
+ # extruders share the same values. In this case, "nozzle size" and "material diameter" are saved in the
+ # GlobalStack's DefinitionChanges container.
+ #
+ # Later, we could have different "nozzle size" for each extruder, but "material diameter" could only be set for
+ # the entire machine. In this case, "nozzle size" should be saved in each ExtruderStack's DefinitionChanges, but
+ # "material diameter" still remains in the GlobalStack's DefinitionChanges.
+ #
+ # Lateer, both "nozzle size" and "material diameter" are settable per-extruder, and both settings should be saved
+ # in the ExtruderStack's DefinitionChanges.
+ #
+ # There were some bugs in upgrade so the data weren't saved correct as described above. This function tries fix
+ # this.
+ #
+ # One more thing is about material diameter and single-extrusion machines. Most single-extrusion machines don't
+ # specifically define their extruder definition, so they reuse "fdmextruder", but for those machines, they may
+ # define "material diameter = 1.75" in their machine definition, but in "fdmextruder", it's still "2.85". This
+ # causes a problem with incorrect default values.
+ #
+ # This is also fixed here in this way: If no "material diameter" is specified, it will look for the default value
+ # in both the Extruder's definition and the Global's definition. If 2 values don't match, we will use the value
+ # from the Global definition by setting it in the Extruder's DefinitionChanges container.
+ #
+ def _fixMaterialDiameterAndNozzleSize(self, global_stack, extruder_stack_list):
+ keys_to_copy = ["material_diameter", "machine_nozzle_size"] # these will be copied over to all extruders
+
+ extruder_positions_to_update = set()
+ for extruder_stack in extruder_stack_list:
+ for key in keys_to_copy:
+ # Only copy the value when this extruder doesn't have the value.
+ if extruder_stack.definitionChanges.hasProperty(key, "value"):
+ continue
+
+ setting_value_in_global_def_changes = global_stack.definitionChanges.getProperty(key, "value")
+ setting_value_in_global_def = global_stack.definition.getProperty(key, "value")
+ setting_value = setting_value_in_global_def
+ if setting_value_in_global_def_changes is not None:
+ setting_value = setting_value_in_global_def_changes
+ if setting_value == extruder_stack.definition.getProperty(key, "value"):
+ continue
+
+ setting_definition = global_stack.getSettingDefinition(key)
+ new_instance = SettingInstance(setting_definition, extruder_stack.definitionChanges)
+ new_instance.setProperty("value", setting_value)
+ new_instance.resetState() # Ensure that the state is not seen as a user state.
+ extruder_stack.definitionChanges.addInstance(new_instance)
+ extruder_stack.definitionChanges.setDirty(True)
+
+ # Make sure the material diameter is up to date for the extruder stack.
+ if key == "material_diameter":
+ position = int(extruder_stack.getMetaDataEntry("position"))
+ extruder_positions_to_update.add(position)
+
+ # We have to remove those settings here because we know that those values have been copied to all
+ # the extruders at this point.
+ for key in keys_to_copy:
+ if global_stack.definitionChanges.hasProperty(key, "value"):
+ global_stack.definitionChanges.removeInstance(key, postpone_emit = True)
+
+ # Update material diameter for extruders
+ for position in extruder_positions_to_update:
+ self.updateMaterialForDiameter(position, global_stack = global_stack)
+
## Get all extruder values for a certain setting.
#
# This is exposed to SettingFunction so it can be used in value functions.
@@ -432,6 +495,8 @@ class ExtruderManager(QObject):
result = []
for extruder in ExtruderManager.getInstance().getMachineExtruders(global_stack.getId()):
+ if not extruder.isEnabled:
+ continue
# only include values from extruders that are "active" for the current machine instance
if int(extruder.getMetaDataEntry("position")) >= global_stack.getProperty("machine_extruder_count", "value"):
continue
@@ -503,10 +568,11 @@ class ExtruderManager(QObject):
return ExtruderManager.getExtruderValues(key)
## Updates the material container to a material that matches the material diameter set for the printer
- def updateMaterialForDiameter(self, extruder_position: int):
- global_stack = Application.getInstance().getGlobalContainerStack()
+ def updateMaterialForDiameter(self, extruder_position: int, global_stack = None):
if not global_stack:
- return
+ global_stack = Application.getInstance().getGlobalContainerStack()
+ if not global_stack:
+ return
if not global_stack.getMetaDataEntry("has_materials", False):
return
diff --git a/cura/Settings/ExtruderStack.py b/cura/Settings/ExtruderStack.py
index 6f89d33393..5cdcba68b0 100644
--- a/cura/Settings/ExtruderStack.py
+++ b/cura/Settings/ExtruderStack.py
@@ -3,16 +3,17 @@
from typing import Any, TYPE_CHECKING, Optional
-from UM.Application import Application
+from PyQt5.QtCore import pyqtProperty, pyqtSignal
+
from UM.Decorators import override
from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.Interfaces import ContainerInterface, PropertyEvaluationContext
-from UM.Settings.SettingInstance import SettingInstance
+from UM.Util import parseBool
from . import Exceptions
-from .CuraContainerStack import CuraContainerStack
+from .CuraContainerStack import CuraContainerStack, _ContainerIndexes
from .ExtruderManager import ExtruderManager
if TYPE_CHECKING:
@@ -30,11 +31,13 @@ class ExtruderStack(CuraContainerStack):
self.propertiesChanged.connect(self._onPropertiesChanged)
+ enabledChanged = pyqtSignal()
+
## Overridden from ContainerStack
#
# This will set the next stack and ensure that we register this stack as an extruder.
@override(ContainerStack)
- def setNextStack(self, stack: ContainerStack) -> None:
+ def setNextStack(self, stack: CuraContainerStack) -> None:
super().setNextStack(stack)
stack.addExtruder(self)
self.addMetaDataEntry("machine", stack.id)
@@ -42,83 +45,47 @@ class ExtruderStack(CuraContainerStack):
# For backward compatibility: Register the extruder with the Extruder Manager
ExtruderManager.getInstance().registerExtruder(self, stack.id)
- # Now each machine will have at least one extruder stack. If this is the first extruder, the extruder-specific
- # settings such as nozzle size and material diameter should be moved from the machine's definition_changes to
- # the this extruder's definition_changes.
- #
- # We do this here because it is tooooo expansive to do it in the version upgrade: During the version upgrade,
- # when we are upgrading a definition_changes container file, there is NO guarantee that other files such as
- # machine an extruder stack files are upgraded before this, so we cannot read those files assuming they are in
- # the latest format.
- #
- # MORE:
- # For single-extrusion machines, nozzle size is saved in the global stack, so the nozzle size value should be
- # carried to the first extruder.
- # For material diameter, it was supposed to be applied to all extruders, so its value should be copied to all
- # extruders.
-
- keys_to_copy = ["material_diameter", "machine_nozzle_size"] # these will be copied over to all extruders
-
- for key in keys_to_copy:
- # Only copy the value when this extruder doesn't have the value.
- if self.definitionChanges.hasProperty(key, "value"):
- continue
-
- # WARNING: this might be very dangerous and should be refactored ASAP!
- #
- # We cannot add a setting definition of "material_diameter" into the extruder's definition at runtime
- # because all other machines which uses "fdmextruder" as the extruder definition will be affected.
- #
- # The problem is that single extrusion machines have their default material diameter defined in the global
- # definitions. Now we automatically create an extruder stack for those machines using "fdmextruder"
- # definition, which doesn't have the specific "material_diameter" and "machine_nozzle_size" defined for
- # each machine. This results in wrong values which can be found in the MachineSettings dialog.
- #
- # To solve this, we put "material_diameter" back into the "fdmextruder" definition because modifying it in
- # the extruder definition will affect all machines which uses the "fdmextruder" definition. Moreover, now
- # we also check the value defined in the machine definition. If present, the value defined in the global
- # stack's definition changes container will be copied. Otherwise, we will check if the default values in the
- # machine definition and the extruder definition are the same, and if not, the default value in the machine
- # definition will be copied to the extruder stack's definition changes.
- #
- setting_value_in_global_def_changes = stack.definitionChanges.getProperty(key, "value")
- setting_value_in_global_def = stack.definition.getProperty(key, "value")
- setting_value = setting_value_in_global_def
- if setting_value_in_global_def_changes is not None:
- setting_value = setting_value_in_global_def_changes
- if setting_value == self.definition.getProperty(key, "value"):
- continue
-
- setting_definition = stack.getSettingDefinition(key)
- new_instance = SettingInstance(setting_definition, self.definitionChanges)
- new_instance.setProperty("value", setting_value)
- new_instance.resetState() # Ensure that the state is not seen as a user state.
- self.definitionChanges.addInstance(new_instance)
- self.definitionChanges.setDirty(True)
-
- # Make sure the material diameter is up to date for the extruder stack.
- if key == "material_diameter":
- from cura.CuraApplication import CuraApplication
- machine_manager = CuraApplication.getInstance().getMachineManager()
- position = self.getMetaDataEntry("position", "0")
- func = lambda p = position: CuraApplication.getInstance().getExtruderManager().updateMaterialForDiameter(p)
- machine_manager.machine_extruder_material_update_dict[stack.getId()].append(func)
-
- # NOTE: We cannot remove the setting from the global stack's definition changes container because for
- # material diameter, it needs to be applied to all extruders, but here we don't know how many extruders
- # a machine actually has and how many extruders has already been loaded for that machine, so we have to
- # keep this setting for any remaining extruders that haven't been loaded yet.
- #
- # Those settings will be removed in ExtruderManager which knows all those info.
-
@override(ContainerStack)
def getNextStack(self) -> Optional["GlobalStack"]:
return super().getNextStack()
+ def setEnabled(self, enabled):
+ if "enabled" not in self._metadata:
+ self.addMetaDataEntry("enabled", "True")
+ self.setMetaDataEntry("enabled", str(enabled))
+ self.enabledChanged.emit()
+
+ @pyqtProperty(bool, notify = enabledChanged)
+ def isEnabled(self):
+ return parseBool(self.getMetaDataEntry("enabled", "True"))
+
@classmethod
def getLoadingPriority(cls) -> int:
return 3
+ ## Return the filament diameter that the machine requires.
+ #
+ # If the machine has no requirement for the diameter, -1 is returned.
+ # \return The filament diameter for the printer
+ @property
+ def materialDiameter(self) -> float:
+ context = PropertyEvaluationContext(self)
+ context.context["evaluate_from_container_index"] = _ContainerIndexes.Variant
+
+ return self.getProperty("material_diameter", "value", context = context)
+
+ ## Return the approximate filament diameter that the machine requires.
+ #
+ # The approximate material diameter is the material diameter rounded to
+ # the nearest millimetre.
+ #
+ # If the machine has no requirement for the diameter, -1 is returned.
+ #
+ # \return The approximate filament diameter for the printer
+ @pyqtProperty(float)
+ def approximateMaterialDiameter(self) -> float:
+ return round(float(self.materialDiameter))
+
## Overridden from ContainerStack
#
# It will perform a few extra checks when trying to get properties.
@@ -187,11 +154,6 @@ class ExtruderStack(CuraContainerStack):
if has_global_dependencies:
self.getNextStack().propertiesChanged.emit(key, properties)
- def findDefaultVariant(self):
- # The default variant is defined in the machine stack and/or definition, so use the machine stack to find
- # the default variant.
- return self.getNextStack().findDefaultVariant()
-
extruder_stack_mime = MimeType(
name = "application/x-cura-extruderstack",
diff --git a/cura/Settings/ExtrudersModel.py b/cura/Settings/ExtrudersModel.py
index 5139b9885d..4ee5ab3c3b 100644
--- a/cura/Settings/ExtrudersModel.py
+++ b/cura/Settings/ExtrudersModel.py
@@ -1,7 +1,7 @@
# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from PyQt5.QtCore import Qt, pyqtSignal, pyqtProperty, QTimer
+from PyQt5.QtCore import Qt, pyqtSignal, pyqtSlot, pyqtProperty, QTimer
from typing import Iterable
from UM.i18n import i18nCatalog
@@ -24,6 +24,8 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
## Human-readable name of the extruder.
NameRole = Qt.UserRole + 2
+ ## Is the extruder enabled?
+ EnabledRole = Qt.UserRole + 9
## Colour of the material loaded in the extruder.
ColorRole = Qt.UserRole + 3
@@ -43,6 +45,7 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
# The variant of the extruder.
VariantRole = Qt.UserRole + 7
+ StackRole = Qt.UserRole + 8
## List of colours to display if there is no material or the material has no known
# colour.
@@ -57,11 +60,13 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
self.addRoleName(self.IdRole, "id")
self.addRoleName(self.NameRole, "name")
+ self.addRoleName(self.EnabledRole, "enabled")
self.addRoleName(self.ColorRole, "color")
self.addRoleName(self.IndexRole, "index")
self.addRoleName(self.DefinitionRole, "definition")
self.addRoleName(self.MaterialRole, "material")
self.addRoleName(self.VariantRole, "variant")
+ self.addRoleName(self.StackRole, "stack")
self._update_extruder_timer = QTimer()
self._update_extruder_timer.setInterval(100)
@@ -183,11 +188,13 @@ class ExtrudersModel(UM.Qt.ListModel.ListModel):
item = {
"id": extruder.getId(),
"name": extruder.getName(),
+ "enabled": extruder.isEnabled,
"color": color,
"index": position,
"definition": extruder.getBottom().getId(),
"material": extruder.material.getName() if extruder.material else "",
"variant": extruder.variant.getName() if extruder.variant else "", # e.g. print core
+ "stack": extruder,
}
items.append(item)
diff --git a/cura/Settings/GlobalStack.py b/cura/Settings/GlobalStack.py
index 6d18bf615b..ae1f1370ed 100755
--- a/cura/Settings/GlobalStack.py
+++ b/cura/Settings/GlobalStack.py
@@ -125,21 +125,6 @@ class GlobalStack(CuraContainerStack):
def setNextStack(self, next_stack: ContainerStack) -> None:
raise Exceptions.InvalidOperationError("Global stack cannot have a next stack!")
- ## Gets the approximate filament diameter that the machine requires.
- #
- # The approximate material diameter is the material diameter rounded to
- # the nearest millimetre.
- #
- # If the machine has no requirement for the diameter, -1 is returned.
- #
- # \return The approximate filament diameter for the printer, as a string.
- @pyqtProperty(str)
- def approximateMaterialDiameter(self) -> str:
- material_diameter = self.definition.getProperty("material_diameter", "value")
- if material_diameter is None:
- return "-1"
- return str(round(float(material_diameter))) #Round, then convert back to string.
-
# protected:
# Determine whether or not we should try to get the "resolve" property instead of the
diff --git a/cura/Settings/MachineManager.py b/cura/Settings/MachineManager.py
index 26b3d3d7ec..eb720000bf 100755
--- a/cura/Settings/MachineManager.py
+++ b/cura/Settings/MachineManager.py
@@ -4,30 +4,28 @@
import collections
import time
#Type hinting.
-from typing import Union, List, Dict
+from typing import Union, List, Dict, TYPE_CHECKING, Optional
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Signal import Signal
from PyQt5.QtCore import QObject, pyqtProperty, pyqtSignal, QTimer
+import UM.FlameProfiler
from UM.FlameProfiler import pyqtSlot
-from PyQt5.QtWidgets import QMessageBox
from UM import Util
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.SettingFunction import SettingFunction
from UM.Signal import postponeSignals, CompressTechnique
-import UM.FlameProfiler
-from cura.QualityManager import QualityManager
+from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
+
from cura.PrinterOutputDevice import PrinterOutputDevice
from cura.Settings.ExtruderManager import ExtruderManager
@@ -36,29 +34,27 @@ from .CuraStackBuilder import CuraStackBuilder
from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
-from cura.Settings.ProfilesModel import ProfilesModel
-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
class MachineManager(QObject):
+
def __init__(self, parent = None):
super().__init__(parent)
self._active_container_stack = None # type: CuraContainerStack
self._global_container_stack = None # type: GlobalStack
- self.machine_extruder_material_update_dict = collections.defaultdict(list)
+ self._current_root_material_id = {}
+ self._current_root_material_name = {}
+ self._current_quality_group = None
+ self._current_quality_changes_group = None
- # Used to store the new containers until after confirming the dialog
- self._new_variant_container = None
- self._new_buildplate_container = None
- self._new_material_container = None
- self._new_quality_containers = []
+ self._default_extruder_position = "0" # to be updated when extruders are switched on and off
+
+ self.machine_extruder_material_update_dict = collections.defaultdict(list)
self._error_check_timer = QTimer()
self._error_check_timer.setInterval(250)
@@ -70,16 +66,19 @@ class MachineManager(QObject):
self._instance_container_timer.setSingleShot(True)
self._instance_container_timer.timeout.connect(self.__emitChangedSignals)
- Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
- Application.getInstance().getContainerRegistry().containerLoadComplete.connect(self._onInstanceContainersChanged)
- self._connected_to_profiles_model = False
+ self._application = Application.getInstance()
+ self._application.globalContainerStackChanged.connect(self._onGlobalContainerChanged)
+ self._application.getContainerRegistry().containerLoadComplete.connect(self._onInstanceContainersChanged)
## When the global container is changed, active material probably needs to be updated.
self.globalContainerChanged.connect(self.activeMaterialChanged)
self.globalContainerChanged.connect(self.activeVariantChanged)
self.globalContainerChanged.connect(self.activeQualityChanged)
- self._stacks_have_errors = None
+ self.globalContainerChanged.connect(self.activeQualityChangesGroupChanged)
+ self.globalContainerChanged.connect(self.activeQualityGroupChanged)
+
+ self._stacks_have_errors = None # type:Optional[bool]
self._empty_definition_changes_container = ContainerRegistry.getInstance().findContainers(id = "empty_definition_changes")[0]
self._empty_variant_container = ContainerRegistry.getInstance().findContainers(id = "empty_variant")[0]
@@ -101,28 +100,16 @@ class MachineManager(QObject):
ExtruderManager.getInstance().activeExtruderChanged.connect(self.activeStackChanged)
self.activeStackChanged.connect(self.activeStackValueChanged)
- # when a user closed dialog check if any delayed material or variant changes need to be applied
- Application.getInstance().onDiscardOrKeepProfileChangesClosed.connect(self._executeDelayedActiveContainerStackChanges)
-
Preferences.getInstance().addPreference("cura/active_machine", "")
self._global_event_keys = set()
- active_machine_id = Preferences.getInstance().getValue("cura/active_machine")
-
self._printer_output_devices = []
Application.getInstance().getOutputDeviceManager().outputDevicesChanged.connect(self._onOutputDevicesChanged)
# There might already be some output devices by the time the signal is connected
self._onOutputDevicesChanged()
- if active_machine_id != "" and ContainerRegistry.getInstance().findContainerStacksMetadata(id = active_machine_id):
- # An active machine was saved, so restore it.
- self.setActiveMachine(active_machine_id)
- # Make sure _active_container_stack is properly initiated
- ExtruderManager.getInstance().setActiveExtruderIndex(0)
-
- self._auto_materials_changed = {}
- self._auto_hotends_changed = {}
+ self._application.callLater(self.setInitialActiveMachine)
self._material_incompatible_message = Message(catalog.i18nc("@info:status",
"The selected material is incompatible with the selected machine or configuration."),
@@ -132,11 +119,23 @@ class MachineManager(QObject):
if containers:
containers[0].nameChanged.connect(self._onMaterialNameChanged)
+ self._material_manager = self._application._material_manager
+ self._quality_manager = self._application.getQualityManager()
+
+ # When the materials lookup table gets updated, it can mean that a material has its name changed, which should
+ # be reflected on the GUI. This signal emission makes sure that it happens.
+ self._material_manager.materialsUpdated.connect(self.rootMaterialChanged)
+ self.rootMaterialChanged.connect(self._onRootMaterialChanged)
+
+ activeQualityGroupChanged = pyqtSignal()
+ activeQualityChangesGroupChanged = pyqtSignal()
+
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()
activeQualityChanged = pyqtSignal()
activeStackChanged = pyqtSignal() # Emitted whenever the active stack is changed (ie: when changing between extruders, changing a profile, but not when changing a value)
+ extruderChanged = pyqtSignal()
globalValueChanged = pyqtSignal() # Emitted whenever a value inside global container is changed.
activeStackValueChanged = pyqtSignal() # Emitted whenever a value inside the active stack is changed.
@@ -147,32 +146,24 @@ class MachineManager(QObject):
outputDevicesChanged = pyqtSignal()
- def _onOutputDevicesChanged(self) -> None:
- for printer_output_device in self._printer_output_devices:
- printer_output_device.hotendIdChanged.disconnect(self._onHotendIdChanged)
- printer_output_device.materialIdChanged.disconnect(self._onMaterialIdChanged)
+ rootMaterialChanged = pyqtSignal()
+ def setInitialActiveMachine(self):
+ active_machine_id = Preferences.getInstance().getValue("cura/active_machine")
+ if active_machine_id != "" and ContainerRegistry.getInstance().findContainerStacksMetadata(id = active_machine_id):
+ # An active machine was saved, so restore it.
+ self.setActiveMachine(active_machine_id)
+ # Make sure _active_container_stack is properly initiated
+ ExtruderManager.getInstance().setActiveExtruderIndex(0)
+
+ def _onOutputDevicesChanged(self) -> None:
self._printer_output_devices = []
for printer_output_device in Application.getInstance().getOutputDeviceManager().getOutputDevices():
if isinstance(printer_output_device, PrinterOutputDevice):
self._printer_output_devices.append(printer_output_device)
- printer_output_device.hotendIdChanged.connect(self._onHotendIdChanged)
- printer_output_device.materialIdChanged.connect(self._onMaterialIdChanged)
self.outputDevicesChanged.emit()
- @property
- def newVariant(self):
- return self._new_variant_container
-
- @property
- def newBuildplate(self):
- return self._new_buildplate_container
-
- @property
- def newMaterial(self):
- return self._new_material_container
-
@pyqtProperty("QVariantList", notify = outputDevicesChanged)
def printerOutputDevices(self):
return self._printer_output_devices
@@ -181,115 +172,7 @@ class MachineManager(QObject):
def totalNumberOfSettings(self) -> int:
return len(ContainerRegistry.getInstance().findDefinitionContainers(id = "fdmprinter")[0].getAllKeys())
- def _onHotendIdChanged(self):
- if not self._global_container_stack or not self._printer_output_devices:
- return
-
- active_printer_model = self._printer_output_devices[0].activePrinter
- if not active_printer_model:
- return
-
- change_found = False
- machine_id = self.activeMachineId
- extruders = sorted(ExtruderManager.getInstance().getMachineExtruders(machine_id),
- key=lambda k: k.getMetaDataEntry("position"))
-
- for extruder_model, extruder in zip(active_printer_model.extruders, extruders):
- containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(type="variant",
- definition=self._global_container_stack.definition.getId(),
- name=extruder_model.hotendID)
- if containers:
- # The hotend ID is known.
- machine_id = self.activeMachineId
- if extruder.variant.getName() != extruder_model.hotendID:
- change_found = True
- self._auto_hotends_changed[extruder.getMetaDataEntry("position")] = containers[0]["id"]
-
- if change_found:
- # A change was found, let the output device handle this.
- self._printer_output_devices[0].materialHotendChangedMessage(self._materialHotendChangedCallback)
-
- def _onMaterialIdChanged(self):
- if not self._global_container_stack or not self._printer_output_devices:
- return
-
- active_printer_model = self._printer_output_devices[0].activePrinter
- if not active_printer_model:
- return
-
- change_found = False
- machine_id = self.activeMachineId
- extruders = sorted(ExtruderManager.getInstance().getMachineExtruders(machine_id),
- key=lambda k: k.getMetaDataEntry("position"))
-
- for extruder_model, extruder in zip(active_printer_model.extruders, extruders):
- if extruder_model.activeMaterial is None:
- continue
- containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(type="material",
- definition=self._global_container_stack.definition.getId(),
- GUID=extruder_model.activeMaterial.guid)
- if containers:
- # The material is known.
- if extruder.material.getMetaDataEntry("GUID") != extruder_model.activeMaterial.guid:
- change_found = True
- if self._global_container_stack.definition.getMetaDataEntry("has_variants") and extruder.variant:
- variant_id = self.getQualityVariantId(self._global_container_stack.definition,
- extruder.variant)
- for container in containers:
- if container.get("variant") == variant_id:
- self._auto_materials_changed[extruder.getMetaDataEntry("position")] = container["id"]
- break
- else:
- # Just use the first result we found.
- self._auto_materials_changed[extruder.getMetaDataEntry("position")] = containers[0]["id"]
- if change_found:
- # A change was found, let the output device handle this.
- self._printer_output_devices[0].materialHotendChangedMessage(self._materialHotendChangedCallback)
-
- def _materialHotendChangedCallback(self, button):
- if button == QMessageBox.No:
- self._auto_materials_changed = {}
- self._auto_hotends_changed = {}
- return
- self._autoUpdateMaterials()
- self._autoUpdateHotends()
-
- def _autoUpdateMaterials(self):
- extruder_manager = ExtruderManager.getInstance()
- for position in self._auto_materials_changed:
- material_id = self._auto_materials_changed[position]
- old_index = extruder_manager.activeExtruderIndex
-
- if old_index != int(position):
- extruder_manager.setActiveExtruderIndex(int(position))
- else:
- old_index = None
-
- Logger.log("d", "Setting material of hotend %s to %s" % (position, material_id))
- self.setActiveMaterial(material_id)
-
- if old_index is not None:
- extruder_manager.setActiveExtruderIndex(old_index)
- self._auto_materials_changed = {} #Processed all of them now.
-
- def _autoUpdateHotends(self):
- extruder_manager = ExtruderManager.getInstance()
- for position in self._auto_hotends_changed:
- hotend_id = self._auto_hotends_changed[position]
- old_index = extruder_manager.activeExtruderIndex
-
- if old_index != int(position):
- extruder_manager.setActiveExtruderIndex(int(position))
- else:
- old_index = None
- Logger.log("d", "Setting hotend variant of hotend %s to %s" % (position, hotend_id))
- self.setActiveVariant(hotend_id)
-
- if old_index is not None:
- extruder_manager.setActiveExtruderIndex(old_index)
- self._auto_hotends_changed = {} # Processed all of them now.
-
- def _onGlobalContainerChanged(self):
+ def _onGlobalContainerChanged(self) -> None:
if self._global_container_stack:
try:
self._global_container_stack.nameChanged.disconnect(self._onMachineNameChanged)
@@ -308,9 +191,11 @@ class MachineManager(QObject):
extruder_stack.propertyChanged.disconnect(self._onPropertyChanged)
extruder_stack.containersChanged.disconnect(self._onInstanceContainersChanged)
- # update the local global container stack reference
+ # Update the local global container stack reference
self._global_container_stack = Application.getInstance().getGlobalContainerStack()
-
+ if self._global_container_stack:
+ self.updateDefaultExtruder()
+ self.updateNumberExtrudersEnabled()
self.globalContainerChanged.emit()
# after switching the global stack we reconnect all the signals and set the variant and material references
@@ -342,50 +227,41 @@ class MachineManager(QObject):
Application.getInstance().callLater(func)
del self.machine_extruder_material_update_dict[self._global_container_stack.getId()]
+ self.activeQualityGroupChanged.emit()
self._error_check_timer.start()
## Update self._stacks_valid according to _checkStacksForErrors and emit if change.
- def _updateStacksHaveErrors(self):
+ def _updateStacksHaveErrors(self) -> None:
old_stacks_have_errors = self._stacks_have_errors
self._stacks_have_errors = self._checkStacksHaveErrors()
if old_stacks_have_errors != self._stacks_have_errors:
self.stacksValidationChanged.emit()
Application.getInstance().stacksValidationFinished.emit()
- def _onActiveExtruderStackChanged(self):
+ def _onActiveExtruderStackChanged(self) -> None:
self.blurSettings.emit() # Ensure no-one has focus.
old_active_container_stack = self._active_container_stack
self._active_container_stack = ExtruderManager.getInstance().getActiveExtruderStack()
- 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 __emitChangedSignals(self):
+ def __emitChangedSignals(self) -> None:
self.activeQualityChanged.emit()
self.activeVariantChanged.emit()
self.activeMaterialChanged.emit()
- self._updateStacksHaveErrors() # Prevents unwanted re-slices after changing machine
+
+ self.rootMaterialChanged.emit()
+
self._error_check_timer.start()
- def _onProfilesModelChanged(self, *args):
- self.__emitChangedSignals()
-
- def _onInstanceContainersChanged(self, container):
- # This should not trigger the ProfilesModel to be created, or there will be an infinite recursion
- if not self._connected_to_profiles_model and ProfilesModel.hasInstance():
- # This triggers updating the qualityModel in SidebarSimple whenever ProfilesModel is updated
- Logger.log("d", "Connecting profiles model...")
- ProfilesModel.getInstance().itemsChanged.connect(self._onProfilesModelChanged)
- self._connected_to_profiles_model = True
-
+ def _onInstanceContainersChanged(self, container) -> None:
self._instance_container_timer.start()
- def _onPropertyChanged(self, key: str, property_name: str):
+ def _onPropertyChanged(self, key: str, property_name: str) -> None:
if property_name == "value":
# Notify UI items, such as the "changed" star in profile pull down menu.
self.activeStackValueChanged.emit()
@@ -393,19 +269,57 @@ class MachineManager(QObject):
elif property_name == "validationState":
self._error_check_timer.start()
+ ## Given a global_stack, make sure that it's all valid by searching for this quality group and applying it again
+ def _initMachineState(self, global_stack):
+ material_dict = {}
+ for position, extruder in global_stack.extruders.items():
+ material_dict[position] = extruder.material.getMetaDataEntry("base_file")
+ self._current_root_material_id = material_dict
+ global_quality = global_stack.quality
+ quality_type = global_quality.getMetaDataEntry("quality_type")
+ global_quality_changes = global_stack.qualityChanges
+ global_quality_changes_name = global_quality_changes.getName()
+
+ if global_quality_changes.getId() != "empty_quality_changes":
+ quality_changes_groups = self._application._quality_manager.getQualityChangesGroups(global_stack)
+ if global_quality_changes_name in quality_changes_groups:
+ new_quality_changes_group = quality_changes_groups[global_quality_changes_name]
+ self._setQualityChangesGroup(new_quality_changes_group)
+ else:
+ quality_groups = self._application._quality_manager.getQualityGroups(global_stack)
+ if quality_type not in quality_groups:
+ Logger.log("w", "Quality type [%s] not found in available qualities [%s]", quality_type, str(quality_groups.values()))
+ self._setEmptyQuality()
+ return
+ new_quality_group = quality_groups[quality_type]
+ self._setQualityGroup(new_quality_group, empty_quality_changes = True)
+
@pyqtSlot(str)
def setActiveMachine(self, stack_id: str) -> None:
self.blurSettings.emit() # Ensure no-one has focus.
- self._cancelDelayedActiveContainerStackChanges()
container_registry = ContainerRegistry.getInstance()
containers = container_registry.findContainerStacks(id = stack_id)
if containers:
- Application.getInstance().setGlobalContainerStack(containers[0])
+ global_stack = containers[0]
+ ExtruderManager.getInstance().setActiveExtruderIndex(0) # Switch to first extruder
+ self._global_container_stack = global_stack
+ Application.getInstance().setGlobalContainerStack(global_stack)
+ ExtruderManager.getInstance()._globalContainerStackChanged()
+ self._initMachineState(containers[0])
+ self._onGlobalContainerChanged()
self.__emitChangedSignals()
+ @staticmethod
+ def getMachine(definition_id: str) -> Optional["GlobalStack"]:
+ machines = ContainerRegistry.getInstance().findContainerStacks(type = "machine")
+ for machine in machines:
+ if machine.definition.getId() == definition_id:
+ return machine
+ return None
+
@pyqtSlot(str, str)
def addMachine(self, name: str, definition_id: str) -> None:
new_stack = CuraStackBuilder.createMachine(name, definition_id)
@@ -440,16 +354,6 @@ class MachineManager(QObject):
Logger.log("d", "Checking %s stacks for errors took %.2f s" % (count, time.time() - time_start))
return False
- ## Remove all instances from the top instanceContainer (effectively removing all user-changed settings)
- @pyqtSlot()
- def clearUserSettings(self):
- if not self._active_container_stack:
- return
-
- self.blurSettings.emit()
- user_settings = self._active_container_stack.getTop()
- user_settings.clear()
-
## Check if the global_container has instances in the user container
@pyqtProperty(bool, notify = activeStackValueChanged)
def hasUserSettings(self) -> bool:
@@ -480,7 +384,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: str):
+ def clearUserSettingAllCurrentStacks(self, key: str) -> None:
if not self._global_container_stack:
return
@@ -515,25 +419,16 @@ class MachineManager(QObject):
def stacksHaveErrors(self) -> bool:
return bool(self._stacks_have_errors)
- @pyqtProperty(str, notify = activeStackChanged)
- def activeUserProfileId(self) -> str:
- if self._active_container_stack:
- return self._active_container_stack.getTop().getId()
-
- return ""
-
@pyqtProperty(str, notify = globalContainerChanged)
def activeMachineName(self) -> str:
if self._global_container_stack:
return self._global_container_stack.getName()
-
return ""
@pyqtProperty(str, notify = globalContainerChanged)
def activeMachineId(self) -> str:
if self._global_container_stack:
return self._global_container_stack.getId()
-
return ""
@pyqtProperty(QObject, notify = globalContainerChanged)
@@ -544,42 +439,11 @@ class MachineManager(QObject):
def activeStackId(self) -> str:
if self._active_container_stack:
return self._active_container_stack.getId()
-
return ""
- @pyqtProperty(str, notify = activeMaterialChanged)
- def activeMaterialName(self) -> str:
- if self._active_container_stack:
- material = self._active_container_stack.material
- if material:
- return material.getName()
-
- return ""
-
- @pyqtProperty("QVariantList", notify=activeVariantChanged)
- def activeVariantNames(self) -> List[str]:
- result = []
-
- active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
- if active_stacks is not None:
- for stack in active_stacks:
- variant_container = stack.variant
- if variant_container and variant_container != self._empty_variant_container:
- result.append(variant_container.getName())
-
- return result
-
- @pyqtProperty("QVariantList", notify = activeMaterialChanged)
- def activeMaterialNames(self) -> List[str]:
- result = []
-
- active_stacks = ExtruderManager.getInstance().getActiveGlobalAndExtruderStacks()
- if active_stacks is not None:
- for stack in active_stacks:
- material_container = stack.material
- if material_container and material_container != self._empty_material_container:
- result.append(material_container.getName())
- return result
+ @pyqtProperty(QObject, notify = activeStackChanged)
+ def activeStack(self) -> Optional["ExtruderStack"]:
+ return self._active_container_stack
@pyqtProperty(str, notify=activeMaterialChanged)
def activeMaterialId(self) -> str:
@@ -587,24 +451,8 @@ class MachineManager(QObject):
material = self._active_container_stack.material
if material:
return material.getId()
-
return ""
- @pyqtProperty("QVariantMap", notify = activeVariantChanged)
- def allActiveVariantIds(self) -> Dict[str, str]:
- result = {}
-
- active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
- if active_stacks is not None: #If we have a global stack.
- for stack in active_stacks:
- variant_container = stack.variant
- if not variant_container:
- continue
-
- result[stack.getId()] = variant_container.getId()
-
- return result
-
## Gets a dict with the active materials ids set in all extruder stacks and the global stack
# (when there is one extruder, the material is set in the global stack)
#
@@ -629,106 +477,45 @@ 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)
+ @pyqtProperty(float, notify = activeQualityGroupChanged)
def activeQualityLayerHeight(self) -> float:
if not self._global_container_stack:
return 0
-
- quality_changes = self._global_container_stack.qualityChanges
- if quality_changes:
- value = self._global_container_stack.getRawProperty("layer_height", "value", skip_until_container = quality_changes.getId())
+ if self._current_quality_changes_group:
+ value = self._global_container_stack.getRawProperty("layer_height", "value", skip_until_container = self._global_container_stack.qualityChanges.getId())
if isinstance(value, SettingFunction):
value = value(self._global_container_stack)
return value
- quality = self._global_container_stack.quality
- if quality:
- value = self._global_container_stack.getRawProperty("layer_height", "value", skip_until_container = quality.getId())
+ elif self._current_quality_group:
+ value = self._global_container_stack.getRawProperty("layer_height", "value", skip_until_container = self._global_container_stack.quality.getId())
if isinstance(value, SettingFunction):
value = value(self._global_container_stack)
return value
+ return 0
- return 0 # No quality profile.
-
- ## Get the Material ID associated with the currently active material
- # \returns MaterialID (string) if found, empty string otherwise
- @pyqtProperty(str, notify=activeQualityChanged)
- def activeQualityMaterialId(self) -> str:
- if self._active_container_stack:
- quality = self._active_container_stack.quality
- if quality:
- material_id = quality.getMetaDataEntry("material")
- if material_id:
- # if the currently active machine inherits its qualities from a different machine
- # definition, make sure to return a material that is relevant to that machine definition
- definition_id = self.activeDefinitionId
- quality_definition_id = self.activeQualityDefinitionId
- if definition_id != quality_definition_id:
- material_id = material_id.replace(definition_id, quality_definition_id, 1)
-
- return material_id
- return ""
-
- @pyqtProperty(str, notify=activeQualityChanged)
- 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)):
- return quality.getName()
- quality = self._active_container_stack.quality
- if quality:
- return quality.getName()
- return ""
-
- @pyqtProperty(str, notify=activeQualityChanged)
- def activeQualityId(self) -> str:
- if self._active_container_stack:
- quality = self._active_container_stack.quality
- if isinstance(quality, type(self._empty_quality_container)):
- return ""
- quality_changes = self._active_container_stack.qualityChanges
- if quality and quality_changes:
- if isinstance(quality_changes, type(self._empty_quality_changes_container)):
- # It's a built-in profile
- return quality.getId()
- else:
- # Custom profile
- return quality_changes.getId()
- return ""
-
- @pyqtProperty(str, notify=activeQualityChanged)
- 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)):
- return quality.getId()
- quality = self._global_container_stack.quality
- if quality:
- return quality.getId()
- return ""
-
- @pyqtProperty(str, notify=activeVariantChanged)
- def globalVariantId(self) -> str:
+ @pyqtProperty(str, notify = activeVariantChanged)
+ def globalVariantName(self) -> str:
if self._global_container_stack:
variant = self._global_container_stack.variant
if variant and not isinstance(variant, type(self._empty_variant_container)):
- return variant.getId()
+ return variant.getName()
return ""
- @pyqtProperty(str, notify = activeQualityChanged)
+ @pyqtProperty(str, notify = activeQualityGroupChanged)
def activeQualityType(self) -> str:
+ quality_type = ""
if self._active_container_stack:
- quality = self._active_container_stack.quality
- if quality:
- return quality.getMetaDataEntry("quality_type")
- return ""
+ if self._current_quality_group:
+ quality_type = self._current_quality_group.quality_type
+ return quality_type
- @pyqtProperty(bool, notify = activeQualityChanged)
+ @pyqtProperty(bool, notify = activeQualityGroupChanged)
def isActiveQualitySupported(self) -> bool:
- if self._active_container_stack:
- quality = self._active_container_stack.quality
- if quality:
- return Util.parseBool(quality.getMetaDataEntry("supported", True))
- return False
+ is_supported = False
+ if self._global_container_stack:
+ if self._current_quality_group:
+ is_supported = self._current_quality_group.is_available
+ return is_supported
## Returns whether there is anything unsupported in the current set-up.
#
@@ -747,29 +534,6 @@ class MachineManager(QObject):
return False
return True
- ## Get the Quality ID associated with the currently active extruder
- # Note that this only returns the "quality", not the "quality_changes"
- # \returns QualityID (string) if found, empty string otherwise
- # \sa activeQualityId()
- # \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) -> 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
- if quality:
- return quality.getId()
- return ""
-
- @pyqtProperty(str, notify = activeQualityChanged)
- def activeQualityChangesId(self) -> str:
- if self._active_container_stack:
- quality_changes = self._active_container_stack.qualityChanges
- if quality_changes and not isinstance(quality_changes, type(self._empty_quality_changes_container)):
- return quality_changes.getId()
- return ""
-
## Check if a container is read_only
@pyqtSlot(str, result = bool)
def isReadOnly(self, container_id: str) -> bool:
@@ -786,389 +550,6 @@ class MachineManager(QObject):
if extruder_stack != self._active_container_stack and extruder_stack.getProperty(key, "value") != new_value:
extruder_stack.userChanges.setProperty(key, "value", new_value) # TODO: nested property access, should be improved
- ## 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: str, always_discard_changes = False):
- with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
- containers = ContainerRegistry.getInstance().findInstanceContainers(id = material_id)
- if not containers or not self._active_container_stack:
- return
- material_container = containers[0]
-
- Logger.log("d", "Attempting to change the active material to %s", material_id)
-
- old_material = self._active_container_stack.material
- old_quality = self._active_container_stack.quality
- old_quality_type = None
- if old_quality and old_quality.getId() != self._empty_quality_container.getId():
- old_quality_type = old_quality.getMetaDataEntry("quality_type")
- old_quality_changes = self._active_container_stack.qualityChanges
- if not old_material:
- Logger.log("w", "While trying to set the active material, no material was found to replace it.")
- return
-
- if old_quality_changes and isinstance(old_quality_changes, type(self._empty_quality_changes_container)):
- old_quality_changes = None
-
- self.blurSettings.emit()
- old_material.nameChanged.disconnect(self._onMaterialNameChanged)
-
- self._new_material_container = material_container # self._active_container_stack will be updated with a delay
- Logger.log("d", "Active material changed")
-
- material_container.nameChanged.connect(self._onMaterialNameChanged)
-
- if material_container.getMetaDataEntry("compatible") == False:
- self._material_incompatible_message.show()
- else:
- self._material_incompatible_message.hide()
-
- quality_type = None
- new_quality_id = None
- if old_quality:
- new_quality_id = old_quality.getId()
- quality_type = old_quality.getMetaDataEntry("quality_type")
- if old_quality_changes:
- quality_type = old_quality_changes.getMetaDataEntry("quality_type")
- new_quality_id = old_quality_changes.getId()
-
- global_stack = Application.getInstance().getGlobalContainerStack()
- if global_stack:
- quality_manager = QualityManager.getInstance()
-
- candidate_quality = None
- if quality_type:
- candidate_quality = quality_manager.findQualityByQualityType(quality_type,
- quality_manager.getWholeMachineDefinition(global_stack.definition),
- [material_container.getMetaData()])
-
- if not candidate_quality or candidate_quality.getId() == self._empty_quality_changes_container:
- Logger.log("d", "Attempting to find fallback quality")
- # 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())
-
- quality_types = sorted([q.getMetaDataEntry("quality_type") for q in new_qualities], reverse = True)
- quality_type_to_use = None
- if quality_types:
- # try to use the same quality as before, otherwise the first one in the quality_types
- quality_type_to_use = quality_types[0]
- if old_quality_type is not None and old_quality_type in quality_type_to_use:
- quality_type_to_use = old_quality_type
-
- new_quality = None
- for q in new_qualities:
- if quality_type_to_use is not None and q.getMetaDataEntry("quality_type") == quality_type_to_use:
- new_quality = q
- break
-
- if new_quality is not None:
- new_quality_id = new_quality.getId() # Just pick the first available one
- else:
- Logger.log("w", "No quality profile found that matches the current machine and extruders.")
- else:
- if not old_quality_changes:
- new_quality_id = candidate_quality.getId()
-
- self.setActiveQuality(new_quality_id, always_discard_changes = always_discard_changes)
-
- @pyqtSlot(str)
- def setActiveVariant(self, variant_id: str, always_discard_changes = False):
- with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
- containers = ContainerRegistry.getInstance().findInstanceContainers(id = variant_id)
- if not containers or not self._active_container_stack:
- return
- Logger.log("d", "Attempting to change the active variant to %s", variant_id)
- old_variant = self._active_container_stack.variant
- old_material = self._active_container_stack.material
- if old_variant:
- self.blurSettings.emit()
- self._new_variant_container = containers[0] # self._active_container_stack will be updated with a delay
- Logger.log("d", "Active variant changed to {active_variant_id}".format(active_variant_id = containers[0].getId()))
- preferred_material_name = None
- if old_material:
- preferred_material_name = old_material.getName()
- preferred_material_id = self._updateMaterialContainer(self._global_container_stack.definition, self._global_container_stack, containers[0], preferred_material_name).id
- self.setActiveMaterial(preferred_material_id, always_discard_changes = always_discard_changes)
- else:
- Logger.log("w", "While trying to set the active variant, no variant was found to replace.")
-
- @pyqtSlot(str)
- def setActiveVariantBuildplate(self, variant_buildplate_id: str):
- with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
- containers = ContainerRegistry.getInstance().findInstanceContainers(id = variant_buildplate_id)
- if not containers or not self._global_container_stack:
- return
- Logger.log("d", "Attempting to change the active buildplate to %s", variant_buildplate_id)
- old_buildplate = self._global_container_stack.variant
- if old_buildplate:
- self.blurSettings.emit()
- self._new_buildplate_container = containers[0] # self._active_container_stack will be updated with a delay
- Logger.log("d", "Active buildplate changed to {active_variant_buildplate_id}".format(active_variant_buildplate_id = containers[0].getId()))
-
- # Force set the active quality as it is so the values are updated
- self.setActiveMaterial(self._active_container_stack.material.getId())
- else:
- Logger.log("w", "While trying to set the active buildplate, no buildplate was found to replace.")
-
- ## 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: str, always_discard_changes = False):
- with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
- self.blurSettings.emit()
-
- Logger.log("d", "Attempting to change the active quality to %s", quality_id)
-
- containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = quality_id)
- if not containers or not self._global_container_stack:
- return
-
- # Quality profile come in two flavours: type=quality and type=quality_changes
- # If we found a quality_changes profile then look up its parent quality profile.
- container_type = containers[0].get("type")
- quality_name = containers[0]["name"]
- quality_type = containers[0].get("quality_type")
-
- # Get quality container and optionally the quality_changes container.
- if container_type == "quality":
- new_quality_settings_list = self.determineQualityAndQualityChangesForQualityType(quality_type)
- elif container_type == "quality_changes":
- new_quality_settings_list = self._determineQualityAndQualityChangesForQualityChanges(quality_name)
- else:
- Logger.log("e", "Tried to set quality to a container that is not of the right type: {container_id}".format(container_id = containers[0]["id"]))
- return
-
- # Check if it was at all possible to find new settings
- if new_quality_settings_list is None:
- return
-
- # check if any of the stacks have a not supported profile
- # if that is the case, all stacks should have a not supported state (otherwise it will show quality_type normal)
- has_not_supported_quality = False
-
- # check all stacks for not supported
- for setting_info in new_quality_settings_list:
- if setting_info["quality"].getMetaDataEntry("quality_type") == "not_supported":
- has_not_supported_quality = True
- break
-
- # set all stacks to not supported if that's the case
- if has_not_supported_quality:
- for setting_info in new_quality_settings_list:
- setting_info["quality"] = self._empty_quality_container
-
- self._new_quality_containers.clear()
-
- # store the upcoming quality profile changes per stack for later execution
- # this prevents re-slicing before the user has made a choice in the discard or keep dialog
- # (see _executeDelayedActiveContainerStackChanges)
- for setting_info in new_quality_settings_list:
- stack = setting_info["stack"]
- stack_quality = setting_info["quality"]
- stack_quality_changes = setting_info["quality_changes"]
-
- self._new_quality_containers.append({
- "stack": stack,
- "quality": stack_quality,
- "quality_changes": stack_quality_changes
- })
-
- Logger.log("d", "Active quality changed")
-
- # show the keep/discard dialog after the containers have been switched. Otherwise, the default values on
- # the dialog will be the those before the switching.
- self._executeDelayedActiveContainerStackChanges()
-
- if self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1 and not always_discard_changes:
- Application.getInstance().discardOrKeepProfileChanges()
-
- ## Used to update material and variant in the active container stack with a delay.
- # This delay prevents the stack from triggering a lot of signals (eventually resulting in slicing)
- # before the user decided to keep or discard any of their changes using the dialog.
- # The Application.onDiscardOrKeepProfileChangesClosed signal triggers this method.
- def _executeDelayedActiveContainerStackChanges(self):
-
- Logger.log("d", "Applying configuration changes...")
-
- if self._new_variant_container is not None:
- self._active_container_stack.variant = self._new_variant_container
- self._new_variant_container = None
-
- if self._new_buildplate_container is not None:
- self._global_container_stack.variant = self._new_buildplate_container
- self._new_buildplate_container = None
-
- if self._new_material_container is not None:
- self._active_container_stack.material = self._new_material_container
- self._new_material_container = None
-
- # apply the new quality to all stacks
- if self._new_quality_containers:
- for new_quality in self._new_quality_containers:
- self._replaceQualityOrQualityChangesInStack(new_quality["stack"], new_quality["quality"], postpone_emit = True)
- self._replaceQualityOrQualityChangesInStack(new_quality["stack"], new_quality["quality_changes"], postpone_emit = True)
-
- for new_quality in self._new_quality_containers:
- new_quality["stack"].nameChanged.connect(self._onQualityNameChanged)
- new_quality["stack"].sendPostponedEmits() # Send the signals that were postponed in _replaceQualityOrQualityChangesInStack
-
- self._new_quality_containers.clear()
-
- Logger.log("d", "New configuration applied")
-
- ## Cancel set changes for material and variant in the active container stack.
- # Used for ignoring any changes when switching between printers (setActiveMachine)
- def _cancelDelayedActiveContainerStackChanges(self):
- self._new_material_container = None
- self._new_buildplate_container = None
- self._new_variant_container = None
-
- ## Determine the quality and quality changes settings for the current machine for a quality name.
- #
- # \param quality_name \type{str} the name of the quality.
- # \return \type{List[Dict]} with keys "stack", "quality" and "quality_changes".
- @UM.FlameProfiler.profile
- def determineQualityAndQualityChangesForQualityType(self, quality_type: str) -> List[Dict[str, Union["CuraContainerStack", InstanceContainer]]]:
- quality_manager = QualityManager.getInstance()
- result = []
- empty_quality_changes = self._empty_quality_changes_container
- global_container_stack = self._global_container_stack
- if not global_container_stack:
- return []
-
- global_machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.definition)
- extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
-
- # find qualities for extruders
- for extruder_stack in extruder_stacks:
- material_metadata = extruder_stack.material.getMetaData()
-
- # TODO: fix this
- if self._new_material_container and extruder_stack.getId() == self._active_container_stack.getId():
- material_metadata = self._new_material_container.getMetaData()
-
- quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material_metadata])
-
- if not quality:
- # No quality profile is found for this quality type.
- quality = self._empty_quality_container
-
- result.append({
- "stack": extruder_stack,
- "quality": quality,
- "quality_changes": empty_quality_changes
- })
-
- # also find a global quality for the machine
- global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [], global_quality = "True")
-
- # if there is not global quality but we're using a single extrusion machine, copy the quality of the first extruder - CURA-4482
- if not global_quality and len(extruder_stacks) == 1:
- global_quality = result[0]["quality"]
-
- # if there is still no global quality, set it to empty (not supported)
- if not global_quality:
- global_quality = self._empty_quality_container
-
- result.append({
- "stack": global_container_stack,
- "quality": global_quality,
- "quality_changes": empty_quality_changes
- })
-
- return result
-
- ## Determine the quality and quality changes settings for the current machine for a quality changes name.
- #
- # \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: str) -> Optional[List[Dict[str, Union["CuraContainerStack", InstanceContainer]]]]:
- result = []
- quality_manager = QualityManager.getInstance()
-
- global_container_stack = self._global_container_stack
- global_machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.definition)
- quality_changes_profiles = quality_manager.findQualityChangesByName(quality_changes_name, global_machine_definition)
-
- global_quality_changes = [qcp for qcp in quality_changes_profiles if qcp.getMetaDataEntry("extruder") is None]
- if global_quality_changes:
- global_quality_changes = global_quality_changes[0]
- else:
- Logger.log("e", "Could not find the global quality changes container with name %s", quality_changes_name)
- return None
-
- # For the global stack, find a quality which matches the quality_type in
- # the quality changes profile and also satisfies any material constraints.
- quality_type = global_quality_changes.getMetaDataEntry("quality_type")
-
- extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
-
- # append the extruder quality changes
- for extruder_stack in extruder_stacks:
- extruder_definition = quality_manager.getParentMachineDefinition(extruder_stack.definition)
-
- quality_changes_list = [qcp for qcp in quality_changes_profiles if qcp.getMetaDataEntry("extruder") == extruder_definition.getId()]
-
- if quality_changes_list:
- quality_changes = quality_changes_list[0]
- else:
- quality_changes = global_quality_changes
- if not quality_changes:
- quality_changes = self._empty_quality_changes_container
-
- material_metadata = extruder_stack.material.getMetaData()
-
- if self._new_material_container and self._active_container_stack.getId() == extruder_stack.getId():
- material_metadata = self._new_material_container.getMetaData()
-
- quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, [material_metadata])
-
- if not quality:
- # No quality profile found for this quality type.
- quality = self._empty_quality_container
-
- result.append({
- "stack": extruder_stack,
- "quality": quality,
- "quality_changes": quality_changes
- })
-
- # append the global quality changes
- global_quality = quality_manager.findQualityByQualityType(quality_type, global_machine_definition, global_quality = "True")
-
- # if there is not global quality but we're using a single extrusion machine, copy the quality of the first extruder - CURA-4482
- if not global_quality and len(extruder_stacks) == 1:
- global_quality = result[0]["quality"]
-
- # if still no global quality changes are found we set it to empty (not supported)
- if not global_quality:
- global_quality = self._empty_quality_container
-
- result.append({
- "stack": global_container_stack,
- "quality": global_quality,
- "quality_changes": global_quality_changes
- })
-
- return result
-
- 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, postpone_emit = postpone_emit)
- stack.quality.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, postpone_emit = postpone_emit)
- stack.qualityChanges.nameChanged.connect(self._onQualityNameChanged)
- self._onQualityNameChanged()
-
@pyqtProperty(str, notify = activeVariantChanged)
def activeVariantName(self) -> str:
if self._active_container_stack:
@@ -1178,15 +559,6 @@ class MachineManager(QObject):
return ""
- @pyqtProperty(str, notify = activeVariantChanged)
- def activeVariantId(self) -> str:
- if self._active_container_stack:
- variant = self._active_container_stack.variant
- if variant:
- return variant.getId()
-
- return ""
-
@pyqtProperty(str, notify = activeVariantChanged)
def activeVariantBuildplateName(self) -> str:
if self._global_container_stack:
@@ -1203,55 +575,14 @@ class MachineManager(QObject):
return ""
- @pyqtProperty(str, notify=globalContainerChanged)
- def activeDefinitionName(self) -> str:
- if self._global_container_stack:
- return self._global_container_stack.definition.getName()
-
- return ""
-
## Get the Definition ID to use to select quality profiles for the currently active machine
# \returns DefinitionID (string) if found, empty string otherwise
- # \sa getQualityDefinitionId
@pyqtProperty(str, notify = globalContainerChanged)
def activeQualityDefinitionId(self) -> str:
if self._global_container_stack:
- return self.getQualityDefinitionId(self._global_container_stack.definition)
+ return getMachineDefinitionIDForQualitySearch(self._global_container_stack)
return ""
- ## Get the Definition ID to use to select quality profiles for machines of the specified definition
- # 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: "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) -> str:
- if self._active_container_stack:
- variant = self._active_container_stack.variant
- if variant:
- return self.getQualityVariantId(self._global_container_stack.definition, variant)
- return ""
-
- ## Get the Variant ID to use to select quality profiles for variants of the specified definitions
- # 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 (InstanceContainer) variant definition
- # \returns VariantID (string) if found, empty string otherwise
- def getQualityVariantId(self, definition: "DefinitionContainer", variant: "InstanceContainer") -> str:
- variant_id = variant.getId()
- definition_id = definition.getId()
- quality_definition_id = self.getQualityDefinitionId(definition)
-
- if definition_id != quality_definition_id:
- variant_id = variant_id.replace(definition_id, quality_definition_id, 1)
- return variant_id
-
## Gets how the active definition calls variants
# Caveat: per-definition-variant-title is currently not translated (though the fallback is)
@pyqtProperty(str, notify = globalContainerChanged)
@@ -1316,6 +647,8 @@ class MachineManager(QObject):
buildplate_compatible = True # It is compatible by default
extruder_stacks = self._global_container_stack.extruders.values()
for stack in extruder_stacks:
+ if not stack.isEnabled:
+ continue
material_container = stack.material
if material_container == self._empty_material_container:
continue
@@ -1373,6 +706,43 @@ class MachineManager(QObject):
if containers:
return containers[0].definition.getId()
+ def getIncompatibleSettingsOnEnabledExtruders(self, container):
+ extruder_count = self._global_container_stack.getProperty("machine_extruder_count", "value")
+ result = []
+ for setting_instance in container.findInstances():
+ setting_key = setting_instance.definition.key
+ setting_enabled = self._global_container_stack.getProperty(setting_key, "enabled")
+ if not setting_enabled:
+ # A setting is not visible anymore
+ result.append(setting_key)
+ Logger.log("d", "Reset setting [%s] from [%s] because the setting is no longer enabled", setting_key, container)
+ continue
+
+ if not self._global_container_stack.getProperty(setting_key, "type") in ("extruder", "optional_extruder"):
+ continue
+
+ old_value = container.getProperty(setting_key, "value")
+ if int(old_value) >= extruder_count or not self._global_container_stack.extruders[str(old_value)].isEnabled:
+ result.append(setting_key)
+ Logger.log("d", "Reset setting [%s] in [%s] because its old value [%s] is no longer valid", setting_key, container, old_value)
+ return result
+
+ ## Update extruder number to a valid value when the number of extruders are changed, or when an extruder is changed
+ def correctExtruderSettings(self):
+ for setting_key in self.getIncompatibleSettingsOnEnabledExtruders(self._global_container_stack.userChanges):
+ self._global_container_stack.userChanges.removeInstance(setting_key)
+ add_user_changes = self.getIncompatibleSettingsOnEnabledExtruders(self._global_container_stack.qualityChanges)
+ for setting_key in add_user_changes:
+ # Apply quality changes that are incompatible to user changes, so we do not change the quality changes itself.
+ self._global_container_stack.userChanges.setProperty(setting_key, "value", self._default_extruder_position)
+ if add_user_changes:
+ caution_message = Message(catalog.i18nc(
+ "@info:generic",
+ "Settings have been changed to match the current availability of extruders: [%s]" % ", ".join(add_user_changes)),
+ lifetime=0,
+ title = catalog.i18nc("@info:title", "Settings updated"))
+ caution_message.show()
+
## Set the amount of extruders on the active machine (global stack)
# \param extruder_count int the number of extruders to set
def setActiveMachineExtruderCount(self, extruder_count):
@@ -1386,16 +756,11 @@ class MachineManager(QObject):
if extruder_count == previous_extruder_count:
return
- # reset all extruder number settings whose value is no longer valid
- for setting_instance in self._global_container_stack.userChanges.findInstances():
- setting_key = setting_instance.definition.key
- if not self._global_container_stack.getProperty(setting_key, "type") in ("extruder", "optional_extruder"):
- continue
+ definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count)
- old_value = int(self._global_container_stack.userChanges.getProperty(setting_key, "value"))
- if old_value >= extruder_count:
- self._global_container_stack.userChanges.removeInstance(setting_key)
- Logger.log("d", "Reset [%s] because its old value [%s] is no longer valid ", setting_key, old_value)
+ self.updateDefaultExtruder()
+ self.updateNumberExtrudersEnabled()
+ self.correctExtruderSettings()
# Check to see if any objects are set to print with an extruder that will no longer exist
root_node = Application.getInstance().getController().getScene().getRoot()
@@ -1406,21 +771,19 @@ class MachineManager(QObject):
if extruder_nr is not None and int(extruder_nr) > extruder_count - 1:
node.callDecoration("setActiveExtruder", extruder_manager.getExtruderStack(extruder_count - 1).getId())
- definition_changes_container.setProperty("machine_extruder_count", "value", extruder_count)
-
# Make sure one of the extruder stacks is active
extruder_manager.setActiveExtruderIndex(0)
# Move settable_per_extruder values out of the global container
# After CURA-4482 this should not be the case anymore, but we still want to support older project files.
- global_user_container = self._global_container_stack.getTop()
+ global_user_container = self._global_container_stack.userChanges
# Make sure extruder_stacks exists
extruder_stacks = []
if previous_extruder_count == 1:
extruder_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
- global_user_container = self._global_container_stack.getTop()
+ global_user_container = self._global_container_stack.userChanges
for setting_instance in global_user_container.findInstances():
setting_key = setting_instance.definition.key
@@ -1429,53 +792,66 @@ class MachineManager(QObject):
if settable_per_extruder:
limit_to_extruder = int(self._global_container_stack.getProperty(setting_key, "limit_to_extruder"))
extruder_stack = extruder_stacks[max(0, limit_to_extruder)]
- extruder_stack.getTop().setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value"))
+ extruder_stack.userChanges.setProperty(setting_key, "value", global_user_container.getProperty(setting_key, "value"))
global_user_container.removeInstance(setting_key)
# Signal that the global stack has changed
Application.getInstance().globalContainerStackChanged.emit()
+ self.forceUpdateAllSettings()
- @staticmethod
- def createMachineManager():
- return MachineManager()
+ @pyqtSlot(int, result = QObject)
+ def getExtruder(self, position: int):
+ extruder = None
+ if self._global_container_stack:
+ extruder = self._global_container_stack.extruders.get(str(position))
+ return extruder
- @deprecated("Use ExtruderStack.material = ... and it won't be necessary", "2.7")
- def _updateMaterialContainer(self, definition: "DefinitionContainer", stack: "ContainerStack", variant_container: Optional["InstanceContainer"] = None, preferred_material_name: Optional[str] = None) -> InstanceContainer:
- if not definition.getMetaDataEntry("has_materials"):
- return self._empty_material_container
+ def updateDefaultExtruder(self):
+ extruder_items = sorted(self._global_container_stack.extruders.items())
+ old_position = self._default_extruder_position
+ new_default_position = "0"
+ for position, extruder in extruder_items:
+ if extruder.isEnabled:
+ new_default_position = position
+ break
+ if new_default_position != old_position:
+ self._default_extruder_position = new_default_position
+ self.extruderChanged.emit()
- approximate_material_diameter = str(round(stack.getProperty("material_diameter", "value")))
- search_criteria = { "type": "material", "approximate_diameter": approximate_material_diameter }
+ def updateNumberExtrudersEnabled(self):
+ definition_changes_container = self._global_container_stack.definitionChanges
+ extruder_count = 0
+ for position, extruder in self._global_container_stack.extruders.items():
+ if extruder.isEnabled:
+ extruder_count += 1
+ definition_changes_container.setProperty("extruders_enabled_count", "value", extruder_count)
- if definition.getMetaDataEntry("has_machine_materials"):
- search_criteria["definition"] = self.getQualityDefinitionId(definition)
+ @pyqtProperty(str, notify = extruderChanged)
+ def defaultExtruderPosition(self):
+ return self._default_extruder_position
- if definition.getMetaDataEntry("has_variants") and variant_container:
- search_criteria["variant"] = self.getQualityVariantId(definition, variant_container)
- else:
- search_criteria["definition"] = "fdmprinter"
+ ## This will fire the propertiesChanged for all settings so they will be updated in the front-end
+ def forceUpdateAllSettings(self):
+ property_names = ["value", "resolve"]
+ for setting_key in self._global_container_stack.getAllKeys():
+ self._global_container_stack.propertiesChanged.emit(setting_key, property_names)
- if preferred_material_name:
- search_criteria["name"] = preferred_material_name
- else:
- preferred_material = definition.getMetaDataEntry("preferred_material")
- if preferred_material:
- search_criteria["id"] = preferred_material
-
- containers = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
- if containers:
- return containers[0]
-
- if "variant" in search_criteria or "id" in search_criteria:
- # If a material by this name can not be found, try a wider set of search criteria
- search_criteria.pop("variant", None)
- search_criteria.pop("id", None)
-
- containers = ContainerRegistry.getInstance().findInstanceContainers(**search_criteria)
- if containers:
- return containers[0]
- Logger.log("w", "Unable to find a material container with provided criteria, returning an empty one instead.")
- return self._empty_material_container
+ @pyqtSlot(int, bool)
+ def setExtruderEnabled(self, position: int, enabled) -> None:
+ extruder = self.getExtruder(position)
+ extruder.setEnabled(enabled)
+ self.updateDefaultExtruder()
+ self.updateNumberExtrudersEnabled()
+ self.correctExtruderSettings()
+ # ensure that the quality profile is compatible with current combination, or choose a compatible one if available
+ self._updateQualityWithMaterial()
+ self.extruderChanged.emit()
+ # update material compatibility color
+ self.activeQualityGroupChanged.emit()
+ # update items in SettingExtruder
+ ExtruderManager.getInstance().extrudersChanged.emit(self._global_container_stack.getId())
+ # Make sure the front end reflects changes
+ self.forceUpdateAllSettings()
def _onMachineNameChanged(self):
self.globalContainerChanged.emit()
@@ -1490,3 +866,279 @@ class MachineManager(QObject):
stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
stacks.append(self._global_container_stack)
return [ s.containersChanged for s in stacks ]
+
+ @pyqtSlot(str, str, str)
+ def setSettingForAllExtruders(self, setting_name: str, property_name: str, property_value: str):
+ for key, extruder in self._global_container_stack.extruders.items():
+ container = extruder.userChanges
+ container.setProperty(setting_name, property_name, property_value)
+
+ @pyqtProperty("QVariantList", notify = globalContainerChanged)
+ def currentExtruderPositions(self):
+ if self._global_container_stack is None:
+ return []
+ return sorted(list(self._global_container_stack.extruders.keys()))
+
+ ## Update _current_root_material_id and _current_root_material_name when
+ # the current root material was changed.
+ def _onRootMaterialChanged(self):
+ self._current_root_material_id = {}
+
+ if self._global_container_stack:
+ for position in self._global_container_stack.extruders:
+ self._current_root_material_id[position] = self._global_container_stack.extruders[position].material.getMetaDataEntry("base_file")
+ self._current_root_material_name = {}
+ for position in self._global_container_stack.extruders:
+ if position not in self._current_root_material_name:
+ material = self._global_container_stack.extruders[position].material
+ self._current_root_material_name[position] = material.getName()
+
+ @pyqtProperty("QVariant", notify = rootMaterialChanged)
+ def currentRootMaterialId(self):
+ return self._current_root_material_id
+
+ @pyqtProperty("QVariant", notify = rootMaterialChanged)
+ def currentRootMaterialName(self):
+ return self._current_root_material_name
+
+ ## Return the variant names in the extruder stack(s).
+ ## For the variant in the global stack, use activeVariantBuildplateName
+ @pyqtProperty("QVariant", notify = activeVariantChanged)
+ def activeVariantNames(self):
+ result = {}
+
+ active_stacks = ExtruderManager.getInstance().getActiveExtruderStacks()
+ if active_stacks is not None:
+ for stack in active_stacks:
+ variant_container = stack.variant
+ position = stack.getMetaDataEntry("position")
+ if variant_container and variant_container != self._empty_variant_container:
+ result[position] = variant_container.getName()
+
+ return result
+
+ #
+ # Sets all quality and quality_changes containers to empty_quality and empty_quality_changes containers
+ # for all stacks in the currently active machine.
+ #
+ def _setEmptyQuality(self):
+ self._current_quality_group = None
+ self._current_quality_changes_group = None
+ self._global_container_stack.quality = self._empty_quality_container
+ self._global_container_stack.qualityChanges = self._empty_quality_changes_container
+ for extruder in self._global_container_stack.extruders.values():
+ extruder.quality = self._empty_quality_container
+ extruder.qualityChanges = self._empty_quality_changes_container
+
+ self.activeQualityGroupChanged.emit()
+ self.activeQualityChangesGroupChanged.emit()
+
+ def _setQualityGroup(self, quality_group, empty_quality_changes = True):
+ self._current_quality_group = quality_group
+ if empty_quality_changes:
+ self._current_quality_changes_group = None
+
+ # Set quality and quality_changes for the GlobalStack
+ self._global_container_stack.quality = quality_group.node_for_global.getContainer()
+ if empty_quality_changes:
+ self._global_container_stack.qualityChanges = self._empty_quality_changes_container
+
+ # Set quality and quality_changes for each ExtruderStack
+ for position, node in quality_group.nodes_for_extruders.items():
+ self._global_container_stack.extruders[str(position)].quality = node.getContainer()
+ if empty_quality_changes:
+ self._global_container_stack.extruders[str(position)].qualityChanges = self._empty_quality_changes_container
+
+ self.activeQualityGroupChanged.emit()
+ self.activeQualityChangesGroupChanged.emit()
+
+ def _setQualityChangesGroup(self, quality_changes_group):
+ quality_type = quality_changes_group.quality_type
+ quality_group_dict = self._quality_manager.getQualityGroups(self._global_container_stack)
+ quality_group = quality_group_dict[quality_type]
+
+ quality_changes_container = self._empty_quality_changes_container
+ quality_container = self._empty_quality_changes_container
+ if quality_changes_group.node_for_global:
+ quality_changes_container = quality_changes_group.node_for_global.getContainer()
+ if quality_group.node_for_global:
+ quality_container = quality_group.node_for_global.getContainer()
+
+ self._global_container_stack.quality = quality_container
+ self._global_container_stack.qualityChanges = quality_changes_container
+
+ for position, extruder in self._global_container_stack.extruders.items():
+ quality_changes_node = quality_changes_group.nodes_for_extruders.get(position)
+ quality_node = quality_group.nodes_for_extruders.get(position)
+
+ quality_changes_container = self._empty_quality_changes_container
+ quality_container = self._empty_quality_container
+ if quality_changes_node:
+ quality_changes_container = quality_changes_node.getContainer()
+ if quality_node:
+ quality_container = quality_node.getContainer()
+
+ extruder.quality = quality_container
+ extruder.qualityChanges = quality_changes_container
+
+ self._current_quality_group = quality_group
+ self._current_quality_changes_group = quality_changes_group
+ self.activeQualityGroupChanged.emit()
+ self.activeQualityChangesGroupChanged.emit()
+
+ def _setVariantNode(self, position, container_node):
+ self._global_container_stack.extruders[position].variant = container_node.getContainer()
+ self.activeVariantChanged.emit()
+
+ def _setGlobalVariant(self, container_node):
+ self._global_container_stack.variant = container_node.getContainer()
+
+ def _setMaterial(self, position, container_node = None):
+ if container_node:
+ self._global_container_stack.extruders[position].material = container_node.getContainer()
+ root_material_id = container_node.metadata["base_file"]
+ root_material_name = container_node.getContainer().getName()
+ else:
+ self._global_container_stack.extruders[position].material = self._empty_material_container
+ root_material_id = None
+ root_material_name = None
+ # The _current_root_material_id is used in the MaterialMenu to see which material is selected
+ if root_material_id != self._current_root_material_id[position]:
+ self._current_root_material_id[position] = root_material_id
+ self._current_root_material_name[position] = root_material_name
+ self.rootMaterialChanged.emit()
+
+ def activeMaterialsCompatible(self):
+ # check material - variant compatibility
+ if Util.parseBool(self._global_container_stack.getMetaDataEntry("has_materials", False)):
+ for position, extruder in self._global_container_stack.extruders.items():
+ if extruder.isEnabled and not extruder.material.getMetaDataEntry("compatible"):
+ return False
+ if not extruder.material.getMetaDataEntry("compatible"):
+ return False
+ return True
+
+ ## Update current quality type and machine after setting material
+ def _updateQualityWithMaterial(self):
+ Logger.log("i", "Updating quality/quality_changes due to material change")
+ current_quality_type = None
+ if self._current_quality_group:
+ current_quality_type = self._current_quality_group.quality_type
+ candidate_quality_groups = self._quality_manager.getQualityGroups(self._global_container_stack)
+ available_quality_types = {qt for qt, g in candidate_quality_groups.items() if g.is_available}
+
+ Logger.log("d", "Current quality type = [%s]", current_quality_type)
+ if not self.activeMaterialsCompatible():
+ Logger.log("i", "Active materials are not compatible, setting all qualities to empty (Not Supported).")
+ self._setEmptyQuality()
+ return
+
+ if not available_quality_types:
+ Logger.log("i", "No available quality types found, setting all qualities to empty (Not Supported).")
+ self._setEmptyQuality()
+ return
+
+ if current_quality_type in available_quality_types:
+ Logger.log("i", "Current available quality type [%s] is available, applying changes.", current_quality_type)
+ self._setQualityGroup(candidate_quality_groups[current_quality_type], empty_quality_changes = False)
+ return
+
+ # The current quality type is not available so we use the preferred quality type if it's available,
+ # otherwise use one of the available quality types.
+ quality_type = sorted(list(available_quality_types))[0]
+ preferred_quality_type = self._global_container_stack.getMetaDataEntry("preferred_quality_type")
+ if preferred_quality_type in available_quality_types:
+ quality_type = preferred_quality_type
+
+ Logger.log("i", "The current quality type [%s] is not available, switching to [%s] instead",
+ current_quality_type, quality_type)
+ self._setQualityGroup(candidate_quality_groups[quality_type], empty_quality_changes = True)
+
+ def _updateMaterialWithVariant(self, position: Optional[str]):
+ if position is None:
+ position_list = list(self._global_container_stack.extruders.keys())
+ else:
+ position_list = [position]
+
+ for position in position_list:
+ extruder = self._global_container_stack.extruders[position]
+
+ current_material_base_name = extruder.material.getMetaDataEntry("base_file")
+ current_variant_name = extruder.variant.getMetaDataEntry("name")
+
+ material_diameter = self._global_container_stack.getProperty("material_diameter", "value")
+ candidate_materials = self._material_manager.getAvailableMaterials(
+ self._global_container_stack.definition.getId(),
+ current_variant_name,
+ material_diameter)
+
+ if not candidate_materials:
+ self._setMaterial(position, container_node = None)
+ continue
+
+ if current_material_base_name in candidate_materials:
+ new_material = candidate_materials[current_material_base_name]
+ self._setMaterial(position, new_material)
+ continue
+
+ @pyqtSlot("QVariant")
+ def setGlobalVariant(self, container_node):
+ self.blurSettings.emit()
+ with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
+ self._setGlobalVariant(container_node)
+ self._updateMaterialWithVariant(None) # Update all materials
+ self._updateQualityWithMaterial()
+
+ @pyqtSlot(str, "QVariant")
+ def setMaterial(self, position, container_node):
+ position = str(position)
+ self.blurSettings.emit()
+ with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
+ self._setMaterial(position, container_node)
+ self._updateQualityWithMaterial()
+
+ @pyqtSlot(str, "QVariant")
+ def setVariantGroup(self, position, container_node):
+ position = str(position)
+ self.blurSettings.emit()
+ with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
+ self._setVariantNode(position, container_node)
+ self._updateMaterialWithVariant(position)
+ self._updateQualityWithMaterial()
+
+ @pyqtSlot(QObject)
+ def setQualityGroup(self, quality_group, no_dialog = False):
+ self.blurSettings.emit()
+ with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
+ self._setQualityGroup(quality_group)
+
+ # See if we need to show the Discard or Keep changes screen
+ if not no_dialog and self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
+ self._application.discardOrKeepProfileChanges()
+
+ @pyqtProperty(QObject, fset = setQualityGroup, notify = activeQualityGroupChanged)
+ def activeQualityGroup(self):
+ return self._current_quality_group
+
+ @pyqtSlot(QObject)
+ def setQualityChangesGroup(self, quality_changes_group, no_dialog = False):
+ self.blurSettings.emit()
+ with postponeSignals(*self._getContainerChangedSignals(), compress = CompressTechnique.CompressPerParameterValue):
+ self._setQualityChangesGroup(quality_changes_group)
+
+ # See if we need to show the Discard or Keep changes screen
+ if not no_dialog and self.hasUserSettings and Preferences.getInstance().getValue("cura/active_mode") == 1:
+ self._application.discardOrKeepProfileChanges()
+
+ @pyqtProperty(QObject, fset = setQualityChangesGroup, notify = activeQualityChangesGroupChanged)
+ def activeQualityChangesGroup(self):
+ return self._current_quality_changes_group
+
+ @pyqtProperty(str, notify = activeQualityGroupChanged)
+ def activeQualityOrQualityChangesName(self):
+ name = self._empty_quality_container.getName()
+ if self._current_quality_changes_group:
+ name = self._current_quality_changes_group.name
+ elif self._current_quality_group:
+ name = self._current_quality_group.name
+ return name
diff --git a/cura/Settings/MaterialManager.py b/cura/Settings/MaterialManager.py
deleted file mode 100644
index 80d2723438..0000000000
--- a/cura/Settings/MaterialManager.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright (c) 2017 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from PyQt5.QtCore import QObject, pyqtSlot #To expose data to QML.
-
-from cura.Settings.ContainerManager import ContainerManager
-from UM.Logger import Logger
-from UM.Message import Message #To create a warning message about material diameter.
-from UM.i18n import i18nCatalog #Translated strings.
-
-catalog = i18nCatalog("cura")
-
-## Handles material-related data, processing requests to change them and
-# providing data for the GUI.
-#
-# TODO: Move material-related managing over from the machine manager to here.
-class MaterialManager(QObject):
- ## Creates the global values for the material manager to use.
- def __init__(self, parent = None):
- super().__init__(parent)
-
- #Material diameter changed warning message.
- self._material_diameter_warning_message = Message(catalog.i18nc("@info:status Has a cancel button next to it.",
- "The selected material diameter causes the material to become incompatible with the current printer."), title = catalog.i18nc("@info:title", "Incompatible Material"))
- self._material_diameter_warning_message.addAction("Undo", catalog.i18nc("@action:button", "Undo"), None, catalog.i18nc("@action", "Undo changing the material diameter."))
- self._material_diameter_warning_message.actionTriggered.connect(self._materialWarningMessageAction)
-
- ## Creates an instance of the MaterialManager.
- #
- # This should only be called by PyQt to create the singleton instance of
- # this class.
- @staticmethod
- def createMaterialManager(engine = None, script_engine = None):
- return MaterialManager()
-
- @pyqtSlot(str, str)
- def showMaterialWarningMessage(self, material_id, previous_diameter):
- self._material_diameter_warning_message.previous_diameter = previous_diameter #Make sure that the undo button can properly undo the action.
- self._material_diameter_warning_message.material_id = material_id
- self._material_diameter_warning_message.show()
-
- ## Called when clicking "undo" on the warning dialogue for disappeared
- # materials.
- #
- # This executes the undo action, restoring the material diameter.
- #
- # \param button The identifier of the button that was pressed.
- def _materialWarningMessageAction(self, message, button):
- if button == "Undo":
- container_manager = ContainerManager.getInstance()
- container_manager.setContainerMetaDataEntry(self._material_diameter_warning_message.material_id, "properties/diameter", self._material_diameter_warning_message.previous_diameter)
- approximate_previous_diameter = str(round(float(self._material_diameter_warning_message.previous_diameter)))
- container_manager.setContainerMetaDataEntry(self._material_diameter_warning_message.material_id, "approximate_diameter", approximate_previous_diameter)
- container_manager.setContainerProperty(self._material_diameter_warning_message.material_id, "material_diameter", "value", self._material_diameter_warning_message.previous_diameter);
- message.hide()
- else:
- Logger.log("w", "Unknown button action for material diameter warning message: {action}".format(action = button))
\ No newline at end of file
diff --git a/cura/Settings/MaterialSettingsVisibilityHandler.py b/cura/Settings/MaterialSettingsVisibilityHandler.py
index 5b6050d2c0..ce545f4551 100644
--- a/cura/Settings/MaterialSettingsVisibilityHandler.py
+++ b/cura/Settings/MaterialSettingsVisibilityHandler.py
@@ -3,13 +3,14 @@
import UM.Settings.Models.SettingVisibilityHandler
+
class MaterialSettingsVisibilityHandler(UM.Settings.Models.SettingVisibilityHandler.SettingVisibilityHandler):
def __init__(self, parent = None, *args, **kwargs):
super().__init__(parent = parent, *args, **kwargs)
material_settings = {
"default_material_print_temperature",
- "material_bed_temperature",
+ "default_material_bed_temperature",
"material_standby_temperature",
#"material_flow_temp_graph",
"cool_fan_speed",
diff --git a/cura/Settings/MaterialsModel.py b/cura/Settings/MaterialsModel.py
deleted file mode 100644
index c4b0329336..0000000000
--- a/cura/Settings/MaterialsModel.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (c) 2017 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from typing import Any, List
-from UM.Settings.ContainerRegistry import ContainerRegistry #To listen for changes to the materials.
-from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel #We're extending this class.
-
-## A model that shows a list of currently valid materials.
-class MaterialsModel(InstanceContainersModel):
- def __init__(self, parent = None):
- super().__init__(parent)
-
- ContainerRegistry.getInstance().containerMetaDataChanged.connect(self._onContainerMetaDataChanged)
-
- ## Called when the metadata of the container was changed.
- #
- # This makes sure that we only update when it was a material that changed.
- #
- # \param container The container whose metadata was changed.
- def _onContainerMetaDataChanged(self, container):
- if container.getMetaDataEntry("type") == "material": #Only need to update if a material was changed.
- self._container_change_timer.start()
-
- def _onContainerChanged(self, container):
- if container.getMetaDataEntry("type", "") == "material":
- super()._onContainerChanged(container)
-
- ## Group brand together
- def _sortKey(self, item) -> List[Any]:
- result = []
- result.append(item["metadata"]["brand"])
- result.append(item["metadata"]["material"])
- result.append(item["metadata"]["name"])
- result.append(item["metadata"]["color_name"])
- result.append(item["metadata"]["id"])
- result.extend(super()._sortKey(item))
- return result
diff --git a/cura/Settings/ProfilesModel.py b/cura/Settings/ProfilesModel.py
deleted file mode 100644
index 77cd407457..0000000000
--- a/cura/Settings/ProfilesModel.py
+++ /dev/null
@@ -1,222 +0,0 @@
-# Copyright (c) 2017 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from collections import OrderedDict
-
-from PyQt5.QtCore import Qt
-
-from UM.Application import Application
-from UM.Settings.ContainerRegistry import ContainerRegistry
-from UM.Settings.Models.InstanceContainersModel import InstanceContainersModel
-
-from cura.QualityManager import QualityManager
-from cura.Settings.ExtruderManager import ExtruderManager
-
-from typing import List, TYPE_CHECKING
-
-if TYPE_CHECKING:
- from cura.Settings.ExtruderStack import ExtruderStack
-
-
-## QML Model for listing the current list of valid quality profiles.
-#
-class ProfilesModel(InstanceContainersModel):
- LayerHeightRole = Qt.UserRole + 1001
- LayerHeightWithoutUnitRole = Qt.UserRole + 1002
- AvailableRole = Qt.UserRole + 1003
-
- def __init__(self, parent = None):
- super().__init__(parent)
- self.addRoleName(self.LayerHeightRole, "layer_height")
- self.addRoleName(self.LayerHeightWithoutUnitRole, "layer_height_without_unit")
- self.addRoleName(self.AvailableRole, "available")
-
- Application.getInstance().globalContainerStackChanged.connect(self._update)
- Application.getInstance().getMachineManager().activeVariantChanged.connect(self._update)
- Application.getInstance().getMachineManager().activeStackChanged.connect(self._update)
- Application.getInstance().getMachineManager().activeMaterialChanged.connect(self._update)
-
- self._empty_quality = ContainerRegistry.getInstance().findContainers(id = "empty_quality")[0]
-
- # Factory function, used by QML
- @staticmethod
- def createProfilesModel(engine, js_engine):
- return ProfilesModel.getInstance()
-
- ## Get the singleton instance for this class.
- @classmethod
- def getInstance(cls) -> "ProfilesModel":
- # Note: Explicit use of class name to prevent issues with inheritance.
- if not ProfilesModel.__instance:
- ProfilesModel.__instance = cls()
- return ProfilesModel.__instance
-
- @classmethod
- def hasInstance(cls) -> bool:
- return ProfilesModel.__instance is not None
-
- __instance = None # type: "ProfilesModel"
-
- ## Fetch the list of containers to display.
- #
- # See UM.Settings.Models.InstanceContainersModel._fetchInstanceContainers().
- def _fetchInstanceContainers(self):
- global_container_stack = Application.getInstance().getGlobalContainerStack()
- if global_container_stack is None:
- return {}, {}
- global_stack_definition = global_container_stack.definition
-
- # Get the list of extruders and place the selected extruder at the front of the list.
- extruder_stacks = self._getOrderedExtruderStacksList()
- materials = [extruder.material for extruder in extruder_stacks]
-
- # Fetch the list of usable qualities across all extruders.
- # The actual list of quality profiles come from the first extruder in the extruder list.
- result = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks)
-
- # The usable quality types are set
- quality_type_set = set([x.getMetaDataEntry("quality_type") for x in result])
-
- # Fetch all qualities available for this machine and the materials selected in extruders
- all_qualities = QualityManager.getInstance().findAllQualitiesForMachineAndMaterials(global_stack_definition, materials)
-
- # If in the all qualities there is some of them that are not available due to incompatibility with materials
- # we also add it so that they will appear in the slide quality bar. However in recomputeItems will be marked as
- # not available so they will be shown in gray
- for quality in all_qualities:
- if quality.getMetaDataEntry("quality_type") not in quality_type_set:
- result.append(quality)
-
- if len(result) > 1 and self._empty_quality in result:
- result.remove(self._empty_quality)
-
- return {item.getId(): item for item in result}, {} #Only return true profiles for now, no metadata. The quality manager is not able to get only metadata yet.
-
- ## Re-computes the items in this model, and adds the layer height role.
- def _recomputeItems(self):
- # Some globals that we can re-use.
- global_container_stack = Application.getInstance().getGlobalContainerStack()
- if global_container_stack is None:
- return
-
- extruder_stacks = self._getOrderedExtruderStacksList()
- container_registry = ContainerRegistry.getInstance()
-
- # Get a list of usable/available qualities for this machine and material
- qualities = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks)
-
- unit = global_container_stack.getBottom().getProperty("layer_height", "unit")
- if not unit:
- unit = ""
-
- # group all quality items according to quality_types, so we know which profile suits the currently
- # active machine and material, and later yield the right ones.
- tmp_all_quality_items = OrderedDict()
- for item in super()._recomputeItems():
- profiles = container_registry.findContainersMetadata(id = item["id"])
- if not profiles or "quality_type" not in profiles[0]:
- quality_type = ""
- else:
- quality_type = profiles[0]["quality_type"]
-
- if quality_type not in tmp_all_quality_items:
- tmp_all_quality_items[quality_type] = {"suitable_container": None, "all_containers": []}
-
- tmp_all_quality_items[quality_type]["all_containers"].append(item)
- if tmp_all_quality_items[quality_type]["suitable_container"] is None:
- tmp_all_quality_items[quality_type]["suitable_container"] = item
-
- # reverse the ordering (finest first, coarsest last)
- all_quality_items = OrderedDict()
- for key in reversed(tmp_all_quality_items.keys()):
- all_quality_items[key] = tmp_all_quality_items[key]
-
- # First the suitable containers are set in the model
- containers = []
- for data_item in all_quality_items.values():
- suitable_item = data_item["suitable_container"]
- if suitable_item is not None:
- containers.append(suitable_item)
-
- # Once the suitable containers are collected, the rest of the containers are appended
- for data_item in all_quality_items.values():
- for item in data_item["all_containers"]:
- if item not in containers:
- containers.append(item)
-
- # Now all the containers are set
- for item in containers:
- profile = container_registry.findContainers(id = item["id"])
-
- # When for some reason there is no profile container in the registry
- if not profile:
- self._setItemLayerHeight(item, "", "")
- item["available"] = False
- yield item
- continue
-
- profile = profile[0]
-
- # When there is a profile but it's an empty quality should. It's shown in the list (they are "Not Supported" profiles)
- if profile.getId() == "empty_quality":
- self._setItemLayerHeight(item, "", "")
- item["available"] = True
- yield item
- continue
-
- item["available"] = profile in qualities
-
- # Easy case: This profile defines its own layer height.
- if profile.hasProperty("layer_height", "value"):
- self._setItemLayerHeight(item, profile.getProperty("layer_height", "value"), unit)
- yield item
- continue
-
- machine_manager = Application.getInstance().getMachineManager()
-
- # Quality-changes profile that has no value for layer height. Get the corresponding quality profile and ask that profile.
- quality_type = profile.getMetaDataEntry("quality_type", None)
- if quality_type:
- quality_results = machine_manager.determineQualityAndQualityChangesForQualityType(quality_type)
- for quality_result in quality_results:
- if quality_result["stack"] is global_container_stack:
- quality = quality_result["quality"]
- break
- else:
- # No global container stack in the results:
- if quality_results:
- # Take any of the extruders.
- quality = quality_results[0]["quality"]
- else:
- quality = None
- if quality and quality.hasProperty("layer_height", "value"):
- self._setItemLayerHeight(item, quality.getProperty("layer_height", "value"), unit)
- yield item
- continue
-
- # Quality has no value for layer height either. Get the layer height from somewhere lower in the stack.
- skip_until_container = global_container_stack.material
- if not skip_until_container or skip_until_container == ContainerRegistry.getInstance().getEmptyInstanceContainer(): # No material in stack.
- skip_until_container = global_container_stack.variant
- if not skip_until_container or skip_until_container == ContainerRegistry.getInstance().getEmptyInstanceContainer(): # No variant in stack.
- skip_until_container = global_container_stack.getBottom()
- self._setItemLayerHeight(item, global_container_stack.getRawProperty("layer_height", "value", skip_until_container = skip_until_container.getId()), unit) # Fall through to the currently loaded material.
- yield item
-
- ## Get a list of extruder stacks with the active extruder at the front of the list.
- @staticmethod
- def _getOrderedExtruderStacksList() -> List["ExtruderStack"]:
- extruder_manager = ExtruderManager.getInstance()
- extruder_stacks = extruder_manager.getActiveExtruderStacks()
- active_extruder = extruder_manager.getActiveExtruderStack()
-
- if active_extruder in extruder_stacks:
- extruder_stacks.remove(active_extruder)
- extruder_stacks = [active_extruder] + extruder_stacks
-
- return extruder_stacks
-
- @staticmethod
- def _setItemLayerHeight(item, value, unit):
- item["layer_height"] = str(value) + unit
- item["layer_height_without_unit"] = str(value)
diff --git a/cura/Settings/QualityAndUserProfilesModel.py b/cura/Settings/QualityAndUserProfilesModel.py
deleted file mode 100644
index 645e63acdb..0000000000
--- a/cura/Settings/QualityAndUserProfilesModel.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (c) 2016 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-from UM.Application import Application
-from UM.Settings.ContainerRegistry import ContainerRegistry
-
-from cura.QualityManager import QualityManager
-from cura.Settings.ProfilesModel import ProfilesModel
-from cura.Settings.ExtruderManager import ExtruderManager
-
-
-## QML Model for listing the current list of valid quality and quality changes profiles.
-#
-class QualityAndUserProfilesModel(ProfilesModel):
- def __init__(self, parent = None):
- super().__init__(parent)
-
- self._empty_quality = ContainerRegistry.getInstance().findInstanceContainers(id = "empty_quality")[0]
-
- ## Fetch the list of containers to display.
- #
- # See UM.Settings.Models.InstanceContainersModel._fetchInstanceContainers().
- def _fetchInstanceContainers(self):
- global_container_stack = Application.getInstance().getGlobalContainerStack()
- if not global_container_stack:
- return {}, {}
-
- # Fetch the list of quality changes.
- quality_manager = QualityManager.getInstance()
- machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.definition)
- quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition)
-
- extruder_manager = ExtruderManager.getInstance()
- active_extruder = extruder_manager.getActiveExtruderStack()
- extruder_stacks = self._getOrderedExtruderStacksList()
-
- # Fetch the list of usable qualities across all extruders.
- # The actual list of quality profiles come from the first extruder in the extruder list.
- quality_list = quality_manager.findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks)
-
- # Filter the quality_change by the list of available quality_types
- quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list])
- # Also show custom profiles based on "Not Supported" quality profile
- quality_type_set.add(self._empty_quality.getMetaDataEntry("quality_type"))
- filtered_quality_changes = {qc.getId(): qc for qc in quality_changes_list if
- qc.getMetaDataEntry("quality_type") in quality_type_set and
- qc.getMetaDataEntry("extruder") is not None and
- (qc.getMetaDataEntry("extruder") == active_extruder.definition.getMetaDataEntry("quality_definition") or
- qc.getMetaDataEntry("extruder") == active_extruder.definition.getId())}
-
- result = filtered_quality_changes
- for q in quality_list:
- if q.getId() != "empty_quality":
- result[q.getId()] = q
- return result, {} #Only return true profiles for now, no metadata. The quality manager is not able to get only metadata yet.
diff --git a/cura/Settings/QualitySettingsModel.py b/cura/Settings/QualitySettingsModel.py
deleted file mode 100644
index fb1aa9a6b2..0000000000
--- a/cura/Settings/QualitySettingsModel.py
+++ /dev/null
@@ -1,249 +0,0 @@
-# Copyright (c) 2017 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from PyQt5.QtCore import pyqtProperty, pyqtSignal, Qt
-
-from UM.Logger import Logger
-import UM.Qt
-from UM.Application import Application
-from UM.Settings.ContainerRegistry import ContainerRegistry
-import os
-
-from UM.i18n import i18nCatalog
-
-
-class QualitySettingsModel(UM.Qt.ListModel.ListModel):
- KeyRole = Qt.UserRole + 1
- LabelRole = Qt.UserRole + 2
- UnitRole = Qt.UserRole + 3
- ProfileValueRole = Qt.UserRole + 4
- ProfileValueSourceRole = Qt.UserRole + 5
- UserValueRole = Qt.UserRole + 6
- CategoryRole = Qt.UserRole + 7
-
- def __init__(self, parent = None):
- super().__init__(parent = parent)
-
- self._container_registry = ContainerRegistry.getInstance()
-
- self._extruder_id = None
- self._extruder_definition_id = None
- self._quality_id = None
- self._material_id = None
- self._i18n_catalog = None
-
- self.addRoleName(self.KeyRole, "key")
- self.addRoleName(self.LabelRole, "label")
- self.addRoleName(self.UnitRole, "unit")
- self.addRoleName(self.ProfileValueRole, "profile_value")
- self.addRoleName(self.ProfileValueSourceRole, "profile_value_source")
- self.addRoleName(self.UserValueRole, "user_value")
- self.addRoleName(self.CategoryRole, "category")
-
- self._empty_quality = self._container_registry.findInstanceContainers(id = "empty_quality")[0]
-
- def setExtruderId(self, extruder_id):
- if extruder_id != self._extruder_id:
- self._extruder_id = extruder_id
- self._update()
- self.extruderIdChanged.emit()
-
- extruderIdChanged = pyqtSignal()
- @pyqtProperty(str, fset = setExtruderId, notify = extruderIdChanged)
- def extruderId(self):
- return self._extruder_id
-
- def setExtruderDefinition(self, extruder_definition):
- if extruder_definition != self._extruder_definition_id:
- self._extruder_definition_id = extruder_definition
- self._update()
- self.extruderDefinitionChanged.emit()
-
- extruderDefinitionChanged = pyqtSignal()
- @pyqtProperty(str, fset = setExtruderDefinition, notify = extruderDefinitionChanged)
- def extruderDefinition(self):
- return self._extruder_definition_id
-
- def setQuality(self, quality):
- if quality != self._quality_id:
- self._quality_id = quality
- self._update()
- self.qualityChanged.emit()
-
- qualityChanged = pyqtSignal()
- @pyqtProperty(str, fset = setQuality, notify = qualityChanged)
- def quality(self):
- return self._quality_id
-
- def setMaterial(self, material):
- if material != self._material_id:
- self._material_id = material
- self._update()
- self.materialChanged.emit()
-
- materialChanged = pyqtSignal()
- @pyqtProperty(str, fset = setMaterial, notify = materialChanged)
- def material(self):
- return self._material_id
-
- def _update(self):
- if not self._quality_id:
- return
-
- items = []
-
- definition_container = Application.getInstance().getGlobalContainerStack().getBottom()
-
- containers = self._container_registry.findInstanceContainers(id = self._quality_id)
- if not containers:
- Logger.log("w", "Could not find a quality container with id %s", self._quality_id)
- return
-
- quality_container = None
- quality_changes_container = None
-
- if containers[0].getMetaDataEntry("type") == "quality":
- quality_container = containers[0]
- else:
- quality_changes_container = containers[0]
-
- if quality_changes_container.getMetaDataEntry("quality_type") == self._empty_quality.getMetaDataEntry("quality_type"):
- quality_container = self._empty_quality
- else:
- criteria = {
- "type": "quality",
- "quality_type": quality_changes_container.getMetaDataEntry("quality_type"),
- "definition": quality_changes_container.getDefinition().getId()
- }
-
- quality_container = self._container_registry.findInstanceContainers(**criteria)
- if not quality_container:
- Logger.log("w", "Could not find a quality container matching quality changes %s", quality_changes_container.getId())
- return
-
- quality_container = quality_container[0]
-
- quality_type = quality_container.getMetaDataEntry("quality_type")
-
- if quality_type == "not_supported":
- containers = []
- else:
- definition_id = Application.getInstance().getMachineManager().getQualityDefinitionId(quality_container.getDefinition())
- definition = quality_container.getDefinition()
-
- # Check if the definition container has a translation file.
- definition_suffix = ContainerRegistry.getMimeTypeForContainer(type(definition)).preferredSuffix
- catalog = i18nCatalog(os.path.basename(definition_id + "." + definition_suffix))
- if catalog.hasTranslationLoaded():
- self._i18n_catalog = catalog
-
- for file_name in quality_container.getDefinition().getInheritedFiles():
- catalog = i18nCatalog(os.path.basename(file_name))
- if catalog.hasTranslationLoaded():
- self._i18n_catalog = catalog
-
- criteria = {"type": "quality", "quality_type": quality_type, "definition": definition_id}
-
- if self._material_id and self._material_id != "empty_material":
- criteria["material"] = self._material_id
-
- criteria["extruder"] = self._extruder_id
-
- containers = self._container_registry.findInstanceContainers(**criteria)
- if not containers:
- # Try again, this time without extruder
- new_criteria = criteria.copy()
- new_criteria.pop("extruder")
- containers = self._container_registry.findInstanceContainers(**new_criteria)
-
- if not containers and "material" in criteria:
- # Try again, this time without material
- criteria.pop("material", None)
- containers = self._container_registry.findInstanceContainers(**criteria)
-
- if not containers:
- # Try again, this time without material or extruder
- criteria.pop("extruder") # "material" has already been popped
- containers = self._container_registry.findInstanceContainers(**criteria)
-
- if not containers:
- Logger.log("w", "Could not find any quality containers matching the search criteria %s" % str(criteria))
- return
-
- if quality_changes_container:
- if quality_type == "not_supported":
- criteria = {"type": "quality_changes", "quality_type": quality_type, "name": quality_changes_container.getName()}
- else:
- criteria = {"type": "quality_changes", "quality_type": quality_type, "definition": definition_id, "name": quality_changes_container.getName()}
- if self._extruder_definition_id != "":
- extruder_definitions = self._container_registry.findDefinitionContainers(id = self._extruder_definition_id)
- if extruder_definitions:
- criteria["extruder"] = Application.getInstance().getMachineManager().getQualityDefinitionId(extruder_definitions[0])
- criteria["name"] = quality_changes_container.getName()
- else:
- criteria["extruder"] = None
-
- changes = self._container_registry.findInstanceContainers(**criteria)
- if changes:
- containers.extend(changes)
-
- global_container_stack = Application.getInstance().getGlobalContainerStack()
-
- current_category = ""
- for definition in definition_container.findDefinitions():
- if definition.type == "category":
- current_category = definition.label
- if self._i18n_catalog:
- current_category = self._i18n_catalog.i18nc(definition.key + " label", definition.label)
- continue
-
- profile_value = None
- profile_value_source = ""
- for container in containers:
- new_value = container.getProperty(definition.key, "value")
-
- if new_value is not None:
- profile_value_source = container.getMetaDataEntry("type")
- profile_value = new_value
-
- # Global tab should use resolve (if there is one)
- if not self._extruder_id:
- resolve_value = global_container_stack.getProperty(definition.key, "resolve")
- if resolve_value is not None and profile_value is not None and profile_value_source != "quality_changes":
- profile_value = resolve_value
-
- user_value = None
- if not self._extruder_id:
- user_value = global_container_stack.getTop().getProperty(definition.key, "value")
- else:
- extruder_stack = self._container_registry.findContainerStacks(id = self._extruder_id)
- if extruder_stack:
- user_value = extruder_stack[0].getTop().getProperty(definition.key, "value")
-
- if profile_value is None and user_value is None:
- continue
-
- settable_per_extruder = global_container_stack.getProperty(definition.key, "settable_per_extruder")
- # If a setting is not settable per extruder (global) and we're looking at an extruder tab, don't show this value.
- if self._extruder_id != "" and not settable_per_extruder:
- continue
-
- # If a setting is settable per extruder (not global) and we're looking at global tab, don't show this value.
- if self._extruder_id == "" and settable_per_extruder:
- continue
-
- label = definition.label
- if self._i18n_catalog:
- label = self._i18n_catalog.i18nc(definition.key + " label", label)
-
- items.append({
- "key": definition.key,
- "label": label,
- "unit": definition.unit,
- "profile_value": "" if profile_value is None else str(profile_value), # it is for display only
- "profile_value_source": profile_value_source,
- "user_value": "" if user_value is None else str(user_value),
- "category": current_category
- })
-
- self.setItems(items)
diff --git a/cura/Settings/SettingOverrideDecorator.py b/cura/Settings/SettingOverrideDecorator.py
index b853c06c8e..9054d9d04f 100644
--- a/cura/Settings/SettingOverrideDecorator.py
+++ b/cura/Settings/SettingOverrideDecorator.py
@@ -3,6 +3,7 @@
import copy
+from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
from UM.Scene.SceneNodeDecorator import SceneNodeDecorator
from UM.Signal import Signal, signalemitter
from UM.Settings.InstanceContainer import InstanceContainer
@@ -61,7 +62,7 @@ class SettingOverrideDecorator(SceneNodeDecorator):
# use value from the stack because there can be a delay in signal triggering and "_is_non_printing_mesh"
# has not been updated yet.
- deep_copy._is_non_printing_mesh = any(bool(self._stack.getProperty(setting, "value")) for setting in self._non_printing_mesh_settings)
+ deep_copy._is_non_printing_mesh = self.evaluateIsNonPrintingMesh()
return deep_copy
@@ -89,10 +90,18 @@ class SettingOverrideDecorator(SceneNodeDecorator):
def isNonPrintingMesh(self):
return self._is_non_printing_mesh
+ def evaluateIsNonPrintingMesh(self):
+ return any(bool(self._stack.getProperty(setting, "value")) for setting in self._non_printing_mesh_settings)
+
def _onSettingChanged(self, instance, property_name): # Reminder: 'property' is a built-in function
- # Trigger slice/need slicing if the value has changed.
- if property_name == "value":
- self._is_non_printing_mesh = any(bool(self._stack.getProperty(setting, "value")) for setting in self._non_printing_mesh_settings)
+ object_has_instance_setting = False
+ for container in self._stack.getContainers():
+ if container.hasProperty(instance, "value"):
+ object_has_instance_setting = True
+ break
+ if property_name == "value" and object_has_instance_setting:
+ # Trigger slice/need slicing if the value has changed.
+ self._is_non_printing_mesh = self.evaluateIsNonPrintingMesh()
Application.getInstance().getBackend().needsSlicing()
Application.getInstance().getBackend().tickle()
diff --git a/cura/Settings/UserProfilesModel.py b/cura/Settings/UserProfilesModel.py
deleted file mode 100644
index 6605f52f8a..0000000000
--- a/cura/Settings/UserProfilesModel.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# Copyright (c) 2017 Ultimaker B.V.
-# Cura is released under the terms of the LGPLv3 or higher.
-
-from UM.Application import Application
-from UM.Settings.ContainerRegistry import ContainerRegistry
-
-from cura.QualityManager import QualityManager
-from cura.Settings.ProfilesModel import ProfilesModel
-from cura.Settings.ExtruderManager import ExtruderManager
-
-## QML Model for listing the current list of valid quality changes profiles.
-#
-class UserProfilesModel(ProfilesModel):
- def __init__(self, parent = None):
- super().__init__(parent)
-
- #Need to connect to the metaDataChanged signal of the active materials.
- self.__current_extruders = []
- self.__current_materials = []
-
- Application.getInstance().getExtruderManager().extrudersChanged.connect(self.__onExtrudersChanged)
- self.__onExtrudersChanged()
- self.__current_materials = [extruder.material for extruder in self.__current_extruders]
- for material in self.__current_materials:
- material.metaDataChanged.connect(self._onContainerChanged)
-
- self._empty_quality = ContainerRegistry.getInstance().findContainers(id = "empty_quality")[0]
-
- ## Fetch the list of containers to display.
- #
- # See UM.Settings.Models.InstanceContainersModel._fetchInstanceContainers().
- def _fetchInstanceContainers(self):
- global_container_stack = Application.getInstance().getGlobalContainerStack()
- if not global_container_stack:
- return {}, {}
-
- # Fetch the list of quality changes.
- quality_manager = QualityManager.getInstance()
- machine_definition = quality_manager.getParentMachineDefinition(global_container_stack.definition)
- quality_changes_list = quality_manager.findAllQualityChangesForMachine(machine_definition)
-
- extruder_manager = ExtruderManager.getInstance()
- active_extruder = extruder_manager.getActiveExtruderStack()
- extruder_stacks = self._getOrderedExtruderStacksList()
-
- # Fetch the list of usable qualities across all extruders.
- # The actual list of quality profiles come from the first extruder in the extruder list.
- quality_list = quality_manager.findAllUsableQualitiesForMachineAndExtruders(global_container_stack, extruder_stacks)
-
- # Filter the quality_change by the list of available quality_types
- quality_type_set = set([x.getMetaDataEntry("quality_type") for x in quality_list])
- quality_type_set.add(self._empty_quality.getMetaDataEntry("quality_type"))
-
- filtered_quality_changes = {qc.getId():qc for qc in quality_changes_list if
- qc.getMetaDataEntry("quality_type") in quality_type_set and
- qc.getMetaDataEntry("extruder") is not None and
- (qc.getMetaDataEntry("extruder") == active_extruder.definition.getMetaDataEntry("quality_definition") or
- qc.getMetaDataEntry("extruder") == active_extruder.definition.getId())}
-
- return filtered_quality_changes, {} #Only return true profiles for now, no metadata. The quality manager is not able to get only metadata yet.
-
- ## Called when a container changed on an extruder stack.
- #
- # If it's the material we need to connect to the metaDataChanged signal of
- # that.
- def __onContainerChanged(self, new_container):
- #Careful not to update when a quality or quality changes profile changed!
- #If you then update you're going to have an infinite recursion because the update may change the container.
- if new_container.getMetaDataEntry("type") == "material":
- for material in self.__current_materials:
- material.metaDataChanged.disconnect(self._onContainerChanged)
- self.__current_materials = [extruder.material for extruder in self.__current_extruders]
- for material in self.__current_materials:
- material.metaDataChanged.connect(self._onContainerChanged)
-
- ## Called when the current set of extruders change.
- #
- # This makes sure that we are listening to the signal for when the
- # materials change.
- def __onExtrudersChanged(self):
- for extruder in self.__current_extruders:
- extruder.containersChanged.disconnect(self.__onContainerChanged)
- self.__current_extruders = Application.getInstance().getExtruderManager().getExtruderStacks()
- for extruder in self.__current_extruders:
- extruder.containersChanged.connect(self.__onContainerChanged)
\ No newline at end of file
diff --git a/cura/Snapshot.py b/cura/Snapshot.py
index 50bbf99008..2a2a49d6cf 100644
--- a/cura/Snapshot.py
+++ b/cura/Snapshot.py
@@ -57,8 +57,9 @@ class Snapshot:
else:
bbox = bbox + node.getBoundingBox()
+ # If there is no bounding box, it means that there is no model in the buildplate
if bbox is None:
- bbox = AxisAlignedBox()
+ return None
look_at = bbox.center
# guessed size so the objects are hopefully big
diff --git a/plugins/3MFReader/ThreeMFReader.py b/plugins/3MFReader/ThreeMFReader.py
index 1726818100..ec590a0212 100755
--- a/plugins/3MFReader/ThreeMFReader.py
+++ b/plugins/3MFReader/ThreeMFReader.py
@@ -4,26 +4,28 @@
import os.path
import zipfile
+import numpy
+
+import Savitar
+
+from UM.Application import Application
from UM.Logger import Logger
from UM.Math.Matrix import Matrix
from UM.Math.Vector import Vector
from UM.Mesh.MeshBuilder import MeshBuilder
from UM.Mesh.MeshReader import MeshReader
from UM.Scene.GroupDecorator import GroupDecorator
+
from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator
-from UM.Application import Application
from cura.Settings.ExtruderManager import ExtruderManager
-from cura.QualityManager import QualityManager
from cura.Scene.CuraSceneNode import CuraSceneNode
from cura.Scene.BuildPlateDecorator import BuildPlateDecorator
from cura.Scene.SliceableObjectDecorator import SliceableObjectDecorator
from cura.Scene.ZOffsetDecorator import ZOffsetDecorator
+from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
MYPY = False
-import Savitar
-import numpy
-
try:
if not MYPY:
import xml.etree.cElementTree as ET
@@ -77,7 +79,7 @@ class ThreeMFReader(MeshReader):
self._object_count += 1
node_name = "Object %s" % self._object_count
- active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate
+ active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
um_node = CuraSceneNode()
um_node.addDecorator(BuildPlateDecorator(active_build_plate))
@@ -120,8 +122,8 @@ class ThreeMFReader(MeshReader):
um_node.callDecoration("setActiveExtruder", default_stack.getId())
# Get the definition & set it
- definition = QualityManager.getInstance().getParentMachineDefinition(global_container_stack.getBottom())
- um_node.callDecoration("getStack").getTop().setDefinition(definition.getId())
+ definition_id = getMachineDefinitionIDForQualitySearch(global_container_stack)
+ um_node.callDecoration("getStack").getTop().setDefinition(definition_id)
setting_container = um_node.callDecoration("getStack").getTop()
diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py
index a2e02fa9d4..3c627a7655 100755
--- a/plugins/3MFReader/ThreeMFWorkspaceReader.py
+++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py
@@ -1,11 +1,19 @@
# Copyright (c) 2017 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
+from configparser import ConfigParser
+import zipfile
+import os
+import threading
+
+import xml.etree.ElementTree as ET
+
from UM.Workspace.WorkspaceReader import WorkspaceReader
from UM.Application import Application
from UM.Logger import Logger
from UM.i18n import i18nCatalog
+from UM.Signal import postponeSignals, CompressTechnique
from UM.Settings.ContainerStack import ContainerStack
from UM.Settings.DefinitionContainer import DefinitionContainer
from UM.Settings.InstanceContainer import InstanceContainer
@@ -13,25 +21,14 @@ from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.MimeTypeDatabase import MimeTypeDatabase
from UM.Job import Job
from UM.Preferences import Preferences
-from UM.Util import parseBool
-from .WorkspaceDialog import WorkspaceDialog
-
-import xml.etree.ElementTree as ET
from cura.Settings.CuraStackBuilder import CuraStackBuilder
-from cura.Settings.ExtruderManager import ExtruderManager
from cura.Settings.ExtruderStack import ExtruderStack
from cura.Settings.GlobalStack import GlobalStack
from cura.Settings.CuraContainerStack import _ContainerIndexes
-from cura.QualityManager import QualityManager
from cura.CuraApplication import CuraApplication
-from configparser import ConfigParser
-import zipfile
-import io
-import configparser
-import os
-import threading
+from .WorkspaceDialog import WorkspaceDialog
i18n_catalog = i18nCatalog("cura")
@@ -67,6 +64,48 @@ def call_on_qt_thread(func):
return _call_on_qt_thread_wrapper
+class ContainerInfo:
+ def __init__(self, file_name: str, serialized: str, parser: ConfigParser):
+ self.file_name = file_name
+ self.serialized = serialized
+ self.parser = parser
+ self.container = None
+ self.definition_id = None
+
+
+class QualityChangesInfo:
+ def __init__(self):
+ self.name = None
+ self.global_info = None
+ self.extruder_info_dict = {}
+
+
+class MachineInfo:
+ def __init__(self):
+ self.container_id = None
+ self.name = None
+ self.definition_id = None
+ self.quality_type = None
+ self.custom_quality_name = None
+ self.quality_changes_info = None
+ self.variant_info = None
+
+ self.definition_changes_info = None
+ self.user_changes_info = None
+
+ self.extruder_info_dict = {}
+
+
+class ExtruderInfo:
+ def __init__(self):
+ self.position = None
+ self.variant_info = None
+ self.root_material_id = None
+
+ self.definition_changes_info = None
+ self.user_changes_info = None
+
+
## Base implementation for reading 3MF workspace files.
class ThreeMFWorkspaceReader(WorkspaceReader):
def __init__(self):
@@ -97,6 +136,18 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# In Cura 2.5 and 2.6, the empty profiles used to have those long names
self._old_empty_profile_id_dict = {"empty_%s" % k: "empty" for k in ["material", "variant"]}
+ self._is_same_machine_type = False
+ self._old_new_materials = {}
+ self._materials_to_select = {}
+ self._machine_info = None
+
+ def _clearState(self):
+ self._is_same_machine_type = False
+ self._id_mapping = {}
+ self._old_new_materials = {}
+ self._materials_to_select = {}
+ self._machine_info = None
+
## Get a unique name based on the old_id. This is different from directly calling the registry in that it caches results.
# This has nothing to do with speed, but with getting consistent new naming for instances & objects.
def getNewId(self, old_id):
@@ -148,6 +199,8 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# \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._clearState()
+
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:
pass
@@ -155,6 +208,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
Logger.log("w", "Could not find reader that was able to read the scene data for 3MF workspace")
return WorkspaceReader.PreReadResult.failed
+ self._machine_info = MachineInfo()
machine_type = ""
variant_type_name = i18n_catalog.i18nc("@label", "Nozzle")
@@ -162,11 +216,6 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
archive = zipfile.ZipFile(file_name, "r")
cura_file_names = [name for name in archive.namelist() if name.startswith("Cura/")]
- # 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.
- instance_container_list = []
-
resolve_strategy_keys = ["machine", "material", "quality_changes"]
self._resolve_strategies = {k: None for k in resolve_strategy_keys}
containers_found_dict = {k: False for k in resolve_strategy_keys}
@@ -174,23 +223,23 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
#
# Read definition containers
#
+ machine_definition_id = None
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 each_definition_container_file in definition_container_files:
- container_id = self._stripFileToId(each_definition_container_file)
+ for definition_container_file in definition_container_files:
+ container_id = self._stripFileToId(definition_container_file)
definitions = self._container_registry.findDefinitionContainersMetadata(id = container_id)
+ serialized = archive.open(definition_container_file).read().decode("utf-8")
if not definitions:
- definition_container = DefinitionContainer(container_id)
- definition_container.deserialize(archive.open(each_definition_container_file).read().decode("utf-8"), file_name = each_definition_container_file)
- definition_container = definition_container.getMetaData()
-
+ definition_container = DefinitionContainer.deserializeMetadata(serialized, container_id)[0]
else:
definition_container = definitions[0]
definition_container_type = definition_container.get("type")
if definition_container_type == "machine":
+ machine_definition_id = container_id
machine_type = definition_container["name"]
variant_type_name = definition_container.get("variants_name", variant_type_name)
@@ -199,22 +248,33 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
extruder_definition_container_count += 1
else:
Logger.log("w", "Unknown definition container type %s for %s",
- definition_container_type, each_definition_container_file)
+ definition_container_type, definition_container_file)
Job.yieldThread()
if machine_definition_container_count != 1:
- return WorkspaceReader.PreReadResult.failed #Not a workspace file but ordinary 3MF.
+ return WorkspaceReader.PreReadResult.failed # Not a workspace file but ordinary 3MF.
material_labels = []
material_conflict = False
xml_material_profile = self._getXmlProfileClass()
+ reverse_material_id_dict = {}
if self._material_container_suffix is None:
self._material_container_suffix = ContainerRegistry.getMimeTypeForContainer(xml_material_profile).preferredSuffix
if xml_material_profile:
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)
- material_labels.append(self._getMaterialLabelFromSerialized(archive.open(material_container_file).read().decode("utf-8")))
+
+ from hashlib import sha1
+ hex_container_id = sha1(container_id.encode('utf-8')).hexdigest()
+
+ serialized = archive.open(material_container_file).read().decode("utf-8")
+ metadata_list = xml_material_profile.deserializeMetadata(serialized, hex_container_id)
+ reverse_map = {metadata["id"].replace(hex_container_id, container_id): container_id.replace(hex_container_id, container_id)
+ for metadata in metadata_list}
+ reverse_material_id_dict.update(reverse_map)
+
+ material_labels.append(self._getMaterialLabelFromSerialized(serialized))
if self._container_registry.findContainersMetadata(id = container_id): #This material already exists.
containers_found_dict["material"] = True
if not self._container_registry.isReadOnly(container_id): # Only non readonly materials can be in conflict
@@ -224,49 +284,52 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# 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
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)
+ self._machine_info.quality_changes_info = QualityChangesInfo()
- # Deserialize InstanceContainer by converting read data from bytes to string
- instance_container.deserialize(archive.open(each_instance_container_file).read().decode("utf-8"),
- file_name = each_instance_container_file)
- instance_container_list.append(instance_container)
+ quality_changes_info_list = []
+ instance_container_info_dict = {} # id -> parser
+ for instance_container_file_name in instance_container_files:
+ container_id = self._stripFileToId(instance_container_file_name)
- container_type = instance_container.getMetaDataEntry("type")
+ serialized = archive.open(instance_container_file_name).read().decode("utf-8")
+ serialized = InstanceContainer._updateSerialized(serialized, instance_container_file_name)
+ parser = ConfigParser(interpolation = None)
+ parser.read_string(serialized)
+ container_info = ContainerInfo(instance_container_file_name, serialized, parser)
+ instance_container_info_dict[container_id] = container_info
+
+ container_type = parser["metadata"]["type"]
if container_type == "quality_changes":
- quality_name = instance_container.getName()
- num_settings_overriden_by_quality_changes += len(instance_container._instances)
+ quality_changes_info_list.append(container_info)
+
+ if not parser.has_option("metadata", "position"):
+ self._machine_info.quality_changes_info.name = parser["general"]["name"]
+ self._machine_info.quality_changes_info.global_info = container_info
+ else:
+ position = parser["metadata"]["position"]
+ self._machine_info.quality_changes_info.extruder_info_dict[position] = container_info
+
+ quality_name = parser["general"]["name"]
+ values = parser["values"] if parser.has_section("values") else dict()
+ num_settings_overriden_by_quality_changes += len(values)
# Check if quality changes already exists.
quality_changes = self._container_registry.findInstanceContainers(id = container_id)
if quality_changes:
containers_found_dict["quality_changes"] = True
# Check if there really is a conflict by comparing the values
+ instance_container = InstanceContainer(container_id)
+ instance_container.deserialize(serialized, file_name = instance_container_file_name)
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)
- # Check if definition changes already exists.
- definition_changes = self._container_registry.findInstanceContainers(id = container_id)
- # Check if there is any difference the loaded settings from the project file and the settings in Cura.
- if definition_changes:
- containers_found_dict["definition_changes"] = True
- # Check if there really is a conflict by comparing the values
- if definition_changes[0] != instance_container:
- definition_changes_conflict = True
elif container_type == "quality":
if not quality_name:
- quality_name = instance_container.getName()
+ quality_name = parser["general"]["name"]
elif container_type == "user":
- num_user_settings += len(instance_container._instances)
+ num_user_settings += len(parser["values"])
elif container_type in self._ignored_instance_container_types:
# Ignore certain instance container types
Logger.log("w", "Ignoring instance container [%s] with type [%s]", container_id, container_type)
@@ -274,6 +337,9 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
Job.yieldThread()
+ if self._machine_info.quality_changes_info.global_info is None:
+ self._machine_info.quality_changes_info = None
+
# Load ContainerStack files and ExtruderStack files
global_stack_file, extruder_stack_files = self._determineGlobalAndExtruderStackFiles(
file_name, cura_file_names)
@@ -282,10 +348,11 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# - the global stack exists but some/all of the extruder stacks DON'T exist
# - the global stack DOESN'T exist but some/all of the extruder stacks exist
# To simplify this, only check if the global stack exists or not
- container_id = self._stripFileToId(global_stack_file)
+ global_stack_id = self._stripFileToId(global_stack_file)
serialized = archive.open(global_stack_file).read().decode("utf-8")
machine_name = self._getMachineNameFromSerializedStack(serialized)
- stacks = self._container_registry.findContainerStacks(id = container_id)
+ stacks = self._container_registry.findContainerStacks(name = machine_name, type = "machine")
+ self._is_same_machine_type = True
if stacks:
global_stack = stacks[0]
containers_found_dict["machine"] = True
@@ -297,30 +364,79 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if global_stack.getContainer(index).getId() != container_id:
machine_conflict = True
break
+ self._is_same_machine_type = global_stack.definition.getId() == machine_definition_id
+
+ # Get quality type
+ parser = ConfigParser(interpolation = None)
+ parser.read_string(serialized)
+ quality_container_id = parser["containers"][str(_ContainerIndexes.Quality)]
+ quality_type = instance_container_info_dict[quality_container_id].parser["metadata"]["quality_type"]
+
+ # Get machine info
+ serialized = archive.open(global_stack_file).read().decode("utf-8")
+ serialized = GlobalStack._updateSerialized(serialized, global_stack_file)
+ parser = ConfigParser(interpolation = None)
+ parser.read_string(serialized)
+ definition_changes_id = parser["containers"][str(_ContainerIndexes.DefinitionChanges)]
+ if definition_changes_id not in ("empty", "empty_definition_changes"):
+ self._machine_info.definition_changes_info = instance_container_info_dict[definition_changes_id]
+ user_changes_id = parser["containers"][str(_ContainerIndexes.UserChanges)]
+ if user_changes_id not in ("empty", "empty_user_changes"):
+ self._machine_info.user_changes_info = instance_container_info_dict[user_changes_id]
+
+ # Also check variant and material in case it doesn't have extruder stacks
+ if not extruder_stack_files:
+ position = "0"
+
+ extruder_info = ExtruderInfo()
+ extruder_info.position = position
+ variant_id = parser["containers"][str(_ContainerIndexes.Variant)]
+ material_id = parser["containers"][str(_ContainerIndexes.Material)]
+ if variant_id not in ("empty", "empty_variant"):
+ extruder_info.variant_info = instance_container_info_dict[variant_id]
+ if material_id not in ("empty", "empty_material"):
+ root_material_id = reverse_material_id_dict[material_id]
+ extruder_info.root_material_id = root_material_id
+ self._machine_info.extruder_info_dict[position] = extruder_info
+ else:
+ variant_id = parser["containers"][str(_ContainerIndexes.Variant)]
+ if variant_id not in ("empty", "empty_variant"):
+ self._machine_info.variant_info = instance_container_info_dict[variant_id]
+
Job.yieldThread()
# if the global stack is found, we check if there are conflicts in the extruder stacks
- if containers_found_dict["machine"] and not machine_conflict:
- for extruder_stack_file in extruder_stack_files:
- serialized = archive.open(extruder_stack_file).read().decode("utf-8")
- parser = configparser.ConfigParser(interpolation = None)
- parser.read_string(serialized)
+ for extruder_stack_file in extruder_stack_files:
+ serialized = archive.open(extruder_stack_file).read().decode("utf-8")
+ serialized = ExtruderStack._updateSerialized(serialized, extruder_stack_file)
+ parser = ConfigParser(interpolation = None)
+ parser.read_string(serialized)
- # The check should be done for the extruder stack that's associated with the existing global stack,
- # and those extruder stacks may have different IDs.
- # So we check according to the positions
+ # The check should be done for the extruder stack that's associated with the existing global stack,
+ # and those extruder stacks may have different IDs.
+ # So we check according to the positions
+ position = parser["metadata"]["position"]
+ variant_id = parser["containers"][str(_ContainerIndexes.Variant)]
+ material_id = parser["containers"][str(_ContainerIndexes.Material)]
- position = str(parser["metadata"]["position"])
+ extruder_info = ExtruderInfo()
+ extruder_info.position = position
+ if variant_id not in ("empty", "empty_variant"):
+ extruder_info.variant_info = instance_container_info_dict[variant_id]
+ if material_id not in ("empty", "empty_material"):
+ root_material_id = reverse_material_id_dict[material_id]
+ extruder_info.root_material_id = root_material_id
+ definition_changes_id = parser["containers"][str(_ContainerIndexes.DefinitionChanges)]
+ if definition_changes_id not in ("empty", "empty_definition_changes"):
+ extruder_info.definition_changes_info = instance_container_info_dict[definition_changes_id]
+ user_changes_id = parser["containers"][str(_ContainerIndexes.UserChanges)]
+ if user_changes_id not in ("empty", "empty_user_changes"):
+ extruder_info.user_changes_info = instance_container_info_dict[user_changes_id]
+ self._machine_info.extruder_info_dict[position] = extruder_info
+
+ if not machine_conflict and containers_found_dict["machine"]:
if position not in global_stack.extruders:
- # The extruder position defined in the project doesn't exist in this global stack.
- # We can say that it is a machine conflict, but it is very hard to override the machine in this
- # case because we need to override the existing extruders and add the non-existing extruders.
- #
- # HACK:
- # To make this simple, we simply say that there is no machine conflict and create a new machine
- # by default.
- machine_conflict = False
- break
+ continue
existing_extruder_stack = global_stack.extruders[position]
# check if there are any changes at all in any of the container stacks.
@@ -361,10 +477,18 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
extruders = num_extruders * [""]
+ self._machine_info.container_id = global_stack_id
+ self._machine_info.name = machine_name
+ self._machine_info.definition_id = machine_definition_id
+ self._machine_info.quality_type = quality_type
+ self._machine_info.custom_quality_name = quality_name
+
+ if machine_conflict and not self._is_same_machine_type:
+ machine_conflict = False
+
# 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.setHasVisibleSettingsField(has_visible_settings_string)
self._dialog.setNumVisibleSettings(num_visible_settings)
@@ -407,7 +531,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
## Overrides an ExtruderStack in the given GlobalStack and returns the new ExtruderStack.
def _overrideExtruderStack(self, global_stack, extruder_file_content, extruder_stack_file):
# Get extruder position first
- extruder_config = configparser.ConfigParser(interpolation = None)
+ extruder_config = ConfigParser(interpolation = None)
extruder_config.read_string(extruder_file_content)
if not extruder_config.has_option("metadata", "position"):
msg = "Could not find 'metadata/position' in extruder stack file"
@@ -435,6 +559,27 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
# \param file_name
@call_on_qt_thread
def read(self, file_name):
+ container_registry = ContainerRegistry.getInstance()
+ signals = [container_registry.containerAdded,
+ container_registry.containerRemoved,
+ container_registry.containerMetaDataChanged]
+ #
+ # We now have different managers updating their lookup tables upon container changes. It is critical to make
+ # sure that the managers have a complete set of data when they update.
+ #
+ # In project loading, lots of the container-related signals are loosely emitted, which can create timing gaps
+ # for incomplete data update or other kinds of issues to happen.
+ #
+ # To avoid this, we postpone all signals so they don't get emitted immediately. But, please also be aware that,
+ # because of this, do not expect to have the latest data in the lookup tables in project loading.
+ #
+ with postponeSignals(*signals, compress = CompressTechnique.NoCompression):
+ return self._read(file_name)
+
+ def _read(self, file_name):
+ application = CuraApplication.getInstance()
+ material_manager = application.getMaterialManager()
+
archive = zipfile.ZipFile(file_name, "r")
cura_file_names = [name for name in archive.namelist() if name.startswith("Cura/")]
@@ -461,52 +606,24 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
else:
global_preferences.setValue("cura/categories_expanded", categories_expanded)
- Application.getInstance().expandedCategoriesChanged.emit() # Notify the GUI of the change
+ application.expandedCategoriesChanged.emit() # Notify the GUI of the change
- self._id_mapping = {}
+ # If a machine with the same name is of a different type, always create a new one.
+ if not self._is_same_machine_type or self._resolve_strategies["machine"] != "override":
+ # We need to create a new machine
+ machine_name = self._container_registry.uniqueName(self._machine_info.name)
- # We don't add containers right away, but wait right until right before the stack serialization.
- # We do this so that if something goes wrong, it's easier to clean up.
- containers_to_add = []
+ global_stack = CuraStackBuilder.createMachine(machine_name, self._machine_info.definition_id)
+ extruder_stack_dict = global_stack.extruders
- global_stack_file, extruder_stack_files = self._determineGlobalAndExtruderStackFiles(file_name, cura_file_names)
+ self._container_registry.addContainer(global_stack)
+ else:
+ # Find the machine
+ global_stack = self._container_registry.findContainerStacks(name = self._machine_info.name, type = "machine")[0]
+ extruder_stacks = self._container_registry.findContainerStacks(machine = global_stack.getId(),
+ type = "extruder_train")
+ extruder_stack_dict = {stack.getMetaDataEntry("position"): stack for stack in extruder_stacks}
- global_stack = None
- extruder_stacks = []
- extruder_stacks_added = []
- container_stacks_added = []
- machine_extruder_count = None
-
- containers_added = []
-
- global_stack_id_original = self._stripFileToId(global_stack_file)
- global_stack_id_new = global_stack_id_original
- global_stack_name_original = self._getMachineNameFromSerializedStack(archive.open(global_stack_file).read().decode("utf-8"))
- global_stack_name_new = global_stack_name_original
- global_stack_need_rename = False
-
- extruder_stack_id_map = {} # new and old ExtruderStack IDs map
- if self._resolve_strategies["machine"] == "new":
- # We need a new id if the id already exists
- if self._container_registry.findContainerStacksMetadata(id = global_stack_id_original):
- global_stack_id_new = self.getNewId(global_stack_id_original)
- global_stack_need_rename = True
-
- if self._container_registry.findContainerStacksMetadata(name = global_stack_id_original):
- global_stack_name_new = self._container_registry.uniqueName(global_stack_name_original)
-
- for each_extruder_stack_file in extruder_stack_files:
- old_container_id = self._stripFileToId(each_extruder_stack_file)
- new_container_id = old_container_id
- if self._container_registry.findContainerStacksMetadata(id = old_container_id):
- # get a new name for this extruder
- new_container_id = self.getNewId(old_container_id)
-
- extruder_stack_id_map[old_container_id] = new_container_id
-
- # TODO: For the moment we use pretty naive existence checking. If the ID is the same, we assume in quite a few
- # TODO: cases that the container loaded is the same (most notable in materials & definitions).
- # TODO: It might be possible that we need to add smarter checking in the future.
Logger.log("d", "Workspace loading is checking definitions...")
# Get all the definition files & check if they exist. If not, add them.
definition_container_files = [name for name in cura_file_names if name.endswith(self._definition_container_suffix)]
@@ -521,7 +638,6 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
Job.yieldThread()
Logger.log("d", "Workspace loading is checking materials...")
- material_containers = []
# Get all the material files and check if they exist. If not, add them.
xml_material_profile = self._getXmlProfileClass()
if self._material_container_suffix is None:
@@ -529,537 +645,57 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
if xml_material_profile:
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:
+ to_deserialize_material = False
container_id = self._stripFileToId(material_container_file)
+ need_new_name = False
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"),
- file_name = material_container_file)
- containers_to_add.append(material_container)
+ # No material found, deserialize this material later and add it
+ to_deserialize_material = True
else:
material_container = materials[0]
- if not self._container_registry.isReadOnly(container_id): # Only create new materials if they are not read only.
+ old_material_root_id = material_container.getMetaDataEntry("base_file")
+ if not self._container_registry.isReadOnly(old_material_root_id): # Only create new materials if they are not read only.
+ to_deserialize_material = True
+
if self._resolve_strategies["material"] == "override":
- material_container.deserialize(archive.open(material_container_file).read().decode("utf-8"),
- file_name = material_container_file)
+ # Remove the old materials and then deserialize the one from the project
+ root_material_id = material_container.getMetaDataEntry("base_file")
+ material_manager.removeMaterialByRootId(root_material_id)
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"),
- file_name = material_container_file)
- containers_to_add.append(material_container)
+ container_id = self.getNewId(container_id)
+ self._old_new_materials[old_material_root_id] = container_id
+ need_new_name = True
- material_containers.append(material_container)
+ if to_deserialize_material:
+ material_container = xml_material_profile(container_id)
+ material_container.deserialize(archive.open(material_container_file).read().decode("utf-8"),
+ file_name = container_id + "." + self._material_container_suffix)
+ if need_new_name:
+ new_name = ContainerRegistry.getInstance().uniqueName(material_container.getName())
+ material_container.setName(new_name)
+ material_container.setDirty(True)
+ self._container_registry.addContainer(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_and_definition_changes_instance_containers = []
- quality_changes_instance_containers = []
- for instance_container_file in instance_container_files:
- container_id = self._stripFileToId(instance_container_file)
- serialized = archive.open(instance_container_file).read().decode("utf-8")
+ # Handle quality changes if any
+ self._processQualityChanges(global_stack)
- # HACK! we ignore "quality" and "variant" instance containers!
- parser = configparser.ConfigParser(interpolation = None)
- parser.read_string(serialized)
- if not parser.has_option("metadata", "type"):
- Logger.log("w", "Cannot find metadata/type in %s, ignoring it", instance_container_file)
- continue
- if parser.get("metadata", "type") in self._ignored_instance_container_types:
- continue
-
- instance_container = InstanceContainer(container_id)
-
- # Deserialize InstanceContainer by converting read data from bytes to string
- instance_container.deserialize(serialized, file_name = instance_container_file)
- container_type = instance_container.getMetaDataEntry("type")
- Job.yieldThread()
-
- #
- # IMPORTANT:
- # If an instance container (or maybe other type of container) exists, and user chooses "Create New",
- # we need to rename this container and all references to it, and changing those references are VERY
- # HARD.
- #
- if container_type in self._ignored_instance_container_types:
- # Ignore certain instance container types
- Logger.log("w", "Ignoring instance container [%s] with type [%s]", container_id, container_type)
- continue
- elif container_type == "user":
- # Check if quality changes already exists.
- user_containers = self._container_registry.findInstanceContainers(id = container_id)
- if not user_containers:
- containers_to_add.append(instance_container)
- else:
- if self._resolve_strategies["machine"] == "override" or self._resolve_strategies["machine"] is None:
- instance_container = user_containers[0]
- instance_container.deserialize(archive.open(instance_container_file).read().decode("utf-8"),
- file_name = instance_container_file)
- instance_container.setDirty(True)
- elif self._resolve_strategies["machine"] == "new":
- # The machine is going to get a spiffy new name, so ensure that the id's of user settings match.
- old_extruder_id = instance_container.getMetaDataEntry("extruder", None)
- if old_extruder_id:
- new_extruder_id = extruder_stack_id_map[old_extruder_id]
- new_id = new_extruder_id + "_current_settings"
- instance_container.setMetaDataEntry("id", new_id)
- instance_container.setName(new_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_machine_id = self.getNewId(machine_id)
- new_id = new_machine_id + "_current_settings"
- instance_container.setMetaDataEntry("id", new_id)
- instance_container.setName(new_id)
- instance_container.setMetaDataEntry("machine", new_machine_id)
- containers_to_add.append(instance_container)
- user_instance_containers.append(instance_container)
- elif container_type in ("quality_changes", "definition_changes"):
- # Check if quality changes already exists.
- changes_containers = self._container_registry.findInstanceContainers(id = container_id)
- if not changes_containers:
- # no existing containers with the same ID, so we can safely add the new one
- containers_to_add.append(instance_container)
- else:
- # we have found existing container with the same ID, so we need to resolve according to the
- # selected strategy.
- if self._resolve_strategies[container_type] == "override":
- instance_container = changes_containers[0]
- instance_container.deserialize(archive.open(instance_container_file).read().decode("utf-8"),
- file_name = instance_container_file)
- instance_container.setDirty(True)
-
- elif self._resolve_strategies[container_type] == "new":
- # TODO: how should we handle the case "new" for quality_changes and definition_changes?
-
- instance_container.setName(self._container_registry.uniqueName(instance_container.getName()))
- new_changes_container_id = self.getNewId(instance_container.getId())
- instance_container.setMetaDataEntry("id", 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.
- old_extruder_id = instance_container.getMetaDataEntry("extruder", None)
- # Note that in case of a quality_changes extruder means the definition id of the extruder stack
- # For the user settings, it means the actual extruder stack id it's assigned to.
- if old_extruder_id and old_extruder_id in extruder_stack_id_map:
- new_extruder_id = extruder_stack_id_map[old_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_and_definition_changes_instance_containers.append(instance_container)
- if container_type == "quality_changes":
- quality_changes_instance_containers.append(instance_container)
-
- if container_type == "definition_changes":
- definition_changes_extruder_count = instance_container.getProperty("machine_extruder_count", "value")
- if definition_changes_extruder_count is not None:
- machine_extruder_count = definition_changes_extruder_count
-
- else:
- existing_container = self._container_registry.findInstanceContainersMetadata(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...")
-
- # load global stack file
- try:
- stack = None
-
- if self._resolve_strategies["machine"] == "override":
- container_stacks = self._container_registry.findContainerStacks(id = global_stack_id_original)
- stack = container_stacks[0]
-
- # HACK
- # There is a machine, check if it has authentication data. If so, keep that data.
- network_authentication_id = stack.getMetaDataEntry("network_authentication_id")
- network_authentication_key = stack.getMetaDataEntry("network_authentication_key")
- stack.deserialize(archive.open(global_stack_file).read().decode("utf-8"), file_name = global_stack_file)
- if network_authentication_id:
- stack.addMetaDataEntry("network_authentication_id", network_authentication_id)
- if network_authentication_key:
- stack.addMetaDataEntry("network_authentication_key", network_authentication_key)
-
- elif self._resolve_strategies["machine"] == "new":
- # create a new global stack
- stack = GlobalStack(global_stack_id_new)
- # Deserialize stack by converting read data from bytes to string
- stack.deserialize(archive.open(global_stack_file).read().decode("utf-8"),
- file_name = global_stack_file)
-
- # Ensure a unique ID and name
- stack.setMetaDataEntry("id", global_stack_id_new)
-
- # Only machines need a new name, stacks may be non-unique
- stack.setName(global_stack_name_new)
-
- container_stacks_added.append(stack)
- # self._container_registry.addContainer(stack)
- containers_added.append(stack)
- else:
- Logger.log("e", "Resolve strategy of %s for machine is not supported", self._resolve_strategies["machine"])
-
- # Create a new definition_changes container if it was empty
- if stack.definitionChanges == self._container_registry.getEmptyInstanceContainer():
- stack.setDefinitionChanges(CuraStackBuilder.createDefinitionChangesContainer(stack, stack.getId() + "_settings"))
- 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
- has_extruder_stack_files = len(extruder_stack_files) > 0
- empty_quality_container = self._container_registry.findInstanceContainers(id = "empty_quality")[0]
- empty_quality_changes_container = self._container_registry.findInstanceContainers(id = "empty_quality_changes")[0]
- try:
- for extruder_stack_file in extruder_stack_files:
- container_id = self._stripFileToId(extruder_stack_file)
- extruder_file_content = archive.open(extruder_stack_file, "r").read().decode("utf-8")
-
- if self._resolve_strategies["machine"] == "override":
- # deserialize new extruder stack over the current ones (if any)
- stack = self._overrideExtruderStack(global_stack, extruder_file_content, extruder_stack_file)
- if stack is None:
- continue
-
- elif self._resolve_strategies["machine"] == "new":
- new_id = extruder_stack_id_map[container_id]
- stack = ExtruderStack(new_id)
-
- # HACK: the global stack can have a new name, so we need to make sure that this extruder stack
- # references to the new name instead of the old one. Normally, this can be done after
- # deserialize() by setting the metadata, but in the case of ExtruderStack, deserialize()
- # also does addExtruder() to its machine stack, so we have to make sure that it's pointing
- # to the right machine BEFORE deserialization.
- extruder_config = configparser.ConfigParser(interpolation = None)
- extruder_config.read_string(extruder_file_content)
- extruder_config.set("metadata", "machine", global_stack_id_new)
- tmp_string_io = io.StringIO()
- extruder_config.write(tmp_string_io)
- extruder_file_content = tmp_string_io.getvalue()
-
- stack.deserialize(extruder_file_content, file_name = extruder_stack_file)
-
- # Ensure a unique ID and name
- stack.setMetaDataEntry("id", new_id)
-
- self._container_registry.addContainer(stack)
- extruder_stacks_added.append(stack)
- containers_added.append(stack)
- else:
- Logger.log("w", "Unknown resolve strategy: %s", self._resolve_strategies["machine"])
-
- # Create a new definition_changes container if it was empty
- if stack.definitionChanges == self._container_registry.getEmptyInstanceContainer():
- stack.setDefinitionChanges(CuraStackBuilder.createDefinitionChangesContainer(stack, stack.getId() + "_settings"))
-
- if stack.getMetaDataEntry("type") == "extruder_train":
- extruder_stacks.append(stack)
-
- # If not extruder stacks were saved in the project file (pre 3.1) create one manually
- # We re-use the container registry's addExtruderStackForSingleExtrusionMachine method for this
- if not extruder_stacks:
- # If we choose to override a machine but to create a new custom quality profile, the custom quality
- # profile is not immediately applied to the global_stack, so this fix for single extrusion machines
- # will use the current custom quality profile on the existing machine. The extra optional argument
- # in that function is used in this case to specify a new global stack quality_changes container so
- # the fix can correctly create and copy over the custom quality settings to the newly created extruder.
- new_global_quality_changes = None
- if self._resolve_strategies["quality_changes"] == "new" and len(quality_changes_instance_containers) > 0:
- new_global_quality_changes = quality_changes_instance_containers[0]
-
- # Depending if the strategy is to create a new or override, the ids must be or not be unique
- stack = self._container_registry.addExtruderStackForSingleExtrusionMachine(global_stack, "fdmextruder",
- new_global_quality_changes,
- create_new_ids = self._resolve_strategies["machine"] == "new")
- if new_global_quality_changes is not None:
- quality_changes_instance_containers.append(stack.qualityChanges)
- quality_and_definition_changes_instance_containers.append(stack.qualityChanges)
- if global_stack.quality.getId() in ("empty", "empty_quality"):
- stack.quality = empty_quality_container
- if self._resolve_strategies["machine"] == "override":
- # in case the extruder is newly created (for a single-extrusion machine), we need to override
- # the existing extruder stack.
- existing_extruder_stack = global_stack.extruders[stack.getMetaDataEntry("position")]
- for idx in range(len(_ContainerIndexes.IndexTypeMap)):
- existing_extruder_stack.replaceContainer(idx, stack._containers[idx], postpone_emit = True)
- extruder_stacks.append(existing_extruder_stack)
- else:
- 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_added:
- self._container_registry.removeContainer(container.getId())
- return
-
- ## In case there is a new machine and once the extruders are created, the global stack is added to the registry,
- # otherwise the accContainers function in CuraContainerRegistry will create an extruder stack and then creating
- # useless files
- if self._resolve_strategies["machine"] == "new":
- self._container_registry.addContainer(global_stack)
-
- # Check quality profiles to make sure that if one stack has the "not supported" quality profile,
- # all others should have the same.
- #
- # This block code tries to fix the following problems in Cura 3.0 and earlier:
- # 1. The upgrade script can rename all "Not Supported" quality profiles to "empty_quality", but it cannot fix
- # the problem that the global stack the extruder stacks may have different quality profiles. The code
- # below loops over all stacks and make sure that if there is one stack with "Not Supported" profile, the
- # rest should also use the "Not Supported" profile.
- # 2. In earlier versions (at least 2.7 and 3.0), a wrong quality profile could be assigned to a stack. For
- # example, a UM3 can have a BB 0.8 variant with "aa04_pla_fast" quality profile enabled. To fix this,
- # in the code below we also check the actual available quality profiles for the machine.
- #
- has_not_supported = False
- for stack in [global_stack] + extruder_stacks:
- if stack.quality.getId() in ("empty", "empty_quality"):
- has_not_supported = True
- break
-
- # We filter out extruder stacks that are not actually used, for example the UM3 and custom FDM printer extruder count setting.
- extruder_stacks_in_use = extruder_stacks
- if machine_extruder_count is not None:
- extruder_stacks_in_use = extruder_stacks[:machine_extruder_count]
-
- available_quality = QualityManager.getInstance().findAllUsableQualitiesForMachineAndExtruders(global_stack,
- extruder_stacks_in_use)
- if not has_not_supported:
- has_not_supported = not available_quality
-
- quality_has_been_changed = False
-
- if has_not_supported:
- for stack in [global_stack] + extruder_stacks_in_use:
- stack.replaceContainer(_ContainerIndexes.Quality, empty_quality_container)
- stack.replaceContainer(_ContainerIndexes.QualityChanges, empty_quality_changes_container)
- quality_has_been_changed = True
-
- else:
- # The machine in the project has non-empty quality and there are usable qualities for this machine.
- # We need to check if the current quality_type is still usable for this machine, if not, then the quality
- # will be reset to the "preferred quality" if present, otherwise "normal".
- available_quality_types = [q.getMetaDataEntry("quality_type") for q in available_quality]
-
- if global_stack.quality.getMetaDataEntry("quality_type") not in available_quality_types:
- # We are here because the quality_type specified in the project is not supported any more,
- # so we need to switch it to the "preferred quality" if present, otherwise "normal".
- quality_has_been_changed = True
-
- # find the preferred quality
- preferred_quality_id = global_stack.getMetaDataEntry("preferred_quality", None)
- if preferred_quality_id is not None:
- definition_id = global_stack.definition.getId()
- definition_id = global_stack.definition.getMetaDataEntry("quality_definition", definition_id)
- if not parseBool(global_stack.getMetaDataEntry("has_machine_quality", "False")):
- definition_id = "fdmprinter"
-
- containers = self._container_registry.findInstanceContainers(id = preferred_quality_id,
- type = "quality",
- definition = definition_id)
- containers = [c for c in containers if not c.getMetaDataEntry("material", "")]
- if containers:
- global_stack.quality = containers[0]
- global_stack.qualityChanges = empty_quality_changes_container
- # also find the quality containers for the extruders
- for extruder_stack in extruder_stacks_in_use:
- search_criteria = {"id": preferred_quality_id,
- "type": "quality",
- "definition": definition_id}
- if global_stack.getMetaDataEntry("has_machine_materials") and extruder_stack.material.getId() not in ("empty", "empty_material"):
- search_criteria["material"] = extruder_stack.material.getId()
- containers = self._container_registry.findInstanceContainers(**search_criteria)
- if containers:
- extruder_stack.quality = containers[0]
- extruder_stack.qualityChanges = empty_quality_changes_container
- else:
- Logger.log("e", "Cannot find preferred quality for extruder [%s].", extruder_stack.getId())
-
- else:
- # we cannot find the preferred quality. THIS SHOULD NOT HAPPEN
- Logger.log("e", "Cannot find the preferred quality for machine [%s]", global_stack.getId())
- else:
- # The quality_type specified in the project file is usable, but the quality container itself may not
- # be correct. For example, for UM2, the quality container can be "draft" while it should be "um2_draft"
- # instead.
- # In this code branch, we try to fix those incorrect quality containers.
- #
- # ***IMPORTANT***: We only do this fix for single-extrusion machines.
- # We will first find the correct quality profile for the extruder, then apply the same
- # quality profile for the global stack.
- #
- if len(extruder_stacks) == 1:
- extruder_stack = extruder_stacks[0]
-
- search_criteria = {"type": "quality", "quality_type": global_stack.quality.getMetaDataEntry("quality_type")}
- search_criteria["definition"] = global_stack.definition.getId()
- if not parseBool(global_stack.getMetaDataEntry("has_machine_quality", "False")):
- search_criteria["definition"] = "fdmprinter"
-
- if global_stack.getMetaDataEntry("has_machine_materials") and extruder_stack.material.getId() not in ("empty", "empty_material"):
- search_criteria["material"] = extruder_stack.material.getId()
- containers = self._container_registry.findInstanceContainers(**search_criteria)
- if containers:
- new_quality_container = containers[0]
- extruder_stack.quality = new_quality_container
- global_stack.quality = new_quality_container
-
- # 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.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.userChanges = container
- continue
-
- changes_container_types = ("quality_changes", "definition_changes")
- if quality_has_been_changed:
- # DO NOT replace quality_changes if the current quality_type is not supported
- changes_container_types = ("definition_changes",)
- for changes_container_type in changes_container_types:
- 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:
- # NOTE: The renaming and giving new IDs are possibly redundant because they are done in the
- # instance container loading part.
- new_id = each_changes_container.getId()
-
- # Find the old (current) changes container in the global stack
- if changes_container_type == "quality_changes":
- old_container = global_stack.qualityChanges
- elif changes_container_type == "definition_changes":
- old_container = global_stack.definitionChanges
-
- # sanity checks
- # NOTE: The following cases SHOULD NOT happen!!!!
- if old_container.getId() in ("empty_quality_changes", "empty_definition_changes", "empty"):
- Logger.log("e", "We try to get [%s] from the global stack [%s] but we got None instead!",
- changes_container_type, global_stack.getId())
- continue
-
- # 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 self._id_mapping.get(old_container.getId()) == new_id:
- if changes_container_type == "quality_changes":
- global_stack.qualityChanges = each_changes_container
- elif changes_container_type == "definition_changes":
- global_stack.definitionChanges = each_changes_container
- continue
-
- # Replace the quality/definition changes container if it's in one of the ExtruderStacks
- # Only apply the change if we have loaded extruder stacks from the project
- if has_extruder_stack_files:
- 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 changes_container.getId() in ("empty_quality_changes", "empty_definition_changes", "empty"):
- 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())
- continue
-
- # NOTE: we can get an empty container here, but the IDs will not match,
- # so this comparison is fine.
- if self._id_mapping.get(changes_container.getId()) == new_id:
- if changes_container_type == "quality_changes":
- each_extruder_stack.qualityChanges = each_changes_container
- elif changes_container_type == "definition_changes":
- each_extruder_stack.definitionChanges = each_changes_container
-
- if self._resolve_strategies["material"] == "new":
- # the actual material instance container can have an ID such as
- # __
- # which cannot be determined immediately, so here we use a HACK to find the right new material
- # instance ID:
- # - get the old material IDs for all material
- # - find the old material with the longest common prefix in ID, that's the old material
- # - update the name by replacing the old prefix with the new
- # - find the new material container and set it to the stack
- old_to_new_material_dict = {}
- for each_material in material_containers:
- # find the material's old name
- for old_id, new_id in self._id_mapping.items():
- if each_material.getId() == new_id:
- old_to_new_material_dict[old_id] = each_material
- break
-
- # replace old material in global and extruder stacks with new
- self._replaceStackMaterialWithNew(global_stack, old_to_new_material_dict)
- if extruder_stacks:
- for each_extruder_stack in extruder_stacks:
- self._replaceStackMaterialWithNew(each_extruder_stack, old_to_new_material_dict)
-
- if extruder_stacks:
- for stack in extruder_stacks:
- ExtruderManager.getInstance().registerExtruder(stack, global_stack.getId())
+ # Prepare the machine
+ self._applyChangesToMachine(global_stack, extruder_stack_dict)
Logger.log("d", "Workspace loading is notifying rest of the code of changes...")
-
- if self._resolve_strategies["machine"] == "new":
- for stack in extruder_stacks:
- stack.setNextStack(global_stack)
- stack.containersChanged.emit(stack.getTop())
- else:
- CuraApplication.getInstance().getMachineManager().activeQualityChanged.emit()
-
# 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())
+ #
+ # This is scheduled for later is because it depends on the Variant/Material/Qualitiy Managers to have the latest
+ # data, but those managers will only update upon a container/container metadata changed signal. Because this
+ # function is running on the main thread (Qt thread), although those "changed" signals have been emitted, but
+ # they won't take effect until this function is done.
+ # To solve this, we schedule _updateActiveMachine() for later so it will have the latest data.
+ self._updateActiveMachine(global_stack)
# Load all the nodes / meshdata of the workspace
nodes = self._3mf_mesh_reader.read(file_name)
@@ -1072,60 +708,277 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
self.setWorkspaceName(base_file_name)
return nodes
- ## HACK: Replaces the material container in the given stack with a newly created material container.
- # This function is used when the user chooses to resolve material conflicts by creating new ones.
- def _replaceStackMaterialWithNew(self, stack, old_new_material_dict):
- # The material containers in the project file are 'parent' material such as "generic_pla",
- # but a material container used in a global/extruder stack is a 'child' material,
- # such as "generic_pla_ultimaker3_AA_0.4", which can be formalised as the following:
- #
- # __
- #
- # In the project loading, when a user chooses to resolve material conflicts by creating new ones,
- # the old 'parent' material ID and the new 'parent' material ID are known, but not the child material IDs.
- # In this case, the global stack and the extruder stacks need to use the newly created material, but the
- # material containers they use are 'child' material. So, here, we need to find the right 'child' material for
- # the stacks.
- #
- # This hack approach works as follows:
- # - No matter there is a child material or not, the actual material we are looking for has the prefix
- # "", which is the old material name. For the material in a stack, we know that the new
- # material's ID will be "_blabla..", so we just need to replace the old material ID
- # with the new one to get the new 'child' material.
- # - Because the material containers have IDs such as "m #nn", if we use simple prefix matching, there can
- # be a problem in the following scenario:
- # - there are two materials in the project file, namely "m #1" and "m #11"
- # - the child materials in use are for example: "m #1_um3_aa04", "m #11_um3_aa04"
- # - if we only check for a simple prefix match, then "m #11_um3_aa04" will match with "m #1", but they
- # are not the same material
- # To avoid this, when doing the prefix matching, we use the result with the longest mactching prefix.
+ def _processQualityChanges(self, global_stack):
+ if self._machine_info.quality_changes_info is None:
+ return
- # find the old material ID
- old_material_id_in_stack = stack.material.getId()
- best_matching_old_material_id = None
- best_matching_old_material_prefix_length = -1
- for old_parent_material_id in old_new_material_dict:
- if len(old_parent_material_id) < best_matching_old_material_prefix_length:
+ application = CuraApplication.getInstance()
+ quality_manager = application.getQualityManager()
+
+ # If we have custom profiles, load them
+ quality_changes_name = self._machine_info.quality_changes_info.name
+ if self._machine_info.quality_changes_info is not None:
+ Logger.log("i", "Loading custom profile [%s] from project file",
+ self._machine_info.quality_changes_info.name)
+
+ # Get the correct extruder definition IDs for quality changes
+ from cura.Machines.QualityManager import getMachineDefinitionIDForQualitySearch
+ machine_definition_id_for_quality = getMachineDefinitionIDForQualitySearch(global_stack)
+ machine_definition_for_quality = self._container_registry.findDefinitionContainers(id = machine_definition_id_for_quality)[0]
+
+ quality_changes_info = self._machine_info.quality_changes_info
+ quality_changes_quality_type = quality_changes_info.global_info.parser["metadata"]["quality_type"]
+
+ quality_changes_name = quality_changes_info.name
+ create_new = self._resolve_strategies.get("quality_changes") != "override"
+ if create_new:
+ container_info_dict = {None: self._machine_info.quality_changes_info.global_info}
+ container_info_dict.update(quality_changes_info.extruder_info_dict)
+
+ quality_changes_name = self._container_registry.uniqueName(quality_changes_name)
+ for position, container_info in container_info_dict.items():
+ extruder_stack = None
+ if position is not None:
+ extruder_stack = global_stack.extruders[position]
+ container = quality_manager._createQualityChanges(quality_changes_quality_type,
+ quality_changes_name,
+ global_stack, extruder_stack)
+ container_info.container = container
+ container.setDirty(True)
+ self._container_registry.addContainer(container)
+
+ Logger.log("d", "Created new quality changes container [%s]", container.getId())
+
+ else:
+ # Find the existing containers
+ quality_changes_containers = self._container_registry.findInstanceContainers(name = quality_changes_name,
+ type = "quality_changes")
+ for container in quality_changes_containers:
+ extruder_definition_id = container.getMetaDataEntry("extruder")
+ if not extruder_definition_id:
+ quality_changes_info.global_info.container = container
+ else:
+ extruder_definition_metadata = self._container_registry.findDefinitionContainersMetadata(id = extruder_definition_id)[0]
+ position = extruder_definition_metadata["position"]
+ if position not in quality_changes_info.extruder_info_dict:
+ quality_changes_info.extruder_info_dict[position] = ContainerInfo(None, None, None)
+ container_info = quality_changes_info.extruder_info_dict[position]
+ container_info.container = container
+
+ # If there is no quality changes for any extruder, create one.
+ if not quality_changes_info.extruder_info_dict:
+ container_info = ContainerInfo(None, None, None)
+ quality_changes_info.extruder_info_dict["0"] = container_info
+ extruder_stack = global_stack.extruders["0"]
+
+ container = quality_manager._createQualityChanges(quality_changes_quality_type, quality_changes_name,
+ global_stack, extruder_stack)
+ container_info.container = container
+ container.setDirty(True)
+ self._container_registry.addContainer(container)
+
+ Logger.log("d", "Created new quality changes container [%s]", container.getId())
+
+ # Clear all existing containers
+ quality_changes_info.global_info.container.clear()
+ for container_info in quality_changes_info.extruder_info_dict.values():
+ container_info.container.clear()
+
+ # Loop over everything and override the existing containers
+ global_info = quality_changes_info.global_info
+ global_info.container.clear() # Clear all
+ for key, value in global_info.parser["values"].items():
+ if not machine_definition_for_quality.getProperty(key, "settable_per_extruder"):
+ global_info.container.setProperty(key, "value", value)
+ else:
+ quality_changes_info.extruder_info_dict["0"].container.setProperty(key, "value", value)
+
+ for position, container_info in quality_changes_info.extruder_info_dict.items():
+ if container_info.parser is None:
+ continue
+
+ if container_info.container is None:
+ extruder_stack = global_stack.extruders[position]
+ container = quality_manager._createQualityChanges(quality_changes_quality_type, quality_changes_name,
+ global_stack, extruder_stack)
+ container_info.container = container
+
+ for key, value in container_info.parser["values"].items():
+ container_info.container.setProperty(key, "value", value)
+
+ self._machine_info.quality_changes_info.name = quality_changes_name
+
+ def _clearStack(self, stack):
+ application = CuraApplication.getInstance()
+
+ stack.definitionChanges.clear()
+ stack.variant = application.empty_variant_container
+ stack.material = application.empty_material_container
+ stack.quality = application.empty_quality_container
+ stack.qualityChanges = application.empty_quality_changes_container
+ stack.userChanges.clear()
+
+ def _applyDefinitionChanges(self, global_stack, extruder_stack_dict):
+ values_to_set_for_extruders = {}
+ if self._machine_info.definition_changes_info is not None:
+ parser = self._machine_info.definition_changes_info.parser
+ for key, value in parser["values"].items():
+ if global_stack.getProperty(key, "settable_per_extruder"):
+ values_to_set_for_extruders[key] = value
+ else:
+ global_stack.definitionChanges.setProperty(key, "value", value)
+
+ for position, extruder_stack in extruder_stack_dict.items():
+ if position not in self._machine_info.extruder_info_dict:
continue
- if len(old_parent_material_id) <= len(old_material_id_in_stack):
- if old_parent_material_id == old_material_id_in_stack[0:len(old_parent_material_id)]:
- best_matching_old_material_prefix_length = len(old_parent_material_id)
- best_matching_old_material_id = old_parent_material_id
- if best_matching_old_material_id is None:
- Logger.log("w", "Cannot find any matching old material ID for stack [%s] material [%s]. Something can go wrong",
- stack.getId(), old_material_id_in_stack)
- return
+ extruder_info = self._machine_info.extruder_info_dict[position]
+ if extruder_info.definition_changes_info is None:
+ continue
+ parser = extruder_info.definition_changes_info.parser
+ for key, value in values_to_set_for_extruders.items():
+ extruder_stack.definitionChanges.setProperty(key, "value", value)
+ if parser is not None:
+ for key, value in parser["values"].items():
+ extruder_stack.definitionChanges.setProperty(key, "value", value)
- # find the new material container
- new_material_id = old_new_material_dict[best_matching_old_material_id].getId() + old_material_id_in_stack[len(best_matching_old_material_id):]
- new_material_containers = self._container_registry.findInstanceContainers(id = new_material_id, type = "material")
- if not new_material_containers:
- Logger.log("e", "Cannot find new material container [%s]", new_material_id)
- return
+ def _applyUserChanges(self, global_stack, extruder_stack_dict):
+ values_to_set_for_extruder_0 = {}
+ if self._machine_info.user_changes_info is not None:
+ parser = self._machine_info.user_changes_info.parser
+ for key, value in parser["values"].items():
+ if global_stack.getProperty(key, "settable_per_extruder"):
+ values_to_set_for_extruder_0[key] = value
+ else:
+ global_stack.userChanges.setProperty(key, "value", value)
- # replace the material in the given stack
- stack.material = new_material_containers[0]
+ for position, extruder_stack in extruder_stack_dict.items():
+ if position not in self._machine_info.extruder_info_dict:
+ continue
+
+ extruder_info = self._machine_info.extruder_info_dict[position]
+ if extruder_info.user_changes_info is not None:
+ parser = self._machine_info.extruder_info_dict[position].user_changes_info.parser
+ if position == "0":
+ for key, value in values_to_set_for_extruder_0.items():
+ extruder_stack.userChanges.setProperty(key, "value", value)
+ if parser is not None:
+ for key, value in parser["values"].items():
+ extruder_stack.userChanges.setProperty(key, "value", value)
+
+ def _applyVariants(self, global_stack, extruder_stack_dict):
+ application = CuraApplication.getInstance()
+ variant_manager = application.getVariantManager()
+
+ if self._machine_info.variant_info is not None:
+ parser = self._machine_info.variant_info.parser
+ variant_name = parser["general"]["name"]
+
+ from cura.Machines.VariantManager import VariantType
+ variant_type = VariantType.BUILD_PLATE
+
+ node = variant_manager.getVariantNode(global_stack.definition.getId(), variant_name, variant_type)
+ if node is not None:
+ global_stack.variant = node.getContainer()
+
+ for position, extruder_stack in extruder_stack_dict.items():
+ if position not in self._machine_info.extruder_info_dict:
+ continue
+ extruder_info = self._machine_info.extruder_info_dict[position]
+ if extruder_info.variant_info is None:
+ continue
+ parser = extruder_info.variant_info.parser
+
+ variant_name = parser["general"]["name"]
+ from cura.Machines.VariantManager import VariantType
+ variant_type = VariantType.NOZZLE
+
+ node = variant_manager.getVariantNode(global_stack.definition.getId(), variant_name, variant_type)
+ if node is not None:
+ extruder_stack.variant = node.getContainer()
+
+ def _applyMaterials(self, global_stack, extruder_stack_dict):
+ application = CuraApplication.getInstance()
+ material_manager = application.getMaterialManager()
+
+ # Force update lookup tables first
+ material_manager.initialize()
+
+ for position, extruder_stack in extruder_stack_dict.items():
+ if position not in self._machine_info.extruder_info_dict:
+ continue
+ extruder_info = self._machine_info.extruder_info_dict[position]
+ if extruder_info.root_material_id is None:
+ continue
+
+ root_material_id = extruder_info.root_material_id
+ root_material_id = self._old_new_materials.get(root_material_id, root_material_id)
+
+ # get material diameter of this extruder
+ machine_material_diameter = extruder_stack.materialDiameter
+ material_node = material_manager.getMaterialNode(global_stack.definition.getId(),
+ extruder_stack.variant.getName(),
+ machine_material_diameter,
+ root_material_id)
+ if material_node is not None:
+ extruder_stack.material = material_node.getContainer()
+
+ def _applyChangesToMachine(self, global_stack, extruder_stack_dict):
+ # Clear all first
+ self._clearStack(global_stack)
+ for extruder_stack in extruder_stack_dict.values():
+ self._clearStack(extruder_stack)
+
+ self._applyDefinitionChanges(global_stack, extruder_stack_dict)
+ self._applyUserChanges(global_stack, extruder_stack_dict)
+ self._applyVariants(global_stack, extruder_stack_dict)
+ self._applyMaterials(global_stack, extruder_stack_dict)
+
+ # prepare the quality to select
+ self._quality_changes_to_apply = None
+ self._quality_type_to_apply = None
+ if self._machine_info.quality_changes_info is not None:
+ self._quality_changes_to_apply = self._machine_info.quality_changes_info.name
+ else:
+ self._quality_type_to_apply = self._machine_info.quality_type
+
+ def _updateActiveMachine(self, global_stack):
+ # Actually change the active machine.
+ machine_manager = Application.getInstance().getMachineManager()
+ material_manager = Application.getInstance().getMaterialManager()
+ quality_manager = Application.getInstance().getQualityManager()
+
+ # Force update the lookup maps first
+ material_manager.initialize()
+ quality_manager.initialize()
+
+ machine_manager.setActiveMachine(global_stack.getId())
+
+ if self._quality_changes_to_apply:
+ quality_changes_group_dict = quality_manager.getQualityChangesGroups(global_stack)
+ if self._quality_changes_to_apply not in quality_changes_group_dict:
+ Logger.log("e", "Could not find quality_changes [%s]", self._quality_changes_to_apply)
+ return
+ quality_changes_group = quality_changes_group_dict[self._quality_changes_to_apply]
+ machine_manager.setQualityChangesGroup(quality_changes_group, no_dialog = True)
+ else:
+ self._quality_type_to_apply = self._quality_type_to_apply.lower()
+ quality_group_dict = quality_manager.getQualityGroups(global_stack)
+ if self._quality_type_to_apply in quality_group_dict:
+ quality_group = quality_group_dict[self._quality_type_to_apply]
+ else:
+ Logger.log("i", "Could not find quality type [%s], switch to default", self._quality_type_to_apply)
+ preferred_quality_type = global_stack.getMetaDataEntry("preferred_quality_type")
+ quality_group_dict = quality_manager.getQualityGroups(global_stack)
+ quality_group = quality_group_dict.get(preferred_quality_type)
+ if quality_group is None:
+ Logger.log("e", "Could not get preferred quality type [%s]", preferred_quality_type)
+
+ if quality_group is not None:
+ machine_manager.setQualityGroup(quality_group, no_dialog = True)
+
+ # Notify everything/one that is to notify about changes.
+ global_stack.containersChanged.emit(global_stack.getTop())
def _stripFileToId(self, file):
mime_type = MimeTypeDatabase.getMimeTypeForFile(file)
@@ -1137,7 +990,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
## Get the list of ID's of all containers in a container stack by partially parsing it's serialized data.
def _getContainerIdListFromSerialized(self, serialized):
- parser = configparser.ConfigParser(interpolation=None, empty_lines_in_values=False)
+ parser = ConfigParser(interpolation=None, empty_lines_in_values=False)
parser.read_string(serialized)
container_ids = []
@@ -1158,7 +1011,7 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
return container_ids
def _getMachineNameFromSerializedStack(self, serialized):
- parser = configparser.ConfigParser(interpolation=None, empty_lines_in_values=False)
+ parser = ConfigParser(interpolation=None, empty_lines_in_values=False)
parser.read_string(serialized)
return parser["general"].get("name", "")
diff --git a/plugins/3MFReader/WorkspaceDialog.py b/plugins/3MFReader/WorkspaceDialog.py
index 5b474843d5..bb31afd40b 100644
--- a/plugins/3MFReader/WorkspaceDialog.py
+++ b/plugins/3MFReader/WorkspaceDialog.py
@@ -52,7 +52,6 @@ class WorkspaceDialog(QObject):
machineConflictChanged = pyqtSignal()
qualityChangesConflictChanged = pyqtSignal()
- definitionChangesConflictChanged = pyqtSignal()
materialConflictChanged = pyqtSignal()
numVisibleSettingsChanged = pyqtSignal()
activeModeChanged = pyqtSignal()
@@ -196,10 +195,6 @@ 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
@@ -229,18 +224,11 @@ 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
diff --git a/plugins/3MFWriter/ThreeMFWorkspaceWriter.py b/plugins/3MFWriter/ThreeMFWorkspaceWriter.py
index 507274d355..3f5e69317e 100644
--- a/plugins/3MFWriter/ThreeMFWorkspaceWriter.py
+++ b/plugins/3MFWriter/ThreeMFWorkspaceWriter.py
@@ -1,14 +1,15 @@
-# Copyright (c) 2017 Ultimaker B.V.
+# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from UM.Workspace.WorkspaceWriter import WorkspaceWriter
+import configparser
+from io import StringIO
+import zipfile
+
from UM.Application import Application
+from UM.Logger import Logger
from UM.Preferences import Preferences
from UM.Settings.ContainerRegistry import ContainerRegistry
-from cura.Settings.ExtruderManager import ExtruderManager
-import zipfile
-from io import StringIO
-import configparser
+from UM.Workspace.WorkspaceWriter import WorkspaceWriter
class ThreeMFWorkspaceWriter(WorkspaceWriter):
@@ -16,7 +17,10 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
super().__init__()
def write(self, stream, nodes, mode=WorkspaceWriter.OutputMode.BinaryMode):
- mesh_writer = Application.getInstance().getMeshFileHandler().getWriter("3MFWriter")
+ application = Application.getInstance()
+ machine_manager = application.getMachineManager()
+
+ mesh_writer = application.getMeshFileHandler().getWriter("3MFWriter")
if not mesh_writer: # We need to have the 3mf mesh writer, otherwise we can't save the entire workspace
return False
@@ -29,17 +33,17 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
if archive is None: # This happens if there was no mesh data to write.
archive = zipfile.ZipFile(stream, "w", compression = zipfile.ZIP_DEFLATED)
- global_container_stack = Application.getInstance().getGlobalContainerStack()
+ global_stack = machine_manager.activeMachine
# Add global container stack data to the archive.
- self._writeContainerToArchive(global_container_stack, archive)
+ self._writeContainerToArchive(global_stack, archive)
# Also write all containers in the stack to the file
- for container in global_container_stack.getContainers():
+ for container in global_stack.getContainers():
self._writeContainerToArchive(container, archive)
# Check if the machine has extruders and save all that data as well.
- for extruder_stack in ExtruderManager.getInstance().getMachineExtruders(global_container_stack.getId()):
+ for extruder_stack in global_stack.extruders.values():
self._writeContainerToArchive(extruder_stack, archive)
for container in extruder_stack.getContainers():
self._writeContainerToArchive(container, archive)
@@ -59,9 +63,9 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
version_file = zipfile.ZipInfo("Cura/version.ini")
version_config_parser = configparser.ConfigParser(interpolation = None)
version_config_parser.add_section("versions")
- version_config_parser.set("versions", "cura_version", Application.getInstance().getVersion())
- version_config_parser.set("versions", "build_type", Application.getInstance().getBuildType())
- version_config_parser.set("versions", "is_debug_mode", str(Application.getInstance().getIsDebugMode()))
+ version_config_parser.set("versions", "cura_version", application.getVersion())
+ version_config_parser.set("versions", "build_type", application.getBuildType())
+ version_config_parser.set("versions", "is_debug_mode", str(application.getIsDebugMode()))
version_file_string = StringIO()
version_config_parser.write(version_file_string)
@@ -85,7 +89,8 @@ class ThreeMFWorkspaceWriter(WorkspaceWriter):
# Some containers have a base file, which should then be the file to use.
if "base_file" in container.getMetaData():
base_file = container.getMetaDataEntry("base_file")
- container = ContainerRegistry.getInstance().findContainers(id = base_file)[0]
+ if base_file != container.getId():
+ container = ContainerRegistry.getInstance().findContainers(id = base_file)[0]
file_name = "Cura/%s.%s" % (container.getId(), file_suffix)
diff --git a/plugins/3MFWriter/ThreeMFWriter.py b/plugins/3MFWriter/ThreeMFWriter.py
index c4b7035cf1..ff6333763a 100644
--- a/plugins/3MFWriter/ThreeMFWriter.py
+++ b/plugins/3MFWriter/ThreeMFWriter.py
@@ -68,7 +68,7 @@ class ThreeMFWriter(MeshWriter):
if not isinstance(um_node, SceneNode):
return None
- active_build_plate_nr = CuraApplication.getInstance().getBuildPlateModel().activeBuildPlate
+ active_build_plate_nr = CuraApplication.getInstance().getMultiBuildPlateModel().activeBuildPlate
if um_node.callDecoration("getBuildPlateNumber") != active_build_plate_nr:
return
diff --git a/plugins/ChangeLogPlugin/ChangeLog.txt b/plugins/ChangeLogPlugin/ChangeLog.txt
index 6b394f1e2e..8a031c9eae 100755
--- a/plugins/ChangeLogPlugin/ChangeLog.txt
+++ b/plugins/ChangeLogPlugin/ChangeLog.txt
@@ -1,3 +1,9 @@
+[3.2.1]
+*Bug fixes
+- Fixed issues where Cura crashes on startup and loading profiles
+- Updated translations
+- Fixed an issue where the text would not render properly
+
[3.2.0]
*Tree support
Experimental tree-like support structure that uses ‘branches’ to support prints. Branches ‘grow’ and multiply towards the model, with fewer contact points than alternative support methods. This results in better surface finishes for organic-shaped prints.
diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py
index 1c275d6d5b..2f57e634e0 100755
--- a/plugins/CuraEngineBackend/CuraEngineBackend.py
+++ b/plugins/CuraEngineBackend/CuraEngineBackend.py
@@ -33,6 +33,9 @@ from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
class CuraEngineBackend(QObject, Backend):
+
+ backendError = Signal()
+
## Starts the back-end plug-in.
#
# This registers all the signal listeners and prepares for communication
@@ -70,7 +73,7 @@ class CuraEngineBackend(QObject, Backend):
# Workaround to disable layer view processing if layer view is not active.
self._layer_view_active = False
Application.getInstance().getController().activeViewChanged.connect(self._onActiveViewChanged)
- Application.getInstance().getBuildPlateModel().activeBuildPlateChanged.connect(self._onActiveViewChanged)
+ Application.getInstance().getMultiBuildPlateModel().activeBuildPlateChanged.connect(self._onActiveViewChanged)
self._onActiveViewChanged()
self._stored_layer_data = []
self._stored_optimized_layer_data = {} # key is build plate number, then arrays are stored until they go to the ProcessSlicesLayersJob
@@ -88,10 +91,11 @@ class CuraEngineBackend(QObject, Backend):
#
self._global_container_stack = None
Application.getInstance().globalContainerStackChanged.connect(self._onGlobalStackChanged)
- Application.getInstance().getExtruderManager().extrudersAdded.connect(self._onGlobalStackChanged)
self._onGlobalStackChanged()
Application.getInstance().stacksValidationFinished.connect(self._onStackErrorCheckFinished)
+ # extruder enable / disable. Actually wanted to use machine manager here, but the initialization order causes it to crash
+ ExtruderManager.getInstance().extrudersChanged.connect(self._extruderChanged)
# A flag indicating if an error check was scheduled
# If so, we will stop the auto-slice timer and start upon the error check
@@ -192,7 +196,7 @@ class CuraEngineBackend(QObject, Backend):
## Perform a slice of the scene.
def slice(self):
- Logger.log("d", "starting to slice!")
+ Logger.log("d", "Starting to slice...")
self._slice_start_time = time()
if not self._build_plates_to_be_sliced:
self.processingProgress.emit(1.0)
@@ -200,14 +204,14 @@ class CuraEngineBackend(QObject, Backend):
return
if self._process_layers_job:
- Logger.log("d", " ## Process layers job still busy, trying later")
+ Logger.log("d", "Process layers job still busy, trying later.")
return
if not hasattr(self._scene, "gcode_dict"):
self._scene.gcode_dict = {}
# see if we really have to slice
- active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate
+ active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
build_plate_to_be_sliced = self._build_plates_to_be_sliced.pop(0)
Logger.log("d", "Going to slice build plate [%s]!" % build_plate_to_be_sliced)
num_objects = self._numObjects()
@@ -290,6 +294,7 @@ class CuraEngineBackend(QObject, Backend):
if job.isCancelled() or job.getError() or job.getResult() == StartSliceJob.StartJobResult.Error:
self.backendStateChange.emit(BackendState.Error)
+ self.backendError.emit(job)
return
if job.getResult() == StartSliceJob.StartJobResult.MaterialIncompatible:
@@ -298,6 +303,7 @@ class CuraEngineBackend(QObject, Backend):
"Unable to slice with the current material as it is incompatible with the selected machine or configuration."), title = catalog.i18nc("@info:title", "Unable to slice"))
self._error_message.show()
self.backendStateChange.emit(BackendState.Error)
+ self.backendError.emit(job)
else:
self.backendStateChange.emit(BackendState.NotStarted)
return
@@ -326,6 +332,7 @@ class CuraEngineBackend(QObject, Backend):
title = catalog.i18nc("@info:title", "Unable to slice"))
self._error_message.show()
self.backendStateChange.emit(BackendState.Error)
+ self.backendError.emit(job)
else:
self.backendStateChange.emit(BackendState.NotStarted)
return
@@ -348,6 +355,7 @@ class CuraEngineBackend(QObject, Backend):
title = catalog.i18nc("@info:title", "Unable to slice"))
self._error_message.show()
self.backendStateChange.emit(BackendState.Error)
+ self.backendError.emit(job)
return
if job.getResult() == StartSliceJob.StartJobResult.BuildPlateError:
@@ -356,6 +364,7 @@ class CuraEngineBackend(QObject, Backend):
title = catalog.i18nc("@info:title", "Unable to slice"))
self._error_message.show()
self.backendStateChange.emit(BackendState.Error)
+ self.backendError.emit(job)
else:
self.backendStateChange.emit(BackendState.NotStarted)
@@ -365,6 +374,7 @@ class CuraEngineBackend(QObject, Backend):
title = catalog.i18nc("@info:title", "Unable to slice"))
self._error_message.show()
self.backendStateChange.emit(BackendState.Error)
+ self.backendError.emit(job)
else:
self.backendStateChange.emit(BackendState.NotStarted)
self._invokeSlice()
@@ -497,7 +507,7 @@ class CuraEngineBackend(QObject, Backend):
node.getParent().removeChild(node)
def markSliceAll(self):
- for build_plate_number in range(Application.getInstance().getBuildPlateModel().maxBuildPlate + 1):
+ for build_plate_number in range(Application.getInstance().getMultiBuildPlateModel().maxBuildPlate + 1):
if build_plate_number not in self._build_plates_to_be_sliced:
self._build_plates_to_be_sliced.append(build_plate_number)
@@ -582,7 +592,7 @@ class CuraEngineBackend(QObject, Backend):
Logger.log("d", "Slicing took %s seconds", time() - self._slice_start_time )
# See if we need to process the sliced layers job.
- active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate
+ active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
if self._layer_view_active and (self._process_layers_job is None or not self._process_layers_job.isRunning()) and active_build_plate == self._start_slice_job_build_plate:
self._startProcessSlicedLayersJob(active_build_plate)
# self._onActiveViewChanged()
@@ -702,7 +712,7 @@ class CuraEngineBackend(QObject, Backend):
application = Application.getInstance()
view = application.getController().getActiveView()
if view:
- active_build_plate = application.getBuildPlateModel().activeBuildPlate
+ active_build_plate = application.getMultiBuildPlateModel().activeBuildPlate
if view.getPluginId() == "SimulationView": # If switching to layer view, we should process the layers if that hasn't been done yet.
self._layer_view_active = True
# There is data and we're not slicing at the moment
@@ -774,3 +784,9 @@ class CuraEngineBackend(QObject, Backend):
def tickle(self):
if self._use_timer:
self._change_timer.start()
+
+ def _extruderChanged(self):
+ for build_plate_number in range(Application.getInstance().getMultiBuildPlateModel().maxBuildPlate + 1):
+ if build_plate_number not in self._build_plates_to_be_sliced:
+ self._build_plates_to_be_sliced.append(build_plate_number)
+ self._invokeSlice()
diff --git a/plugins/CuraEngineBackend/ProcessGCodeJob.py b/plugins/CuraEngineBackend/ProcessGCodeJob.py
index ed430f8fa9..817daa9f85 100644
--- a/plugins/CuraEngineBackend/ProcessGCodeJob.py
+++ b/plugins/CuraEngineBackend/ProcessGCodeJob.py
@@ -12,6 +12,6 @@ class ProcessGCodeLayerJob(Job):
self._message = message
def run(self):
- active_build_plate_id = Application.getInstance().getBuildPlateModel().activeBuildPlate
+ active_build_plate_id = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
gcode_list = self._scene.gcode_dict[active_build_plate_id]
gcode_list.append(self._message.data.decode("utf-8", "replace"))
diff --git a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py
index c1fc597d80..cbc097bb33 100644
--- a/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py
+++ b/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py
@@ -81,7 +81,8 @@ class ProcessSlicedLayersJob(Job):
Application.getInstance().getController().activeViewChanged.connect(self._onActiveViewChanged)
- new_node = CuraSceneNode()
+ # The no_setting_override is here because adding the SettingOverrideDecorator will trigger a reslice
+ new_node = CuraSceneNode(no_setting_override = True)
new_node.addDecorator(BuildPlateDecorator(self._build_plate_number))
# Force garbage collection.
diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py
index df19b1dc9e..f3f34f4c3d 100644
--- a/plugins/CuraEngineBackend/StartSliceJob.py
+++ b/plugins/CuraEngineBackend/StartSliceJob.py
@@ -55,19 +55,19 @@ class GcodeStartEndFormatter(Formatter):
extruder_nr = int(kwargs["-1"][key_fragments[1]]) # get extruder_nr values from the global stack
except (KeyError, ValueError):
# either the key does not exist, or the value is not an int
- Logger.log("w", "Unable to determine stack nr '%s' for key '%s' in start/end gcode, using global stack", key_fragments[1], key_fragments[0])
+ Logger.log("w", "Unable to determine stack nr '%s' for key '%s' in start/end g-code, using global stack", key_fragments[1], key_fragments[0])
elif len(key_fragments) != 1:
- Logger.log("w", "Incorrectly formatted placeholder '%s' in start/end gcode", key)
+ Logger.log("w", "Incorrectly formatted placeholder '%s' in start/end g-code", key)
return "{" + str(key) + "}"
key = key_fragments[0]
try:
return kwargs[str(extruder_nr)][key]
except KeyError:
- Logger.log("w", "Unable to replace '%s' placeholder in start/end gcode", key)
+ Logger.log("w", "Unable to replace '%s' placeholder in start/end g-code", key)
return "{" + key + "}"
else:
- Logger.log("w", "Incorrectly formatted placeholder '%s' in start/end gcode", key)
+ Logger.log("w", "Incorrectly formatted placeholder '%s' in start/end g-code", key)
return "{" + str(key) + "}"
@@ -129,16 +129,19 @@ class StartSliceJob(Job):
self.setResult(StartJobResult.MaterialIncompatible)
return
- for extruder_stack in ExtruderManager.getInstance().getMachineExtruders(stack.getId()):
+ for position, extruder_stack in stack.extruders.items():
material = extruder_stack.findContainer({"type": "material"})
+ if not extruder_stack.isEnabled:
+ continue
if material:
if material.getMetaDataEntry("compatible") == False:
self.setResult(StartJobResult.MaterialIncompatible)
return
+
# Don't slice if there is a per object setting with an error value.
for node in DepthFirstIterator(self._scene.getRoot()):
- if node.isSelectable():
+ if not isinstance(node, CuraSceneNode) or not node.isSelectable():
continue
if self._checkStackForErrors(node.callDecoration("getStack")):
@@ -188,11 +191,18 @@ class StartSliceJob(Job):
if per_object_stack:
is_non_printing_mesh = any(per_object_stack.getProperty(key, "value") for key in NON_PRINTING_MESH_SETTINGS)
- if node.callDecoration("getBuildPlateNumber") == self._build_plate_number:
- if not getattr(node, "_outside_buildarea", False) or is_non_printing_mesh:
- temp_list.append(node)
- if not is_non_printing_mesh:
- has_printing_mesh = True
+ # Find a reason not to add the node
+ if node.callDecoration("getBuildPlateNumber") != self._build_plate_number:
+ continue
+ if getattr(node, "_outside_buildarea", False) and not is_non_printing_mesh:
+ continue
+ node_position = node.callDecoration("getActiveExtruderPosition")
+ if not stack.extruders[str(node_position)].isEnabled:
+ continue
+
+ temp_list.append(node)
+ if not is_non_printing_mesh:
+ has_printing_mesh = True
Job.yieldThread()
@@ -268,9 +278,15 @@ class StartSliceJob(Job):
# \return A dictionary of replacement tokens to the values they should be
# replaced with.
def _buildReplacementTokens(self, stack) -> dict:
+ default_extruder_position = int(Application.getInstance().getMachineManager().defaultExtruderPosition)
result = {}
for key in stack.getAllKeys():
- result[key] = stack.getProperty(key, "value")
+ setting_type = stack.getProperty(key, "type")
+ value = stack.getProperty(key, "value")
+ if setting_type == "extruder" and value == -1:
+ # replace with the default value
+ value = default_extruder_position
+ result[key] = value
Job.yieldThread()
result["print_bed_temperature"] = result["material_bed_temperature"] # Renamed settings.
@@ -308,7 +324,7 @@ class StartSliceJob(Job):
settings["default_extruder_nr"] = default_extruder_nr
return str(fmt.format(value, **settings))
except:
- Logger.logException("w", "Unable to do token replacement on start/end gcode")
+ Logger.logException("w", "Unable to do token replacement on start/end g-code")
return str(value)
## Create extruder message from stack
@@ -376,11 +392,11 @@ class StartSliceJob(Job):
# limit_to_extruder property.
def _buildGlobalInheritsStackMessage(self, stack):
for key in stack.getAllKeys():
- extruder = int(round(float(stack.getProperty(key, "limit_to_extruder"))))
- if extruder >= 0: #Set to a specific extruder.
+ extruder_position = int(round(float(stack.getProperty(key, "limit_to_extruder"))))
+ if extruder_position >= 0: # Set to a specific extruder.
setting_extruder = self._slice_message.addRepeatedMessage("limit_to_extruder")
setting_extruder.name = key
- setting_extruder.extruder = extruder
+ setting_extruder.extruder = extruder_position
Job.yieldThread()
## Check if a node has per object settings and ensure that they are set correctly in the message
diff --git a/plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py b/plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py
index 8e4c70517f..23a040f2e2 100644
--- a/plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py
+++ b/plugins/FirmwareUpdateChecker/FirmwareUpdateChecker.py
@@ -20,7 +20,7 @@ i18n_catalog = i18nCatalog("cura")
# The plugin is currently only usable for applications maintained by Ultimaker. But it should be relatively easy
# to change it to work for other applications.
class FirmwareUpdateChecker(Extension):
- JEDI_VERSION_URL = "http://software.ultimaker.com/jedi/releases/latest.version"
+ JEDI_VERSION_URL = "http://software.ultimaker.com/jedi/releases/latest.version?utm_source=cura&utm_medium=software&utm_campaign=resources"
def __init__(self):
super().__init__()
diff --git a/plugins/GCodeProfileReader/GCodeProfileReader.py b/plugins/GCodeProfileReader/GCodeProfileReader.py
index 9d7f0059f9..d6bda85a48 100644
--- a/plugins/GCodeProfileReader/GCodeProfileReader.py
+++ b/plugins/GCodeProfileReader/GCodeProfileReader.py
@@ -9,7 +9,7 @@ from UM.Logger import Logger
from UM.i18n import i18nCatalog
catalog = i18nCatalog("cura")
-from cura.ProfileReader import ProfileReader
+from cura.ProfileReader import ProfileReader, NoProfileException
## A class that reads profile data from g-code files.
#
@@ -66,12 +66,17 @@ class GCodeProfileReader(ProfileReader):
return None
serialized = unescapeGcodeComment(serialized)
+ serialized = serialized.strip()
+
+ if not serialized:
+ Logger.log("i", "No custom profile to import from this g-code: %s", file_name)
+ raise NoProfileException()
# serialized data can be invalid JSON
try:
json_data = json.loads(serialized)
except Exception as e:
- Logger.log("e", "Could not parse serialized JSON data from GCode %s, error: %s", file_name, e)
+ Logger.log("e", "Could not parse serialized JSON data from g-code %s, error: %s", file_name, e)
return None
profiles = []
diff --git a/plugins/GCodeProfileReader/plugin.json b/plugins/GCodeProfileReader/plugin.json
index 8111bc687c..f8f7d4c291 100644
--- a/plugins/GCodeProfileReader/plugin.json
+++ b/plugins/GCodeProfileReader/plugin.json
@@ -1,5 +1,5 @@
{
- "name": "GCode Profile Reader",
+ "name": "G-code Profile Reader",
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides support for importing profiles from g-code files.",
diff --git a/plugins/GCodeReader/FlavorParser.py b/plugins/GCodeReader/FlavorParser.py
index f63ba3ca69..c064ffbf10 100644
--- a/plugins/GCodeReader/FlavorParser.py
+++ b/plugins/GCodeReader/FlavorParser.py
@@ -437,7 +437,7 @@ class FlavorParser:
scene_node.addDecorator(gcode_list_decorator)
# gcode_dict stores gcode_lists for a number of build plates.
- active_build_plate_id = Application.getInstance().getBuildPlateModel().activeBuildPlate
+ active_build_plate_id = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
gcode_dict = {active_build_plate_id: gcode_list}
Application.getInstance().getController().getScene().gcode_dict = gcode_dict
diff --git a/plugins/GCodeWriter/GCodeWriter.py b/plugins/GCodeWriter/GCodeWriter.py
index 2dfaf5aef7..1b3b7264a1 100644
--- a/plugins/GCodeWriter/GCodeWriter.py
+++ b/plugins/GCodeWriter/GCodeWriter.py
@@ -5,6 +5,7 @@ from UM.Mesh.MeshWriter import MeshWriter
from UM.Logger import Logger
from UM.Application import Application
from UM.Settings.InstanceContainer import InstanceContainer
+from UM.Util import parseBool
from cura.Settings.ExtruderManager import ExtruderManager
@@ -56,10 +57,10 @@ class GCodeWriter(MeshWriter):
# file. This must always be text mode.
def write(self, stream, nodes, mode = MeshWriter.OutputMode.TextMode):
if mode != MeshWriter.OutputMode.TextMode:
- Logger.log("e", "GCode Writer does not support non-text mode.")
+ Logger.log("e", "GCodeWriter does not support non-text mode.")
return False
- active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate
+ active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
scene = Application.getInstance().getController().getScene()
gcode_dict = getattr(scene, "gcode_dict")
if not gcode_dict:
@@ -108,7 +109,7 @@ class GCodeWriter(MeshWriter):
container_with_profile = stack.qualityChanges
if container_with_profile.getId() == "empty_quality_changes":
- Logger.log("e", "No valid quality profile found, not writing settings to GCode!")
+ Logger.log("e", "No valid quality profile found, not writing settings to g-code!")
return ""
flat_global_container = self._createFlattenedContainerInstance(stack.getTop(), container_with_profile)
@@ -120,6 +121,14 @@ class GCodeWriter(MeshWriter):
if flat_global_container.getMetaDataEntry("quality_type", None) is None:
flat_global_container.addMetaDataEntry("quality_type", stack.quality.getMetaDataEntry("quality_type", "normal"))
+ # Change the default defintion
+ default_machine_definition = "fdmprinter"
+ if parseBool(stack.getMetaDataEntry("has_machine_quality", "False")):
+ default_machine_definition = stack.getMetaDataEntry("quality_definition")
+ if not default_machine_definition:
+ default_machine_definition = stack.definition.getId()
+ flat_global_container.setMetaDataEntry("definition", default_machine_definition)
+
serialized = flat_global_container.serialize()
data = {"global_quality": serialized}
@@ -140,6 +149,10 @@ class GCodeWriter(MeshWriter):
# Ensure that quality_type is set. (Can happen if we have empty quality changes).
if flat_extruder_quality.getMetaDataEntry("quality_type", None) is None:
flat_extruder_quality.addMetaDataEntry("quality_type", extruder.quality.getMetaDataEntry("quality_type", "normal"))
+
+ # Change the default defintion
+ flat_extruder_quality.setMetaDataEntry("definition", default_machine_definition)
+
extruder_serialized = flat_extruder_quality.serialize()
data.setdefault("extruder_quality", []).append(extruder_serialized)
diff --git a/plugins/GCodeWriter/__init__.py b/plugins/GCodeWriter/__init__.py
index a89332a371..1a5728f510 100644
--- a/plugins/GCodeWriter/__init__.py
+++ b/plugins/GCodeWriter/__init__.py
@@ -13,7 +13,7 @@ def getMetaData():
"mesh_writer": {
"output": [{
"extension": "gcode",
- "description": catalog.i18nc("@item:inlistbox", "GCode File"),
+ "description": catalog.i18nc("@item:inlistbox", "G-code File"),
"mime_type": "text/x-gcode",
"mode": GCodeWriter.GCodeWriter.OutputMode.TextMode
}]
diff --git a/plugins/GCodeWriter/plugin.json b/plugins/GCodeWriter/plugin.json
index 5788b01375..5fcb1a3bd7 100644
--- a/plugins/GCodeWriter/plugin.json
+++ b/plugins/GCodeWriter/plugin.json
@@ -1,8 +1,8 @@
{
- "name": "GCode Writer",
+ "name": "G-code Writer",
"author": "Ultimaker B.V.",
"version": "1.0.0",
- "description": "Writes GCode to a file.",
+ "description": "Writes g-code to a file.",
"api": 4,
"i18n-catalog": "cura"
}
diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.py b/plugins/MachineSettingsAction/MachineSettingsAction.py
index baa0639d3f..ded59bf934 100755
--- a/plugins/MachineSettingsAction/MachineSettingsAction.py
+++ b/plugins/MachineSettingsAction/MachineSettingsAction.py
@@ -2,20 +2,16 @@
# Cura is released under the terms of the LGPLv3 or higher.
from PyQt5.QtCore import pyqtProperty, pyqtSignal
+
+import UM.i18n
from UM.FlameProfiler import pyqtSlot
-
-from cura.MachineAction import MachineAction
-
from UM.Application import Application
from UM.Settings.ContainerRegistry import ContainerRegistry
from UM.Settings.DefinitionContainer import DefinitionContainer
-from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
-from UM.Logger import Logger
-from cura.Settings.ExtruderManager import ExtruderManager
+from cura.MachineAction import MachineAction
from cura.Settings.CuraStackBuilder import CuraStackBuilder
-import UM.i18n
catalog = UM.i18n.i18nCatalog("cura")
@@ -26,6 +22,8 @@ class MachineSettingsAction(MachineAction):
super().__init__("MachineSettingsAction", catalog.i18nc("@action", "Machine Settings"))
self._qml_url = "MachineSettingsAction.qml"
+ self._application = Application.getInstance()
+
self._global_container_stack = None
from cura.Settings.CuraContainerStack import _ContainerIndexes
@@ -34,38 +32,44 @@ class MachineSettingsAction(MachineAction):
self._container_registry = ContainerRegistry.getInstance()
self._container_registry.containerAdded.connect(self._onContainerAdded)
self._container_registry.containerRemoved.connect(self._onContainerRemoved)
- Application.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerChanged)
+ self._application.globalContainerStackChanged.connect(self._onGlobalContainerChanged)
- self._empty_container = self._container_registry.getEmptyInstanceContainer()
+ self._backend = self._application.getBackend()
- self._backend = Application.getInstance().getBackend()
+ self._empty_definition_container_id_list = []
+
+ def _isEmptyDefinitionChanges(self, container_id: str):
+ if not self._empty_definition_container_id_list:
+ self._empty_definition_container_id_list = [self._application.empty_container.getId(),
+ self._application.empty_definition_changes_container.getId()]
+ return container_id in self._empty_definition_container_id_list
def _onContainerAdded(self, container):
# Add this action as a supported action to all machine definitions
if isinstance(container, DefinitionContainer) and container.getMetaDataEntry("type") == "machine":
- Application.getInstance().getMachineActionManager().addSupportedAction(container.getId(), self.getKey())
+ self._application.getMachineActionManager().addSupportedAction(container.getId(), self.getKey())
def _onContainerRemoved(self, container):
# Remove definition_changes containers when a stack is removed
if container.getMetaDataEntry("type") in ["machine", "extruder_train"]:
- definition_changes_container = container.definitionChanges
- if definition_changes_container == self._empty_container:
+ definition_changes_id = container.definitionChanges.getId()
+ if self._isEmptyDefinitionChanges(definition_changes_id):
return
- self._container_registry.removeContainer(definition_changes_container.getId())
+ self._container_registry.removeContainer(definition_changes_id)
def _reset(self):
if not self._global_container_stack:
return
# Make sure there is a definition_changes container to store the machine settings
- definition_changes_container = self._global_container_stack.definitionChanges
- if definition_changes_container == self._empty_container:
- definition_changes_container = CuraStackBuilder.createDefinitionChangesContainer(
- self._global_container_stack, self._global_container_stack.getName() + "_settings")
+ definition_changes_id = self._global_container_stack.definitionChanges.getId()
+ if self._isEmptyDefinitionChanges(definition_changes_id):
+ CuraStackBuilder.createDefinitionChangesContainer(self._global_container_stack,
+ self._global_container_stack.getName() + "_settings")
# Notify the UI in which container to store the machine settings data
- from cura.Settings.CuraContainerStack import CuraContainerStack, _ContainerIndexes
+ from cura.Settings.CuraContainerStack import _ContainerIndexes
container_index = _ContainerIndexes.DefinitionChanges
if container_index != self._container_index:
@@ -107,13 +111,13 @@ class MachineSettingsAction(MachineAction):
def setMachineExtruderCount(self, extruder_count):
# Note: this method was in this class before, but since it's quite generic and other plugins also need it
# it was moved to the machine manager instead. Now this method just calls the machine manager.
- Application.getInstance().getMachineManager().setActiveMachineExtruderCount(extruder_count)
+ self._application.getMachineManager().setActiveMachineExtruderCount(extruder_count)
@pyqtSlot()
def forceUpdate(self):
# Force rebuilding the build volume by reloading the global container stack.
# This is a bit of a hack, but it seems quick enough.
- Application.getInstance().globalContainerStackChanged.emit()
+ self._application.globalContainerStackChanged.emit()
@pyqtSlot()
def updateHasMaterialsMetadata(self):
@@ -126,9 +130,11 @@ class MachineSettingsAction(MachineAction):
# In other words: only continue for the UM2 (extended), but not for the UM2+
return
- stacks = ExtruderManager.getInstance().getExtruderStacks()
+ machine_manager = self._application.getMachineManager()
+ extruder_positions = list(self._global_container_stack.extruders.keys())
has_materials = self._global_container_stack.getProperty("machine_gcode_flavor", "value") != "UltiGCode"
+ material_node = None
if has_materials:
if "has_materials" in self._global_container_stack.getMetaData():
self._global_container_stack.setMetaDataEntry("has_materials", True)
@@ -136,26 +142,22 @@ class MachineSettingsAction(MachineAction):
self._global_container_stack.addMetaDataEntry("has_materials", True)
# Set the material container for each extruder to a sane default
- for stack in stacks:
- material_container = stack.material
- if material_container == self._empty_container:
- machine_approximate_diameter = str(round(self._global_container_stack.getProperty("material_diameter", "value")))
- search_criteria = { "type": "material", "definition": "fdmprinter", "id": self._global_container_stack.getMetaDataEntry("preferred_material"), "approximate_diameter": machine_approximate_diameter}
- materials = self._container_registry.findInstanceContainers(**search_criteria)
- if materials:
- stack.material = materials[0]
+ material_manager = self._application.getMaterialManager()
+ material_node = material_manager.getDefaultMaterial(self._global_container_stack, None)
+
else:
# The metadata entry is stored in an ini, and ini files are parsed as strings only.
# Because any non-empty string evaluates to a boolean True, we have to remove the entry to make it False.
if "has_materials" in self._global_container_stack.getMetaData():
self._global_container_stack.removeMetaDataEntry("has_materials")
- for stack in stacks:
- stack.material = ContainerRegistry.getInstance().getEmptyInstanceContainer()
+ # set materials
+ for position in extruder_positions:
+ machine_manager.setMaterial(position, material_node)
- Application.getInstance().globalContainerStackChanged.emit()
+ self._application.globalContainerStackChanged.emit()
@pyqtSlot(int)
def updateMaterialForDiameter(self, extruder_position: int):
# Updates the material container to a material that matches the material diameter set for the printer
- Application.getInstance().getExtruderManager().updateMaterialForDiameter(extruder_position)
+ self._application.getExtruderManager().updateMaterialForDiameter(extruder_position)
diff --git a/plugins/MachineSettingsAction/MachineSettingsAction.qml b/plugins/MachineSettingsAction/MachineSettingsAction.qml
index 0aad716300..f941ef87b4 100644
--- a/plugins/MachineSettingsAction/MachineSettingsAction.qml
+++ b/plugins/MachineSettingsAction/MachineSettingsAction.qml
@@ -70,8 +70,8 @@ Cura.MachineAction
anchors.top: pageTitle.bottom
anchors.topMargin: UM.Theme.getSize("default_margin").height
- property real columnWidth: ((width - 3 * UM.Theme.getSize("default_margin").width) / 2) | 0
- property real labelColumnWidth: columnWidth * 0.5
+ property real columnWidth: Math.round((width - 3 * UM.Theme.getSize("default_margin").width) / 2)
+ property real labelColumnWidth: Math.round(columnWidth / 2)
Tab
{
@@ -165,7 +165,7 @@ Cura.MachineAction
id: gcodeFlavorComboBox
sourceComponent: comboBoxWithOptions
property string settingKey: "machine_gcode_flavor"
- property string label: catalog.i18nc("@label", "Gcode flavor")
+ property string label: catalog.i18nc("@label", "G-code flavor")
property bool forceUpdateOnChange: true
property var afterOnActivate: manager.updateHasMaterialsMetadata
}
@@ -244,6 +244,7 @@ Cura.MachineAction
height: childrenRect.height
width: childrenRect.width
text: machineExtruderCountProvider.properties.description
+ visible: extruderCountModel.count >= 2
Row
{
@@ -307,7 +308,7 @@ Cura.MachineAction
width: settingsTabs.columnWidth
Label
{
- text: catalog.i18nc("@label", "Start Gcode")
+ text: catalog.i18nc("@label", "Start G-code")
font.bold: true
}
Loader
@@ -317,7 +318,7 @@ Cura.MachineAction
property int areaWidth: parent.width
property int areaHeight: parent.height - y
property string settingKey: "machine_start_gcode"
- property string tooltip: catalog.i18nc("@tooltip", "Gcode commands to be executed at the very start.")
+ property string tooltip: catalog.i18nc("@tooltip", "G-code commands to be executed at the very start.")
}
}
@@ -326,7 +327,7 @@ Cura.MachineAction
width: settingsTabs.columnWidth
Label
{
- text: catalog.i18nc("@label", "End Gcode")
+ text: catalog.i18nc("@label", "End G-code")
font.bold: true
}
Loader
@@ -336,7 +337,7 @@ Cura.MachineAction
property int areaWidth: parent.width
property int areaHeight: parent.height - y
property string settingKey: "machine_end_gcode"
- property string tooltip: catalog.i18nc("@tooltip", "Gcode commands to be executed at the very end.")
+ property string tooltip: catalog.i18nc("@tooltip", "G-code commands to be executed at the very end.")
}
}
}
@@ -441,7 +442,7 @@ Cura.MachineAction
width: settingsTabs.columnWidth
Label
{
- text: catalog.i18nc("@label", "Extruder Start Gcode")
+ text: catalog.i18nc("@label", "Extruder Start G-code")
font.bold: true
}
Loader
@@ -459,7 +460,7 @@ Cura.MachineAction
width: settingsTabs.columnWidth
Label
{
- text: catalog.i18nc("@label", "Extruder End Gcode")
+ text: catalog.i18nc("@label", "Extruder End G-code")
font.bold: true
}
Loader
diff --git a/plugins/MonitorStage/MonitorStage.py b/plugins/MonitorStage/MonitorStage.py
index 1a999ca896..1a1d37cbdf 100644
--- a/plugins/MonitorStage/MonitorStage.py
+++ b/plugins/MonitorStage/MonitorStage.py
@@ -69,9 +69,11 @@ class MonitorStage(CuraStage):
self._printer_output_device.connectionStateChanged.connect(self._updateIconSource)
self._setActivePrinter(self._printer_output_device.activePrinter)
- # Force an update of the icon source
- self._updateIconSource()
+ # Force an update of the icon source
+ self._updateIconSource()
except IndexError:
+ #If index error occurs, then the icon on monitor button also should be updated
+ self._updateIconSource()
pass
def _onEngineCreated(self):
diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
index eb492d8de2..03a2ce1bf4 100644
--- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
+++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
@@ -237,7 +237,7 @@ Item {
Button
{
- width: Math.floor(UM.Theme.getSize("setting").height / 2)
+ width: Math.round(UM.Theme.getSize("setting").height / 2)
height: UM.Theme.getSize("setting").height
onClicked: addedSettingsModel.setVisible(model.key, false)
diff --git a/plugins/PluginBrowser/PluginBrowser.py b/plugins/PluginBrowser/PluginBrowser.py
index 0e6992c51d..c8a5e1e545 100644
--- a/plugins/PluginBrowser/PluginBrowser.py
+++ b/plugins/PluginBrowser/PluginBrowser.py
@@ -287,7 +287,7 @@ class PluginBrowser(QObject, Extension):
@pyqtProperty(QObject, notify=pluginsMetadataChanged)
def pluginsModel(self):
- self._plugins_model = PluginsModel(self._view)
+ self._plugins_model = PluginsModel(None, self._view)
# self._plugins_model.update()
# Check each plugin the registry for matching plugin from server
diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.py b/plugins/PostProcessingPlugin/PostProcessingPlugin.py
index 2c6fc3f492..c4b760724b 100644
--- a/plugins/PostProcessingPlugin/PostProcessingPlugin.py
+++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.py
@@ -62,7 +62,7 @@ class PostProcessingPlugin(QObject, Extension):
return
# get gcode list for the active build plate
- active_build_plate_id = Application.getInstance().getBuildPlateModel().activeBuildPlate
+ active_build_plate_id = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
gcode_list = gcode_dict[active_build_plate_id]
if not gcode_list:
return
@@ -118,27 +118,30 @@ class PostProcessingPlugin(QObject, Extension):
for loader, script_name, ispkg in scripts:
# Iterate over all scripts.
if script_name not in sys.modules:
- spec = importlib.util.spec_from_file_location(__name__ + "." + script_name, os.path.join(path, script_name + ".py"))
- loaded_script = importlib.util.module_from_spec(spec)
- spec.loader.exec_module(loaded_script)
- sys.modules[script_name] = loaded_script
-
- loaded_class = getattr(loaded_script, script_name)
- temp_object = loaded_class()
- Logger.log("d", "Begin loading of script: %s", script_name)
try:
- setting_data = temp_object.getSettingData()
- if "name" in setting_data and "key" in setting_data:
- self._script_labels[setting_data["key"]] = setting_data["name"]
- self._loaded_scripts[setting_data["key"]] = loaded_class
- else:
- Logger.log("w", "Script %s.py has no name or key", script_name)
- self._script_labels[script_name] = script_name
- self._loaded_scripts[script_name] = loaded_class
- except AttributeError:
- Logger.log("e", "Script %s.py is not a recognised script type. Ensure it inherits Script", script_name)
- except NotImplementedError:
- Logger.log("e", "Script %s.py has no implemented settings", script_name)
+ spec = importlib.util.spec_from_file_location(__name__ + "." + script_name, os.path.join(path, script_name + ".py"))
+ loaded_script = importlib.util.module_from_spec(spec)
+ spec.loader.exec_module(loaded_script)
+ sys.modules[script_name] = loaded_script
+
+ loaded_class = getattr(loaded_script, script_name)
+ temp_object = loaded_class()
+ Logger.log("d", "Begin loading of script: %s", script_name)
+ try:
+ setting_data = temp_object.getSettingData()
+ if "name" in setting_data and "key" in setting_data:
+ self._script_labels[setting_data["key"]] = setting_data["name"]
+ self._loaded_scripts[setting_data["key"]] = loaded_class
+ else:
+ Logger.log("w", "Script %s.py has no name or key", script_name)
+ self._script_labels[script_name] = script_name
+ self._loaded_scripts[script_name] = loaded_class
+ except AttributeError:
+ Logger.log("e", "Script %s.py is not a recognised script type. Ensure it inherits Script", script_name)
+ except NotImplementedError:
+ Logger.log("e", "Script %s.py has no implemented settings", script_name)
+ except Exception as e:
+ Logger.logException("e", "Exception occurred while loading post processing plugin: {error_msg}".format(error_msg = str(e)))
self.loadedScriptListChanged.emit()
loadedScriptListChanged = pyqtSignal()
@@ -170,19 +173,19 @@ class PostProcessingPlugin(QObject, Extension):
Logger.log("d", "Creating post processing plugin view.")
## Load all scripts in the scripts folders
- for root in [PluginRegistry.getInstance().getPluginPath("PostProcessingPlugin"), Resources.getStoragePath(Resources.Preferences)]:
- try:
- path = os.path.join(root, "scripts")
- if not os.path.isdir(path):
- try:
- os.makedirs(path)
- except OSError:
- Logger.log("w", "Unable to create a folder for scripts: " + path)
- continue
+ # The PostProcessingPlugin path is for built-in scripts.
+ # The Resources path is where the user should store custom scripts.
+ # The Preferences path is legacy, where the user may previously have stored scripts.
+ for root in [PluginRegistry.getInstance().getPluginPath("PostProcessingPlugin"), Resources.getStoragePath(Resources.Resources), Resources.getStoragePath(Resources.Preferences)]:
+ path = os.path.join(root, "scripts")
+ if not os.path.isdir(path):
+ try:
+ os.makedirs(path)
+ except OSError:
+ Logger.log("w", "Unable to create a folder for scripts: " + path)
+ continue
- self.loadAllScripts(path)
- except Exception as e:
- Logger.logException("e", "Exception occurred while loading post processing plugin: {error_msg}".format(error_msg = str(e)))
+ self.loadAllScripts(path)
# Create the plugin dialog component
path = os.path.join(PluginRegistry.getInstance().getPluginPath("PostProcessingPlugin"), "PostProcessingPlugin.qml")
diff --git a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml
index d64d60a04a..489ea6dcfb 100644
--- a/plugins/PostProcessingPlugin/PostProcessingPlugin.qml
+++ b/plugins/PostProcessingPlugin/PostProcessingPlugin.qml
@@ -25,8 +25,8 @@ UM.Dialog
{
UM.I18nCatalog{id: catalog; name:"cura"}
id: base
- property int columnWidth: Math.floor((base.width / 2) - UM.Theme.getSize("default_margin").width)
- property int textMargin: Math.floor(UM.Theme.getSize("default_margin").width / 2)
+ property int columnWidth: Math.round((base.width / 2) - UM.Theme.getSize("default_margin").width)
+ property int textMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
property string activeScriptName
SystemPalette{ id: palette }
SystemPalette{ id: disabledPalette; colorGroup: SystemPalette.Disabled }
@@ -129,8 +129,8 @@ UM.Dialog
{
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
- width: Math.floor(control.width / 2.7)
- height: Math.floor(control.height / 2.7)
+ width: Math.round(control.width / 2.7)
+ height: Math.round(control.height / 2.7)
sourceSize.width: width
sourceSize.height: width
color: palette.text
@@ -164,8 +164,8 @@ UM.Dialog
{
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
- width: Math.floor(control.width / 2.5)
- height: Math.floor(control.height / 2.5)
+ width: Math.round(control.width / 2.5)
+ height: Math.round(control.height / 2.5)
sourceSize.width: width
sourceSize.height: width
color: control.enabled ? palette.text : disabledPalette.text
@@ -199,8 +199,8 @@ UM.Dialog
{
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
- width: Math.floor(control.width / 2.5)
- height: Math.floor(control.height / 2.5)
+ width: Math.round(control.width / 2.5)
+ height: Math.round(control.height / 2.5)
sourceSize.width: width
sourceSize.height: width
color: control.enabled ? palette.text : disabledPalette.text
@@ -478,15 +478,15 @@ UM.Dialog
control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button")
Behavior on color { ColorAnimation { duration: 50; } }
anchors.left: parent.left
- anchors.leftMargin: Math.floor(UM.Theme.getSize("save_button_text_margin").width / 2);
+ anchors.leftMargin: Math.round(UM.Theme.getSize("save_button_text_margin").width / 2);
width: parent.height
height: parent.height
UM.RecolorImage {
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
- width: Math.floor(parent.width / 2)
- height: Math.floor(parent.height / 2)
+ width: Math.round(parent.width / 2)
+ height: Math.round(parent.height / 2)
sourceSize.width: width
sourceSize.height: height
color: !control.enabled ? UM.Theme.getColor("action_button_disabled_text") :
diff --git a/plugins/PostProcessingPlugin/Script.py b/plugins/PostProcessingPlugin/Script.py
index 7d603ba11f..7f419cd422 100644
--- a/plugins/PostProcessingPlugin/Script.py
+++ b/plugins/PostProcessingPlugin/Script.py
@@ -105,6 +105,58 @@ class Script:
except:
return default
+ ## Convenience function to produce a line of g-code.
+ #
+ # You can put in an original g-code line and it'll re-use all the values
+ # in that line.
+ # All other keyword parameters are put in the result in g-code's format.
+ # For instance, if you put ``G=1`` in the parameters, it will output
+ # ``G1``. If you put ``G=1, X=100`` in the parameters, it will output
+ # ``G1 X100``. The parameters G and M will always be put first. The
+ # parameters T and S will be put second (or first if there is no G or M).
+ # The rest of the parameters will be put in arbitrary order.
+ # \param line The original g-code line that must be modified. If not
+ # provided, an entirely new g-code line will be produced.
+ # \return A line of g-code with the desired parameters filled in.
+ def putValue(self, line = "", **kwargs):
+ #Strip the comment.
+ comment = ""
+ if ";" in line:
+ comment = line[line.find(";"):]
+ line = line[:line.find(";")] #Strip the comment.
+
+ #Parse the original g-code line.
+ for part in line.split(" "):
+ if part == "":
+ continue
+ parameter = part[0]
+ if parameter in kwargs:
+ continue #Skip this one. The user-provided parameter overwrites the one in the line.
+ value = part[1:]
+ kwargs[parameter] = value
+
+ #Write the new g-code line.
+ result = ""
+ priority_parameters = ["G", "M", "T", "S", "F", "X", "Y", "Z", "E"] #First some parameters that get priority. In order of priority!
+ for priority_key in priority_parameters:
+ if priority_key in kwargs:
+ if result != "":
+ result += " "
+ result += priority_key + str(kwargs[priority_key])
+ del kwargs[priority_key]
+ for key, value in kwargs.items():
+ if result != "":
+ result += " "
+ result += key + str(value)
+
+ #Put the comment back in.
+ if comment != "":
+ if result != "":
+ result += " "
+ result += ";" + comment
+
+ return result
+
## This is called when the script is executed.
# It gets a list of g-code strings and needs to return a (modified) list.
def execute(self, data):
diff --git a/plugins/PostProcessingPlugin/scripts/TweakAtZ.py b/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py
similarity index 82%
rename from plugins/PostProcessingPlugin/scripts/TweakAtZ.py
rename to plugins/PostProcessingPlugin/scripts/ChangeAtZ.py
index aca91f907a..54d6fdb155 100644
--- a/plugins/PostProcessingPlugin/scripts/TweakAtZ.py
+++ b/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py
@@ -1,10 +1,10 @@
-# TweakAtZ script - Change printing parameters at a given height
+# ChangeAtZ script - Change printing parameters at a given height
# This script is the successor of the TweakAtZ plugin for legacy Cura.
# It contains code from the TweakAtZ plugin V1.0-V4.x and from the ExampleScript by Jaime van Kessel, Ultimaker B.V.
# It runs with the PostProcessingPlugin which is released under the terms of the AGPLv3 or higher.
# This script is licensed under the Creative Commons - Attribution - Share Alike (CC BY-SA) terms
-#Authors of the TweakAtZ plugin / script:
+#Authors of the ChangeAtZ plugin / script:
# Written by Steven Morlock, smorloc@gmail.com
# Modified by Ricardo Gomez, ricardoga@otulook.com, to add Bed Temperature and make it work with Cura_13.06.04+
# Modified by Stefan Heule, Dim3nsioneer@gmx.ch since V3.0 (see changelog below)
@@ -46,7 +46,7 @@ from ..Script import Script
#from UM.Logger import Logger
import re
-class TweakAtZ(Script):
+class ChangeAtZ(Script):
version = "5.1.1"
def __init__(self):
super().__init__()
@@ -54,7 +54,7 @@ class TweakAtZ(Script):
def getSettingDataString(self):
return """{
"name":"ChangeAtZ """ + self.version + """ (Experimental)",
- "key":"TweakAtZ",
+ "key":"ChangeAtZ",
"metadata": {},
"version": 2,
"settings":
@@ -109,7 +109,7 @@ class TweakAtZ(Script):
"maximum_value_warning": "50",
"enabled": "c_behavior == 'keep_value'"
},
- "e1_Tweak_speed":
+ "e1_Change_speed":
{
"label": "Change Speed",
"description": "Select if total speed (print and travel) has to be cahnged",
@@ -126,9 +126,9 @@ class TweakAtZ(Script):
"minimum_value": "1",
"minimum_value_warning": "10",
"maximum_value_warning": "200",
- "enabled": "e1_Tweak_speed"
+ "enabled": "e1_Change_speed"
},
- "f1_Tweak_printspeed":
+ "f1_Change_printspeed":
{
"label": "Change Print Speed",
"description": "Select if print speed has to be changed",
@@ -145,9 +145,9 @@ class TweakAtZ(Script):
"minimum_value": "1",
"minimum_value_warning": "10",
"maximum_value_warning": "200",
- "enabled": "f1_Tweak_printspeed"
+ "enabled": "f1_Change_printspeed"
},
- "g1_Tweak_flowrate":
+ "g1_Change_flowrate":
{
"label": "Change Flow Rate",
"description": "Select if flow rate has to be changed",
@@ -164,9 +164,9 @@ class TweakAtZ(Script):
"minimum_value": "1",
"minimum_value_warning": "10",
"maximum_value_warning": "200",
- "enabled": "g1_Tweak_flowrate"
+ "enabled": "g1_Change_flowrate"
},
- "g3_Tweak_flowrateOne":
+ "g3_Change_flowrateOne":
{
"label": "Change Flow Rate 1",
"description": "Select if first extruder flow rate has to be changed",
@@ -183,9 +183,9 @@ class TweakAtZ(Script):
"minimum_value": "1",
"minimum_value_warning": "10",
"maximum_value_warning": "200",
- "enabled": "g3_Tweak_flowrateOne"
+ "enabled": "g3_Change_flowrateOne"
},
- "g5_Tweak_flowrateTwo":
+ "g5_Change_flowrateTwo":
{
"label": "Change Flow Rate 2",
"description": "Select if second extruder flow rate has to be changed",
@@ -202,9 +202,9 @@ class TweakAtZ(Script):
"minimum_value": "1",
"minimum_value_warning": "10",
"maximum_value_warning": "200",
- "enabled": "g5_Tweak_flowrateTwo"
+ "enabled": "g5_Change_flowrateTwo"
},
- "h1_Tweak_bedTemp":
+ "h1_Change_bedTemp":
{
"label": "Change Bed Temp",
"description": "Select if Bed Temperature has to be changed",
@@ -221,9 +221,9 @@ class TweakAtZ(Script):
"minimum_value": "0",
"minimum_value_warning": "30",
"maximum_value_warning": "120",
- "enabled": "h1_Tweak_bedTemp"
+ "enabled": "h1_Change_bedTemp"
},
- "i1_Tweak_extruderOne":
+ "i1_Change_extruderOne":
{
"label": "Change Extruder 1 Temp",
"description": "Select if First Extruder Temperature has to be changed",
@@ -240,9 +240,9 @@ class TweakAtZ(Script):
"minimum_value": "0",
"minimum_value_warning": "160",
"maximum_value_warning": "250",
- "enabled": "i1_Tweak_extruderOne"
+ "enabled": "i1_Change_extruderOne"
},
- "i3_Tweak_extruderTwo":
+ "i3_Change_extruderTwo":
{
"label": "Change Extruder 2 Temp",
"description": "Select if Second Extruder Temperature has to be changed",
@@ -259,9 +259,9 @@ class TweakAtZ(Script):
"minimum_value": "0",
"minimum_value_warning": "160",
"maximum_value_warning": "250",
- "enabled": "i3_Tweak_extruderTwo"
+ "enabled": "i3_Change_extruderTwo"
},
- "j1_Tweak_fanSpeed":
+ "j1_Change_fanSpeed":
{
"label": "Change Fan Speed",
"description": "Select if Fan Speed has to be changed",
@@ -278,17 +278,17 @@ class TweakAtZ(Script):
"minimum_value": "0",
"minimum_value_warning": "15",
"maximum_value_warning": "255",
- "enabled": "j1_Tweak_fanSpeed"
+ "enabled": "j1_Change_fanSpeed"
}
}
}"""
def getValue(self, line, key, default = None): #replace default getvalue due to comment-reading feature
if not key in line or (";" in line and line.find(key) > line.find(";") and
- not ";TweakAtZ" in key and not ";LAYER:" in key):
+ not ";ChangeAtZ" in key and not ";LAYER:" in key):
return default
subPart = line[line.find(key) + len(key):] #allows for string lengths larger than 1
- if ";TweakAtZ" in key:
+ if ";ChangeAtZ" in key:
m = re.search("^[0-4]", subPart)
elif ";LAYER:" in key:
m = re.search("^[+-]?[0-9]*", subPart)
@@ -303,17 +303,17 @@ class TweakAtZ(Script):
return default
def execute(self, data):
- #Check which tweaks should apply
- TweakProp = {"speed": self.getSettingValueByKey("e1_Tweak_speed"),
- "flowrate": self.getSettingValueByKey("g1_Tweak_flowrate"),
- "flowrateOne": self.getSettingValueByKey("g3_Tweak_flowrateOne"),
- "flowrateTwo": self.getSettingValueByKey("g5_Tweak_flowrateTwo"),
- "bedTemp": self.getSettingValueByKey("h1_Tweak_bedTemp"),
- "extruderOne": self.getSettingValueByKey("i1_Tweak_extruderOne"),
- "extruderTwo": self.getSettingValueByKey("i3_Tweak_extruderTwo"),
- "fanSpeed": self.getSettingValueByKey("j1_Tweak_fanSpeed")}
- TweakPrintSpeed = self.getSettingValueByKey("f1_Tweak_printspeed")
- TweakStrings = {"speed": "M220 S%f\n",
+ #Check which changes should apply
+ ChangeProp = {"speed": self.getSettingValueByKey("e1_Change_speed"),
+ "flowrate": self.getSettingValueByKey("g1_Change_flowrate"),
+ "flowrateOne": self.getSettingValueByKey("g3_Change_flowrateOne"),
+ "flowrateTwo": self.getSettingValueByKey("g5_Change_flowrateTwo"),
+ "bedTemp": self.getSettingValueByKey("h1_Change_bedTemp"),
+ "extruderOne": self.getSettingValueByKey("i1_Change_extruderOne"),
+ "extruderTwo": self.getSettingValueByKey("i3_Change_extruderTwo"),
+ "fanSpeed": self.getSettingValueByKey("j1_Change_fanSpeed")}
+ ChangePrintSpeed = self.getSettingValueByKey("f1_Change_printspeed")
+ ChangeStrings = {"speed": "M220 S%f\n",
"flowrate": "M221 S%f\n",
"flowrateOne": "M221 T0 S%f\n",
"flowrateTwo": "M221 T1 S%f\n",
@@ -369,14 +369,14 @@ class TweakAtZ(Script):
for line in lines:
if ";Generated with Cura_SteamEngine" in line:
TWinstances += 1
- modified_gcode += ";TweakAtZ instances: %d\n" % TWinstances
- if not ("M84" in line or "M25" in line or ("G1" in line and TweakPrintSpeed and (state==3 or state==4)) or
- ";TweakAtZ instances:" in line):
+ modified_gcode += ";ChangeAtZ instances: %d\n" % TWinstances
+ if not ("M84" in line or "M25" in line or ("G1" in line and ChangePrintSpeed and (state==3 or state==4)) or
+ ";ChangeAtZ instances:" in line):
modified_gcode += line + "\n"
IsUM2 = ("FLAVOR:UltiGCode" in line) or IsUM2 #Flavor is UltiGCode!
- if ";TweakAtZ-state" in line: #checks for state change comment
- state = self.getValue(line, ";TweakAtZ-state", state)
- if ";TweakAtZ instances:" in line:
+ if ";ChangeAtZ-state" in line: #checks for state change comment
+ state = self.getValue(line, ";ChangeAtZ-state", state)
+ if ";ChangeAtZ instances:" in line:
try:
tempTWi = int(line[20:])
except:
@@ -390,7 +390,7 @@ class TweakAtZ(Script):
state = old["state"]
layer = self.getValue(line, ";LAYER:", layer)
if targetL_i > -100000: #target selected by layer no.
- if (state == 2 or targetL_i == 0) and layer == targetL_i: #determine targetZ from layer no.; checks for tweak on layer 0
+ if (state == 2 or targetL_i == 0) and layer == targetL_i: #determine targetZ from layer no.; checks for change on layer 0
state = 2
targetZ = z + 0.001
if (self.getValue(line, "T", None) is not None) and (self.getValue(line, "M", None) is None): #looking for single T-cmd
@@ -415,7 +415,7 @@ class TweakAtZ(Script):
elif tmp_extruder == 1: #second extruder
old["flowrateOne"] = self.getValue(line, "S", old["flowrateOne"])
if ("M84" in line or "M25" in line):
- if state>0 and TweakProp["speed"]: #"finish" commands for UM Original and UM2
+ if state>0 and ChangeProp["speed"]: #"finish" commands for UM Original and UM2
modified_gcode += "M220 S100 ; speed reset to 100% at the end of print\n"
modified_gcode += "M117 \n"
modified_gcode += line + "\n"
@@ -425,14 +425,14 @@ class TweakAtZ(Script):
y = self.getValue(line, "Y", None)
e = self.getValue(line, "E", None)
f = self.getValue(line, "F", None)
- if 'G1' in line and TweakPrintSpeed and (state==3 or state==4):
+ if 'G1' in line and ChangePrintSpeed and (state==3 or state==4):
# check for pure print movement in target range:
if x != None and y != None and f != None and e != None and newZ==z:
modified_gcode += "G1 F%d X%1.3f Y%1.3f E%1.5f\n" % (int(f / 100.0 * float(target_values["printspeed"])), self.getValue(line, "X"),
self.getValue(line, "Y"), self.getValue(line, "E"))
else: #G1 command but not a print movement
modified_gcode += line + "\n"
- # no tweaking on retraction hops which have no x and y coordinate:
+ # no changing on retraction hops which have no x and y coordinate:
if (newZ != z) and (x is not None) and (y is not None):
z = newZ
if z < targetZ and state == 1:
@@ -440,56 +440,56 @@ class TweakAtZ(Script):
if z >= targetZ and state == 2:
state = 3
done_layers = 0
- for key in TweakProp:
- if TweakProp[key] and old[key]==-1: #old value is not known
+ for key in ChangeProp:
+ if ChangeProp[key] and old[key]==-1: #old value is not known
oldValueUnknown = True
- if oldValueUnknown: #the tweaking has to happen within one layer
+ if oldValueUnknown: #the changing has to happen within one layer
twLayers = 1
if IsUM2: #Parameters have to be stored in the printer (UltiGCode=UM2)
- modified_gcode += "M605 S%d;stores parameters before tweaking\n" % (TWinstances-1)
- if behavior == 1: #single layer tweak only and then reset
+ modified_gcode += "M605 S%d;stores parameters before changing\n" % (TWinstances-1)
+ if behavior == 1: #single layer change only and then reset
twLayers = 1
- if TweakPrintSpeed and behavior == 0:
+ if ChangePrintSpeed and behavior == 0:
twLayers = done_layers + 1
if state==3:
if twLayers-done_layers>0: #still layers to go?
if targetL_i > -100000:
- modified_gcode += ";TweakAtZ V%s: executed at Layer %d\n" % (self.version,layer)
- modified_gcode += "M117 Printing... tw@L%4d\n" % layer
+ modified_gcode += ";ChangeAtZ V%s: executed at Layer %d\n" % (self.version,layer)
+ modified_gcode += "M117 Printing... ch@L%4d\n" % layer
else:
- modified_gcode += (";TweakAtZ V%s: executed at %1.2f mm\n" % (self.version,z))
- modified_gcode += "M117 Printing... tw@%5.1f\n" % z
- for key in TweakProp:
- if TweakProp[key]:
- modified_gcode += TweakStrings[key] % float(old[key]+(float(target_values[key])-float(old[key]))/float(twLayers)*float(done_layers+1))
+ modified_gcode += (";ChangeAtZ V%s: executed at %1.2f mm\n" % (self.version,z))
+ modified_gcode += "M117 Printing... ch@%5.1f\n" % z
+ for key in ChangeProp:
+ if ChangeProp[key]:
+ modified_gcode += ChangeStrings[key] % float(old[key]+(float(target_values[key])-float(old[key]))/float(twLayers)*float(done_layers+1))
done_layers += 1
else:
state = 4
if behavior == 1: #reset values after one layer
if targetL_i > -100000:
- modified_gcode += ";TweakAtZ V%s: reset on Layer %d\n" % (self.version,layer)
+ modified_gcode += ";ChangeAtZ V%s: reset on Layer %d\n" % (self.version,layer)
else:
- modified_gcode += ";TweakAtZ V%s: reset at %1.2f mm\n" % (self.version,z)
+ modified_gcode += ";ChangeAtZ V%s: reset at %1.2f mm\n" % (self.version,z)
if IsUM2 and oldValueUnknown: #executes on UM2 with Ultigcode and machine setting
modified_gcode += "M606 S%d;recalls saved settings\n" % (TWinstances-1)
else: #executes on RepRap, UM2 with Ultigcode and Cura setting
- for key in TweakProp:
- if TweakProp[key]:
- modified_gcode += TweakStrings[key] % float(old[key])
+ for key in ChangeProp:
+ if ChangeProp[key]:
+ modified_gcode += ChangeStrings[key] % float(old[key])
# re-activates the plugin if executed by pre-print G-command, resets settings:
- if (z < targetZ or layer == 0) and state >= 3: #resets if below tweak level or at level 0
+ if (z < targetZ or layer == 0) and state >= 3: #resets if below change level or at level 0
state = 2
done_layers = 0
if targetL_i > -100000:
- modified_gcode += ";TweakAtZ V%s: reset below Layer %d\n" % (self.version,targetL_i)
+ modified_gcode += ";ChangeAtZ V%s: reset below Layer %d\n" % (self.version,targetL_i)
else:
- modified_gcode += ";TweakAtZ V%s: reset below %1.2f mm\n" % (self.version,targetZ)
+ modified_gcode += ";ChangeAtZ V%s: reset below %1.2f mm\n" % (self.version,targetZ)
if IsUM2 and oldValueUnknown: #executes on UM2 with Ultigcode and machine setting
modified_gcode += "M606 S%d;recalls saved settings\n" % (TWinstances-1)
else: #executes on RepRap, UM2 with Ultigcode and Cura setting
- for key in TweakProp:
- if TweakProp[key]:
- modified_gcode += TweakStrings[key] % float(old[key])
+ for key in ChangeProp:
+ if ChangeProp[key]:
+ modified_gcode += ChangeStrings[key] % float(old[key])
data[index] = modified_gcode
index += 1
return data
diff --git a/plugins/PostProcessingPlugin/scripts/ColorChange.py b/plugins/PostProcessingPlugin/scripts/FilamentChange.py
similarity index 79%
rename from plugins/PostProcessingPlugin/scripts/ColorChange.py
rename to plugins/PostProcessingPlugin/scripts/FilamentChange.py
index 8db45f4033..2bb7891634 100644
--- a/plugins/PostProcessingPlugin/scripts/ColorChange.py
+++ b/plugins/PostProcessingPlugin/scripts/FilamentChange.py
@@ -2,17 +2,15 @@
# under the terms of the AGPLv3 or higher
from ..Script import Script
-#from UM.Logger import Logger
-# from cura.Settings.ExtruderManager import ExtruderManager
-class ColorChange(Script):
+class FilamentChange(Script):
def __init__(self):
super().__init__()
def getSettingDataString(self):
return """{
- "name":"Color Change",
- "key": "ColorChange",
+ "name":"Filament Change",
+ "key": "FilamentChange",
"metadata": {},
"version": 2,
"settings":
@@ -60,17 +58,17 @@ class ColorChange(Script):
if later_retract is not None and later_retract > 0.:
color_change = color_change + (" L%.2f" % later_retract)
- color_change = color_change + " ; Generated by ColorChange plugin"
+ color_change = color_change + " ; Generated by FilamentChange plugin"
- layer_targets = layer_nums.split(',')
+ layer_targets = layer_nums.split(",")
if len(layer_targets) > 0:
for layer_num in layer_targets:
- layer_num = int( layer_num.strip() )
+ layer_num = int(layer_num.strip())
if layer_num < len(data):
- layer = data[ layer_num - 1 ]
+ layer = data[layer_num - 1]
lines = layer.split("\n")
- lines.insert(2, color_change )
- final_line = "\n".join( lines )
- data[ layer_num - 1 ] = final_line
+ lines.insert(2, color_change)
+ final_line = "\n".join(lines)
+ data[layer_num - 1] = final_line
return data
diff --git a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py
index 925a5a7ac5..805ab0a2c3 100644
--- a/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py
+++ b/plugins/PostProcessingPlugin/scripts/PauseAtHeight.py
@@ -7,19 +7,40 @@ class PauseAtHeight(Script):
def getSettingDataString(self):
return """{
- "name":"Pause at height",
+ "name": "Pause at height",
"key": "PauseAtHeight",
"metadata": {},
"version": 2,
"settings":
{
+ "pause_at":
+ {
+ "label": "Pause at",
+ "description": "Whether to pause at a certain height or at a certain layer.",
+ "type": "enum",
+ "options": {"height": "Height", "layer_no": "Layer No."},
+ "default_value": "height"
+ },
"pause_height":
{
"label": "Pause Height",
"description": "At what height should the pause occur",
"unit": "mm",
"type": "float",
- "default_value": 5.0
+ "default_value": 5.0,
+ "minimum_value": "0",
+ "minimum_value_warning": "0.27",
+ "enabled": "pause_at == 'height'"
+ },
+ "pause_layer":
+ {
+ "label": "Pause Layer",
+ "description": "At what layer should the pause occur",
+ "type": "int",
+ "value": "math.floor((pause_height - 0.27) / 0.1) + 1",
+ "minimum_value": "0",
+ "minimum_value_warning": "1",
+ "enabled": "pause_at == 'layer_no'"
},
"head_park_x":
{
@@ -102,8 +123,9 @@ class PauseAtHeight(Script):
x = 0.
y = 0.
- current_z = 0.
+ pause_at = self.getSettingValueByKey("pause_at")
pause_height = self.getSettingValueByKey("pause_height")
+ pause_layer = self.getSettingValueByKey("pause_layer")
retraction_amount = self.getSettingValueByKey("retraction_amount")
retraction_speed = self.getSettingValueByKey("retraction_speed")
extrude_amount = self.getSettingValueByKey("extrude_amount")
@@ -121,101 +143,133 @@ class PauseAtHeight(Script):
# use offset to calculate the current height: = -
layer_0_z = 0.
+ current_z = 0
got_first_g_cmd_on_layer_0 = False
- for layer in data:
+ for index, layer in enumerate(data):
lines = layer.split("\n")
for line in lines:
if ";LAYER:0" in line:
layers_started = True
- continue
-
if not layers_started:
continue
- if self.getValue(line, 'G') == 1 or self.getValue(line, 'G') == 0:
- current_z = self.getValue(line, 'Z')
+ if self.getValue(line, "Z") is not None:
+ current_z = self.getValue(line, "Z")
+
+ if pause_at == "height":
+ if self.getValue(line, "G") != 1 and self.getValue(line, "G") != 0:
+ continue
+
if not got_first_g_cmd_on_layer_0:
layer_0_z = current_z
got_first_g_cmd_on_layer_0 = True
- x = self.getValue(line, 'X', x)
- y = self.getValue(line, 'Y', y)
- if current_z is not None:
- current_height = current_z - layer_0_z
- if current_height >= pause_height:
- index = data.index(layer)
- prevLayer = data[index - 1]
- prevLines = prevLayer.split("\n")
- current_e = 0.
- for prevLine in reversed(prevLines):
- current_e = self.getValue(prevLine, 'E', -1)
- if current_e >= 0:
- break
+ x = self.getValue(line, "X", x)
+ y = self.getValue(line, "Y", y)
- # include a number of previous layers
- for i in range(1, redo_layers + 1):
- prevLayer = data[index - i]
- layer = prevLayer + layer
+ current_height = current_z - layer_0_z
+ if current_height < pause_height:
+ break #Try the next layer.
+ else: #Pause at layer.
+ if not line.startswith(";LAYER:"):
+ continue
+ current_layer = line[len(";LAYER:"):]
+ try:
+ current_layer = int(current_layer)
+ except ValueError: #Couldn't cast to int. Something is wrong with this g-code data.
+ continue
+ if current_layer < pause_layer:
+ break #Try the next layer.
- prepend_gcode = ";TYPE:CUSTOM\n"
- prepend_gcode += ";added code by post processing\n"
- prepend_gcode += ";script: PauseAtHeight.py\n"
- prepend_gcode += ";current z: %f \n" % current_z
- prepend_gcode += ";current height: %f \n" % current_height
+ prevLayer = data[index - 1]
+ prevLines = prevLayer.split("\n")
+ current_e = 0.
- # Retraction
- prepend_gcode += "M83\n"
- if retraction_amount != 0:
- prepend_gcode += "G1 E-%f F%f\n" % (retraction_amount, retraction_speed * 60)
-
- # Move the head away
- prepend_gcode += "G1 Z%f F300\n" % (current_z + 1)
- prepend_gcode += "G1 X%f Y%f F9000\n" % (park_x, park_y)
- if current_z < 15:
- prepend_gcode += "G1 Z15 F300\n"
-
- # Disable the E steppers
- prepend_gcode += "M84 E0\n"
-
- # Set extruder standby temperature
- prepend_gcode += "M104 S%i; standby temperature\n" % (standby_temperature)
-
- # Wait till the user continues printing
- prepend_gcode += "M0 ;Do the actual pause\n"
-
- # Set extruder resume temperature
- prepend_gcode += "M109 S%i; resume temperature\n" % (resume_temperature)
-
- # Push the filament back,
- if retraction_amount != 0:
- prepend_gcode += "G1 E%f F%f\n" % (retraction_amount, retraction_speed * 60)
-
- # Optionally extrude material
- if extrude_amount != 0:
- prepend_gcode += "G1 E%f F%f\n" % (extrude_amount, extrude_speed * 60)
-
- # and retract again, the properly primes the nozzle
- # when changing filament.
- if retraction_amount != 0:
- prepend_gcode += "G1 E-%f F%f\n" % (retraction_amount, retraction_speed * 60)
-
- # Move the head back
- prepend_gcode += "G1 Z%f F300\n" % (current_z + 1)
- prepend_gcode += "G1 X%f Y%f F9000\n" % (x, y)
- if retraction_amount != 0:
- prepend_gcode += "G1 E%f F%f\n" % (retraction_amount, retraction_speed * 60)
- prepend_gcode += "G1 F9000\n"
- prepend_gcode += "M82\n"
-
- # reset extrude value to pre pause value
- prepend_gcode += "G92 E%f\n" % (current_e)
-
- layer = prepend_gcode + layer
-
-
- # Override the data of this layer with the
- # modified data
- data[index] = layer
- return data
+ # Access last layer, browse it backwards to find
+ # last extruder absolute position
+ for prevLine in reversed(prevLines):
+ current_e = self.getValue(prevLine, "E", -1)
+ if current_e >= 0:
break
+
+ # include a number of previous layers
+ for i in range(1, redo_layers + 1):
+ prevLayer = data[index - i]
+ layer = prevLayer + layer
+
+ # Get extruder's absolute position at the
+ # begining of the first layer redone
+ # see https://github.com/nallath/PostProcessingPlugin/issues/55
+ if i == redo_layers:
+ prevLines = prevLayer.split("\n")
+ for line in prevLines:
+ new_e = self.getValue(line, 'E', current_e)
+
+ if new_e != current_e:
+ current_e = new_e
+ break
+
+ prepend_gcode = ";TYPE:CUSTOM\n"
+ prepend_gcode += ";added code by post processing\n"
+ prepend_gcode += ";script: PauseAtHeight.py\n"
+ if pause_at == "height":
+ prepend_gcode += ";current z: {z}\n".format(z = current_z)
+ prepend_gcode += ";current height: {height}\n".format(height = current_height)
+ else:
+ prepend_gcode += ";current layer: {layer}\n".format(layer = current_layer)
+
+ # Retraction
+ prepend_gcode += self.putValue(M = 83) + "\n"
+ if retraction_amount != 0:
+ prepend_gcode += self.putValue(G = 1, E = -retraction_amount, F = retraction_speed * 60) + "\n"
+
+ # Move the head away
+ prepend_gcode += self.putValue(G = 1, Z = current_z + 1, F = 300) + "\n"
+ prepend_gcode += self.putValue(G = 1, X = park_x, Y = park_y, F = 9000) + "\n"
+ if current_z < 15:
+ prepend_gcode += self.putValue(G = 1, Z = 15, F = 300) + "\n"
+
+ # Disable the E steppers
+ prepend_gcode += self.putValue(M = 84, E = 0) + "\n"
+
+ # Set extruder standby temperature
+ prepend_gcode += self.putValue(M = 104, S = standby_temperature) + "; standby temperature\n"
+
+ # Wait till the user continues printing
+ prepend_gcode += self.putValue(M = 0) + ";Do the actual pause\n"
+
+ # Set extruder resume temperature
+ prepend_gcode += self.putValue(M = 109, S = resume_temperature) + "; resume temperature\n"
+
+ # Push the filament back,
+ if retraction_amount != 0:
+ prepend_gcode += self.putValue(G = 1, E = retraction_amount, F = retraction_speed * 60) + "\n"
+
+ # Optionally extrude material
+ if extrude_amount != 0:
+ prepend_gcode += self.putValue(G = 1, E = extrude_amount, F = extrude_speed * 60) + "\n"
+
+ # and retract again, the properly primes the nozzle
+ # when changing filament.
+ if retraction_amount != 0:
+ prepend_gcode += self.putValue(G = 1, E = -retraction_amount, F = retraction_speed * 60) + "\n"
+
+ # Move the head back
+ prepend_gcode += self.putValue(G = 1, Z = current_z + 1, F = 300) + "\n"
+ prepend_gcode += self.putValue(G = 1, X = x, Y = y, F = 9000) + "\n"
+ if retraction_amount != 0:
+ prepend_gcode += self.putValue(G = 1, E = retraction_amount, F = retraction_speed * 60) + "\n"
+ prepend_gcode += self.putValue(G = 1, F = 9000) + "\n"
+ prepend_gcode += self.putValue(M = 82) + "\n"
+
+ # reset extrude value to pre pause value
+ prepend_gcode += self.putValue(G = 92, E = current_e) + "\n"
+
+ layer = prepend_gcode + layer
+
+
+ # Override the data of this layer with the
+ # modified data
+ data[index] = layer
+ return data
return data
diff --git a/plugins/PostProcessingPlugin/scripts/PauseAtHeightforRepetier.py b/plugins/PostProcessingPlugin/scripts/PauseAtHeightforRepetier.py
index 710baab26a..f6c93d9ae6 100644
--- a/plugins/PostProcessingPlugin/scripts/PauseAtHeightforRepetier.py
+++ b/plugins/PostProcessingPlugin/scripts/PauseAtHeightforRepetier.py
@@ -35,7 +35,7 @@ class PauseAtHeightforRepetier(Script):
"type": "float",
"default_value": 5.0
},
- "head_move_Z":
+ "head_move_Z":
{
"label": "Head move Z",
"description": "The Hieght of Z-axis retraction before parking.",
diff --git a/plugins/SimulationView/SimulationPass.py b/plugins/SimulationView/SimulationPass.py
index 76d7127534..cd0eda2929 100644
--- a/plugins/SimulationView/SimulationPass.py
+++ b/plugins/SimulationView/SimulationPass.py
@@ -93,7 +93,7 @@ class SimulationPass(RenderPass):
self.bind()
tool_handle_batch = RenderBatch(self._tool_handle_shader, type = RenderBatch.RenderType.Overlay, backface_cull = True)
- active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate
+ active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
head_position = None # Indicates the current position of the print head
nozzle_node = None
diff --git a/plugins/SimulationView/SimulationSliderLabel.qml b/plugins/SimulationView/SimulationSliderLabel.qml
index 1c8daf867f..6f7749df63 100644
--- a/plugins/SimulationView/SimulationSliderLabel.qml
+++ b/plugins/SimulationView/SimulationSliderLabel.qml
@@ -49,7 +49,7 @@ UM.PointingRectangle {
anchors {
left: parent.left
- leftMargin: Math.floor(UM.Theme.getSize("default_margin").width / 2)
+ leftMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
verticalCenter: parent.verticalCenter
}
@@ -91,7 +91,7 @@ UM.PointingRectangle {
anchors {
left: parent.right
- leftMargin: Math.floor(UM.Theme.getSize("default_margin").width / 2)
+ leftMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
verticalCenter: parent.verticalCenter
}
diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py
index 253ece315e..35ce9cc37a 100644
--- a/plugins/SimulationView/SimulationView.py
+++ b/plugins/SimulationView/SimulationView.py
@@ -342,6 +342,11 @@ class SimulationView(View):
min_layer_number = sys.maxsize
max_layer_number = -sys.maxsize
for layer_id in layer_data.getLayers():
+
+ # If a layer doesn't contain any polygons, skip it (for infill meshes taller than print objects
+ if len(layer_data.getLayer(layer_id).polygons) < 1:
+ continue
+
# Store the max and min feedrates and thicknesses for display purposes
for p in layer_data.getLayer(layer_id).polygons:
self._max_feedrate = max(float(p.lineFeedrates.max()), self._max_feedrate)
@@ -634,4 +639,3 @@ class _CreateTopLayersJob(Job):
def cancel(self):
self._cancel = True
super().cancel()
-
diff --git a/plugins/SimulationView/SimulationView.qml b/plugins/SimulationView/SimulationView.qml
index db92fac798..6aad413f9b 100644
--- a/plugins/SimulationView/SimulationView.qml
+++ b/plugins/SimulationView/SimulationView.qml
@@ -61,7 +61,7 @@ Item
Button {
id: collapseButton
anchors.top: parent.top
- anchors.topMargin: Math.floor(UM.Theme.getSize("default_margin").height + (UM.Theme.getSize("layerview_row").height - UM.Theme.getSize("default_margin").height) / 2)
+ anchors.topMargin: Math.round(UM.Theme.getSize("default_margin").height + (UM.Theme.getSize("layerview_row").height - UM.Theme.getSize("default_margin").height) / 2)
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width
@@ -193,7 +193,7 @@ Item
Item
{
- height: Math.floor(UM.Theme.getSize("default_margin").width / 2)
+ height: Math.round(UM.Theme.getSize("default_margin").width / 2)
width: width
}
@@ -231,7 +231,7 @@ Item
width: UM.Theme.getSize("layerview_legend_size").width
height: UM.Theme.getSize("layerview_legend_size").height
color: model.color
- radius: width / 2
+ radius: Math.round(width / 2)
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
visible: !viewSettings.show_legend & !viewSettings.show_gradient
@@ -249,7 +249,7 @@ Item
anchors.verticalCenter: parent.verticalCenter
anchors.left: extrudersModelCheckBox.left;
anchors.right: extrudersModelCheckBox.right;
- anchors.leftMargin: UM.Theme.getSize("checkbox").width + UM.Theme.getSize("default_margin").width /2
+ anchors.leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width/2)
anchors.rightMargin: UM.Theme.getSize("default_margin").width * 2
}
}
@@ -316,7 +316,7 @@ Item
anchors.verticalCenter: parent.verticalCenter
anchors.left: legendModelCheckBox.left;
anchors.right: legendModelCheckBox.right;
- anchors.leftMargin: UM.Theme.getSize("checkbox").width + UM.Theme.getSize("default_margin").width /2
+ anchors.leftMargin: UM.Theme.getSize("checkbox").width + Math.round(UM.Theme.getSize("default_margin").width/2)
anchors.rightMargin: UM.Theme.getSize("default_margin").width * 2
}
}
@@ -461,7 +461,7 @@ Item
visible: viewSettings.show_feedrate_gradient
anchors.left: parent.right
height: parent.width
- width: UM.Theme.getSize("layerview_row").height * 1.5
+ width: Math.round(UM.Theme.getSize("layerview_row").height * 1.5)
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
transform: Rotation {origin.x: 0; origin.y: 0; angle: 90}
@@ -492,7 +492,7 @@ Item
visible: viewSettings.show_thickness_gradient
anchors.left: parent.right
height: parent.width
- width: UM.Theme.getSize("layerview_row").height * 1.5
+ width: Math.round(UM.Theme.getSize("layerview_row").height * 1.5)
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
transform: Rotation {origin.x: 0; origin.y: 0; angle: 90}
diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py
index 50ff2864b7..de9f922267 100644
--- a/plugins/SolidView/SolidView.py
+++ b/plugins/SolidView/SolidView.py
@@ -78,17 +78,13 @@ class SolidView(View):
for node in DepthFirstIterator(scene.getRoot()):
if not node.render(renderer):
- if node.getMeshData() and node.isVisible():
+ if node.getMeshData() and node.isVisible() and not node.callDecoration("getLayerData"):
uniforms = {}
shade_factor = 1.0
per_mesh_stack = node.callDecoration("getStack")
- # Get color to render this mesh in from ExtrudersModel
- extruder_index = 0
- extruder_id = node.callDecoration("getActiveExtruder")
- if extruder_id:
- extruder_index = max(0, self._extruders_model.find("id", extruder_id))
+ extruder_index = int(node.callDecoration("getActiveExtruderPosition"))
# Use the support extruder instead of the active extruder if this is a support_mesh
if per_mesh_stack:
diff --git a/plugins/SupportEraser/SupportEraser.py b/plugins/SupportEraser/SupportEraser.py
index 9e2d41014d..8b3ad0f4dd 100644
--- a/plugins/SupportEraser/SupportEraser.py
+++ b/plugins/SupportEraser/SupportEraser.py
@@ -1,6 +1,6 @@
# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-
+from UM.Math.Vector import Vector
from UM.Tool import Tool
from PyQt5.QtCore import Qt, QUrl
from UM.Application import Application
@@ -41,8 +41,11 @@ class SupportEraser(Tool):
mesh = MeshBuilder()
mesh.addCube(10,10,10)
node.setMeshData(mesh.build())
+ # Place the cube in the platform. Do it manually so it works if the "automatic drop models" is OFF
+ move_vector = Vector(0, 5, 0)
+ node.setPosition(move_vector)
- active_build_plate = Application.getInstance().getBuildPlateModel().activeBuildPlate
+ active_build_plate = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
node.addDecorator(SettingOverrideDecorator())
node.addDecorator(BuildPlateDecorator(active_build_plate))
diff --git a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py
index 26b445ef90..bcd11b3cb7 100644
--- a/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py
+++ b/plugins/UM3NetworkPrinting/ClusterUM3OutputDevice.py
@@ -77,11 +77,14 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
self._cluster_size = int(properties.get(b"cluster_size", 0))
+ self._latest_reply_handler = None
+
+
def requestWrite(self, nodes, file_name=None, filter_by_machine=False, file_handler=None, **kwargs):
self.writeStarted.emit(self)
gcode_dict = getattr(Application.getInstance().getController().getScene(), "gcode_dict", [])
- active_build_plate_id = Application.getInstance().getBuildPlateModel().activeBuildPlate
+ active_build_plate_id = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
gcode_list = gcode_dict[active_build_plate_id]
if not gcode_list:
@@ -90,13 +93,15 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
self._gcode = gcode_list
+ is_job_sent = True
if len(self._printers) > 1:
self._spawnPrinterSelectionDialog()
else:
- self.sendPrintJob()
+ is_job_sent = self.sendPrintJob()
# Notify the UI that a switch to the print monitor should happen
- Application.getInstance().getController().setActiveStage("MonitorStage")
+ if is_job_sent:
+ Application.getInstance().getController().setActiveStage("MonitorStage")
def _spawnPrinterSelectionDialog(self):
if self._printer_selection_dialog is None:
@@ -118,7 +123,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
i18n_catalog.i18nc("@info:status",
"Sending new jobs (temporarily) blocked, still sending the previous print job."))
self._error_message.show()
- return
+ return False
self._sending_gcode = True
@@ -131,7 +136,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
compressed_gcode = self._compressGCode()
if compressed_gcode is None:
# Abort was called.
- return
+ return False
parts = []
@@ -147,7 +152,9 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
parts.append(self._createFormPart("name=\"file\"; filename=\"%s\"" % file_name, compressed_gcode))
- self.postFormWithParts("print_jobs/", parts, onFinished=self._onPostPrintJobFinished, onProgress=self._onUploadPrintJobProgress)
+ self._latest_reply_handler = self.postFormWithParts("print_jobs/", parts, onFinished=self._onPostPrintJobFinished, onProgress=self._onUploadPrintJobProgress)
+
+ return True
@pyqtProperty(QObject, notify=activePrinterChanged)
def activePrinter(self) -> Optional["PrinterOutputModel"]:
@@ -187,6 +194,13 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
self._sending_gcode = False
Application.getInstance().getController().setActiveStage("PrepareStage")
+ # After compressing the sliced model Cura sends data to printer, to stop receiving updates from the request
+ # the "reply" should be disconnected
+ if self._latest_reply_handler:
+ self._latest_reply_handler.disconnect()
+ self._latest_reply_handler = None
+
+
@pyqtSlot()
def openPrintJobControlPanel(self):
Logger.log("d", "Opening print job control panel...")
@@ -287,8 +301,8 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
self._updatePrintJob(print_job, print_job_data)
if print_job.state != "queued": # Print job should be assigned to a printer.
- if print_job.state == "failed":
- # Print job was failed, so don't attach it to a printer.
+ if print_job.state in ["failed", "finished", "aborted"]:
+ # Print job was already completed, so don't attach it to a printer.
printer = None
else:
printer = self._getPrinterByKey(print_job_data["printer_uuid"])
@@ -396,7 +410,7 @@ class ClusterUM3OutputDevice(NetworkedPrinterOutputDevice):
color = material_data["color"]
brand = material_data["brand"]
material_type = material_data["material"]
- name = "Unknown"
+ name = "Empty" if material_data["material"] == "empty" else "Unknown"
material = MaterialOutputModel(guid=material_data["guid"], type=material_type,
brand=brand, color=color, name=name)
diff --git a/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml b/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml
index 0e58d8e991..c0cb5a78b7 100644
--- a/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml
+++ b/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml
@@ -114,7 +114,7 @@ Cura.MachineAction
Column
{
- width: Math.floor(parent.width * 0.5)
+ width: Math.round(parent.width * 0.5)
spacing: UM.Theme.getSize("default_margin").height
ScrollView
@@ -198,7 +198,7 @@ Cura.MachineAction
}
Column
{
- width: Math.floor(parent.width * 0.5)
+ width: Math.round(parent.width * 0.5)
visible: base.selectedDevice ? true : false
spacing: UM.Theme.getSize("default_margin").height
Label
@@ -216,13 +216,13 @@ Cura.MachineAction
columns: 2
Label
{
- width: Math.floor(parent.width * 0.5)
+ width: Math.round(parent.width * 0.5)
wrapMode: Text.WordWrap
text: catalog.i18nc("@label", "Type")
}
Label
{
- width: Math.floor(parent.width * 0.5)
+ width: Math.round(parent.width * 0.5)
wrapMode: Text.WordWrap
text:
{
@@ -247,25 +247,25 @@ Cura.MachineAction
}
Label
{
- width: Math.floor(parent.width * 0.5)
+ width: Math.round(parent.width * 0.5)
wrapMode: Text.WordWrap
text: catalog.i18nc("@label", "Firmware version")
}
Label
{
- width: Math.floor(parent.width * 0.5)
+ width: Math.round(parent.width * 0.5)
wrapMode: Text.WordWrap
text: base.selectedDevice ? base.selectedDevice.firmwareVersion : ""
}
Label
{
- width: Math.floor(parent.width * 0.5)
+ width: Math.round(parent.width * 0.5)
wrapMode: Text.WordWrap
text: catalog.i18nc("@label", "Address")
}
Label
{
- width: Math.floor(parent.width * 0.5)
+ width: Math.round(parent.width * 0.5)
wrapMode: Text.WordWrap
text: base.selectedDevice ? base.selectedDevice.ipAddress : ""
}
diff --git a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py
index 647a7f822c..42f00beceb 100644
--- a/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py
+++ b/plugins/UM3NetworkPrinting/LegacyUM3OutputDevice.py
@@ -184,7 +184,7 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
self.writeStarted.emit(self)
gcode_dict = getattr(Application.getInstance().getController().getScene(), "gcode_dict", [])
- active_build_plate_id = Application.getInstance().getBuildPlateModel().activeBuildPlate
+ active_build_plate_id = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
gcode_list = gcode_dict[active_build_plate_id]
if not gcode_list:
@@ -419,8 +419,6 @@ class LegacyUM3OutputDevice(NetworkedPrinterOutputDevice):
self._authentication_failed_message.show()
elif status_code == 200:
self.setAuthenticationState(AuthState.Authenticated)
- # Now we know for sure that we are authenticated, send the material profiles to the machine.
- self._sendMaterialProfiles()
def _checkAuthentication(self):
Logger.log("d", "Checking if authentication is correct for id %s and key %s", self._authentication_id, self._getSafeAuthKey())
diff --git a/plugins/UM3NetworkPrinting/PrintCoreConfiguration.qml b/plugins/UM3NetworkPrinting/PrintCoreConfiguration.qml
index 70fa65da5e..267516091b 100644
--- a/plugins/UM3NetworkPrinting/PrintCoreConfiguration.qml
+++ b/plugins/UM3NetworkPrinting/PrintCoreConfiguration.qml
@@ -10,7 +10,7 @@ Item
id: extruderInfo
property var printCoreConfiguration
- width: Math.floor(parent.width / 2)
+ width: Math.round(parent.width / 2)
height: childrenRect.height
Label
{
diff --git a/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml b/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml
index eb5cbff8e3..54a34fae46 100644
--- a/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml
+++ b/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml
@@ -78,7 +78,7 @@ Rectangle
Rectangle
{
- width: Math.floor(parent.width / 3)
+ width: Math.round(parent.width / 3)
height: parent.height
Label // Print job name
@@ -123,7 +123,7 @@ Rectangle
Rectangle
{
- width: Math.floor(parent.width / 3 * 2)
+ width: Math.round(parent.width / 3 * 2)
height: parent.height
Label // Friendly machine name
@@ -131,7 +131,7 @@ Rectangle
id: printerNameLabel
anchors.top: parent.top
anchors.left: parent.left
- width: Math.floor(parent.width / 2 - UM.Theme.getSize("default_margin").width - showCameraIcon.width)
+ width: Math.round(parent.width / 2 - UM.Theme.getSize("default_margin").width - showCameraIcon.width)
text: printer.name
font: UM.Theme.getFont("default_bold")
elide: Text.ElideRight
@@ -141,7 +141,7 @@ Rectangle
{
id: printerTypeLabel
anchors.top: printerNameLabel.bottom
- width: Math.floor(parent.width / 2 - UM.Theme.getSize("default_margin").width)
+ width: Math.round(parent.width / 2 - UM.Theme.getSize("default_margin").width)
text: printer.type
anchors.left: parent.left
elide: Text.ElideRight
@@ -175,7 +175,7 @@ Rectangle
id: extruderInfo
anchors.bottom: parent.bottom
- width: Math.floor(parent.width / 2 - UM.Theme.getSize("default_margin").width)
+ width: Math.round(parent.width / 2 - UM.Theme.getSize("default_margin").width)
height: childrenRect.height
spacing: UM.Theme.getSize("default_margin").width
@@ -183,7 +183,7 @@ Rectangle
PrintCoreConfiguration
{
id: leftExtruderInfo
- width: Math.floor((parent.width - extruderSeperator.width) / 2)
+ width: Math.round((parent.width - extruderSeperator.width) / 2)
printCoreConfiguration: printer.extruders[0]
}
@@ -198,7 +198,7 @@ Rectangle
PrintCoreConfiguration
{
id: rightExtruderInfo
- width: Math.floor((parent.width - extruderSeperator.width) / 2)
+ width: Math.round((parent.width - extruderSeperator.width) / 2)
printCoreConfiguration: printer.extruders[1]
}
}
@@ -209,7 +209,7 @@ Rectangle
anchors.right: parent.right
anchors.top: parent.top
height: showExtended ? parent.height: printProgressTitleBar.height
- width: Math.floor(parent.width / 2 - UM.Theme.getSize("default_margin").width)
+ width: Math.round(parent.width / 2 - UM.Theme.getSize("default_margin").width)
border.width: UM.Theme.getSize("default_lining").width
border.color: lineColor
radius: cornerRadius
@@ -264,6 +264,7 @@ Rectangle
case "wait_for_configuration":
return catalog.i18nc("@label:status", "Reserved")
case "wait_cleanup":
+ case "wait_user_action":
return catalog.i18nc("@label:status", "Finished")
case "pre_print":
case "sent_to_printer":
@@ -278,6 +279,7 @@ Rectangle
case "aborted":
return catalog.i18nc("@label:status", "Print aborted");
default:
+ // If print job has unknown status show printer.status
return printerStatusText(printer);
}
}
diff --git a/plugins/UM3NetworkPrinting/PrinterVideoStream.qml b/plugins/UM3NetworkPrinting/PrinterVideoStream.qml
index 3e6f6a8fd8..7f7b2ad546 100644
--- a/plugins/UM3NetworkPrinting/PrinterVideoStream.qml
+++ b/plugins/UM3NetworkPrinting/PrinterVideoStream.qml
@@ -57,7 +57,7 @@ Item
{
id: cameraImage
width: Math.min(sourceSize.width === 0 ? 800 * screenScaleFactor : sourceSize.width, maximumWidth)
- height: Math.floor((sourceSize.height === 0 ? 600 * screenScaleFactor : sourceSize.height) * width / sourceSize.width)
+ height: Math.round((sourceSize.height === 0 ? 600 * screenScaleFactor : sourceSize.height) * width / sourceSize.width)
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
z: 1
diff --git a/plugins/UM3NetworkPrinting/UM3InfoComponents.qml b/plugins/UM3NetworkPrinting/UM3InfoComponents.qml
index 18b481a6ed..5a9cc096e7 100644
--- a/plugins/UM3NetworkPrinting/UM3InfoComponents.qml
+++ b/plugins/UM3NetworkPrinting/UM3InfoComponents.qml
@@ -10,7 +10,8 @@ Item
{
id: base
- property bool isUM3: Cura.MachineManager.activeQualityDefinitionId == "ultimaker3"
+ property string activeQualityDefinitionId: Cura.MachineManager.activeQualityDefinitionId
+ property bool isUM3: activeQualityDefinitionId == "ultimaker3" || activeQualityDefinitionId.match("ultimaker_") != null
property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
property bool printerAcceptsCommands: printerConnected && Cura.MachineManager.printerOutputDevices[0].acceptsCommands
property bool authenticationRequested: printerConnected && (Cura.MachineManager.printerOutputDevices[0].authenticationState == 2 || Cura.MachineManager.printerOutputDevices[0].authenticationState == 5) // AuthState.AuthenticationRequested or AuthenticationReceived.
diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py
index b53f502d81..11cc7bf472 100644
--- a/plugins/USBPrinting/USBPrinterOutputDevice.py
+++ b/plugins/USBPrinting/USBPrinterOutputDevice.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2016 Ultimaker B.V.
+# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from UM.Logger import Logger
@@ -17,7 +17,7 @@ from .avr_isp import stk500v2, intelHex
from PyQt5.QtCore import pyqtSlot, pyqtSignal, pyqtProperty
-from serial import Serial, SerialException
+from serial import Serial, SerialException, SerialTimeoutException
from threading import Thread
from time import time, sleep
from queue import Queue
@@ -99,7 +99,7 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
Application.getInstance().getController().setActiveStage("MonitorStage")
# find the G-code for the active build plate to print
- active_build_plate_id = Application.getInstance().getBuildPlateModel().activeBuildPlate
+ active_build_plate_id = Application.getInstance().getMultiBuildPlateModel().activeBuildPlate
gcode_dict = getattr(Application.getInstance().getController().getScene(), "gcode_dict")
gcode_list = gcode_dict[active_build_plate_id]
@@ -266,8 +266,11 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
command = (command + "\n").encode()
if not command.endswith(b"\n"):
command += b"\n"
- self._serial.write(b"\n")
- self._serial.write(command)
+ try:
+ self._serial.write(b"\n")
+ self._serial.write(command)
+ except SerialTimeoutException:
+ Logger.log("w", "Timeout when sending command to printer via USB.")
def _update(self):
while self._connection_state == ConnectionState.connected and self._serial is not None:
diff --git a/plugins/UltimakerMachineActions/BedLevelMachineAction.py b/plugins/UltimakerMachineActions/BedLevelMachineAction.py
index 04b6cf1acc..6a8a337d8c 100644
--- a/plugins/UltimakerMachineActions/BedLevelMachineAction.py
+++ b/plugins/UltimakerMachineActions/BedLevelMachineAction.py
@@ -1,3 +1,8 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from typing import List
+
from cura.MachineAction import MachineAction
from cura.PrinterOutputDevice import PrinterOutputDevice
@@ -5,6 +10,7 @@ from UM.FlameProfiler import pyqtSlot
from UM.Application import Application
from UM.i18n import i18nCatalog
+from UM.Logger import Logger
catalog = i18nCatalog("cura")
@@ -26,38 +32,45 @@ class BedLevelMachineAction(MachineAction):
@pyqtSlot()
def startBedLeveling(self):
self._bed_level_position = 0
- printer_output_devices = self._getPrinterOutputDevices()
- if printer_output_devices:
- printer_output_devices[0].homeBed()
- printer_output_devices[0].moveHead(0, 0, 3)
- printer_output_devices[0].homeHead()
- def _getPrinterOutputDevices(self):
+ printer_output_devices = self._getPrinterOutputDevices()
+ if not printer_output_devices:
+ Logger.log("e", "Can't start bed levelling. The printer connection seems to have been lost.")
+ return
+ printer = printer_output_devices[0].activePrinter
+
+ printer.homeBed()
+ printer.moveHead(0, 0, 3)
+ printer.homeHead()
+
+ def _getPrinterOutputDevices(self) -> List[PrinterOutputDevice]:
return [printer_output_device for printer_output_device in Application.getInstance().getOutputDeviceManager().getOutputDevices() if isinstance(printer_output_device, PrinterOutputDevice)]
@pyqtSlot()
def moveToNextLevelPosition(self):
output_devices = self._getPrinterOutputDevices()
- if output_devices: # We found at least one output device
- output_device = output_devices[0]
+ if not output_devices: #No output devices. Can't move.
+ Logger.log("e", "Can't move to the next position. The printer connection seems to have been lost.")
+ return
+ printer = output_devices[0].activePrinter
- if self._bed_level_position == 0:
- output_device.moveHead(0, 0, 3)
- output_device.homeHead()
- output_device.moveHead(0, 0, 3)
- output_device.moveHead(Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value") - 10, 0, 0)
- output_device.moveHead(0, 0, -3)
- self._bed_level_position += 1
- elif self._bed_level_position == 1:
- output_device.moveHead(0, 0, 3)
- output_device.moveHead(-Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value" ) / 2, Application.getInstance().getGlobalContainerStack().getProperty("machine_depth", "value") - 10, 0)
- output_device.moveHead(0, 0, -3)
- self._bed_level_position += 1
- elif self._bed_level_position == 2:
- output_device.moveHead(0, 0, 3)
- output_device.moveHead(-Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value") / 2 + 10, -(Application.getInstance().getGlobalContainerStack().getProperty("machine_depth", "value") + 10), 0)
- output_device.moveHead(0, 0, -3)
- self._bed_level_position += 1
- elif self._bed_level_position >= 3:
- output_device.sendCommand("M18") # Turn off all motors so the user can move the axes
- self.setFinished()
\ No newline at end of file
+ if self._bed_level_position == 0:
+ printer.moveHead(0, 0, 3)
+ printer.homeHead()
+ printer.moveHead(0, 0, 3)
+ printer.moveHead(Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value") - 10, 0, 0)
+ printer.moveHead(0, 0, -3)
+ self._bed_level_position += 1
+ elif self._bed_level_position == 1:
+ printer.moveHead(0, 0, 3)
+ printer.moveHead(-Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value" ) / 2, Application.getInstance().getGlobalContainerStack().getProperty("machine_depth", "value") - 10, 0)
+ printer.moveHead(0, 0, -3)
+ self._bed_level_position += 1
+ elif self._bed_level_position == 2:
+ printer.moveHead(0, 0, 3)
+ printer.moveHead(-Application.getInstance().getGlobalContainerStack().getProperty("machine_width", "value") / 2 + 10, -(Application.getInstance().getGlobalContainerStack().getProperty("machine_depth", "value") + 10), 0)
+ printer.moveHead(0, 0, -3)
+ self._bed_level_position += 1
+ elif self._bed_level_position >= 3:
+ output_devices[0].sendCommand("M18") # Turn off all motors so the user can move the axes
+ self.setFinished()
\ No newline at end of file
diff --git a/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml b/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml
index 5a1f8f26a7..b92638aa12 100644
--- a/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml
+++ b/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml
@@ -180,7 +180,7 @@ Cura.MachineAction
height: childrenRect.height
anchors.top: nozzleTempLabel.top
anchors.left: bedTempStatus.right
- anchors.leftMargin: UM.Theme.getSize("default_margin").width/2
+ anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").width/2)
visible: checkupMachineAction.usbConnected
Button
{
@@ -241,7 +241,7 @@ Cura.MachineAction
height: childrenRect.height
anchors.top: bedTempLabel.top
anchors.left: bedTempStatus.right
- anchors.leftMargin: UM.Theme.getSize("default_margin").width/2
+ anchors.leftMargin: Math.round(UM.Theme.getSize("default_margin").width/2)
visible: checkupMachineAction.usbConnected && manager.hasHeatedBed
Button
{
diff --git a/plugins/UserAgreementPlugin/UserAgreement.qml b/plugins/UserAgreementPlugin/UserAgreement.qml
index c7f3f165e3..4ee03f4ad5 100644
--- a/plugins/UserAgreementPlugin/UserAgreement.qml
+++ b/plugins/UserAgreementPlugin/UserAgreement.qml
@@ -9,8 +9,8 @@ import UM 1.3 as UM
UM.Dialog
{
id: baseDialog
- minimumWidth: Math.floor(UM.Theme.getSize("modal_window_minimum").width * 0.75)
- minimumHeight: Math.floor(UM.Theme.getSize("modal_window_minimum").height * 0.5)
+ minimumWidth: Math.round(UM.Theme.getSize("modal_window_minimum").width * 0.75)
+ minimumHeight: Math.round(UM.Theme.getSize("modal_window_minimum").height * 0.5)
width: minimumWidth
height: minimumHeight
title: catalog.i18nc("@title:window", "User Agreement")
diff --git a/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py b/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py
index d7b2c1a001..a88ff5ac1c 100644
--- a/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py
+++ b/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py
@@ -3,14 +3,9 @@
import configparser #To parse preference files.
import io #To serialise the preference files afterwards.
-import os
-from urllib.parse import quote_plus
-from UM.Resources import Resources
from UM.VersionUpgrade import VersionUpgrade #We're inheriting from this.
-from cura.CuraApplication import CuraApplication
-
# a list of all legacy "Not Supported" quality profiles
_OLD_NOT_SUPPORTED_PROFILES = [
@@ -130,7 +125,6 @@ class VersionUpgrade30to31(VersionUpgrade):
parser.write(output)
return [filename], [output.getvalue()]
-
## Upgrades a container stack from version 3.0 to 3.1.
#
# \param serialised The serialised form of a container stack.
@@ -172,71 +166,3 @@ class VersionUpgrade30to31(VersionUpgrade):
output = io.StringIO()
parser.write(output)
return [filename], [output.getvalue()]
-
- def _getSingleExtrusionMachineQualityChanges(self, quality_changes_container):
- quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer)
- quality_changes_containers = []
-
- for item in os.listdir(quality_changes_dir):
- file_path = os.path.join(quality_changes_dir, item)
- if not os.path.isfile(file_path):
- continue
-
- parser = configparser.ConfigParser(interpolation = None)
- try:
- parser.read([file_path])
- except:
- # skip, it is not a valid stack file
- continue
-
- if not parser.has_option("metadata", "type"):
- continue
- if "quality_changes" != parser["metadata"]["type"]:
- continue
-
- if not parser.has_option("general", "name"):
- continue
- if quality_changes_container["general"]["name"] != parser["general"]["name"]:
- continue
-
- quality_changes_containers.append(parser)
-
- return quality_changes_containers
-
- def _createExtruderQualityChangesForSingleExtrusionMachine(self, filename, global_quality_changes):
- suffix = "_" + quote_plus(global_quality_changes["general"]["name"].lower())
- machine_name = os.path.os.path.basename(filename).replace(".inst.cfg", "").replace(suffix, "")
-
- # Why is this here?!
- # When we load a .curaprofile file the deserialize will trigger a version upgrade, creating a dangling file.
- # This file can be recognized by it's lack of a machine name in the target filename.
- # So when we detect that situation here, we don't create the file and return.
- if machine_name == "":
- return
-
- new_filename = machine_name + "_" + "fdmextruder" + suffix
-
- extruder_quality_changes_parser = configparser.ConfigParser(interpolation = None)
- extruder_quality_changes_parser.add_section("general")
- extruder_quality_changes_parser["general"]["version"] = str(2)
- extruder_quality_changes_parser["general"]["name"] = global_quality_changes["general"]["name"]
- extruder_quality_changes_parser["general"]["definition"] = global_quality_changes["general"]["definition"]
-
- # check renamed definition
- if extruder_quality_changes_parser["general"]["definition"] in _RENAMED_DEFINITION_DICT:
- extruder_quality_changes_parser["general"]["definition"] = _RENAMED_DEFINITION_DICT[extruder_quality_changes_parser["general"]["definition"]]
-
- extruder_quality_changes_parser.add_section("metadata")
- extruder_quality_changes_parser["metadata"]["quality_type"] = global_quality_changes["metadata"]["quality_type"]
- extruder_quality_changes_parser["metadata"]["type"] = global_quality_changes["metadata"]["type"]
- extruder_quality_changes_parser["metadata"]["setting_version"] = str(4)
- extruder_quality_changes_parser["metadata"]["extruder"] = "fdmextruder"
-
- extruder_quality_changes_output = io.StringIO()
- extruder_quality_changes_parser.write(extruder_quality_changes_output)
- extruder_quality_changes_filename = quote_plus(new_filename) + ".inst.cfg"
-
- quality_changes_dir = Resources.getPath(CuraApplication.ResourceTypes.QualityInstanceContainer)
-
- with open(os.path.join(quality_changes_dir, extruder_quality_changes_filename), "w", encoding = "utf-8") as f:
- f.write(extruder_quality_changes_output.getvalue())
diff --git a/plugins/VersionUpgrade/VersionUpgrade30to31/__init__.py b/plugins/VersionUpgrade/VersionUpgrade30to31/__init__.py
index b4b75dddf7..c853e2b93b 100644
--- a/plugins/VersionUpgrade/VersionUpgrade30to31/__init__.py
+++ b/plugins/VersionUpgrade/VersionUpgrade30to31/__init__.py
@@ -33,6 +33,10 @@ def getMetaData():
"get_version": upgrade.getCfgVersion,
"location": {"./extruders"}
},
+ "quality": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./quality"}
+ },
"quality_changes": {
"get_version": upgrade.getCfgVersion,
"location": {"./quality"}
diff --git a/plugins/VersionUpgrade/VersionUpgrade32to33/VersionUpgrade32to33.py b/plugins/VersionUpgrade/VersionUpgrade32to33/VersionUpgrade32to33.py
new file mode 100644
index 0000000000..de2240a7c6
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade32to33/VersionUpgrade32to33.py
@@ -0,0 +1,111 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+import configparser #To parse preference files.
+import io #To serialise the preference files afterwards.
+
+from UM.VersionUpgrade import VersionUpgrade #We're inheriting from this.
+
+## Mapping extruder definition IDs to the positions that they are in.
+_EXTRUDER_TO_POSITION = {
+ "builder_premium_large_front": 1,
+ "builder_premium_large_rear": 0,
+ "builder_premium_medium_front": 1,
+ "builder_premium_medium_rear": 0,
+ "builder_premium_small_front": 1,
+ "builder_premium_small_rear": 0,
+ "cartesio_extruder_0": 0,
+ "cartesio_extruder_1": 1,
+ "cartesio_extruder_2": 2,
+ "cartesio_extruder_3": 3,
+ "custom_extruder_1": 0, #Warning, non-programmers are attempting to count here.
+ "custom_extruder_2": 1,
+ "custom_extruder_3": 2,
+ "custom_extruder_4": 3,
+ "custom_extruder_5": 4,
+ "custom_extruder_6": 5,
+ "custom_extruder_7": 6,
+ "custom_extruder_8": 7,
+ "hBp_extruder_left": 0,
+ "hBp_extruder_right": 1,
+ "makeit_dual_1st": 0,
+ "makeit_dual_2nd": 1,
+ "makeit_l_dual_1st": 0,
+ "makeit_l_dual_2nd": 1,
+ "ord_extruder_0": 0,
+ "ord_extruder_1": 1,
+ "ord_extruder_2": 2,
+ "ord_extruder_3": 3,
+ "ord_extruder_4": 4,
+ "punchtec_connect_xl_extruder_left": 0,
+ "punchtec_connect_xl_extruder_right": 1,
+ "raise3D_N2_dual_extruder_0": 0,
+ "raise3D_N2_dual_extruder_1": 1,
+ "raise3D_N2_plus_dual_extruder_0": 0,
+ "raise3D_N2_plus_dual_extruder_1": 1,
+ "ultimaker3_extended_extruder_left": 0,
+ "ultimaker3_extended_extruder_right": 1,
+ "ultimaker3_extruder_left": 0,
+ "ultimaker3_extruder_right": 1,
+ "ultimaker_original_dual_1st": 0,
+ "ultimaker_original_dual_2nd": 1,
+ "vertex_k8400_dual_1st": 0,
+ "vertex_k8400_dual_2nd": 1
+}
+
+## Upgrades configurations from the state they were in at version 3.2 to the
+# state they should be in at version 3.3.
+class VersionUpgrade32to33(VersionUpgrade):
+ ## Gets the version number from a CFG file in Uranium's 3.2 format.
+ #
+ # Since the format may change, this is implemented for the 3.2 format only
+ # and needs to be included in the version upgrade system rather than
+ # globally in Uranium.
+ #
+ # \param serialised The serialised form of a CFG file.
+ # \return The version number stored in the CFG file.
+ # \raises ValueError The format of the version number in the file is
+ # incorrect.
+ # \raises KeyError The format of the file is incorrect.
+ def getCfgVersion(self, serialised):
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialised)
+ 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 non-quality-changes instance containers to have the new version
+ # number.
+ def upgradeInstanceContainer(self, serialized, filename):
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialized)
+
+ #Update version number.
+ parser["general"]["version"] = "3"
+
+ result = io.StringIO()
+ parser.write(result)
+ return [filename], [result.getvalue()]
+
+ ## Upgrades a quality changes container to the new format.
+ def upgradeQualityChanges(self, serialized, filename):
+ parser = configparser.ConfigParser(interpolation = None)
+ parser.read_string(serialized)
+
+ #Extruder quality changes profiles have the extruder position instead of the ID of the extruder definition.
+ if "metadata" in parser and "extruder" in parser["metadata"]: #Only do this for extruder profiles.
+ extruder_id = parser["metadata"]["extruder"]
+ if extruder_id in _EXTRUDER_TO_POSITION:
+ extruder_position = _EXTRUDER_TO_POSITION[extruder_id]
+ else:
+ extruder_position = 0 #The user was using custom extruder definitions. He's on his own then.
+
+ parser["metadata"]["position"] = str(extruder_position)
+ del parser["metadata"]["extruder"]
+
+ #Update version number.
+ parser["general"]["version"] = "3"
+
+ result = io.StringIO()
+ parser.write(result)
+ return [filename], [result.getvalue()]
\ No newline at end of file
diff --git a/plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py b/plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py
new file mode 100644
index 0000000000..c411b4190e
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade32to33/__init__.py
@@ -0,0 +1,33 @@
+# Copyright (c) 2018 Ultimaker B.V.
+# Cura is released under the terms of the LGPLv3 or higher.
+
+from . import VersionUpgrade32to33
+
+upgrade = VersionUpgrade32to33.VersionUpgrade32to33()
+
+def getMetaData():
+ return {
+ "version_upgrade": {
+ # From To Upgrade function
+ ("definition_changes", 2000004): ("definition_changes", 3000004, upgrade.upgradeInstanceContainer),
+ ("quality_changes", 2000004): ("quality_changes", 3000004, upgrade.upgradeQualityChanges),
+ ("user", 2000004): ("user", 3000004, upgrade.upgradeInstanceContainer)
+ },
+ "sources": {
+ "definition_changes": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./definition_changes"}
+ },
+ "quality_changes": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./quality"}
+ },
+ "user": {
+ "get_version": upgrade.getCfgVersion,
+ "location": {"./user"}
+ }
+ }
+ }
+
+def register(app):
+ return { "version_upgrade": upgrade }
\ No newline at end of file
diff --git a/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json b/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json
new file mode 100644
index 0000000000..fbce09c807
--- /dev/null
+++ b/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json
@@ -0,0 +1,8 @@
+ {
+ "name": "Version Upgrade 3.2 to 3.3",
+ "author": "Ultimaker B.V.",
+ "version": "1.0.0",
+ "description": "Upgrades configurations from Cura 3.2 to Cura 3.3.",
+ "api": 4,
+ "i18n-catalog": "cura"
+}
diff --git a/plugins/XRayView/XRayPass.py b/plugins/XRayView/XRayPass.py
index 38c88a256e..a75d393b35 100644
--- a/plugins/XRayView/XRayPass.py
+++ b/plugins/XRayView/XRayPass.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015 Ultimaker B.V.
+# Copyright (c) 2018 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import os.path
@@ -10,7 +10,7 @@ from UM.View.RenderPass import RenderPass
from UM.View.RenderBatch import RenderBatch
from UM.View.GL.OpenGL import OpenGL
-from UM.Scene.SceneNode import SceneNode
+from cura.Scene.CuraSceneNode import CuraSceneNode
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
class XRayPass(RenderPass):
@@ -27,7 +27,7 @@ class XRayPass(RenderPass):
batch = RenderBatch(self._shader, type = RenderBatch.RenderType.NoType, backface_cull = False, blend_mode = RenderBatch.BlendMode.Additive)
for node in DepthFirstIterator(self._scene.getRoot()):
- if type(node) is SceneNode and node.getMeshData() and node.isVisible():
+ if isinstance(node, CuraSceneNode) and node.getMeshData() and node.isVisible():
batch.addItem(node.getWorldTransformation(), node.getMeshData())
self.bind()
diff --git a/plugins/XRayView/xray_composite.shader b/plugins/XRayView/xray_composite.shader
index 82dca52cf9..0a8f6364d7 100644
--- a/plugins/XRayView/xray_composite.shader
+++ b/plugins/XRayView/xray_composite.shader
@@ -13,9 +13,9 @@ vertex =
}
fragment =
- uniform sampler2D u_layer0;
- uniform sampler2D u_layer1;
- uniform sampler2D u_layer2;
+ uniform sampler2D u_layer0; //Default pass.
+ uniform sampler2D u_layer1; //Selection pass.
+ uniform sampler2D u_layer2; //X-ray pass.
uniform vec2 u_offset[9];
@@ -83,9 +83,9 @@ vertex41core =
fragment41core =
#version 410
- uniform sampler2D u_layer0;
- uniform sampler2D u_layer1;
- uniform sampler2D u_layer2;
+ uniform sampler2D u_layer0; //Default pass.
+ uniform sampler2D u_layer1; //Selection pass.
+ uniform sampler2D u_layer2; //X-ray pass.
uniform vec2 u_offset[9];
diff --git a/plugins/XmlMaterialProfile/XmlMaterialProfile.py b/plugins/XmlMaterialProfile/XmlMaterialProfile.py
index f0d016025e..bbf5dfe2ba 100644
--- a/plugins/XmlMaterialProfile/XmlMaterialProfile.py
+++ b/plugins/XmlMaterialProfile/XmlMaterialProfile.py
@@ -48,18 +48,35 @@ class XmlMaterialProfile(InstanceContainer):
## Overridden from InstanceContainer
# set the meta data for all machine / variant combinations
- def setMetaDataEntry(self, key, value):
+ #
+ # The "apply_to_all" flag indicates whether this piece of metadata should be applied to all material containers
+ # or just this specific container.
+ # For example, when you change the material name, you want to apply it to all its derived containers, but for
+ # some specific settings, they should only be applied to a machine/variant-specific container.
+ #
+ def setMetaDataEntry(self, key, value, apply_to_all = True):
registry = ContainerRegistry.getInstance()
if registry.isReadOnly(self.getId()):
return
- super().setMetaDataEntry(key, value)
+ # Prevent recursion
+ if not apply_to_all:
+ super().setMetaDataEntry(key, value)
+ return
- basefile = self.getMetaDataEntry("base_file", self.getId()) #if basefile is self.getId, this is a basefile.
- # Update all containers that share basefile
- for container in registry.findInstanceContainers(base_file = basefile):
- if container.getMetaDataEntry(key, None) != value: # Prevent recursion
- container.setMetaDataEntry(key, value)
+ # Get the MaterialGroup
+ material_manager = CuraApplication.getInstance().getMaterialManager()
+ root_material_id = self.getMetaDataEntry("base_file") #if basefile is self.getId, this is a basefile.
+ material_group = material_manager.getMaterialGroup(root_material_id)
+
+ # Update the root material container
+ root_material_container = material_group.root_material_node.getContainer()
+ root_material_container.setMetaDataEntry(key, value, apply_to_all = False)
+
+ # Update all containers derived from it
+ for node in material_group.derived_material_node_list:
+ container = node.getContainer()
+ container.setMetaDataEntry(key, value, apply_to_all = False)
## Overridden from InstanceContainer, similar to setMetaDataEntry.
# without this function the setName would only set the name of the specific nozzle / material / machine combination container
@@ -183,28 +200,39 @@ class XmlMaterialProfile(InstanceContainer):
## Begin Settings Block
builder.start("settings")
- if self.getDefinition().getId() == "fdmprinter":
+ if self.getMetaDataEntry("definition") == "fdmprinter":
for instance in self.findInstances():
self._addSettingElement(builder, instance)
machine_container_map = {}
- machine_nozzle_map = {}
+ machine_variant_map = {}
+
+ variant_manager = CuraApplication.getInstance().getVariantManager()
+ material_manager = CuraApplication.getInstance().getMaterialManager()
+
+ root_material_id = self.getMetaDataEntry("base_file") # if basefile is self.getId, this is a basefile.
+ material_group = material_manager.getMaterialGroup(root_material_id)
+
+ all_containers = []
+ for node in [material_group.root_material_node] + material_group.derived_material_node_list:
+ all_containers.append(node.getContainer())
- all_containers = registry.findInstanceContainers(GUID = self.getMetaDataEntry("GUID"), base_file = self.getId())
for container in all_containers:
- definition_id = container.getDefinition().getId()
+ definition_id = container.getMetaDataEntry("definition")
if definition_id == "fdmprinter":
continue
if definition_id not in machine_container_map:
machine_container_map[definition_id] = container
- if definition_id not in machine_nozzle_map:
- machine_nozzle_map[definition_id] = {}
+ if definition_id not in machine_variant_map:
+ machine_variant_map[definition_id] = {}
- variant = container.getMetaDataEntry("variant")
- if variant:
- machine_nozzle_map[definition_id][variant] = container
+ variant_name = container.getMetaDataEntry("variant_name")
+ if variant_name:
+ variant_dict = {"variant_node": variant_manager.getVariantNode(definition_id, variant_name),
+ "material_container": container}
+ machine_variant_map[definition_id][variant_name] = variant_dict
continue
machine_container_map[definition_id] = container
@@ -213,7 +241,8 @@ class XmlMaterialProfile(InstanceContainer):
product_id_map = self.getProductIdMap()
for definition_id, container in machine_container_map.items():
- definition = container.getDefinition()
+ definition_id = container.getMetaDataEntry("definition")
+ definition_metadata = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = definition_id)[0]
product = definition_id
for product_name, product_id_list in product_id_map.items():
@@ -223,45 +252,74 @@ class XmlMaterialProfile(InstanceContainer):
builder.start("machine")
builder.start("machine_identifier", {
- "manufacturer": container.getMetaDataEntry("machine_manufacturer", definition.getMetaDataEntry("manufacturer", "Unknown")),
+ "manufacturer": container.getMetaDataEntry("machine_manufacturer",
+ definition_metadata.get("manufacturer", "Unknown")),
"product": product
})
builder.end("machine_identifier")
for instance in container.findInstances():
- if self.getDefinition().getId() == "fdmprinter" and self.getInstance(instance.definition.key) and self.getProperty(instance.definition.key, "value") == instance.value:
+ if self.getMetaDataEntry("definition") == "fdmprinter" and self.getInstance(instance.definition.key) and self.getProperty(instance.definition.key, "value") == instance.value:
# If the settings match that of the base profile, just skip since we inherit the base profile.
continue
self._addSettingElement(builder, instance)
# Find all hotend sub-profiles corresponding to this material and machine and add them to this profile.
- for hotend_id, hotend in machine_nozzle_map[definition_id].items():
- variant_containers = registry.findInstanceContainersMetadata(id = hotend.getMetaDataEntry("variant"))
- if not variant_containers:
- continue
+ buildplate_dict = {}
+ for variant_name, variant_dict in machine_variant_map[definition_id].items():
+ variant_type = variant_dict["variant_node"].metadata["hardware_type"]
+ from cura.Machines.VariantManager import VariantType
+ variant_type = VariantType(variant_type)
+ if variant_type == VariantType.NOZZLE:
+ # The hotend identifier is not the containers name, but its "name".
+ builder.start("hotend", {"id": variant_name})
- # The hotend identifier is not the containers name, but its "name".
- builder.start("hotend", {"id": variant_containers[0]["name"]})
+ # Compatible is a special case, as it's added as a meta data entry (instead of an instance).
+ material_container = variant_dict["material_container"]
+ compatible = container.getMetaDataEntry("compatible")
+ if compatible is not None:
+ builder.start("setting", {"key": "hardware compatible"})
+ if compatible:
+ builder.data("yes")
+ else:
+ builder.data("no")
+ builder.end("setting")
- # Compatible is a special case, as it's added as a meta data entry (instead of an instance).
- compatible = hotend.getMetaDataEntry("compatible")
- if compatible is not None:
- builder.start("setting", {"key": "hardware compatible"})
- if compatible:
- builder.data("yes")
- else:
- builder.data("no")
- builder.end("setting")
+ for instance in material_container.findInstances():
+ if container.getInstance(instance.definition.key) and container.getProperty(instance.definition.key, "value") == instance.value:
+ # If the settings match that of the machine profile, just skip since we inherit the machine profile.
+ continue
- for instance in hotend.findInstances():
- if container.getInstance(instance.definition.key) and container.getProperty(instance.definition.key, "value") == instance.value:
- # If the settings match that of the machine profile, just skip since we inherit the machine profile.
- continue
+ self._addSettingElement(builder, instance)
- self._addSettingElement(builder, instance)
+ if material_container.getMetaDataEntry("buildplate_compatible") and not buildplate_dict:
+ buildplate_dict["buildplate_compatible"] = material_container.getMetaDataEntry("buildplate_compatible")
+ buildplate_dict["buildplate_recommended"] = material_container.getMetaDataEntry("buildplate_recommended")
+ buildplate_dict["material_container"] = material_container
- builder.end("hotend")
+ builder.end("hotend")
+
+ if buildplate_dict:
+ for variant_name in buildplate_dict["buildplate_compatible"]:
+ builder.start("buildplate", {"id": variant_name})
+
+ material_container = buildplate_dict["material_container"]
+ buildplate_compatible_dict = material_container.getMetaDataEntry("buildplate_compatible")
+ buildplate_recommended_dict = material_container.getMetaDataEntry("buildplate_recommended")
+ if buildplate_compatible_dict:
+ compatible = buildplate_compatible_dict[variant_name]
+ recommended = buildplate_recommended_dict[variant_name]
+
+ builder.start("setting", {"key": "hardware compatible"})
+ builder.data("yes" if compatible else "no")
+ builder.end("setting")
+
+ builder.start("setting", {"key": "hardware recommended"})
+ builder.data("yes" if recommended else "no")
+ builder.end("setting")
+
+ builder.end("buildplate")
builder.end("machine")
@@ -590,14 +648,11 @@ class XmlMaterialProfile(InstanceContainer):
if buildplate_id is None:
continue
- variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(
- id = buildplate_id)
- if not variant_containers:
- # It is not really properly defined what "ID" is so also search for variants by name.
- variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(
- definition = machine_id, name = buildplate_id)
-
- if not variant_containers:
+ from cura.Machines.VariantManager import VariantType
+ variant_manager = CuraApplication.getInstance().getVariantManager()
+ variant_node = variant_manager.getVariantNode(machine_id, buildplate_id,
+ variant_type = VariantType.BUILD_PLATE)
+ if not variant_node:
continue
buildplate_compatibility = machine_compatibility
@@ -618,16 +673,14 @@ class XmlMaterialProfile(InstanceContainer):
hotends = machine.iterfind("./um:hotend", self.__namespaces)
for hotend in hotends:
- hotend_id = hotend.get("id")
- if hotend_id is None:
+ # The "id" field for hotends in material profiles are actually
+ hotend_name = hotend.get("id")
+ if hotend_name is None:
continue
- variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = hotend_id)
- if not variant_containers:
- # It is not really properly defined what "ID" is so also search for variants by name.
- variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(definition = machine_id, name = hotend_id)
-
- if not variant_containers:
+ variant_manager = CuraApplication.getInstance().getVariantManager()
+ variant_node = variant_manager.getVariantNode(machine_id, hotend_name)
+ if not variant_node:
continue
hotend_compatibility = machine_compatibility
@@ -643,20 +696,20 @@ class XmlMaterialProfile(InstanceContainer):
else:
Logger.log("d", "Unsupported material setting %s", key)
- new_hotend_id = self.getId() + "_" + machine_id + "_" + hotend_id.replace(" ", "_")
+ new_hotend_specific_material_id = self.getId() + "_" + machine_id + "_" + hotend_name.replace(" ", "_")
# Same as machine compatibility, keep the derived material containers consistent with the parent material
- if ContainerRegistry.getInstance().isLoaded(new_hotend_id):
- new_hotend_material = ContainerRegistry.getInstance().findContainers(id = new_hotend_id)[0]
+ if ContainerRegistry.getInstance().isLoaded(new_hotend_specific_material_id):
+ new_hotend_material = ContainerRegistry.getInstance().findContainers(id = new_hotend_specific_material_id)[0]
is_new_material = False
else:
- new_hotend_material = XmlMaterialProfile(new_hotend_id)
+ new_hotend_material = XmlMaterialProfile(new_hotend_specific_material_id)
is_new_material = True
new_hotend_material.setMetaData(copy.deepcopy(self.getMetaData()))
- new_hotend_material.getMetaData()["id"] = new_hotend_id
+ new_hotend_material.getMetaData()["id"] = new_hotend_specific_material_id
new_hotend_material.getMetaData()["name"] = self.getName()
- new_hotend_material.getMetaData()["variant"] = variant_containers[0]["id"]
+ new_hotend_material.getMetaData()["variant_name"] = hotend_name
new_hotend_material.setDefinition(machine_id)
# Don't use setMetadata, as that overrides it for all materials with same base file
new_hotend_material.getMetaData()["compatible"] = hotend_compatibility
@@ -822,6 +875,8 @@ class XmlMaterialProfile(InstanceContainer):
continue
settings = buildplate.iterfind("./um:setting", cls.__namespaces)
+ buildplate_compatibility = True
+ buildplate_recommended = True
for entry in settings:
key = entry.get("key")
if key == "hardware compatible":
@@ -829,43 +884,34 @@ class XmlMaterialProfile(InstanceContainer):
elif key == "hardware recommended":
buildplate_recommended = cls._parseCompatibleValue(entry.text)
- buildplate_map["buildplate_compatible"][buildplate_id] = buildplate_map["buildplate_compatible"]
- buildplate_map["buildplate_recommended"][buildplate_id] = buildplate_map["buildplate_recommended"]
+ buildplate_map["buildplate_compatible"][buildplate_id] = buildplate_compatibility
+ buildplate_map["buildplate_recommended"][buildplate_id] = buildplate_recommended
for hotend in machine.iterfind("./um:hotend", cls.__namespaces):
- hotend_id = hotend.get("id")
- if hotend_id is None:
+ hotend_name = hotend.get("id")
+ if hotend_name is None:
continue
- variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = hotend_id)
- if not variant_containers:
- # It is not really properly defined what "ID" is so also search for variants by name.
- variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(definition = machine_id, name = hotend_id)
-
hotend_compatibility = machine_compatibility
for entry in hotend.iterfind("./um:setting", cls.__namespaces):
key = entry.get("key")
if key == "hardware compatible":
hotend_compatibility = cls._parseCompatibleValue(entry.text)
- new_hotend_id = container_id + "_" + machine_id + "_" + hotend_id.replace(" ", "_")
+ new_hotend_specific_material_id = container_id + "_" + machine_id + "_" + hotend_name.replace(" ", "_")
# Same as machine compatibility, keep the derived material containers consistent with the parent material
- found_materials = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = new_hotend_id)
+ found_materials = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = new_hotend_specific_material_id)
if found_materials:
new_hotend_material_metadata = found_materials[0]
else:
new_hotend_material_metadata = {}
new_hotend_material_metadata.update(base_metadata)
- if variant_containers:
- new_hotend_material_metadata["variant"] = variant_containers[0]["id"]
- else:
- new_hotend_material_metadata["variant"] = hotend_id
- _with_missing_variants.append(new_hotend_material_metadata)
+ new_hotend_material_metadata["variant_name"] = hotend_name
new_hotend_material_metadata["compatible"] = hotend_compatibility
new_hotend_material_metadata["machine_manufacturer"] = machine_manufacturer
- new_hotend_material_metadata["id"] = new_hotend_id
+ new_hotend_material_metadata["id"] = new_hotend_specific_material_id
new_hotend_material_metadata["definition"] = machine_id
if buildplate_map["buildplate_compatible"]:
new_hotend_material_metadata["buildplate_compatible"] = buildplate_map["buildplate_compatible"]
@@ -992,21 +1038,3 @@ def _indent(elem, level = 0):
# before the last }
def _tag_without_namespace(element):
return element.tag[element.tag.rfind("}") + 1:]
-
-#While loading XML profiles, some of these profiles don't know what variant
-#they belong to. We'd like to search by the machine ID and the variant's
-#name, but we don't know the variant's ID. Not all variants have been loaded
-#yet so we can't run a filter on the name and machine. The ID is unknown
-#so we can't lazily load the variant either. So we have to wait until all
-#the rest is loaded properly and then assign the correct variant to the
-#material files that were missing it.
-_with_missing_variants = []
-def _fillMissingVariants():
- registry = ContainerRegistry.getInstance()
- for variant_metadata in _with_missing_variants:
- variants = registry.findContainersMetadata(definition = variant_metadata["definition"], name = variant_metadata["variant"])
- if not variants:
- Logger.log("w", "Could not find variant for variant-specific material {material_id}.".format(material_id = variant_metadata["id"]))
- continue
- variant_metadata["variant"] = variants[0]["id"]
-ContainerRegistry.allMetadataLoaded.connect(_fillMissingVariants)
diff --git a/resources/definitions/anycubic_i3_mega.def.json b/resources/definitions/anycubic_i3_mega.def.json
index cba868900c..7106038193 100644
--- a/resources/definitions/anycubic_i3_mega.def.json
+++ b/resources/definitions/anycubic_i3_mega.def.json
@@ -12,7 +12,7 @@
"platform": "anycubic_i3_mega_platform.stl",
"has_materials": false,
"has_machine_quality": true,
- "preferred_quality": "*normal*"
+ "preferred_quality_type": "normal"
},
"overrides":
diff --git a/resources/definitions/builder_premium_large.def.json b/resources/definitions/builder_premium_large.def.json
index b496dc524e..deb1539a9a 100644
--- a/resources/definitions/builder_premium_large.def.json
+++ b/resources/definitions/builder_premium_large.def.json
@@ -12,16 +12,14 @@
"platform": "builder_premium_platform.stl",
"platform_offset": [-126, -36, 117],
"has_machine_quality": true,
- "preferred_quality": "*Normal*",
+ "preferred_quality_type": "normal",
"machine_extruder_trains":
{
"0": "builder_premium_large_rear",
"1": "builder_premium_large_front"
}
},
-
-
-
+
"overrides": {
"machine_name": { "default_value": "Builder Premium Large" },
"machine_heated_bed": { "default_value": true },
@@ -36,7 +34,7 @@
"default_material_print_temperature": { "value": "215" },
"material_print_temperature_layer_0": { "value": "material_print_temperature + 5" },
"material_standby_temperature": { "value": "material_print_temperature" },
-
+
"switch_extruder_retraction_speeds": {"default_value": 15 },
"switch_extruder_retraction_speed": {"default_value": 15 },
"switch_extruder_prime_speed": {"default_value": 15 },
@@ -58,9 +56,9 @@
"prime_tower_wipe_enabled": { "default_value": false },
"prime_tower_min_volume": { "default_value": 50 },
"dual_pre_wipe": { "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)" },
@@ -71,7 +69,7 @@
"acceleration_travel": { "value": "acceleration_print" },
"acceleration_wall": { "value": "math.ceil(acceleration_print * 1000 / 3000)" },
"acceleration_wall_0": { "value": "math.ceil(acceleration_wall * 1000 / 1000)" },
-
+
"cool_fan_full_at_height": { "value": "layer_height_0 + 2 * layer_height" },
"cool_min_layer_time": { "default_value": 10 },
@@ -84,9 +82,9 @@
"jerk_topbottom": { "value": "math.ceil(jerk_print * 5 / 25)" },
"jerk_wall": { "value": "math.ceil(jerk_print * 10 / 25)" },
"jerk_wall_0": { "value": "math.ceil(jerk_wall * 5 / 10)" },
-
+
"wall_thickness": { "value": "1.2" },
-
+
"retraction_amount": { "default_value": 3 },
"retraction_speed": { "default_value": 15 },
"retraction_retract_speed": { "default_value": 15 },
@@ -113,4 +111,4 @@
},
"machine_extruder_count": { "default_value": 2 }
}
-}
\ No newline at end of file
+}
diff --git a/resources/definitions/builder_premium_medium.def.json b/resources/definitions/builder_premium_medium.def.json
index fe8a039fc4..c28c7c5de6 100644
--- a/resources/definitions/builder_premium_medium.def.json
+++ b/resources/definitions/builder_premium_medium.def.json
@@ -12,16 +12,14 @@
"platform": "builder_premium_platform.stl",
"platform_offset": [-126, -36, 117],
"has_machine_quality": true,
- "preferred_quality": "*Normal*",
+ "preferred_quality_type": "normal",
"machine_extruder_trains":
{
"0": "builder_premium_medium_rear",
"1": "builder_premium_medium_front"
}
},
-
-
-
+
"overrides": {
"machine_name": { "default_value": "Builder Premium Medium" },
"machine_heated_bed": { "default_value": true },
@@ -36,7 +34,7 @@
"default_material_print_temperature": { "value": "215" },
"material_print_temperature_layer_0": { "value": "material_print_temperature + 5" },
"material_standby_temperature": { "value": "material_print_temperature" },
-
+
"switch_extruder_retraction_speeds": {"default_value": 15 },
"switch_extruder_retraction_speed": {"default_value": 15 },
"switch_extruder_prime_speed": {"default_value": 15 },
@@ -58,9 +56,9 @@
"prime_tower_wipe_enabled": { "default_value": false },
"prime_tower_min_volume": { "default_value": 50 },
"dual_pre_wipe": { "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)" },
@@ -71,7 +69,7 @@
"acceleration_travel": { "value": "acceleration_print" },
"acceleration_wall": { "value": "math.ceil(acceleration_print * 1000 / 3000)" },
"acceleration_wall_0": { "value": "math.ceil(acceleration_wall * 1000 / 1000)" },
-
+
"cool_fan_full_at_height": { "value": "layer_height_0 + 2 * layer_height" },
"cool_min_layer_time": { "default_value": 10 },
@@ -84,9 +82,9 @@
"jerk_topbottom": { "value": "math.ceil(jerk_print * 5 / 25)" },
"jerk_wall": { "value": "math.ceil(jerk_print * 10 / 25)" },
"jerk_wall_0": { "value": "math.ceil(jerk_wall * 5 / 10)" },
-
+
"wall_thickness": { "value": "1.2" },
-
+
"retraction_amount": { "default_value": 3 },
"retraction_speed": { "default_value": 15 },
"retraction_retract_speed": { "default_value": 15 },
@@ -113,4 +111,4 @@
},
"machine_extruder_count": { "default_value": 2 }
}
-}
\ No newline at end of file
+}
diff --git a/resources/definitions/builder_premium_small.def.json b/resources/definitions/builder_premium_small.def.json
index a1660b63cf..8e2fe44631 100644
--- a/resources/definitions/builder_premium_small.def.json
+++ b/resources/definitions/builder_premium_small.def.json
@@ -11,16 +11,14 @@
"platform": "builder_premium_platform.stl",
"platform_offset": [-126, -36, 117],
"has_machine_quality": true,
- "preferred_quality": "*Normal*",
+ "preferred_quality_type": "normal",
"machine_extruder_trains":
{
"0": "builder_premium_small_rear",
"1": "builder_premium_small_front"
}
},
-
-
-
+
"overrides": {
"machine_name": { "default_value": "Builder Premium Small" },
"machine_heated_bed": { "default_value": true },
@@ -35,7 +33,7 @@
"default_material_print_temperature": { "value": "215" },
"material_print_temperature_layer_0": { "value": "material_print_temperature + 5" },
"material_standby_temperature": { "value": "material_print_temperature" },
-
+
"switch_extruder_retraction_speeds": {"default_value": 15 },
"switch_extruder_retraction_speed": {"default_value": 15 },
"switch_extruder_prime_speed": {"default_value": 15 },
@@ -57,9 +55,9 @@
"prime_tower_wipe_enabled": { "default_value": false },
"prime_tower_min_volume": { "default_value": 50 },
"dual_pre_wipe": { "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)" },
@@ -70,7 +68,7 @@
"acceleration_travel": { "value": "acceleration_print" },
"acceleration_wall": { "value": "math.ceil(acceleration_print * 1000 / 3000)" },
"acceleration_wall_0": { "value": "math.ceil(acceleration_wall * 1000 / 1000)" },
-
+
"cool_fan_full_at_height": { "value": "layer_height_0 + 2 * layer_height" },
"cool_min_layer_time": { "default_value": 10 },
@@ -83,9 +81,9 @@
"jerk_topbottom": { "value": "math.ceil(jerk_print * 5 / 25)" },
"jerk_wall": { "value": "math.ceil(jerk_print * 10 / 25)" },
"jerk_wall_0": { "value": "math.ceil(jerk_wall * 5 / 10)" },
-
+
"wall_thickness": { "value": "1.2" },
-
+
"retraction_amount": { "default_value": 3 },
"retraction_speed": { "default_value": 15 },
"retraction_retract_speed": { "default_value": 15 },
@@ -112,4 +110,4 @@
},
"machine_extruder_count": { "default_value": 2 }
}
-}
\ No newline at end of file
+}
diff --git a/resources/definitions/cartesio.def.json b/resources/definitions/cartesio.def.json
index 44f3153015..5ca891d6c5 100644
--- a/resources/definitions/cartesio.def.json
+++ b/resources/definitions/cartesio.def.json
@@ -5,7 +5,7 @@
"metadata": {
"visible": true,
"author": "Scheepers",
- "manufacturer": "Cartesio bv",
+ "manufacturer": "MaukCC",
"file_formats": "text/x-gcode",
"has_machine_quality": true,
@@ -14,10 +14,10 @@
"has_variant_materials": true,
"has_variants": true,
- "variants_name": "Nozzle size",
- "preferred_variant": "*0.8*",
- "preferred_material": "*pla*",
- "preferred_quality": "*normal*",
+ "variants_name": "Tool",
+ "preferred_variant_name": "0.8 mm",
+ "preferred_material": "generic_pla",
+ "preferred_quality_type": "normal",
"machine_extruder_trains":
{
@@ -44,7 +44,7 @@
"machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
"material_print_temp_wait": { "default_value": false },
"material_bed_temp_wait": { "default_value": false },
- "prime_tower_enable": { "default_value": true },
+ "prime_tower_enable": { "default_value": false },
"prime_tower_wall_thickness": { "resolve": 0.7 },
"prime_tower_size": { "value": 24.0 },
"prime_tower_position_x": { "value": 125 },
@@ -55,15 +55,16 @@
[[215, 135], [-215, 135], [-215, 75], [215, 75]]
]},
"machine_start_gcode": {
- "default_value": "\nM92 E159 ;2288 for V5 extruder\n\nM140 S{material_bed_temperature_layer_0}\nM104 S120 T1\nM104 S120 T2\nM104 S120 T3\n\nG21\nG90\nM42 S255 P13 ;chamber lights\nM42 S255 P12 ;fume extraction\nM204 S300 ;default acceleration\nM205 X10 ;default jerk\n\nM117 Homing Y ......\nG28 Y\nM117 Homing X ......\nG28 X\nM117 Homing Z ......\nG28 Z F100\nG1 Z10 F600\nG1 X70 Y20 F9000;go to wipe point\n\nM190 S{material_bed_temperature_layer_0}\n\nM117 Heating for 50 sec.\nG4 S20\nM117 Heating for 30 sec.\nG4 S20\nM117 Heating for 10 sec.\nM300 S1200 P1000\nG4 S9\n\nM117 purging nozzle....\nT0\nG92 E0;set E\nG1 E10 F100\nG92 E0\nG1 E-1 F600\n\nM117 wiping nozzle....\nG1 X1 Y24 F3000\nG1 X70 F9000\nG1 Z10 F900\n\nM104 S21 T1\nM104 S21 T2\nM104 S21 T3\n\nM117 Printing .....\n"
+ "default_value": "\nM92 E159 ;2288 for V5 extruder\n\nM140 S{material_bed_temperature_layer_0}\nM104 T1 S120\nM104 T2 S120\nM104 T3 S120\n\nG21\nG90\nM42 S255 P13 ;chamber lights\nM42 S255 P12 ;fume extraction\nM204 S300 ;default acceleration\nM205 X10 ;default jerk\n\nM117 Homing Y ......\nG28 Y\nM117 Homing X ......\nG28 X\nM117 Homing Z ......\nG28 Z F100\nG1 Z10 F600\nG1 X70 Y20 F9000;go to wipe point\n\nM190 S{material_bed_temperature_layer_0}\n\nM117 Heating for 50 sec.\nG4 S20\nM117 Heating for 30 sec.\nG4 S20\nM117 Heating for 10 sec.\nM300 S1200 P1000\nG4 S9\n\nM117 purging nozzle....\nT0\nG92 E0;set E\nG1 E10 F100\nG92 E0\nG1 E-1 F600\n\nM117 wiping nozzle....\nG1 X1 Y24 F3000\nG1 X70 F9000\nG1 Z10 F900\n\nM104 T1 S21\nM104 T2 S21\nM104 T3 S21\n\nM117 Printing .....\n"
},
"machine_end_gcode": {
- "default_value": "; -- END GCODE --\nM117 cooling down....\nM106 S255\nM140 S5\nM104 S5 T0\nM104 S5 T1\nM104 S5 T2\nM104 S5 T3\n\nG91\nG1 Z1 F900\nG90\n\nG1 X20.0 Y260.0 F6000\nG4 S7\nM84\nG4 S90\nM107\nM42 P12 S0\nM42 P13 S0\nM84\nT0\nM117 Finished.\n; -- end of GCODE --"
+ "default_value": "; -- END GCODE --\nM117 cooling down....\nM106 S255\nM140 S5\nM104 T0 S5\nM104 T1 S5\nM104 T2 S5\nM104 T3 S5\n\nG91\nG1 Z1 F900\nG90\n\nG1 X20.0 Y260.0 F6000\nG4 S7\nM84\nG4 S90\nM107\nM42 P12 S0\nM42 P13 S0\nM84\nT0\nM117 Finished.\n; -- end of GCODE --"
},
"layer_height": { "maximum_value": "(0.8 * min(extruderValues('machine_nozzle_size')))" },
"layer_height_0": { "maximum_value": "(0.8 * min(extruderValues('machine_nozzle_size')))" },
"retraction_extra_prime_amount": { "minimum_value_warning": "-2.0" },
"optimize_wall_printing_order": { "default_value": true },
+ "material_initial_print_temperature": {"maximum_value_warning": "material_print_temperature + 15" },
"machine_nozzle_heat_up_speed": {"default_value": 20},
"machine_nozzle_cool_down_speed": {"default_value": 20},
"machine_min_cool_heat_time_window": {"default_value": 5}
diff --git a/resources/definitions/creality_cr10.def.json b/resources/definitions/creality_cr10.def.json
index 7a58adcd4d..eb0b8c7306 100644
--- a/resources/definitions/creality_cr10.def.json
+++ b/resources/definitions/creality_cr10.def.json
@@ -7,7 +7,7 @@
"author": "Michael Wildermuth",
"manufacturer": "Creality3D",
"file_formats": "text/x-gcode",
- "preferred_quality": "*Draft*"
+ "preferred_quality_type": "draft"
},
"overrides": {
"machine_width": {
diff --git a/resources/definitions/dagoma_discoeasy200.def.json b/resources/definitions/dagoma_discoeasy200.def.json
index 9bcc2402f2..4f0fddc41d 100644
--- a/resources/definitions/dagoma_discoeasy200.def.json
+++ b/resources/definitions/dagoma_discoeasy200.def.json
@@ -7,7 +7,6 @@
"author": "Dagoma",
"manufacturer": "Dagoma",
"file_formats": "text/x-gcode",
- "icon": "icon_discoeasy200.png",
"platform": "discoeasy200.stl",
"platform_offset": [ 105, -59, 280]
},
@@ -39,13 +38,25 @@
"default_value": 10
},
"machine_start_gcode": {
- "default_value": ";Gcode by Cura\nG90 ;absolute positioning\nM106 S250 ;fan on for the palpeur\nG28 X Y\nG1 X50\nM109 S180\nG28\nM104 S{material_print_temperature_layer_0}\n;Activation palpeur\n;bloc palpeur\nG29 ;Auto level\nM107 ;start with the fan off\nG1 X100 Y20 F3000\nG1 Z0.5\nM109 S{material_print_temperature_layer_0}\nM82 ;set extruder to absolute mode\nG92 E0 ;zero the extruded length\nG1 F200 E10 ;extrude 10mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 Z3\nG1 F6000"
+ "default_value": ";Gcode by Cura\nG90\nM106 S250\nG28 X Y\nG1 X50\nM109 S180\nG28\nM104 S{material_print_temperature_layer_0}\nG29\nM107\nG1 X100 Y20 F3000\nG1 Z0.5\nM109 S{material_print_temperature_layer_0}\nM82\nG92 E0\nG1 F200 E10\nG92 E0\nG1 Z3\nG1 F6000\n"
},
"machine_end_gcode": {
- "default_value": "M104 S0\nM106 S255 ;start fan full power\nM140 S0 ;heated bed heater off (if you have it)\n;Home machine\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+3 F3000 ;move Z up a bit and retract filament even more\nG90\nG28 X Y\n;Ventilation forcee\nM107 ;stop fan\n;Shut down motor\nM84 ;shut down motors"
+ "default_value": "\nM104 S0\nM106 S255\nM140 S0\nG91\nG1 E-1 F300\nG1 Z+3 F3000\nG90\nG28 X Y\nM107\nM84\n"
},
"material_diameter": {
"default_value": 1.75
+ },
+ "speed_print": {
+ "default_value": 60
+ },
+ "speed_travel": {
+ "value": "100"
+ },
+ "retraction_amount": {
+ "default_value": 3.5
+ },
+ "retraction_speed": {
+ "default_value": 50
}
}
}
diff --git a/resources/definitions/dagoma_neva.def.json b/resources/definitions/dagoma_neva.def.json
new file mode 100644
index 0000000000..21a557ac22
--- /dev/null
+++ b/resources/definitions/dagoma_neva.def.json
@@ -0,0 +1,69 @@
+{
+ "id": "Dagoma_neva",
+ "name": "Dagoma NEVA",
+ "version": 2,
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "Dagoma",
+ "manufacturer": "Dagoma",
+ "file_formats": "text/x-gcode",
+ "platform": "neva.stl",
+ "platform_offset": [ 0, 0, 0]
+ },
+ "overrides": {
+ "machine_width": {
+ "default_value": 195.55
+ },
+ "machine_height": {
+ "default_value": 205
+ },
+ "machine_depth": {
+ "default_value": 195.55
+ },
+ "machine_center_is_zero": {
+ "default_value": true
+ },
+ "machine_nozzle_size": {
+ "default_value": 0.4
+ },
+ "machine_head_with_fans_polygon": {
+ "default_value": [
+ [17, 40],
+ [17, -70],
+ [-17, -70],
+ [17, 40]
+ ]
+ },
+ "gantry_height": {
+ "default_value": 0
+ },
+ "machine_shape": {
+ "default_value": "elliptic"
+ },
+ "machine_gcode_flavor": {
+ "default_value": "RepRap (RepRap)"
+ },
+ "machine_start_gcode": {
+ "default_value": ";Gcode by Cura\nG90\nG28\nM109 S100\nG29\nM104 S{material_print_temperature_layer_0}\nG0 X0 Y-85\nG0 Z0.26\nM109 S{material_print_temperature_layer_0}\nM82\nG92 E0\nG1 F200 E6\nG92 E0\nG1 F200 E-3.5\nG0 Z0.15\nG0 X10\nG0 Z3\nG1 F6000\n"
+ },
+ "machine_end_gcode": {
+ "default_value": "\nM104 S0\nM106 S255\nM140 S0\nG91\nG1 E-1 F300\nG1 Z+3 E-2 F9000\nG90\nG28\n"
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ },
+ "speed_print": {
+ "default_value": 40
+ },
+ "speed_travel": {
+ "default_value": 120
+ },
+ "retraction_amount": {
+ "default_value": 3.8
+ },
+ "retraction_speed": {
+ "default_value": 60
+ }
+ }
+}
diff --git a/resources/definitions/fabtotum.def.json b/resources/definitions/fabtotum.def.json
index 87ce11a35c..d66de07c4a 100644
--- a/resources/definitions/fabtotum.def.json
+++ b/resources/definitions/fabtotum.def.json
@@ -13,18 +13,18 @@
"has_machine_quality": true,
"has_variants": true,
"variants_name": "Head",
- "preferred_variant": "*lite04*",
- "preferred_material": "*fabtotum_pla*",
+ "preferred_variant_name": "Lite 0.4 mm",
+ "preferred_material": "fabtotum_pla",
"supports_usb_connection": false
},
"overrides": {
"machine_name": { "default_value": "FABtotum Personal Fabricator" },
"machine_start_gcode": {
- "default_value": ";Layer height: {layer_height}\n;Walls: {wall_thickness}\n;Fill: {infill_sparse_density}\n;Top\\Bottom Thickness: {top_bottom_thickness}\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nG4 S1 ;1 millisecond pause to buffer the bep bep \nM728 ;FAB bep bep (start the print, go check the oozing and skirt lines adesion) \nG4 S1 ;1 second pause to reach the printer (run fast)\nG92 E0 ;zero the extruded length \nG1 F200 E35 ;slowly extrude 35mm of filament to clean the nozzle and build up extrusion pressure \nG92 E0 ;zero the extruded length again \nG1 F{speed_travel} ;Set travel speed \n;print"
+ "default_value": ";Layer height: {layer_height}\n;Walls: {wall_thickness}\n;Fill: {infill_sparse_density}\n;Top\\Bottom Thickness: {top_bottom_thickness}\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nG4 S1 ;1 millisecond pause to buffer the bep bep \nM300 S2 ;FAB bep bep (start the print, go check the oozing and skirt lines adesion) \nG4 S1 ;1 second pause to reach the printer (run fast)\nG92 E0 ;zero the extruded length \nG1 F200 E35 ;slowly extrude 35mm of filament to clean the nozzle and build up extrusion pressure \nG92 E0 ;zero the extruded length again \n;print"
},
"machine_end_gcode": {
- "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-3 X+5 Y+5 F5000 ;move Z up a bit and retract filament even more\n;end of the print\nM84 ;steppers off\nG90 ;absolute positioning\nM728 ;FAB bep bep (end print)"
+ "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-3 X+5 Y+5 F5000 ;move Z up a bit and retract filament even more\n;end of the print\nM84 ;steppers off\nG90 ;absolute positioning\nM300 S2 ;FAB bep bep (end print)"
},
"gantry_height": { "default_value": 55 },
"machine_width": { "default_value": 214 },
diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json
index bdce508df0..6d4688bb52 100644
--- a/resources/definitions/fdmprinter.def.json
+++ b/resources/definitions/fdmprinter.def.json
@@ -11,8 +11,8 @@
"file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g",
"visible": false,
"has_materials": true,
- "preferred_material": "*generic_pla*",
- "preferred_quality": "*normal*",
+ "preferred_material": "generic_pla",
+ "preferred_quality_type": "normal",
"machine_extruder_trains":
{
"0": "fdmextruder"
@@ -51,8 +51,8 @@
},
"machine_start_gcode":
{
- "label": "Start GCode",
- "description": "Gcode commands to be executed at the very start - separated by \\n.",
+ "label": "Start G-code",
+ "description": "G-code commands to be executed at the very start - separated by \\n.",
"default_value": "G28 ;Home\nG1 Z15.0 F6000 ;Move the platform down 15mm\n;Prime the extruder\nG92 E0\nG1 F200 E3\nG92 E0",
"type": "str",
"settable_per_mesh": false,
@@ -61,8 +61,8 @@
},
"machine_end_gcode":
{
- "label": "End GCode",
- "description": "Gcode commands to be executed at the very end - separated by \\n.",
+ "label": "End G-code",
+ "description": "G-code commands to be executed at the very end - separated by \\n.",
"default_value": "M104 S0\nM140 S0\n;Retract the filament\nG92 E1\nG1 E-1 F300\nG28 X0 Y0\nM84",
"type": "str",
"settable_per_mesh": false,
@@ -163,7 +163,7 @@
"options":
{
"glass": "Glass",
- "aluminium": "Aluminium"
+ "aluminum": "Aluminum"
},
"settable_per_mesh": false,
"settable_per_extruder": false,
@@ -211,6 +211,18 @@
"settable_per_extruder": false,
"settable_per_meshgroup": false
},
+ "extruders_enabled_count":
+ {
+ "label": "Number of Extruders that are enabled",
+ "description": "Number of extruder trains that are enabled; automatically set in software",
+ "default_value": "machine_extruder_count",
+ "minimum_value": "1",
+ "maximum_value": "16",
+ "type": "int",
+ "settable_per_mesh": false,
+ "settable_per_extruder": false,
+ "settable_per_meshgroup": false
+ },
"machine_nozzle_tip_outer_diameter":
{
"label": "Outer nozzle diameter",
@@ -312,8 +324,8 @@
},
"machine_gcode_flavor":
{
- "label": "Gcode flavour",
- "description": "The type of gcode to be generated.",
+ "label": "G-code flavour",
+ "description": "The type of g-code to be generated.",
"type": "enum",
"options":
{
@@ -887,7 +899,7 @@
"settable_per_extruder": false,
"settable_per_meshgroup": true,
"settable_globally": true,
- "enabled": "machine_extruder_count > 1",
+ "enabled": "extruders_enabled_count > 1",
"children": {
"wall_0_extruder_nr":
{
@@ -900,7 +912,7 @@
"settable_per_extruder": false,
"settable_per_meshgroup": true,
"settable_globally": true,
- "enabled": "machine_extruder_count > 1"
+ "enabled": "extruders_enabled_count > 1"
},
"wall_x_extruder_nr":
{
@@ -913,7 +925,7 @@
"settable_per_extruder": false,
"settable_per_meshgroup": true,
"settable_globally": true,
- "enabled": "machine_extruder_count > 1"
+ "enabled": "extruders_enabled_count > 1"
}
}
},
@@ -970,7 +982,7 @@
"settable_per_extruder": false,
"settable_per_meshgroup": true,
"settable_globally": true,
- "enabled": "machine_extruder_count > 1 and max(extruderValues('roofing_layer_count')) > 0 and max(extruderValues('top_layers')) > 0"
+ "enabled": "extruders_enabled_count > 1 and max(extruderValues('roofing_layer_count')) > 0 and max(extruderValues('top_layers')) > 0"
},
"roofing_layer_count":
{
@@ -995,7 +1007,7 @@
"settable_per_extruder": false,
"settable_per_meshgroup": true,
"settable_globally": true,
- "enabled": "machine_extruder_count > 1"
+ "enabled": "extruders_enabled_count > 1"
},
"top_bottom_thickness":
{
@@ -1465,7 +1477,7 @@
"settable_per_extruder": false,
"settable_per_meshgroup": true,
"settable_globally": true,
- "enabled": "machine_extruder_count > 1"
+ "enabled": "extruders_enabled_count > 1"
},
"infill_sparse_density":
{
@@ -1527,8 +1539,10 @@
"label": "Connect Infill Lines",
"description": "Connect the ends where the infill pattern meets the inner wall using a line which follows the shape of the inner wall. Enabling this setting can make the infill adhere to the walls better and reduce the effects of infill on the quality of vertical surfaces. Disabling this setting reduces the amount of material used.",
"type": "bool",
- "default_value": true,
- "enabled": "infill_pattern == 'cross' or infill_pattern == 'cross_3d'",
+ "default_value": false,
+ "value": "infill_pattern == 'cross' or infill_pattern == 'cross_3d'",
+ "enabled": "infill_pattern == 'grid' or infill_pattern == 'triangles' or infill_pattern == 'trihexagon' or infill_pattern == 'cubic' or infill_pattern == 'tetrahedral' or infill_pattern == 'quarter_cubic' or infill_pattern == 'cross' or infill_pattern == 'cross_3d'",
+ "limit_to_extruder": "infill_extruder_nr",
"settable_per_mesh": true
},
"infill_angles":
@@ -1914,7 +1928,7 @@
"minimum_value": "0",
"maximum_value_warning": "10.0",
"maximum_value": "machine_nozzle_heat_up_speed",
- "enabled": "material_flow_dependent_temperature or (machine_extruder_count > 1 and material_final_print_temperature != material_print_temperature)",
+ "enabled": "material_flow_dependent_temperature or (extruders_enabled_count > 1 and material_final_print_temperature != material_print_temperature)",
"settable_per_mesh": false,
"settable_per_extruder": true
},
@@ -2135,6 +2149,7 @@
"default_value": 1.5,
"value": "line_width * 2",
"minimum_value": "0",
+ "minimum_value_warning": "line_width * 1.5",
"maximum_value_warning": "10",
"enabled": "retraction_enable",
"settable_per_mesh": false,
@@ -2176,7 +2191,7 @@
"minimum_value": "-273.15",
"minimum_value_warning": "0",
"maximum_value_warning": "260",
- "enabled": "machine_extruder_count > 1 and machine_nozzle_temp_enabled",
+ "enabled": "extruders_enabled_count > 1 and machine_nozzle_temp_enabled",
"settable_per_mesh": false,
"settable_per_extruder": true
},
@@ -3278,7 +3293,7 @@
"description": "After the machine switched from one extruder to the other, the build plate is lowered to create clearance between the nozzle and the print. This prevents the nozzle from leaving oozed material on the outside of a print.",
"type": "bool",
"default_value": true,
- "enabled": "retraction_hop_enabled and machine_extruder_count > 1",
+ "enabled": "retraction_hop_enabled and extruders_enabled_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": true
}
@@ -3456,7 +3471,8 @@
"description": "The extruder train to use for printing the support. This is used in multi-extrusion.",
"type": "extruder",
"default_value": "0",
- "enabled": "(support_enable or support_tree_enable) and machine_extruder_count > 1",
+ "value": "-1",
+ "enabled": "(support_enable or support_tree_enable) and extruders_enabled_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": false,
"children": {
@@ -3467,7 +3483,7 @@
"type": "extruder",
"default_value": "0",
"value": "support_extruder_nr",
- "enabled": "(support_enable or support_tree_enable) and machine_extruder_count > 1",
+ "enabled": "(support_enable or support_tree_enable) and extruders_enabled_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": false
},
@@ -3478,7 +3494,7 @@
"type": "extruder",
"default_value": "0",
"value": "support_extruder_nr",
- "enabled": "(support_enable or support_tree_enable) and machine_extruder_count > 1",
+ "enabled": "(support_enable or support_tree_enable) and extruders_enabled_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": false
},
@@ -3489,7 +3505,7 @@
"type": "extruder",
"default_value": "0",
"value": "support_extruder_nr",
- "enabled": "(support_enable or support_tree_enable) and machine_extruder_count > 1",
+ "enabled": "(support_enable or support_tree_enable) and extruders_enabled_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": false,
"children":
@@ -3501,7 +3517,7 @@
"type": "extruder",
"default_value": "0",
"value": "support_interface_extruder_nr",
- "enabled": "(support_enable or support_tree_enable) and machine_extruder_count > 1",
+ "enabled": "(support_enable or support_tree_enable) and extruders_enabled_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": false
},
@@ -3512,7 +3528,7 @@
"type": "extruder",
"default_value": "0",
"value": "support_interface_extruder_nr",
- "enabled": "(support_enable or support_tree_enable) and machine_extruder_count > 1",
+ "enabled": "(support_enable or support_tree_enable) and extruders_enabled_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": false
}
@@ -3571,6 +3587,18 @@
"settable_per_mesh": false,
"settable_per_extruder": true
},
+ "zig_zaggify_support":
+ {
+ "label": "Connect Support Lines",
+ "description": "Connect the ends of the support lines together. Enabling this setting can make your support more sturdy and reduce underextrusion, but it will cost more material.",
+ "type": "bool",
+ "default_value": false,
+ "value": "support_pattern == 'cross'",
+ "enabled": "support_pattern == 'grid' or support_pattern == 'triangles' or support_pattern == 'cross'",
+ "limit_to_extruder": "support_infill_extruder_nr",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
"support_connect_zigzags":
{
"label": "Connect Support ZigZags",
@@ -4170,7 +4198,8 @@
"description": "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion.",
"type": "extruder",
"default_value": "0",
- "enabled": "machine_extruder_count > 1 and resolveOrValue('adhesion_type') != 'none'",
+ "value": "-1",
+ "enabled": "extruders_enabled_count > 1 and resolveOrValue('adhesion_type') != 'none'",
"settable_per_mesh": false,
"settable_per_extruder": false
},
@@ -4741,12 +4770,23 @@
"label": "Enable Prime Tower",
"description": "Print a tower next to the print which serves to prime the material after each nozzle switch.",
"type": "bool",
- "enabled": "machine_extruder_count > 1",
+ "enabled": "extruders_enabled_count > 1",
"default_value": false,
"resolve": "any(extruderValues('prime_tower_enable'))",
"settable_per_mesh": false,
"settable_per_extruder": false
},
+ "prime_tower_circular":
+ {
+ "label": "Circular Prime Tower",
+ "description": "Make the prime tower as a circular shape.",
+ "type": "bool",
+ "enabled": "resolveOrValue('prime_tower_enable')",
+ "default_value": true,
+ "resolve": "any(extruderValues('prime_tower_circular'))",
+ "settable_per_mesh": false,
+ "settable_per_extruder": false
+ },
"prime_tower_size":
{
"label": "Prime Tower Size",
@@ -4770,8 +4810,9 @@
"unit": "mm³",
"type": "float",
"default_value": 10,
+ "value": "8.48 if prime_tower_circular else 10",
"minimum_value": "0",
- "maximum_value_warning": "resolveOrValue('prime_tower_size') ** 2 * resolveOrValue('layer_height')",
+ "maximum_value_warning": "round((resolveOrValue('prime_tower_size') * 0.5) ** 2 * 3.14159 * resolveOrValue('layer_height'), 2) if prime_tower_circular else resolveOrValue('prime_tower_size') ** 2 * resolveOrValue('layer_height')",
"enabled": "resolveOrValue('prime_tower_enable')",
"settable_per_mesh": false,
"settable_per_extruder": true,
@@ -4784,7 +4825,7 @@
"unit": "mm",
"type": "float",
"default_value": 2,
- "value": "round(max(2 * prime_tower_line_width, 0.5 * (prime_tower_size - math.sqrt(max(0, prime_tower_size ** 2 - prime_tower_min_volume / layer_height)))), 3)",
+ "value": "round(max(2 * prime_tower_line_width, (0.5 * (prime_tower_size - math.sqrt(max(0, prime_tower_size ** 2 - 4 * prime_tower_min_volume / (3.14159 * layer_height))))) if prime_tower_circular else (0.5 * (prime_tower_size - math.sqrt(max(0, prime_tower_size ** 2 - prime_tower_min_volume / layer_height))))), 3)",
"resolve": "max(extruderValues('prime_tower_wall_thickness'))",
"minimum_value": "0.001",
"minimum_value_warning": "2 * min(extruderValues('prime_tower_line_width')) - 0.0001",
@@ -4877,7 +4918,7 @@
"description": "Enable exterior ooze shield. This will create a shell around the model which is likely to wipe a second nozzle if it's at the same height as the first nozzle.",
"type": "bool",
"resolve": "any(extruderValues('ooze_shield_enabled'))",
- "enabled": "machine_extruder_count > 1",
+ "enabled": "extruders_enabled_count > 1",
"default_value": false,
"settable_per_mesh": false,
"settable_per_extruder": false
@@ -4947,7 +4988,7 @@
"meshfix_keep_open_polygons":
{
"label": "Keep Disconnected Faces",
- "description": "Normally Cura tries to stitch up small holes in the mesh and remove parts of a layer with big holes. Enabling this option keeps those parts which cannot be stitched. This option should be used as a last resort option when everything else fails to produce proper GCode.",
+ "description": "Normally Cura tries to stitch up small holes in the mesh and remove parts of a layer with big holes. Enabling this option keeps those parts which cannot be stitched. This option should be used as a last resort option when everything else fails to produce proper g-code.",
"type": "bool",
"default_value": false,
"settable_per_mesh": true
@@ -4970,7 +5011,7 @@
"description": "Remove areas where multiple meshes are overlapping with each other. This may be used if merged dual material objects overlap with each other.",
"type": "bool",
"default_value": true,
- "value": "machine_extruder_count > 1",
+ "value": "extruders_enabled_count > 1",
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": true
@@ -5017,7 +5058,7 @@
"one_at_a_time": "One at a Time"
},
"default_value": "all_at_once",
- "enabled": "machine_extruder_count == 1",
+ "enabled": "extruders_enabled_count == 1",
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": false
@@ -5162,7 +5203,7 @@
"relative_extrusion":
{
"label": "Relative Extrusion",
- "description": "Use relative extrusion rather than absolute extrusion. Using relative E-steps makes for easier post-processing of the Gcode. However, it's not supported by all printers and it may produce very slight deviations in the amount of deposited material compared to absolute E-steps. Irrespective of this setting, the extrusion mode will always be set to absolute before any Gcode script is output.",
+ "description": "Use relative extrusion rather than absolute extrusion. Using relative E-steps makes for easier post-processing of the g-code. However, it's not supported by all printers and it may produce very slight deviations in the amount of deposited material compared to absolute E-steps. Irrespective of this setting, the extrusion mode will always be set to absolute before any g-code script is output.",
"type": "bool",
"default_value": false,
"value": "machine_gcode_flavor==\"RepRap (RepRap)\"",
@@ -6202,6 +6243,258 @@
"settable_per_mesh": false,
"settable_per_extruder": false,
"settable_per_meshgroup": false
+ },
+ "bridge_settings_enabled":
+ {
+ "label": "Enable Bridge Settings",
+ "description": "Detect bridges and modify print speed, flow and fan settings while bridges are printed.",
+ "type": "bool",
+ "default_value": false,
+ "settable_per_mesh": true,
+ "settable_per_extruder": false,
+ "settable_per_meshgroup": false
+ },
+ "bridge_wall_min_length":
+ {
+ "label": "Minimum Bridge Wall Length",
+ "description": "Unsupported walls shorter than this will be printed using the normal wall settings. Longer unsupported walls will be printed using the bridge wall settings.",
+ "unit": "mm",
+ "type": "float",
+ "minimum_value": "0",
+ "default_value": 5,
+ "enabled": "bridge_settings_enabled",
+ "settable_per_mesh": false,
+ "settable_per_extruder": true
+ },
+ "bridge_skin_support_threshold":
+ {
+ "label": "Bridge Skin Support Threshold",
+ "description": "If a skin region is supported for less than this percentage of its area, print it using the bridge settings. Otherwise it is printed using the normal skin settings.",
+ "unit": "%",
+ "default_value": 50,
+ "type": "float",
+ "minimum_value": "0",
+ "maximum_value": "100",
+ "enabled": "bridge_settings_enabled",
+ "settable_per_mesh": true
+ },
+ "bridge_wall_max_overhang":
+ {
+ "label": "Bridge Wall Max Overhang",
+ "description": "The maximum allowed width of the region of air below a wall line before the wall is printed using bridge settings. Expressed as a percentage of the wall line width. When the air gap is wider than this, the wall line is printed using the bridge settings. Otherwise, the wall line is printed using the normal settings. The lower the value, the more likely it is that overhung wall lines will be printed using bridge settings.",
+ "unit": "%",
+ "default_value": 100,
+ "type": "float",
+ "minimum_value": "0",
+ "maximum_value": "100",
+ "enabled": "bridge_settings_enabled",
+ "settable_per_mesh": true
+ },
+ "bridge_wall_coast":
+ {
+ "label": "Bridge Wall Coasting",
+ "description": "This controls the distance the extruder should coast immediately before a bridge wall begins. Coasting before the bridge starts can reduce the pressure in the nozzle and may produce a flatter bridge.",
+ "unit": "%",
+ "default_value": 100,
+ "type": "float",
+ "minimum_value": "0",
+ "maximum_value": "500",
+ "enabled": "bridge_settings_enabled",
+ "settable_per_mesh": false
+ },
+ "bridge_wall_speed":
+ {
+ "label": "Bridge Wall Speed",
+ "description": "The speed at which the bridge walls are printed.",
+ "unit": "mm/s",
+ "type": "float",
+ "minimum_value": "cool_min_speed",
+ "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
+ "maximum_value_warning": "300",
+ "default_value": 15,
+ "value": "max(cool_min_speed, speed_wall_0 / 2)",
+ "enabled": "bridge_settings_enabled",
+ "settable_per_mesh": true
+ },
+ "bridge_wall_material_flow":
+ {
+ "label": "Bridge Wall Flow",
+ "description": "When printing bridge walls, the amount of material extruded is multiplied by this value.",
+ "unit": "%",
+ "default_value": 50,
+ "type": "float",
+ "minimum_value": "5",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "enabled": "bridge_settings_enabled",
+ "settable_per_mesh": true
+ },
+ "bridge_skin_speed":
+ {
+ "label": "Bridge Skin Speed",
+ "description": "The speed at which bridge skin regions are printed.",
+ "unit": "mm/s",
+ "type": "float",
+ "minimum_value": "cool_min_speed",
+ "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
+ "maximum_value_warning": "300",
+ "default_value": 15,
+ "value": "max(cool_min_speed, speed_topbottom / 2)",
+ "enabled": "bridge_settings_enabled",
+ "settable_per_mesh": true
+ },
+ "bridge_skin_material_flow":
+ {
+ "label": "Bridge Skin Flow",
+ "description": "When printing bridge skin regions, the amount of material extruded is multiplied by this value.",
+ "unit": "%",
+ "default_value": 60,
+ "type": "float",
+ "minimum_value": "5",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "enabled": "bridge_settings_enabled",
+ "settable_per_mesh": true
+ },
+ "bridge_skin_density":
+ {
+ "label": "Bridge Skin Density",
+ "description": "The density of the bridge skin layer. Values less than 100 will increase the gaps between the skin lines.",
+ "unit": "%",
+ "default_value": 100,
+ "type": "float",
+ "minimum_value": "5",
+ "maximum_value": "100",
+ "minimum_value_warning": "20",
+ "enabled": "bridge_settings_enabled",
+ "settable_per_mesh": true
+ },
+ "bridge_fan_speed":
+ {
+ "label": "Bridge Fan Speed",
+ "description": "Percentage fan speed to use when printing bridge walls and skin.",
+ "unit": "%",
+ "minimum_value": "0",
+ "maximum_value": "100",
+ "default_value": 100,
+ "type": "float",
+ "enabled": "bridge_settings_enabled",
+ "settable_per_mesh": true
+ },
+ "bridge_enable_more_layers":
+ {
+ "label": "Bridge Has Multiple Layers",
+ "description": "If enabled, the second and third layers above the air are printed using the following settings. Otherwise, those layers are printed using the normal settings.",
+ "type": "bool",
+ "default_value": true,
+ "enabled": "bridge_settings_enabled",
+ "settable_per_mesh": true
+ },
+ "bridge_skin_speed_2":
+ {
+ "label": "Bridge Second Skin Speed",
+ "description": "Print speed to use when printing the second bridge skin layer.",
+ "unit": "mm/s",
+ "type": "float",
+ "minimum_value": "cool_min_speed",
+ "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
+ "maximum_value_warning": "300",
+ "default_value": 25,
+ "value": "bridge_skin_speed",
+ "enabled": "bridge_settings_enabled and bridge_enable_more_layers",
+ "settable_per_mesh": true
+ },
+ "bridge_skin_material_flow_2":
+ {
+ "label": "Bridge Second Skin Flow",
+ "description": "When printing the second bridge skin layer, the amount of material extruded is multiplied by this value.",
+ "unit": "%",
+ "default_value": 100,
+ "type": "float",
+ "minimum_value": "5",
+ "maximum_value": "500",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "enabled": "bridge_settings_enabled and bridge_enable_more_layers",
+ "settable_per_mesh": true
+ },
+ "bridge_skin_density_2":
+ {
+ "label": "Bridge Second Skin Density",
+ "description": "The density of the second bridge skin layer. Values less than 100 will increase the gaps between the skin lines.",
+ "unit": "%",
+ "default_value": 75,
+ "type": "float",
+ "minimum_value": "5",
+ "maximum_value": "100",
+ "minimum_value_warning": "20",
+ "enabled": "bridge_settings_enabled and bridge_enable_more_layers",
+ "settable_per_mesh": true
+ },
+ "bridge_fan_speed_2":
+ {
+ "label": "Bridge Second Skin Fan Speed",
+ "description": "Percentage fan speed to use when printing the second bridge skin layer.",
+ "unit": "%",
+ "minimum_value": "0",
+ "maximum_value": "100",
+ "default_value": 0,
+ "type": "float",
+ "enabled": "bridge_settings_enabled and bridge_enable_more_layers",
+ "settable_per_mesh": true
+ },
+ "bridge_skin_speed_3":
+ {
+ "label": "Bridge Third Skin Speed",
+ "description": "Print speed to use when printing the third bridge skin layer.",
+ "unit": "mm/s",
+ "type": "float",
+ "minimum_value": "cool_min_speed",
+ "maximum_value": "math.sqrt(machine_max_feedrate_x ** 2 + machine_max_feedrate_y ** 2)",
+ "maximum_value_warning": "300",
+ "default_value": 15,
+ "value": "bridge_skin_speed",
+ "enabled": "bridge_settings_enabled and bridge_enable_more_layers",
+ "settable_per_mesh": true
+ },
+ "bridge_skin_material_flow_3":
+ {
+ "label": "Bridge Third Skin Flow",
+ "description": "When printing the third bridge skin layer, the amount of material extruded is multiplied by this value.",
+ "unit": "%",
+ "default_value": 110,
+ "type": "float",
+ "minimum_value": "5",
+ "maximum_value": "500",
+ "minimum_value_warning": "50",
+ "maximum_value_warning": "150",
+ "enabled": "bridge_settings_enabled and bridge_enable_more_layers",
+ "settable_per_mesh": true
+ },
+ "bridge_skin_density_3":
+ {
+ "label": "Bridge Third Skin Density",
+ "description": "The density of the third bridge skin layer. Values less than 100 will increase the gaps between the skin lines.",
+ "unit": "%",
+ "default_value": 80,
+ "type": "float",
+ "minimum_value": "5",
+ "maximum_value": "100",
+ "minimum_value_warning": "20",
+ "enabled": "bridge_settings_enabled and bridge_enable_more_layers",
+ "settable_per_mesh": true
+ },
+ "bridge_fan_speed_3":
+ {
+ "label": "Bridge Third Skin Fan Speed",
+ "description": "Percentage fan speed to use when printing the third bridge skin layer.",
+ "unit": "%",
+ "minimum_value": "0",
+ "maximum_value": "100",
+ "default_value": 0,
+ "type": "float",
+ "enabled": "bridge_settings_enabled and bridge_enable_more_layers",
+ "settable_per_mesh": true
}
}
},
diff --git a/resources/definitions/gmax15plus.def.json b/resources/definitions/gmax15plus.def.json
index d651a86bb3..897d492bb2 100644
--- a/resources/definitions/gmax15plus.def.json
+++ b/resources/definitions/gmax15plus.def.json
@@ -10,11 +10,10 @@
"category": "Other",
"file_formats": "text/x-gcode",
"platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl",
+ "has_machine_quality": true,
"has_variants": true,
"variants_name": "Hotend",
- "preferred_variant": "*0.5mm E3D (Default)*"
-
-
+ "preferred_variant_name": "0.5mm E3D (Default)"
},
"overrides": {
diff --git a/resources/definitions/gmax15plus_dual.def.json b/resources/definitions/gmax15plus_dual.def.json
index 4e9a91e88d..8c57c8af63 100644
--- a/resources/definitions/gmax15plus_dual.def.json
+++ b/resources/definitions/gmax15plus_dual.def.json
@@ -11,12 +11,13 @@
"file_formats": "text/x-gcode",
"platform": "gmax_1-5_xt-plus_s3d_full model_150707.stl",
"has_variants": true,
+ "has_machine_quality": true,
"variants_name": "Hotend",
- "preferred_variant": "*0.5mm E3D (Default)*",
+ "preferred_variant_name": "0.5mm E3D (Default)",
"machine_extruder_trains": {
"0": "gmax15plus_dual_extruder_0",
"1": "gmax15plus_dual_extruder_1"
- }
+ }
},
"overrides": {
diff --git a/resources/definitions/imade3d_jellybox.def.json b/resources/definitions/imade3d_jellybox.def.json
index 11df730408..b234e4b2cd 100644
--- a/resources/definitions/imade3d_jellybox.def.json
+++ b/resources/definitions/imade3d_jellybox.def.json
@@ -9,9 +9,8 @@
"platform": "imade3d_jellybox_platform.stl",
"platform_offset": [ 0, -0.3, 0],
"file_formats": "text/x-gcode",
- "preferred_variant": "*0.4*",
- "preferred_material": "*generic_pla*",
- "preferred_quality": "*fast*",
+ "preferred_variant_name": "0.4 mm",
+ "preferred_quality_type": "fast",
"has_materials": true,
"has_variants": true,
"has_machine_materials": true,
diff --git a/resources/definitions/malyan_m200.def.json b/resources/definitions/malyan_m200.def.json
index 365b031c43..a3f4f81ecf 100644
--- a/resources/definitions/malyan_m200.def.json
+++ b/resources/definitions/malyan_m200.def.json
@@ -11,7 +11,7 @@
"platform": "malyan_m200_platform.stl",
"has_machine_quality": true,
"has_materials": true,
- "preferred_quality": "*normal*",
+ "preferred_quality_type": "normal",
"supports_usb_connection": true,
"visible": true,
"first_start_actions": ["MachineSettingsAction"],
diff --git a/resources/definitions/monoprice_select_mini_v2.def.json b/resources/definitions/monoprice_select_mini_v2.def.json
index 87014c136b..99bb7ef50a 100644
--- a/resources/definitions/monoprice_select_mini_v2.def.json
+++ b/resources/definitions/monoprice_select_mini_v2.def.json
@@ -10,7 +10,7 @@
"file_formats": "text/x-gcode",
"has_machine_quality": true,
"has_materials": true,
- "preferred_quality": "*normal*",
+ "preferred_quality_type": "normal",
"visible": true
},
diff --git a/resources/definitions/seemecnc_artemis.def.json b/resources/definitions/seemecnc_artemis.def.json
new file mode 100644
index 0000000000..88a1b28de6
--- /dev/null
+++ b/resources/definitions/seemecnc_artemis.def.json
@@ -0,0 +1,43 @@
+{
+ "version": 2,
+ "name": "SeeMeCNC Artemis",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "PouncingIguana, JJ",
+ "manufacturer": "SeeMeCNC",
+ "file_formats": "text/x-gcode",
+ "icon": "icon_ultimaker2",
+ "platform": "artemis_platform.stl",
+ "has_materials": true
+ },
+
+ "overrides": {
+ "layer_height": { "default_value": 0.1618 },
+ "layer_height_0": { "default_value": 0.2 },
+ "machine_center_is_zero": { "default_value": true },
+ "machine_depth": { "default_value": 290 },
+ "machine_gcode_flavor": { "default_value": "RepRap (RepRap)" },
+ "machine_heated_bed": { "default_value": true },
+ "machine_height": { "default_value": 530 },
+ "machine_max_feedrate_z": { "default_value": 400 },
+ "machine_name": { "default_value": "Artemis" },
+ "machine_nozzle_size": { "default_value": 0.5 },
+ "machine_shape": { "default_value": "elliptic" },
+ "machine_width": { "default_value": 290 },
+ "relative_extrusion": { "default_value": false },
+ "retraction_amount": { "default_value": 3.2 },
+ "retraction_combing": { "default_value": "off" },
+ "retraction_hop_enabled": { "default_value": true },
+ "retraction_hop_only_when_collides": { "default_value": false },
+ "retraction_prime_speed": { "default_value": 45 },
+ "retraction_retract_speed": { "default_value": 45 },
+ "retraction_speed": { "default_value": 45 },
+ "machine_start_gcode": {
+ "default_value": "G28\nG1 Z15.0 F10000\nG92 E0"
+ },
+ "machine_end_gcode": {
+ "default_value": "M203 Z24000\nM104 S0\nM140 S0\nM107\nG28\nM84"
+ }
+ }
+}
diff --git a/resources/definitions/seemecnc_v32.def.json b/resources/definitions/seemecnc_v32.def.json
new file mode 100644
index 0000000000..5932403bc5
--- /dev/null
+++ b/resources/definitions/seemecnc_v32.def.json
@@ -0,0 +1,43 @@
+{
+ "version": 2,
+ "name": "SeeMeCNC Rostock Max V3.2",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "PouncingIguana, JJ",
+ "manufacturer": "SeeMeCNC",
+ "file_formats": "text/x-gcode",
+ "icon": "icon_ultimaker2",
+ "platform": "rostock_platform.stl",
+ "has_materials": true
+ },
+
+ "overrides": {
+ "layer_height": { "default_value": 0.1618 },
+ "layer_height_0": { "default_value": 0.2 },
+ "machine_center_is_zero": { "default_value": true },
+ "machine_depth": { "default_value": 265 },
+ "machine_gcode_flavor": { "default_value": "RepRap (RepRap)" },
+ "machine_heated_bed": { "default_value": true },
+ "machine_height": { "default_value": 395 },
+ "machine_max_feedrate_z": { "default_value": 300 },
+ "machine_name": { "default_value": "Rostock Max V3.2" },
+ "machine_nozzle_size": { "default_value": 0.5 },
+ "machine_shape": { "default_value": "elliptic" },
+ "machine_width": { "default_value": 265 },
+ "relative_extrusion": { "default_value": false },
+ "retraction_amount": { "default_value": 3.2 },
+ "retraction_combing": { "default_value": "off" },
+ "retraction_hop_enabled": { "default_value": true },
+ "retraction_hop_only_when_collides": { "default_value": false },
+ "retraction_prime_speed": { "default_value": 45 },
+ "retraction_retract_speed": { "default_value": 45 },
+ "retraction_speed": { "default_value": 45 },
+ "machine_start_gcode": {
+ "default_value": "G28\nG1 Z15.0 F10000\nG92 E0"
+ },
+ "machine_end_gcode": {
+ "default_value": "M203 Z24000\nM104 S0\nM140 S0\nM107\nG28\nM84"
+ }
+ }
+}
diff --git a/resources/definitions/tevo_blackwidow.def.json b/resources/definitions/tevo_blackwidow.def.json
index 04cadfb160..22f7095e17 100644
--- a/resources/definitions/tevo_blackwidow.def.json
+++ b/resources/definitions/tevo_blackwidow.def.json
@@ -11,7 +11,7 @@
"has_materials": false,
"has_machine_quality": true,
"platform": "tevo_blackwidow.stl",
- "preferred_quality": "*normal*"
+ "preferred_quality_type": "normal"
},
"overrides":
{
diff --git a/resources/definitions/tevo_tarantula.def.json b/resources/definitions/tevo_tarantula.def.json
index a9f9cefff2..c3bfb38192 100644
--- a/resources/definitions/tevo_tarantula.def.json
+++ b/resources/definitions/tevo_tarantula.def.json
@@ -2,7 +2,8 @@
"version": 2,
"name": "Tevo Tarantula",
"inherits": "fdmprinter",
- "metadata": {
+ "metadata":
+ {
"visible": true,
"author": "TheAssassin",
"manufacturer": "Tevo",
@@ -11,62 +12,39 @@
"platform": "prusai3_platform.stl"
},
- "overrides": {
- "machine_name": {
- "default_value": "Tevo Tarantula"
- },
- "machine_heated_bed": {
- "default_value": true
- },
- "machine_width": {
- "default_value": 200
- },
- "machine_height": {
- "default_value": 200
- },
- "machine_depth": {
- "default_value": 200
- },
- "machine_center_is_zero": {
- "default_value": false
- },
- "machine_nozzle_size": {
- "default_value": 0.4
- },
- "material_diameter": {
- "default_value": 1.75
- },
- "machine_head_polygon": {
- "default_value": [
+ "overrides":
+ {
+ "machine_name": { "default_value": "Tevo Tarantula" },
+ "machine_heated_bed": { "default_value": true },
+ "machine_width": { "default_value": 200 },
+ "machine_height": { "default_value": 200 },
+ "machine_depth": { "default_value": 200 },
+ "machine_center_is_zero": { "default_value": false },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 },
+ "machine_head_polygon":
+ {
+ "default_value":
+ [
[-75, -18],
[-75, 35],
[18, 35],
[18, -18]
]
},
- "gantry_height": {
- "default_value": 55
- },
- "machine_gcode_flavor": {
- "default_value": "RepRap (Marlin/Sprinter)"
- },
- "machine_acceleration": {
- "default_value": 500
- },
- "machine_max_jerk_xy": {
- "default_value": 4.0
- },
- "machine_max_jerk_z": {
- "default_value": 0.2
- },
- "machine_max_jerk_e": {
- "default_value": 2.5
- },
- "machine_start_gcode": {
- "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..."
- },
- "machine_end_gcode": {
- "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG90 ;absolute positioning\nG1 X0 Y200 F3600 ;move extruder out of the way by moving the baseplate to the front for easier access to printed object\nM84 ;steppers off"
- }
+ "gantry_height": { "default_value": 55 },
+ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
+ "machine_acceleration": { "default_value": 2650 },
+ "machine_max_jerk_xy": { "default_value": 15.0 },
+ "machine_max_jerk_z": { "default_value": 0.4 },
+ "machine_max_jerk_e": { "default_value": 5 },
+ "machine_max_feedrate_x": { "default_value": 255 },
+ "machine_max_feedrate_y": { "default_value": 225 },
+ "machine_max_feedrate_z": { "default_value": 3 },
+ "machine_max_acceleration_x": { "default_value": 2620 },
+ "machine_max_acceleration_y": { "default_value": 2650 },
+ "acceleration_print": { "default_value": 2650 },
+ "machine_start_gcode": { "default_value": "G21 ;metric values\nG90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 X0 Y0 ;move X/Y to min endstops\nG28 Z0 ;move Z to min endstops\nG1 Z15.0 F9000 ;move the platform down 15mm\nG92 E0 ;zero the extruded length\nG1 F200 E3 ;extrude 3mm of feed stock\nG92 E0 ;zero the extruded length again\nG1 F9000\n;Put printing message on LCD screen\nM117 Printing..." },
+ "machine_end_gcode": { "default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off (if you have it)\nG91 ;relative positioning\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\nG90 ;absolute positioning\nG1 X0 Y200 F3600 ;move extruder out of the way by moving the baseplate to the front for easier access to printed object\nM84 ;steppers off" }
}
}
diff --git a/resources/definitions/ubuild-3d_mr_bot_280.def.json b/resources/definitions/ubuild-3d_mr_bot_280.def.json
new file mode 100644
index 0000000000..4febdcd350
--- /dev/null
+++ b/resources/definitions/ubuild-3d_mr_bot_280.def.json
@@ -0,0 +1,49 @@
+{
+ "id": "ubuild-3d_mr_bot_280",
+ "version": 2,
+ "name": "uBuild-3D Mr Bot 280",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "uBuild-3D",
+ "manufacturer": "uBuild-3D",
+ "category": "Other",
+ "file_formats": "text/x-gcode",
+ "icon": "icon_uBuild-3D",
+ "platform": "mr_bot_280_platform.stl",
+ "has_materials": true,
+ "preferred_quality_type": "draft"
+ },
+
+ "overrides": {
+ "machine_name": { "default_value": "Mr Bot 280" },
+ "machine_heated_bed": { "default_value": true },
+ "machine_width": { "default_value": 275 },
+ "machine_height": { "default_value": 275 },
+ "machine_depth": { "default_value": 275 },
+ "machine_center_is_zero": { "default_value": false },
+ "material_diameter": { "default_value": 1.75 },
+ "material_bed_temperature": { "default_value": 70 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "layer_height_0": { "default_value": 0.1 },
+ "retraction_amount": { "default_value": 2 },
+ "retraction_speed": { "default_value": 50 },
+ "retraction_retract_speed": { "default_value": 50 },
+ "retraction_prime_speed": { "default_value": 30 },
+ "adhesion_type": { "default_value": "skirt" },
+ "machine_nozzle_heat_up_speed": { "default_value": 2 },
+ "machine_nozzle_cool_down_speed": { "default_value": 2 },
+ "machine_head_with_fans_polygon": { "default_value": [[-20,20],[10,10],[10,10],[10,10]] },
+ "gantry_height": { "default_value": 275 },
+ "machine_max_feedrate_z": { "default_value": 15 },
+ "machine_max_feedrate_e": { "default_value": 60 },
+ "machine_max_acceleration_z": { "default_value": 1000 },
+ "machine_acceleration": { "default_value": 2000 },
+ "machine_max_jerk_xy": { "default_value": 20 },
+ "machine_max_jerk_z": { "default_value": 0.4 },
+ "machine_max_jerk_e": { "default_value": 5 },
+ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
+ "machine_start_gcode": { "default_value": "G21 ; set units to millimeters\nG90 ; use absolute positioning\nM82 ; absolute extrusion mode\nM140 S{material_bed_temperature} ; set bed temp\nM104 S{material_print_temperature} ; set extruder temp\nG28 ; home X, Y and Z\nG29 ; probe sequence (for auto-leveling)\nG1 Z15 F600 ; go to Z15 position\nG1 X0 Y-20 F10000 ; go to X0 Y-20 position\nM190 S{material_bed_temperature} ; wait for bed temp\nM109 S{material_print_temperature} ; wait for extruder temp\nG92 E0 ; reset extruder distance position\nG1 E25 F100 ; extrude 25mm of material\nG92 E0 ; reset extruder distance position\nM117 Printing..." },
+ "machine_end_gcode": { "default_value": "M400 ; wait for moves to finish\nG92 Z0 E0 ; reset Z position\nG1 E-2 F9000 ; retract material\nG1 Z2 ; get extruder out of the way\nM104 S0 ; turn off extruder\nG1 Y285 F3000 ; present finished print\nM140 S0 ; turn off bed\nM84 ; disable motors\nM117 Print complete" }
+ }
+}
diff --git a/resources/definitions/ultimaker2.def.json b/resources/definitions/ultimaker2.def.json
index 038071574f..33b48116be 100644
--- a/resources/definitions/ultimaker2.def.json
+++ b/resources/definitions/ultimaker2.def.json
@@ -20,12 +20,10 @@
"overrides": {
"machine_name": { "default_value": "Ultimaker 2" },
"machine_start_gcode" : {
- "default_value": "",
"value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"G21 ;metric values\\nG90 ;absolute positioning\\nM82 ;set extruder to absolute mode\\nM107 ;start with the fan off\\nG28 Z0 ;move Z to bottom endstops\\nG28 X0 Y0 ;move X/Y to endstops\\nG1 X15 Y0 F4000 ;move X/Y to front of printer\\nG1 Z15.0 F9000 ;move the platform to 15mm\\nG92 E0 ;zero the extruded length\\nG1 F200 E10 ;extrude 10 mm of feed stock\\nG92 E0 ;zero the extruded length again\\nG1 F9000\\n;Put printing message on LCD screen\\nM117 Printing...\""
},
"machine_end_gcode" : {
- "default_value": "",
- "value": "\"\" if machine_gcode_flavor == \"UltiGCode\" else \"M104 S0 ;extruder heater off\\nM140 S0 ;heated bed heater off (if you have it)\\nG91 ;relative positioning\\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\\nM84 ;steppers off\\nG90 ;absolute positioning\""
+ "value": "\";Version _2.6 of the firmware can abort the print too early if the file ends\\n;too soon. However if the file hasn't ended yet because there are comments at\\n;the end of the file, it won't abort yet. Therefore we have to put at least 512\\n;bytes at the end of the g-code so that the file is not yet finished by the\\n;time that the motion planner gets flushed. With firmware version _3.3 this\\n;should be fixed, so this comment wouldn't be necessary any more. Now we have\\n;to pad this text to make precisely 512 bytes.\" if machine_gcode_flavor == \"UltiGCode\" else \"M104 S0 ;extruder heater off\\nM140 S0 ;heated bed heater off (if you have it)\\nG91 ;relative positioning\\nG1 E-1 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure\\nG1 Z+0.5 E-5 X-20 Y-20 F9000 ;move Z up a bit and retract filament even more\\nG28 X0 Y0 ;move X/Y to min endstops, so the head is out of the way\\nM84 ;steppers off\\nG90 ;absolute positioning\\n;Version _2.6 of the firmware can abort the print too early if the file ends\\n;too soon. However if the file hasn't ended yet because there are comments at\\n;the end of the file, it won't abort yet. Therefore we have to put at least 512\\n;bytes at the end of the g-code so that the file is not yet finished by the\\n;time that the motion planner gets flushed. With firmware version _3.3 this\\n;should be fixed, so this comment wouldn't be necessary any more. Now we have\\n;to pad this text to make precisely 512 bytes.\""
},
"machine_width": {
"default_value": 223
diff --git a/resources/definitions/ultimaker2_plus.def.json b/resources/definitions/ultimaker2_plus.def.json
index 58833904d2..935bf5b6c0 100644
--- a/resources/definitions/ultimaker2_plus.def.json
+++ b/resources/definitions/ultimaker2_plus.def.json
@@ -9,7 +9,7 @@
"file_formats": "text/x-gcode",
"platform": "ultimaker2_platform.obj",
"platform_texture": "Ultimaker2Plusbackplate.png",
- "preferred_variant": "*0.4*",
+ "preferred_variant_name": "0.4 mm",
"has_variants": true,
"has_materials": true,
"has_machine_materials": true,
diff --git a/resources/definitions/ultimaker3.def.json b/resources/definitions/ultimaker3.def.json
index 1864a9b24a..57cfbe960f 100644
--- a/resources/definitions/ultimaker3.def.json
+++ b/resources/definitions/ultimaker3.def.json
@@ -15,8 +15,8 @@
"has_machine_materials": true,
"has_variant_materials": true,
"has_variants": true,
- "preferred_variant": "*aa04*",
- "preferred_quality": "*Normal*",
+ "preferred_variant_name": "AA 0.4",
+ "preferred_quality_type": "normal",
"variants_name": "Print core",
"machine_extruder_trains":
{
@@ -43,10 +43,10 @@
{
"default_value":
[
- [ -29, 6.1 ],
- [ -29, -33.9 ],
- [ 71, 6.1 ],
- [ 71, -33.9 ]
+ [ -41.9, -45.8 ],
+ [ -41.9, 33.9 ],
+ [ 59.9, 33.9 ],
+ [ 59.9, -45.8 ]
]
},
"machine_gcode_flavor": { "default_value": "Griffin" },
diff --git a/resources/definitions/ultimaker3_extended.def.json b/resources/definitions/ultimaker3_extended.def.json
index 385199f4f1..3a1be3a303 100644
--- a/resources/definitions/ultimaker3_extended.def.json
+++ b/resources/definitions/ultimaker3_extended.def.json
@@ -16,7 +16,7 @@
"has_variant_materials": true,
"has_materials": true,
"has_variants": true,
- "preferred_variant": "*aa04*",
+ "preferred_variant_name": "AA 0.4",
"variants_name": "Print core",
"machine_extruder_trains":
{
diff --git a/resources/extruders/cartesio_extruder_0.def.json b/resources/extruders/cartesio_extruder_0.def.json
index 5558d9325e..47b5b5abf5 100644
--- a/resources/extruders/cartesio_extruder_0.def.json
+++ b/resources/extruders/cartesio_extruder_0.def.json
@@ -16,17 +16,10 @@
"machine_nozzle_offset_x": { "default_value": 0.0 },
"machine_nozzle_offset_y": { "default_value": 0.0 },
"machine_extruder_start_code": {
- "default_value": "\n;start extruder_0\n\nM117 printing...\n"
+ "default_value": "\n;start T0\n\nM104 T0 S{material_print_temperature_layer_0}\nG1 X65 Y35 F9000 ; go to wipe position\nM109 T0 S{material_print_temperature_layer_0}; wait for temp\nG1 E10 F300; prime\nG92 E0\nG1 X45 Y15 F3000; wipe\nG1 X55 F9000\nG1 Y35 F6000; wipe again\n\nM117 printing...\n"
},
"machine_extruder_end_code": {
- "default_value": "\nM104 T0 S120\n;end extruder_0\nM117 temp is {material_print_temp}\n"
- },
-
- "machine_extruder_start_pos_abs": { "default_value": true },
- "machine_extruder_start_pos_x": { "default_value": 24 },
- "machine_extruder_start_pos_y": { "default_value": 16 },
- "machine_extruder_end_pos_abs": { "default_value": true },
- "machine_extruder_end_pos_x": { "default_value": 48 },
- "machine_extruder_end_pos_y": { "default_value": 16 }
+ "default_value": "\nM104 T0 S{material_standby_temperature}\nG1 X65 Y35 F9000 ; go to wipe position\nM109 T0 R{material_standby_temperature}; wait for temp\nG1 X45 Y15 F3000; wipe\nG1 X55 F9000\nG1 Y35 F6000; wipe again\n\n;end T0\n\n"
+ }
}
}
diff --git a/resources/extruders/cartesio_extruder_1.def.json b/resources/extruders/cartesio_extruder_1.def.json
index f8350f8091..78bcccd12a 100644
--- a/resources/extruders/cartesio_extruder_1.def.json
+++ b/resources/extruders/cartesio_extruder_1.def.json
@@ -16,17 +16,10 @@
"machine_nozzle_offset_x": { "default_value": 24.0 },
"machine_nozzle_offset_y": { "default_value": 0.0 },
"machine_extruder_start_code": {
- "default_value": "\n;start extruder_1\n\nM117 printing...\n"
+ "default_value": "\n;start T1\n\nM104 T1 S{material_print_temperature_layer_0}\nG1 X41 Y35 F9000 ; go to wipe position\nM109 T1 S{material_print_temperature_layer_0}; wait for temp\nG1 E10 F300; prime\nG92 E0\nG1 X21 Y15 F3000; wipe\nG1 X34 F9000\nG1 Y35 F6000; wipe again\n\nM117 printing...\n"
},
"machine_extruder_end_code": {
- "default_value": "\nM104 T1 S120\n;end extruder_1\n"
- },
-
- "machine_extruder_start_pos_abs": { "default_value": true },
- "machine_extruder_start_pos_x": { "default_value": 48 },
- "machine_extruder_start_pos_y": { "default_value": 16 },
- "machine_extruder_end_pos_abs": { "default_value": true },
- "machine_extruder_end_pos_x": { "default_value": 24 },
- "machine_extruder_end_pos_y": { "default_value": 16 }
+ "default_value": "\nM104 T1 S{material_standby_temperature}\nG1 X41 Y35 F9000 ; go to wipe position\nM109 T1 R{material_standby_temperature}; wait for temp\nG1 X21 Y15 F3000; wipe\nG1 X31 F9000\nG1 Y35 F6000; wipe again\n\n;end T1\n\n"
+ }
}
}
diff --git a/resources/extruders/cartesio_extruder_2.def.json b/resources/extruders/cartesio_extruder_2.def.json
index bfc10e75c3..dbd6643bfe 100644
--- a/resources/extruders/cartesio_extruder_2.def.json
+++ b/resources/extruders/cartesio_extruder_2.def.json
@@ -13,20 +13,13 @@
"default_value": 2,
"maximum_value": "3"
},
- "machine_nozzle_offset_x": { "default_value": 0.0 },
- "machine_nozzle_offset_y": { "default_value": 0.0 },
+ "machine_nozzle_offset_x": { "default_value": 24.0 },
+ "machine_nozzle_offset_y": { "default_value": -100.0 },
"machine_extruder_start_code": {
- "default_value": "\n;start extruder_2\n\nM117 printing...\n"
+ "default_value": "\n;start T2\n\nM104 T2 S{material_print_temperature_layer_0}\nG1 X41 Y215 F9000 ; go to wipe position\nM109 T2 S{material_print_temperature_layer_0}; wait for temp\nG1 E10 F300; prime\nG92 E0\nG1 X21 Y235 F3000; wipe\nG1 X31 F9000\nG1 Y215 F6000; wipe again\n\nM117 printing...\n"
},
"machine_extruder_end_code": {
- "default_value": "\nM104 T2 S120\n;end extruder_2\n"
- },
-
- "machine_extruder_start_pos_abs": { "default_value": true },
- "machine_extruder_start_pos_x": { "default_value": 24 },
- "machine_extruder_start_pos_y": { "default_value": 309 },
- "machine_extruder_end_pos_abs": { "default_value": true },
- "machine_extruder_end_pos_x": { "default_value": 48 },
- "machine_extruder_end_pos_y": { "default_value": 309 }
+ "default_value": "\nM104 T2 S{material_standby_temperature}\nG1 X41 Y215 F9000 ; go to wipe position\nM109 T2 R{material_standby_temperature}; wait for temp\nG1 X21 Y235 F3000; wipe\nG1 X31 F9000\nG1 Y215 F6000; wipe again\n\n;end T2\n\n"
+ }
}
}
diff --git a/resources/extruders/cartesio_extruder_3.def.json b/resources/extruders/cartesio_extruder_3.def.json
index f0be53e564..beed117abe 100644
--- a/resources/extruders/cartesio_extruder_3.def.json
+++ b/resources/extruders/cartesio_extruder_3.def.json
@@ -14,19 +14,12 @@
"maximum_value": "3"
},
"machine_nozzle_offset_x": { "default_value": 0.0 },
- "machine_nozzle_offset_y": { "default_value": 0.0 },
+ "machine_nozzle_offset_y": { "default_value": -100.0 },
"machine_extruder_start_code": {
- "default_value": "\n;start extruder_3\n\nM117 printing...\n"
+ "default_value": "\n;start T3\n\nM104 T3 S{material_print_temperature_layer_0}\nG1 X65 Y215 F9000 ; go to wipe position\nM109 T3 S{material_print_temperature_layer_0}; wait for temp\nG1 E10 F300; prime\nG92 E0\nG1 X45 Y235 F3000; wipe\nG1 X55 F9000\nG1 Y215 F6000; wipe again\n\nM117 printing...\n"
},
"machine_extruder_end_code": {
- "default_value": "\nM104 T3 S120\n;end extruder_3\n"
- },
-
- "machine_extruder_start_pos_abs": { "default_value": true },
- "machine_extruder_start_pos_x": { "default_value": 48 },
- "machine_extruder_start_pos_y": { "default_value": 309 },
- "machine_extruder_end_pos_abs": { "default_value": true },
- "machine_extruder_end_pos_x": { "default_value": 24 },
- "machine_extruder_end_pos_y": { "default_value": 309}
+ "default_value": "\nM104 T3 S{material_standby_temperature}\nG1 X65 Y215 F9000 ; go to wipe position\nM109 T3 R{material_standby_temperature}; wait for temp\nG1 X45 Y235 F3000; wipe\nG1 X55 F9000\nG1 Y215 F6000; wipe again\n\n;end T3\n\n"
+ }
}
}
diff --git a/resources/extruders/punchtec_connect_xl_extruder_left.def.json b/resources/extruders/punchtec_connect_xl_extruder_0.def.json
similarity index 100%
rename from resources/extruders/punchtec_connect_xl_extruder_left.def.json
rename to resources/extruders/punchtec_connect_xl_extruder_0.def.json
diff --git a/resources/extruders/punchtec_connect_xl_extruder_right.def.json b/resources/extruders/punchtec_connect_xl_extruder_1.def.json
similarity index 100%
rename from resources/extruders/punchtec_connect_xl_extruder_right.def.json
rename to resources/extruders/punchtec_connect_xl_extruder_1.def.json
diff --git a/resources/i18n/cura.pot b/resources/i18n/cura.pot
index e8148997ce..1620e11d81 100644
--- a/resources/i18n/cura.pot
+++ b/resources/i18n/cura.pot
@@ -3598,6 +3598,11 @@ msgctxt "@label"
msgid "SVG icons"
msgstr ""
+#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:139
+msgctxt "@label"
+msgid "Linux cross-distribution application deployment"
+msgstr ""
+
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:41
msgctxt "@label"
msgid "Profile:"
diff --git a/resources/i18n/de_DE/cura.po b/resources/i18n/de_DE/cura.po
index e55354febb..250e3e5e1b 100644
--- a/resources/i18n/de_DE/cura.po
+++ b/resources/i18n/de_DE/cura.po
@@ -8,13 +8,15 @@ msgstr ""
"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
"POT-Creation-Date: 2018-01-29 09:48+0000\n"
-"PO-Revision-Date: 2018-02-05 13:25+0100\n"
+"PO-Revision-Date: 2018-02-12 13:25+0100\n"
"Last-Translator: Bothof \n"
"Language-Team: German\n"
"Language: de_DE\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 2.0.4\n"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:26
msgctxt "@action"
@@ -145,7 +147,7 @@ msgstr "Drucker nicht verfügbar"
#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:485
msgctxt "@info:status"
msgid "This printer does not support USB printing because it uses UltiGCode flavor."
-msgstr "Der Drucker unterstützt keinen USB-Druck, da er die UltiGCode-Variante verwendet."
+msgstr "Der Drucker unterstützt keinen USB-Druck, da er UltiGCode verwendet."
#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:485
msgctxt "@info:title"
@@ -294,7 +296,7 @@ msgstr "Drucken über Netzwerk"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:110
msgctxt "@properties:tooltip"
msgid "Print over network"
-msgstr "Drücken über Netzwerk"
+msgstr "Drucken über Netzwerk"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:159
msgctxt "@info:status"
@@ -630,7 +632,10 @@ msgid ""
"Found no models inside your drawing. Could you please check it's content again and make sure one part or assembly is inside?\n"
"\n"
" Thanks!."
-msgstr "Keine Modelle in Ihrer Zeichnung gefunden. Bitte überprüfen Sie den Inhalt erneut und stellen Sie sicher, dass ein Teil oder eine Baugruppe enthalten ist.\n\n Danke!"
+msgstr ""
+"Keine Modelle in Ihrer Zeichnung gefunden. Bitte überprüfen Sie den Inhalt erneut und stellen Sie sicher, dass ein Teil oder eine Baugruppe enthalten ist.\n"
+"\n"
+" Danke!"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksReader.py:595
msgctxt "@info:status"
@@ -638,7 +643,10 @@ msgid ""
"Found more then one part or assembly inside your drawing. We currently only support drawings with exactly one part or assembly inside.\n"
"\n"
"Sorry!"
-msgstr "Es wurde mehr als ein Teil oder eine Baugruppe in Ihrer Zeichnung gefunden. Wir unterstützen derzeit nur Zeichnungen mit exakt einem Teil oder einer Baugruppe.\n\nEs tut uns leid!"
+msgstr ""
+"Es wurde mehr als ein Teil oder eine Baugruppe in Ihrer Zeichnung gefunden. Wir unterstützen derzeit nur Zeichnungen mit exakt einem Teil oder einer Baugruppe.\n"
+"\n"
+"Es tut uns leid!"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:25
msgctxt "@item:inlistbox"
@@ -663,7 +671,12 @@ msgid ""
"\n"
"With kind regards\n"
" - Thomas Karl Pietrowski"
-msgstr "Sehr geehrter Kunde,\nwir konnten keine gültige Installation von SolidWorks auf Ihrem System finden. Das bedeutet, dass SolidWorks entweder nicht installiert ist oder sie keine gültige Lizenz besitzen. Stellen Sie bitte sicher, dass SolidWorks problemlos läuft und/oder wenden Sie sich an Ihre ICT-Abteilung.\n\nMit freundlichen Grüßen\n - Thomas Karl Pietrowski"
+msgstr ""
+"Sehr geehrter Kunde,\n"
+"wir konnten keine gültige Installation von SolidWorks auf Ihrem System finden. Das bedeutet, dass SolidWorks entweder nicht installiert ist oder sie keine gültige Lizenz besitzen. Stellen Sie bitte sicher, dass SolidWorks problemlos läuft und/oder wenden Sie sich an Ihre ICT-Abteilung.\n"
+"\n"
+"Mit freundlichen Grüßen\n"
+" - Thomas Karl Pietrowski"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:57
msgctxt "@info:status"
@@ -673,7 +686,12 @@ msgid ""
"\n"
"With kind regards\n"
" - Thomas Karl Pietrowski"
-msgstr "Sehr geehrter Kunde,\nSie verwenden dieses Plugin derzeit auf einem anderen Betriebssystem als Windows. Dieses Plugin funktioniert nur auf Windows mit installiertem SolidWorks und einer gültigen Lizenz. Installieren Sie dieses Plugin bitte auf einem Windows-Rechner mit installiertem SolidWorks.\n\nMit freundlichen Grüßen\n - Thomas Karl Pietrowski"
+msgstr ""
+"Sehr geehrter Kunde,\n"
+"Sie verwenden dieses Plugin derzeit auf einem anderen Betriebssystem als Windows. Dieses Plugin funktioniert nur auf Windows mit installiertem SolidWorks und einer gültigen Lizenz. Installieren Sie dieses Plugin bitte auf einem Windows-Rechner mit installiertem SolidWorks.\n"
+"\n"
+"Mit freundlichen Grüßen\n"
+" - Thomas Karl Pietrowski"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksDialogHandler.py:70
msgid "Configure"
@@ -747,7 +765,9 @@ msgctxt "@info:status"
msgid ""
"Could not export using \"{}\" quality!\n"
"Felt back to \"{}\"."
-msgstr "Exportieren in \"{}\" Qualität nicht möglich!\nZurückgeschaltet auf \"{}\"."
+msgstr ""
+"Exportieren in \"{}\" Qualität nicht möglich!\n"
+"Zurückgeschaltet auf \"{}\"."
#: /home/ruben/Projects/Cura/plugins/GCodeProfileReader/__init__.py:14
#: /home/ruben/Projects/Cura/plugins/GCodeReader/__init__.py:14
@@ -1242,7 +1262,10 @@ msgid ""
"A fatal error has occurred. Please send us this Crash Report to fix the problem
\n"
" Please use the \"Send report\" button to post a bug report automatically to our servers
\n"
" "
-msgstr "Ein schwerer Fehler ist aufgetreten. Senden Sie uns diesen Absturzbericht, um das Problem zu beheben
\n Verwenden Sie bitte die Schaltfläche „Bericht senden“, um den Fehlerbericht automatisch an unsere Server zu senden
\n "
+msgstr ""
+"Ein schwerer Fehler ist aufgetreten. Senden Sie uns diesen Absturzbericht, um das Problem zu beheben
\n"
+" Verwenden Sie bitte die Schaltfläche „Bericht senden“, um den Fehlerbericht automatisch an unsere Server zu senden
\n"
+" "
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:102
msgctxt "@title:groupbox"
@@ -1610,7 +1633,7 @@ msgstr "Unbekannter Fehlercode: %1"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:55
msgctxt "@title:window"
msgid "Connect to Networked Printer"
-msgstr "Anschluss an vernetzten Drucker"
+msgstr "Anschluss an Netzwerk Drucker"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:65
msgctxt "@label"
@@ -1618,7 +1641,10 @@ msgid ""
"To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n"
"\n"
"Select your printer from the list below:"
-msgstr "Um über das Netzwerk direkt auf Ihrem Drucker zu drucken, stellen Sie bitte sicher, dass der Drucker mit dem Netzwerkkabel verbunden ist oder verbinden Sie Ihren Drucker mit Ihrem WLAN-Netzwerk. Wenn Sie Cura nicht mit Ihrem Drucker verbinden, können Sie dennoch ein USB-Laufwerk für die Übertragung von G-Code-Dateien auf Ihren Drucker verwenden.\n\nWählen Sie Ihren Drucker aus der folgenden Liste:"
+msgstr ""
+"Um über das Netzwerk direkt auf Ihrem Drucker zu drucken, stellen Sie bitte sicher, dass der Drucker mit dem Netzwerkkabel verbunden ist oder verbinden Sie Ihren Drucker mit Ihrem WLAN-Netzwerk. Wenn Sie Cura nicht mit Ihrem Drucker verbinden, können Sie dennoch ein USB-Laufwerk für die Übertragung von G-Code-Dateien auf Ihren Drucker verwenden.\n"
+"\n"
+"Wählen Sie Ihren Drucker aus der folgenden Liste:"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:75
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:44
@@ -1928,7 +1954,9 @@ msgctxt "@action:button"
msgid ""
"Open the directory\n"
"with macro and icon"
-msgstr "Verzeichnis\nmit Makro und Symbol öffnen"
+msgstr ""
+"Verzeichnis\n"
+"mit Makro und Symbol öffnen"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:160
msgctxt "@description:label"
@@ -2420,7 +2448,10 @@ msgid ""
"This plugin contains a license.\n"
"You need to accept this license to install this plugin.\n"
"Do you agree with the terms below?"
-msgstr "Dieses Plugin enthält eine Lizenz.\nSie müssen diese Lizenz akzeptieren, um das Plugin zu installieren.\nStimmen Sie den nachfolgenden Bedingungen zu?"
+msgstr ""
+"Dieses Plugin enthält eine Lizenz.\n"
+"Sie müssen diese Lizenz akzeptieren, um das Plugin zu installieren.\n"
+"Stimmen Sie den nachfolgenden Bedingungen zu?"
#: /home/ruben/Projects/Cura/plugins/PluginBrowser/PluginBrowser.qml:242
msgctxt "@action:button"
@@ -2685,7 +2716,9 @@ msgctxt "@text:window"
msgid ""
"You have customized some profile settings.\n"
"Would you like to keep or discard those settings?"
-msgstr "Sie haben einige Profileinstellungen angepasst.\nMöchten Sie diese Einstellungen übernehmen oder verwerfen?"
+msgstr ""
+"Sie haben einige Profileinstellungen angepasst.\n"
+"Möchten Sie diese Einstellungen übernehmen oder verwerfen?"
#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:110
msgctxt "@title:column"
@@ -2728,7 +2761,7 @@ msgstr "Verwerfen"
#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:209
msgctxt "@action:button"
msgid "Keep"
-msgstr "Übernehmen"
+msgstr "Beibehalten"
#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:222
msgctxt "@action:button"
@@ -3353,7 +3386,9 @@ msgctxt "@info:credit"
msgid ""
"Cura is developed by Ultimaker B.V. in cooperation with the community.\n"
"Cura proudly uses the following open source projects:"
-msgstr "Cura wurde von Ultimaker B.V. in Zusammenarbeit mit der Community entwickelt.\nCura verwendet mit Stolz die folgenden Open Source-Projekte:"
+msgstr ""
+"Cura wurde von Ultimaker B.V. in Zusammenarbeit mit der Community entwickelt.\n"
+"Cura verwendet mit Stolz die folgenden Open Source-Projekte:"
#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:118
msgctxt "@label"
@@ -3450,6 +3485,11 @@ msgctxt "@label"
msgid "SVG icons"
msgstr "SVG-Symbole"
+#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:139
+msgctxt "@label"
+msgid "Linux cross-distribution application deployment"
+msgstr "Distributionsunabhängiges Format für Linux-Anwendungen"
+
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:41
msgctxt "@label"
msgid "Profile:"
@@ -3461,7 +3501,10 @@ msgid ""
"Some setting/override values are different from the values stored in the profile.\n"
"\n"
"Click to open the profile manager."
-msgstr "Einige Einstellungs-/Überschreibungswerte unterscheiden sich von den im Profil gespeicherten Werten.\n\nKlicken Sie, um den Profilmanager zu öffnen."
+msgstr ""
+"Einige Einstellungs-/Überschreibungswerte unterscheiden sich von den im Profil gespeicherten Werten.\n"
+"\n"
+"Klicken Sie, um den Profilmanager zu öffnen."
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:150
msgctxt "@label:textbox"
@@ -3499,7 +3542,10 @@ msgid ""
"Some hidden settings use values different from their normal calculated value.\n"
"\n"
"Click to make these settings visible."
-msgstr "Einige ausgeblendete Einstellungen verwenden Werte, die von ihren normalen, berechneten Werten abweichen.\n\nKlicken Sie, um diese Einstellungen sichtbar zu machen."
+msgstr ""
+"Einige ausgeblendete Einstellungen verwenden Werte, die von ihren normalen, berechneten Werten abweichen.\n"
+"\n"
+"Klicken Sie, um diese Einstellungen sichtbar zu machen."
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:61
msgctxt "@label Header for list of settings."
@@ -3527,7 +3573,10 @@ msgid ""
"This setting has a value that is different from the profile.\n"
"\n"
"Click to restore the value of the profile."
-msgstr "Diese Einstellung hat einen vom Profil abweichenden Wert.\n\nKlicken Sie, um den Wert des Profils wiederherzustellen."
+msgstr ""
+"Diese Einstellung hat einen vom Profil abweichenden Wert.\n"
+"\n"
+"Klicken Sie, um den Wert des Profils wiederherzustellen."
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:288
msgctxt "@label"
@@ -3535,7 +3584,10 @@ msgid ""
"This setting is normally calculated, but it currently has an absolute value set.\n"
"\n"
"Click to restore the calculated value."
-msgstr "Diese Einstellung wird normalerweise berechnet; aktuell ist jedoch ein Absolutwert eingestellt.\n\nKlicken Sie, um den berechneten Wert wiederherzustellen."
+msgstr ""
+"Diese Einstellung wird normalerweise berechnet; aktuell ist jedoch ein Absolutwert eingestellt.\n"
+"\n"
+"Klicken Sie, um den berechneten Wert wiederherzustellen."
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:128
msgctxt "@label:listbox"
@@ -3547,7 +3599,9 @@ msgctxt "@label:listbox"
msgid ""
"Print Setup disabled\n"
"G-code files cannot be modified"
-msgstr "Druckeinrichtung deaktiviert\nG-Code-Dateien können nicht geändert werden"
+msgstr ""
+"Druckeinrichtung deaktiviert\n"
+"G-Code-Dateien können nicht geändert werden"
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:342
msgctxt "@label Hours and minutes"
diff --git a/resources/i18n/de_DE/fdmextruder.def.json.po b/resources/i18n/de_DE/fdmextruder.def.json.po
index 039cc5dcb6..4c81c54c35 100644
--- a/resources/i18n/de_DE/fdmextruder.def.json.po
+++ b/resources/i18n/de_DE/fdmextruder.def.json.po
@@ -1,11 +1,11 @@
-# Cura JSON setting files
-# Copyright (C) 2017 Ultimaker
+# Cura
+# Copyright (C) 2018 Ultimaker
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2017.
+# Ruben Dulek , 2018.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.0\n"
+"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
"POT-Creation-Date: 2017-08-02 16:53+0000\n"
"PO-Revision-Date: 2017-11-30 13:05+0100\n"
diff --git a/resources/i18n/de_DE/fdmprinter.def.json.po b/resources/i18n/de_DE/fdmprinter.def.json.po
index 3f4309f371..95422bb589 100644
--- a/resources/i18n/de_DE/fdmprinter.def.json.po
+++ b/resources/i18n/de_DE/fdmprinter.def.json.po
@@ -1,13 +1,13 @@
-# Cura JSON setting files
-# Copyright (C) 2017 Ultimaker
+# Cura
+# Copyright (C) 2018 Ultimaker
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2017.
+# Ruben Dulek , 2018.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.0\n"
+"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2017-08-02 16:53+0000\n"
+"POT-Creation-Date: 2018-01-29 09:48+0000\n"
"PO-Revision-Date: 2017-11-30 13:05+0100\n"
"Last-Translator: Bothof \n"
"Language-Team: German\n"
diff --git a/resources/i18n/es_ES/cura.po b/resources/i18n/es_ES/cura.po
index ae780685dd..fa8cf61985 100644
--- a/resources/i18n/es_ES/cura.po
+++ b/resources/i18n/es_ES/cura.po
@@ -8,13 +8,15 @@ msgstr ""
"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
"POT-Creation-Date: 2018-01-29 09:48+0000\n"
-"PO-Revision-Date: 2018-02-05 13:25+0100\n"
+"PO-Revision-Date: 2018-02-12 13:40+0100\n"
"Last-Translator: Bothof \n"
"Language-Team: Spanish\n"
"Language: es_ES\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Poedit 2.0.6\n"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:26
msgctxt "@action"
@@ -630,7 +632,10 @@ msgid ""
"Found no models inside your drawing. Could you please check it's content again and make sure one part or assembly is inside?\n"
"\n"
" Thanks!."
-msgstr "No se han encontrado modelos en el dibujo. ¿Puede comprobar el contenido de nuevo y asegurarse de que hay una parte o un ensamblado dentro?\n\n Gracias."
+msgstr ""
+"No se han encontrado modelos en el dibujo. ¿Puede comprobar el contenido de nuevo y asegurarse de que hay una parte o un ensamblado dentro?\n"
+"\n"
+" Gracias."
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksReader.py:595
msgctxt "@info:status"
@@ -638,7 +643,10 @@ msgid ""
"Found more then one part or assembly inside your drawing. We currently only support drawings with exactly one part or assembly inside.\n"
"\n"
"Sorry!"
-msgstr "Se ha encontrado más de una parte o ensamblado en el dibujo. Actualmente únicamente son compatibles dibujos con una sola parte o ensamblado.\n\n Disculpe."
+msgstr ""
+"Se ha encontrado más de una parte o ensamblado en el dibujo. Actualmente únicamente son compatibles dibujos con una sola parte o ensamblado.\n"
+"\n"
+" Disculpe."
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:25
msgctxt "@item:inlistbox"
@@ -663,7 +671,12 @@ msgid ""
"\n"
"With kind regards\n"
" - Thomas Karl Pietrowski"
-msgstr "Estimado cliente:\nNo hemos encontrado una instalación válida de SolidWorks en el sistema. Esto significa que SolidWorks no está instalado o que no dispone de una licencia válida. Asegúrese de que la ejecución del propio SolidWorks funciona sin problemas o póngase en contacto con su CDTI.\n\nAtentamente\n - Thomas Karl Pietrowski"
+msgstr ""
+"Estimado cliente:\n"
+"No hemos encontrado una instalación válida de SolidWorks en el sistema. Esto significa que SolidWorks no está instalado o que no dispone de una licencia válida. Asegúrese de que la ejecución del propio SolidWorks funciona sin problemas o póngase en contacto con su CDTI.\n"
+"\n"
+"Atentamente\n"
+" - Thomas Karl Pietrowski"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:57
msgctxt "@info:status"
@@ -673,7 +686,12 @@ msgid ""
"\n"
"With kind regards\n"
" - Thomas Karl Pietrowski"
-msgstr "Estimado cliente:\nActualmente está ejecutando este complemento en un sistema operativo diferente a Windows. Este complemento solo funcionará en Windows con SolidWorks instalado, siempre que se disponga de una licencia válida. Instale este complemento en un equipo Windows con SolidWorks instalado.\n\nAtentamente\n - Thomas Karl Pietrowski"
+msgstr ""
+"Estimado cliente:\n"
+"Actualmente está ejecutando este complemento en un sistema operativo diferente a Windows. Este complemento solo funcionará en Windows con SolidWorks instalado, siempre que se disponga de una licencia válida. Instale este complemento en un equipo Windows con SolidWorks instalado.\n"
+"\n"
+"Atentamente\n"
+" - Thomas Karl Pietrowski"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksDialogHandler.py:70
msgid "Configure"
@@ -747,7 +765,9 @@ msgctxt "@info:status"
msgid ""
"Could not export using \"{}\" quality!\n"
"Felt back to \"{}\"."
-msgstr "No ha podido exportarse con la calidad \"{}\"\nRetroceder a \"{}»."
+msgstr ""
+"No ha podido exportarse con la calidad \"{}\"\n"
+"Retroceder a \"{}»."
#: /home/ruben/Projects/Cura/plugins/GCodeProfileReader/__init__.py:14
#: /home/ruben/Projects/Cura/plugins/GCodeReader/__init__.py:14
@@ -995,12 +1015,12 @@ msgstr "Relleno"
#: /home/ruben/Projects/Cura/cura/PrintInformation.py:102
msgctxt "@tooltip"
msgid "Support Infill"
-msgstr "Relleno de soporte"
+msgstr "Relleno del soporte"
#: /home/ruben/Projects/Cura/cura/PrintInformation.py:103
msgctxt "@tooltip"
msgid "Support Interface"
-msgstr "Interfaz de soporte"
+msgstr "Interfaz del soporte"
#: /home/ruben/Projects/Cura/cura/PrintInformation.py:104
msgctxt "@tooltip"
@@ -1242,7 +1262,10 @@ msgid ""
"A fatal error has occurred. Please send us this Crash Report to fix the problem
\n"
" Please use the \"Send report\" button to post a bug report automatically to our servers
\n"
" "
-msgstr "Se ha producido un error grave. Envíenos este informe de incidencias para que podamos solucionar el problema.
\n Utilice el botón «Enviar informe» para publicar automáticamente un informe de errores en nuestros servidores.
\n "
+msgstr ""
+"Se ha producido un error grave. Envíenos este informe de incidencias para que podamos solucionar el problema.
\n"
+" Utilice el botón «Enviar informe» para publicar automáticamente un informe de errores en nuestros servidores.
\n"
+" "
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:102
msgctxt "@title:groupbox"
@@ -1618,7 +1641,10 @@ msgid ""
"To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n"
"\n"
"Select your printer from the list below:"
-msgstr "Para imprimir directamente en la impresora a través de la red, asegúrese de que esta está conectada a la red utilizando un cable de red o conéctela a la red wifi. Si no conecta Cura con la impresora, también puede utilizar una unidad USB para transferir archivos GCode a la impresora.\n\nSeleccione la impresora de la siguiente lista:"
+msgstr ""
+"Para imprimir directamente en la impresora a través de la red, asegúrese de que esta está conectada a la red utilizando un cable de red o conéctela a la red wifi. Si no conecta Cura con la impresora, también puede utilizar una unidad USB para transferir archivos GCode a la impresora.\n"
+"\n"
+"Seleccione la impresora de la siguiente lista:"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:75
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:44
@@ -1928,7 +1954,9 @@ msgctxt "@action:button"
msgid ""
"Open the directory\n"
"with macro and icon"
-msgstr "Abra el directorio\ncon la macro y el icono"
+msgstr ""
+"Abra el directorio\n"
+"con la macro y el icono"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:160
msgctxt "@description:label"
@@ -2420,7 +2448,10 @@ msgid ""
"This plugin contains a license.\n"
"You need to accept this license to install this plugin.\n"
"Do you agree with the terms below?"
-msgstr "Este complemento incluye una licencia.\nDebe aceptar dicha licencia para instalar el complemento.\n¿Acepta las condiciones que aparecen a continuación?"
+msgstr ""
+"Este complemento incluye una licencia.\n"
+"Debe aceptar dicha licencia para instalar el complemento.\n"
+"¿Acepta las condiciones que aparecen a continuación?"
#: /home/ruben/Projects/Cura/plugins/PluginBrowser/PluginBrowser.qml:242
msgctxt "@action:button"
@@ -2685,7 +2716,9 @@ msgctxt "@text:window"
msgid ""
"You have customized some profile settings.\n"
"Would you like to keep or discard those settings?"
-msgstr "Ha personalizado parte de los ajustes del perfil.\n¿Desea descartar los cambios o guardarlos?"
+msgstr ""
+"Ha personalizado parte de los ajustes del perfil.\n"
+"¿Desea descartar los cambios o guardarlos?"
#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:110
msgctxt "@title:column"
@@ -2783,7 +2816,7 @@ msgstr "Coste del filamento"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:203
msgctxt "@label"
msgid "Filament weight"
-msgstr "Anchura del filamento"
+msgstr "Peso del filamento"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:220
msgctxt "@label"
@@ -3353,7 +3386,9 @@ msgctxt "@info:credit"
msgid ""
"Cura is developed by Ultimaker B.V. in cooperation with the community.\n"
"Cura proudly uses the following open source projects:"
-msgstr "Ultimaker B.V. ha desarrollado Cura en cooperación con la comunidad.\nCura se enorgullece de utilizar los siguientes proyectos de código abierto:"
+msgstr ""
+"Ultimaker B.V. ha desarrollado Cura en cooperación con la comunidad.\n"
+"Cura se enorgullece de utilizar los siguientes proyectos de código abierto:"
#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:118
msgctxt "@label"
@@ -3461,7 +3496,10 @@ msgid ""
"Some setting/override values are different from the values stored in the profile.\n"
"\n"
"Click to open the profile manager."
-msgstr "Algunos valores de los ajustes o sobrescrituras son distintos a los valores almacenados en el perfil.\n\nHaga clic para abrir el administrador de perfiles."
+msgstr ""
+"Algunos valores de los ajustes o sobrescrituras son distintos a los valores almacenados en el perfil.\n"
+"\n"
+"Haga clic para abrir el administrador de perfiles."
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:150
msgctxt "@label:textbox"
@@ -3499,7 +3537,10 @@ msgid ""
"Some hidden settings use values different from their normal calculated value.\n"
"\n"
"Click to make these settings visible."
-msgstr "Algunos ajustes ocultos utilizan valores diferentes de los valores normales calculados.\n\nHaga clic para mostrar estos ajustes."
+msgstr ""
+"Algunos ajustes ocultos utilizan valores diferentes de los valores normales calculados.\n"
+"\n"
+"Haga clic para mostrar estos ajustes."
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:61
msgctxt "@label Header for list of settings."
@@ -3527,7 +3568,10 @@ msgid ""
"This setting has a value that is different from the profile.\n"
"\n"
"Click to restore the value of the profile."
-msgstr "Este ajuste tiene un valor distinto del perfil.\n\nHaga clic para restaurar el valor del perfil."
+msgstr ""
+"Este ajuste tiene un valor distinto del perfil.\n"
+"\n"
+"Haga clic para restaurar el valor del perfil."
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:288
msgctxt "@label"
@@ -3535,7 +3579,10 @@ msgid ""
"This setting is normally calculated, but it currently has an absolute value set.\n"
"\n"
"Click to restore the calculated value."
-msgstr "Este ajuste se calcula normalmente pero actualmente tiene un valor absoluto establecido.\n\nHaga clic para restaurar el valor calculado."
+msgstr ""
+"Este ajuste se calcula normalmente pero actualmente tiene un valor absoluto establecido.\n"
+"\n"
+"Haga clic para restaurar el valor calculado."
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:128
msgctxt "@label:listbox"
@@ -3547,7 +3594,9 @@ msgctxt "@label:listbox"
msgid ""
"Print Setup disabled\n"
"G-code files cannot be modified"
-msgstr "Ajustes de impresión deshabilitados\nNo se pueden modificar los archivos GCode"
+msgstr ""
+"Ajustes de impresión deshabilitados\n"
+"No se pueden modificar los archivos GCode"
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:342
msgctxt "@label Hours and minutes"
@@ -3824,7 +3873,7 @@ msgstr "&Agregar impresora..."
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:162
msgctxt "@action:inmenu menubar:printer"
msgid "Manage Pr&inters..."
-msgstr "Adm&inistrar impresoras ..."
+msgstr "Adm&inistrar impresoras..."
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:169
msgctxt "@action:inmenu"
@@ -4020,12 +4069,12 @@ msgstr "Listo para %1"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:42
msgctxt "@label:PrintjobStatus"
msgid "Unable to Slice"
-msgstr "No se puede segmentar."
+msgstr "No se puede segmentar"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:44
msgctxt "@label:PrintjobStatus"
msgid "Slicing unavailable"
-msgstr "No se puede segmentar"
+msgstr "Segmentación no disponible"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:171
msgctxt "@info:tooltip"
@@ -4685,7 +4734,7 @@ msgstr "Herramienta de ajustes por modelo"
#: cura-siemensnx-plugin/plugin.json
msgctxt "description"
msgid "Helps you to install an 'export to Cura' button in Siemens NX."
-msgstr "Ayuda a instalar el botón para exportar a Cura en in Siemens NX."
+msgstr "Ayuda a instalar el botón para exportar a Cura en Siemens NX."
#: cura-siemensnx-plugin/plugin.json
msgctxt "name"
diff --git a/resources/i18n/es_ES/fdmprinter.def.json.po b/resources/i18n/es_ES/fdmprinter.def.json.po
index e8e2a289e8..98c2d1da7f 100644
--- a/resources/i18n/es_ES/fdmprinter.def.json.po
+++ b/resources/i18n/es_ES/fdmprinter.def.json.po
@@ -1,20 +1,21 @@
# Cura JSON setting files
-# Copyright (C) 2017 Ultimaker
+# Copyright (C) 2018 Ultimaker
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2017.
+# Ruben Dulek , 2018.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.0\n"
+"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2017-08-02 16:53+0000\n"
-"PO-Revision-Date: 2017-11-30 13:05+0100\n"
+"POT-Creation-Date: 2018-01-29 09:48+0000\n"
+"PO-Revision-Date: 2018-02-12 13:40+0100\n"
"Last-Translator: Bothof \n"
"Language-Team: Spanish\n"
"Language: es_ES\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 2.0.6\n"
#: fdmprinter.def.json
msgctxt "machine_settings label"
@@ -56,7 +57,9 @@ msgctxt "machine_start_gcode description"
msgid ""
"Gcode commands to be executed at the very start - separated by \n"
"."
-msgstr "Los comandos de Gcode que se ejecutarán justo al inicio - separados por \n."
+msgstr ""
+"Los comandos de Gcode que se ejecutarán justo al inicio - separados por \n"
+"."
#: fdmprinter.def.json
msgctxt "machine_end_gcode label"
@@ -68,7 +71,9 @@ msgctxt "machine_end_gcode description"
msgid ""
"Gcode commands to be executed at the very end - separated by \n"
"."
-msgstr "Los comandos de Gcode que se ejecutarán justo al final - separados por \n."
+msgstr ""
+"Los comandos de Gcode que se ejecutarán justo al final - separados por \n"
+"."
#: fdmprinter.def.json
msgctxt "material_guid label"
@@ -93,7 +98,7 @@ msgstr "Elija si desea escribir un comando para esperar a que la temperatura de
#: fdmprinter.def.json
msgctxt "material_print_temp_wait label"
msgid "Wait for Nozzle Heatup"
-msgstr "Esperar a la que la tobera se caliente"
+msgstr "Esperar a que la tobera se caliente"
#: fdmprinter.def.json
msgctxt "material_print_temp_wait description"
@@ -408,12 +413,12 @@ msgstr "Diferencia de altura entre la punta de la tobera y el sistema del puente
#: fdmprinter.def.json
msgctxt "machine_nozzle_id label"
msgid "Nozzle ID"
-msgstr "Id. de la tobera"
+msgstr "ID de la tobera"
#: fdmprinter.def.json
msgctxt "machine_nozzle_id description"
msgid "The nozzle ID for an extruder train, such as \"AA 0.4\" and \"BB 0.8\"."
-msgstr "Id. de la tobera de un tren extrusor, como \"AA 0.4\" y \"BB 0.8\"."
+msgstr "ID de la tobera de un tren extrusor, como \"AA 0.4\" y \"BB 0.8\"."
#: fdmprinter.def.json
msgctxt "machine_nozzle_size label"
@@ -1003,7 +1008,7 @@ msgstr "Compensar superposiciones de pared"
#: fdmprinter.def.json
msgctxt "travel_compensate_overlapping_walls_enabled description"
msgid "Compensate the flow for parts of a wall being printed where there is already a wall in place."
-msgstr "Compensa el flujo en partes de una pared que se están imprimiendo dónde ya hay una pared."
+msgstr "Compensa el flujo en partes de una pared que se están imprimiendo donde ya hay una pared."
#: fdmprinter.def.json
msgctxt "travel_compensate_overlapping_walls_0_enabled label"
@@ -1343,7 +1348,7 @@ msgstr "Patrón de relleno"
#: fdmprinter.def.json
msgctxt "infill_pattern description"
msgid "The pattern of the infill material of the print. The line and zig zag infill swap direction on alternate layers, reducing material cost. The grid, triangle, tri-hexagon, cubic, octet, quarter cubic, cross and concentric patterns are fully printed every layer. Cubic, quarter cubic and octet infill change with every layer to provide a more equal distribution of strength over each direction."
-msgstr "Patrón del material de relleno de la impresión. El relleno de línea y zigzag cambia de dirección en capas alternas, con lo que se reduce el coste del material. Los patrones de rejilla, triángulo, trihexagonal, cúbico, de octeto, cúbico bitruncado y transversal y concéntrico se imprimen en todas las capas por completo. El relleno cúbico, cúbico bitruncado y de octeto cambian en cada capa para proporcionar una distribución de fuerza equitativa en cada dirección."
+msgstr "Patrón del material de relleno de la impresión. El relleno de línea y zigzag cambia de dirección en capas alternas, con lo que se reduce el coste del material. Los patrones de rejilla, triángulo, trihexagonal, cúbico, octeto, cúbico bitruncado y transversal y concéntrico se imprimen en todas las capas por completo. El relleno cúbico, cúbico bitruncado y octeto cambian en cada capa para proporcionar una distribución de fuerza equitativa en cada dirección."
#: fdmprinter.def.json
msgctxt "infill_pattern option grid"
@@ -1788,7 +1793,7 @@ msgstr "Retracción en el cambio de capa"
#: fdmprinter.def.json
msgctxt "retract_at_layer_change description"
msgid "Retract the filament when the nozzle is moving to the next layer."
-msgstr "Retrae el filamento cuando la tobera se mueve a la siguiente capa. "
+msgstr "Retrae el filamento cuando la tobera se mueve a la siguiente capa."
#: fdmprinter.def.json
msgctxt "retraction_amount label"
@@ -3500,7 +3505,9 @@ msgctxt "skirt_gap description"
msgid ""
"The horizontal distance between the skirt and the first layer of the print.\n"
"This is the minimum distance. Multiple skirt lines will extend outwards from this distance."
-msgstr "La distancia horizontal entre la falda y la primera capa de la impresión.\nSe trata de la distancia mínima. Múltiples líneas de falda se extenderán hacia el exterior a partir de esta distancia."
+msgstr ""
+"La distancia horizontal entre la falda y la primera capa de la impresión.\n"
+"Se trata de la distancia mínima. Múltiples líneas de falda se extenderán hacia el exterior a partir de esta distancia."
#: fdmprinter.def.json
msgctxt "skirt_brim_minimal_length label"
@@ -4937,7 +4944,9 @@ msgctxt "wireframe_up_half_speed description"
msgid ""
"Distance of an upward move which is extruded with half speed.\n"
"This can cause better adhesion to previous layers, while not heating the material in those layers too much. Only applies to Wire Printing."
-msgstr "Distancia de un movimiento ascendente que se extrude a media velocidad.\nEsto puede causar una mejor adherencia a las capas anteriores, aunque no calienta demasiado el material en esas capas. Solo se aplica a la impresión de alambre."
+msgstr ""
+"Distancia de un movimiento ascendente que se extrude a media velocidad.\n"
+"Esto puede causar una mejor adherencia a las capas anteriores, aunque no calienta demasiado el material en esas capas. Solo se aplica a la impresión de alambre."
#: fdmprinter.def.json
msgctxt "wireframe_top_jump label"
diff --git a/resources/i18n/fr_FR/cura.po b/resources/i18n/fr_FR/cura.po
index 9170316f5b..ee4e175f8a 100644
--- a/resources/i18n/fr_FR/cura.po
+++ b/resources/i18n/fr_FR/cura.po
@@ -8,13 +8,15 @@ msgstr ""
"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
"POT-Creation-Date: 2018-01-29 09:48+0000\n"
-"PO-Revision-Date: 2018-02-05 13:25+0100\n"
+"PO-Revision-Date: 2018-02-13 17:26+0100\n"
"Last-Translator: Bothof \n"
"Language-Team: French\n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+"X-Generator: Poedit 2.0.6\n"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:26
msgctxt "@action"
@@ -105,12 +107,12 @@ msgstr "Afficher le récapitulatif des changements"
#: /home/ruben/Projects/Cura/plugins/ProfileFlattener/ProfileFlattener.py:20
msgctxt "@item:inmenu"
msgid "Flatten active settings"
-msgstr "Aplatir les paramètres actifs"
+msgstr "Réduire les paramètres actifs"
#: /home/ruben/Projects/Cura/plugins/ProfileFlattener/ProfileFlattener.py:32
msgctxt "@info:status"
msgid "Profile has been flattened & activated."
-msgstr "Le profil a été aplati et activé."
+msgstr "Le profil a été réduit et activé."
#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:27
msgctxt "@item:inmenu"
@@ -145,7 +147,7 @@ msgstr "Imprimante indisponible"
#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:485
msgctxt "@info:status"
msgid "This printer does not support USB printing because it uses UltiGCode flavor."
-msgstr "L'imprimante ne prend pas en charge l'impression par USB car elle utilise UltiGCode parfum."
+msgstr "L'imprimante ne prend pas en charge l'impression par USB car elle utilise UltiGCode."
#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:485
msgctxt "@info:title"
@@ -209,7 +211,7 @@ msgstr "Enregistrement sur le lecteur amovible {0}"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:89
msgctxt "@info:title"
msgid "Saving"
-msgstr "Enregistrement..."
+msgstr "Enregistrement"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:99
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:102
@@ -267,7 +269,7 @@ msgstr "Ejecter le lecteur amovible {0}"
#, python-brace-format
msgctxt "@info:status"
msgid "Ejected {0}. You can now safely remove the drive."
-msgstr "Lecteur {0} éjecté. Vous pouvez maintenant le retirer en tout sécurité."
+msgstr "Lecteur {0} éjecté. Vous pouvez maintenant le retirer en toute sécurité."
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:156
msgctxt "@info:title"
@@ -372,22 +374,22 @@ msgstr "Connecté sur le réseau. Pas d'accès pour commander l'imprimante."
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:410
msgctxt "@info:status"
msgid "Access request was denied on the printer."
-msgstr "La demande d'accès a été refusée sur l'imprimante."
+msgstr "La demande d'accès à l'imprimante a été refusée."
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:413
msgctxt "@info:status"
msgid "Access request failed due to a timeout."
-msgstr "Échec de la demande d'accès à cause de la durée limite."
+msgstr "Durée d'attente dépassée. Échec de la demande d'accès."
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:478
msgctxt "@info:status"
msgid "The connection with the network was lost."
-msgstr "La connexion avec le réseau a été perdue."
+msgstr "Interruption de connexion au le réseau."
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:501
msgctxt "@info:status"
msgid "The connection with the printer was lost. Check your printer to see if it is connected."
-msgstr "La connexion avec l'imprimante a été perdue. Vérifiez que votre imprimante est connectée."
+msgstr "La connexion avec l'imprimante est interrompue. Vérifiez que votre imprimante est connectée."
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:666
#, python-format
@@ -416,19 +418,19 @@ msgstr "Impossible de démarrer une nouvelle tâche d'impression car l'imprimant
#, python-brace-format
msgctxt "@label"
msgid "Not enough material for spool {0}."
-msgstr "Pas suffisamment de matériau pour bobine {0}."
+msgstr "Pas suffisamment de matériau pour la bobine {0}."
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:720
#, python-brace-format
msgctxt "@label"
msgid "Different PrintCore (Cura: {0}, Printer: {1}) selected for extruder {2}"
-msgstr "PrintCore différent (Cura : {0}, Imprimante : {1}) sélectionné pour l'extrudeuse {2}"
+msgstr "PrintCore différent (Cura : {0}, Imprimante : {1}) sélectionné pour l'extrudeur {2}"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:734
#, python-brace-format
msgctxt "@label"
msgid "Different material (Cura: {0}, Printer: {1}) selected for extruder {2}"
-msgstr "Matériau différent (Cura : {0}, Imprimante : {1}) sélectionné pour l'extrudeuse {2}"
+msgstr "Matériau différent (Cura : {0}, Imprimante : {1}) sélectionné pour l'extrudeur {2}"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:742
#, python-brace-format
@@ -444,7 +446,7 @@ msgstr "Êtes-vous sûr(e) de vouloir imprimer avec la configuration sélectionn
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:748
msgctxt "@label"
msgid "There is a mismatch between the configuration or calibration of the printer and Cura. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
-msgstr "Problème de compatibilité entre la configuration ou l'étalonnage de l'imprimante et Cura. Pour un résultat optimal, découpez toujours pour les PrintCores et matériaux insérés dans votre imprimante."
+msgstr "Problème de compatibilité entre la configuration ou la calibration de l'imprimante et Cura. Pour un résultat optimal, découpez toujours les PrintCores et matériaux insérés dans votre imprimante."
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:754
msgctxt "@window:title"
@@ -465,7 +467,7 @@ msgstr "Envoi des données à l'imprimante"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:874
msgctxt "@info:title"
msgid "Sending Data"
-msgstr "Envoi des données..."
+msgstr "Envoi des données"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:945
msgctxt "@info:status"
@@ -501,12 +503,12 @@ msgstr "Synchroniser avec votre imprimante"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:1293
msgctxt "@label"
msgid "Would you like to use your current printer configuration in Cura?"
-msgstr "Voulez-vous utiliser votre configuration d'imprimante actuelle dans Cura ?"
+msgstr "Voulez-vous utiliser votre configuration actuelle d'imprimante dans Cura ?"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:1295
msgctxt "@label"
msgid "The PrintCores and/or materials on your printer differ from those within your current project. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
-msgstr "Les PrintCores et / ou matériaux sur votre imprimante diffèrent de ceux de votre projet actuel. Pour un résultat optimal, découpez toujours pour les PrintCores et matériaux insérés dans votre imprimante."
+msgstr "Les PrintCores et / ou les matériaux sur votre imprimante sont différents de ceux de votre projet actuel. Pour un résultat optimal, découpez toujours les PrintCores et matériaux insérés dans votre imprimante."
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py:112
msgid "This printer is not set up to host a group of connected Ultimaker 3 printers."
@@ -521,7 +523,7 @@ msgstr "L'imprimante n'est pas configurée pour héberger un groupe de {count} i
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py:114
#, python-brace-format
msgid "{printer_name} has finished printing '{job_name}'. Please collect the print and confirm clearing the build plate."
-msgstr "{printer_name} a terminé d'imprimer '{job_name}'. Veuillez enlever l'impression et confirmer avoir débarrassé le plateau."
+msgstr "{printer_name} a terminé d'imprimer '{job_name}'. Veuillez enlever l'impression et confirmer avoir nettoyé le plateau."
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py:115
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py:533
@@ -601,7 +603,7 @@ msgstr "Surveiller"
#, python-brace-format
msgctxt "@info Don't translate {machine_name}, since it gets replaced by a printer name!"
msgid "New features are available for your {machine_name}! It is recommended to update the firmware on your printer."
-msgstr "De nouvelles fonctionnalités sont disponibles pour votre {machine_name} ! Il est recommandé de mettre à jour le firmware sur votre imprimante."
+msgstr "De nouvelles fonctionnalités sont disponibles pour votre {machine_name} ! Il est recommandé de mettre à jour le firmware de votre imprimante."
#: /home/ruben/Projects/Cura/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py:67
#, python-format
@@ -630,7 +632,10 @@ msgid ""
"Found no models inside your drawing. Could you please check it's content again and make sure one part or assembly is inside?\n"
"\n"
" Thanks!."
-msgstr "Aucun modèle n'a été trouvé à l'intérieur de votre dessin. Pouvez-vous vérifier son contenu de nouveau et vous assurer qu'une pièce ou un assemblage est présent ?\n\n Merci !"
+msgstr ""
+"Aucun modèle n'a été trouvé à l'intérieur de votre dessin. Pouvez-vous vérifier son contenu de nouveau et vous assurer qu'une pièce ou un assemblage est présent ?\n"
+"\n"
+" Merci !"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksReader.py:595
msgctxt "@info:status"
@@ -638,7 +643,10 @@ msgid ""
"Found more then one part or assembly inside your drawing. We currently only support drawings with exactly one part or assembly inside.\n"
"\n"
"Sorry!"
-msgstr "Plus d'une pièce ou d'un assemblage ont été trouvés dans votre dessin. Nous ne prenons actuellement en charge que les dessins comptant exactement une pièce ou un assemblage.\n\nDésolé !"
+msgstr ""
+"Plus d'une pièce ou d'un ensemble de pièces ont été trouvés dans votre dessin. Nous ne prenons actuellement en charge que les dessins comptant exactement une pièce ou un ensemble de pièces.\n"
+"\n"
+"Désolé !"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:25
msgctxt "@item:inlistbox"
@@ -663,7 +671,12 @@ msgid ""
"\n"
"With kind regards\n"
" - Thomas Karl Pietrowski"
-msgstr "Cher client,\nNous n'avons pas pu trouver une installation valide de SolidWorks sur votre système. Cela signifie soit que SolidWorks n'est pas installé, soit que vous ne possédez pas de licence valide. Veuillez vous assurer que l'exécution de SolidWorks lui-même fonctionne sans problèmes et / ou contactez votre service IT.\n\nCordialement,\n - Thomas Karl Pietrowski"
+msgstr ""
+"Cher client,\n"
+"Nous n'avons pas pu trouver une installation valide de SolidWorks sur votre système. Cela signifie soit que SolidWorks n'est pas installé, soit que vous ne possédez pas de licence valide. Veuillez vous assurer que l'exécution de SolidWorks lui-même fonctionne sans problèmes et / ou contactez votre service IT.\n"
+"\n"
+"Cordialement,\n"
+" - Thomas Karl Pietrowski"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:57
msgctxt "@info:status"
@@ -673,7 +686,12 @@ msgid ""
"\n"
"With kind regards\n"
" - Thomas Karl Pietrowski"
-msgstr "Cher client,\nVous exécutez actuellement ce plug-in sur un système d'exploitation autre que Windows. Ce plug-in fonctionne uniquement sous Windows et lorsque SolidWorks est installé avec une licence valide. Veuillez installer ce plug-in sur un poste Windows où SolidWorks est installé.\n\nCordialement,\n - Thomas Karl Pietrowski"
+msgstr ""
+"Cher client,\n"
+"Vous exécutez actuellement ce plug-in sur un système d'exploitation autre que Windows. Ce plug-in fonctionne uniquement sous Windows et lorsque SolidWorks est installé avec une licence valide. Veuillez installer ce plug-in sur un poste Windows où SolidWorks est installé.\n"
+"\n"
+"Cordialement,\n"
+" - Thomas Karl Pietrowski"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksDialogHandler.py:70
msgid "Configure"
@@ -710,7 +728,7 @@ msgstr "Cura recueille des statistiques d'utilisation anonymes."
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:46
msgctxt "@info:title"
msgid "Collecting Data"
-msgstr "Collecte des données..."
+msgstr "Collecte de données"
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:48
msgctxt "@action:button"
@@ -747,7 +765,9 @@ msgctxt "@info:status"
msgid ""
"Could not export using \"{}\" quality!\n"
"Felt back to \"{}\"."
-msgstr "Impossible d'exporter avec la qualité \"{}\" !\nQualité redéfinie sur \"{}\"."
+msgstr ""
+"Impossible d'exporter avec la qualité \"{}\" !\n"
+"Qualité redéfinie sur \"{}\"."
#: /home/ruben/Projects/Cura/plugins/GCodeProfileReader/__init__.py:14
#: /home/ruben/Projects/Cura/plugins/GCodeReader/__init__.py:14
@@ -965,12 +985,12 @@ msgstr "Mise à niveau du firmware"
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.py:14
msgctxt "@action"
msgid "Checkup"
-msgstr "Check-up"
+msgstr "Vérification"
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.py:15
msgctxt "@action"
msgid "Level build plate"
-msgstr "Nivellement du plateau"
+msgstr "Paramétrage du plateau de fabrication"
#: /home/ruben/Projects/Cura/cura/PrintInformation.py:98
msgctxt "@tooltip"
@@ -1010,7 +1030,7 @@ msgstr "Support"
#: /home/ruben/Projects/Cura/cura/PrintInformation.py:105
msgctxt "@tooltip"
msgid "Skirt"
-msgstr "Jupe"
+msgstr "Contourner"
#: /home/ruben/Projects/Cura/cura/PrintInformation.py:106
msgctxt "@tooltip"
@@ -1074,7 +1094,7 @@ msgstr "Matériau personnalisé"
#: /home/ruben/Projects/Cura/cura/Settings/ExtrudersModel.py:205
msgctxt "@menuitem"
msgid "Not overridden"
-msgstr "Pas écrasé"
+msgstr "Pas pris en compte"
#: /home/ruben/Projects/Cura/cura/Settings/MachineManager.py:124
msgctxt "@info:status"
@@ -1204,7 +1224,7 @@ msgstr "Multiplication et placement d'objets"
#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:78
msgctxt "@info:title"
msgid "Placing Object"
-msgstr "Placement de l'objet..."
+msgstr "Placement de l'objet"
#: /home/ruben/Projects/Cura/cura/MultiplyObjectsJob.py:78
#: /home/ruben/Projects/Cura/cura/Arranging/ArrangeObjectsJob.py:88
@@ -1242,7 +1262,10 @@ msgid ""
"A fatal error has occurred. Please send us this Crash Report to fix the problem
\n"
" Please use the \"Send report\" button to post a bug report automatically to our servers
\n"
" "
-msgstr "Une erreur fatale s'est produite. Veuillez nous envoyer ce Rapport d'incident pour résoudre le problème
\n Veuillez utiliser le bouton « Envoyer rapport » pour publier automatiquement un rapport d'erreur sur nos serveurs
\n "
+msgstr ""
+"Une erreur fatale s'est produite. Veuillez nous envoyer ce Rapport d'incident pour résoudre le problème
\n"
+" Veuillez utiliser le bouton « Envoyer rapport » pour publier automatiquement un rapport d'erreur sur nos serveurs
\n"
+" "
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:102
msgctxt "@title:groupbox"
@@ -1310,7 +1333,7 @@ msgstr "Retraçage de l'erreur"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:214
msgctxt "@title:groupbox"
msgid "Logs"
-msgstr "Journaux"
+msgstr "Registres"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:237
msgctxt "@title:groupbox"
@@ -1330,7 +1353,7 @@ msgstr "Chargement des machines..."
#: /home/ruben/Projects/Cura/cura/CuraApplication.py:660
msgctxt "@info:progress"
msgid "Setting up scene..."
-msgstr "Préparation de la scène..."
+msgstr "Préparation de la tâche..."
#: /home/ruben/Projects/Cura/cura/CuraApplication.py:702
msgctxt "@info:progress"
@@ -1481,7 +1504,7 @@ msgstr "La différence de hauteur entre la pointe de la buse et le système de p
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:254
msgctxt "@label"
msgid "Number of Extruders"
-msgstr "Nombre d'extrudeuses"
+msgstr "Nombre d'extrudeurs"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:310
msgctxt "@label"
@@ -1536,12 +1559,12 @@ msgstr "Décalage buse Y"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:444
msgctxt "@label"
msgid "Extruder Start Gcode"
-msgstr "Extrudeuse Gcode de démarrage"
+msgstr "Extrudeur Gcode de démarrage"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:462
msgctxt "@label"
msgid "Extruder End Gcode"
-msgstr "Extrudeuse Gcode de fin"
+msgstr "Extrudeur Gcode de fin"
#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:18
msgctxt "@label"
@@ -1618,7 +1641,10 @@ msgid ""
"To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n"
"\n"
"Select your printer from the list below:"
-msgstr "Pour imprimer directement sur votre imprimante sur le réseau, assurez-vous que votre imprimante est connectée au réseau via un câble réseau ou en connectant votre imprimante à votre réseau Wi-Fi. Si vous ne connectez pas Cura avec votre imprimante, vous pouvez utiliser une clé USB pour transférer les fichiers g-code sur votre imprimante.\n\nSélectionnez votre imprimante dans la liste ci-dessous :"
+msgstr ""
+"Pour imprimer directement sur votre imprimante sur le réseau, assurez-vous que votre imprimante est connectée au réseau via un câble réseau ou en connectant votre imprimante à votre réseau Wi-Fi. Si vous ne connectez pas Cura avec votre imprimante, vous pouvez utiliser une clé USB pour transférer les fichiers g-code sur votre imprimante.\n"
+"\n"
+"Sélectionnez votre imprimante dans la liste ci-dessous :"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:75
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:44
@@ -1725,7 +1751,7 @@ msgstr "Imprimer"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/ClusterMonitorItem.qml:36
msgctxt "@label: arg 1 is group name"
msgid "%1 is not set up to host a group of connected Ultimaker 3 printers"
-msgstr "%1 n'est pas configurée pour héberger un groupe d'imprimantes connectées Ultimaker 3."
+msgstr "%1 n'est pas configurée pour héberger un groupe d'imprimantes connectées Ultimaker 3"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/ClusterMonitorItem.qml:55
msgctxt "@label link to connect manager"
@@ -1748,7 +1774,7 @@ msgstr "Afficher les tâches d'impression"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml:408
msgctxt "@label"
msgid "Preparing to print"
-msgstr "Préparation de l'impression..."
+msgstr "Préparation de l'impression"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml:39
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml:271
@@ -1928,7 +1954,9 @@ msgctxt "@action:button"
msgid ""
"Open the directory\n"
"with macro and icon"
-msgstr "Ouvrez le répertoire\ncontenant la macro et l'icône"
+msgstr ""
+"Ouvrez le répertoire\n"
+"contenant la macro et l'icône"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:160
msgctxt "@description:label"
@@ -2104,12 +2132,12 @@ msgstr "Paroi interne"
#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:410
msgctxt "@label"
msgid "min"
-msgstr "min."
+msgstr "min"
#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:452
msgctxt "@label"
msgid "max"
-msgstr "max."
+msgstr "max"
#: /home/ruben/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:18
msgctxt "@title:window"
@@ -2276,7 +2304,7 @@ msgstr "Créer"
#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:72
msgctxt "@action:title"
msgid "Summary - Cura Project"
-msgstr "Résumé - Projet Cura"
+msgstr "Sommaire - Projet Cura"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:92
#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:90
@@ -2287,7 +2315,7 @@ msgstr "Paramètres de l'imprimante"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:108
msgctxt "@info:tooltip"
msgid "How should the conflict in the machine be resolved?"
-msgstr "Comment le conflit de la machine doit-il être résolu ?"
+msgstr "Comment le problème de la machine doit-il être résolu ?"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:128
#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:99
@@ -2313,7 +2341,7 @@ msgstr "Paramètres de profil"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:181
msgctxt "@info:tooltip"
msgid "How should the conflict in the profile be resolved?"
-msgstr "Comment le conflit du profil doit-il être résolu ?"
+msgstr "Comment le problème du profil doit-il être résolu ?"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:216
#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:174
@@ -2349,7 +2377,7 @@ msgstr "Paramètres du matériau"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:269
msgctxt "@info:tooltip"
msgid "How should the conflict in the material be resolved?"
-msgstr "Comment le conflit du matériau doit-il être résolu ?"
+msgstr "Comment le problème du matériau doit-il être résolu ?"
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.qml:312
#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:209
@@ -2412,7 +2440,7 @@ msgstr "Télécharger"
#: /home/ruben/Projects/Cura/plugins/PluginBrowser/PluginBrowser.qml:199
msgctxt "@title:window"
msgid "Plugin License Agreement"
-msgstr "Plug-in d'accord de licence"
+msgstr "Plug-in de l'accord de licence"
#: /home/ruben/Projects/Cura/plugins/PluginBrowser/PluginBrowser.qml:220
msgctxt "@label"
@@ -2420,7 +2448,10 @@ msgid ""
"This plugin contains a license.\n"
"You need to accept this license to install this plugin.\n"
"Do you agree with the terms below?"
-msgstr "Ce plug-in contient une licence.\nVous devez approuver cette licence pour installer ce plug-in.\nAcceptez-vous les clauses ci-dessous ?"
+msgstr ""
+"Ce plug-in contient une licence.\n"
+"Vous devez approuver cette licence pour installer ce plug-in.\n"
+"Acceptez-vous les clauses ci-dessous ?"
#: /home/ruben/Projects/Cura/plugins/PluginBrowser/PluginBrowser.qml:242
msgctxt "@action:button"
@@ -2609,7 +2640,7 @@ msgstr "Contrôlée"
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:284
msgctxt "@label"
msgid "Everything is in order! You're done with your CheckUp."
-msgstr "Tout est en ordre ! Vous avez terminé votre check-up."
+msgstr "Tout est en ordre ! Vous avez terminé votre vérification."
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:87
msgctxt "@label:MonitorStatus"
@@ -2625,7 +2656,7 @@ msgstr "L'imprimante n'accepte pas les commandes"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:194
msgctxt "@label:MonitorStatus"
msgid "In maintenance. Please check the printer"
-msgstr "En maintenance. Vérifiez l'imprimante"
+msgstr "En maintenance. Veuillez vérifier l'imprimante"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:102
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:184
@@ -2648,7 +2679,7 @@ msgstr "Préparation..."
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:110
msgctxt "@label:MonitorStatus"
msgid "Please remove the print"
-msgstr "Supprimez l'imprimante"
+msgstr "Veuillez supprimer l'imprimante"
#: /home/ruben/Projects/Cura/resources/qml/MonitorButton.qml:241
msgctxt "@label:"
@@ -2685,7 +2716,9 @@ msgctxt "@text:window"
msgid ""
"You have customized some profile settings.\n"
"Would you like to keep or discard those settings?"
-msgstr "Vous avez personnalisé certains paramètres du profil.\nSouhaitez-vous conserver ces changements, ou les annuler ?"
+msgstr ""
+"Vous avez personnalisé certains paramètres du profil.\n"
+"Souhaitez-vous conserver ces changements, ou les annuler ?"
#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:110
msgctxt "@title:column"
@@ -3353,7 +3386,9 @@ msgctxt "@info:credit"
msgid ""
"Cura is developed by Ultimaker B.V. in cooperation with the community.\n"
"Cura proudly uses the following open source projects:"
-msgstr "Cura a été développé par Ultimaker B.V. en coopération avec la communauté Ultimaker.\nCura est fier d'utiliser les projets open source suivants :"
+msgstr ""
+"Cura a été développé par Ultimaker B.V. en coopération avec la communauté Ultimaker.\n"
+"Cura est fier d'utiliser les projets open source suivants :"
#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:118
msgctxt "@label"
@@ -3373,7 +3408,7 @@ msgstr "Générateur GCode"
#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:121
msgctxt "@label"
msgid "Interprocess communication library"
-msgstr "Bibliothèque de communication interprocess"
+msgstr "Bibliothèque de communication inter-process"
#: /home/ruben/Projects/Cura/resources/qml/AboutDialog.qml:123
msgctxt "@label"
@@ -3461,7 +3496,10 @@ msgid ""
"Some setting/override values are different from the values stored in the profile.\n"
"\n"
"Click to open the profile manager."
-msgstr "Certaines valeurs de paramètre / forçage sont différentes des valeurs enregistrées dans le profil. \n\nCliquez pour ouvrir le gestionnaire de profils."
+msgstr ""
+"Certaines valeurs de paramètre / forçage sont différentes des valeurs enregistrées dans le profil. \n"
+"\n"
+"Cliquez pour ouvrir le gestionnaire de profils."
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:150
msgctxt "@label:textbox"
@@ -3499,7 +3537,10 @@ msgid ""
"Some hidden settings use values different from their normal calculated value.\n"
"\n"
"Click to make these settings visible."
-msgstr "Certains paramètres masqués utilisent des valeurs différentes de leur valeur normalement calculée.\n\nCliquez pour rendre ces paramètres visibles."
+msgstr ""
+"Certains paramètres masqués utilisent des valeurs différentes de leur valeur normalement calculée.\n"
+"\n"
+"Cliquez pour rendre ces paramètres visibles."
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:61
msgctxt "@label Header for list of settings."
@@ -3514,7 +3555,7 @@ msgstr "Touché par"
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:156
msgctxt "@label"
msgid "This setting is always shared between all extruders. Changing it here will change the value for all extruders."
-msgstr "Ce paramètre est toujours partagé par toutes les extrudeuses. Le modifier ici entraînera la modification de la valeur pour toutes les extrudeuses."
+msgstr "Ce paramètre est toujours partagé par tous les extrudeurs. Le modifier ici entraînera la modification de la valeur pour tous les extrudeurs."
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:159
msgctxt "@label"
@@ -3527,7 +3568,10 @@ msgid ""
"This setting has a value that is different from the profile.\n"
"\n"
"Click to restore the value of the profile."
-msgstr "Ce paramètre possède une valeur qui est différente du profil.\n\nCliquez pour restaurer la valeur du profil."
+msgstr ""
+"Ce paramètre possède une valeur qui est différente du profil.\n"
+"\n"
+"Cliquez pour restaurer la valeur du profil."
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:288
msgctxt "@label"
@@ -3535,7 +3579,10 @@ msgid ""
"This setting is normally calculated, but it currently has an absolute value set.\n"
"\n"
"Click to restore the calculated value."
-msgstr "Ce paramètre est normalement calculé mais il possède actuellement une valeur absolue définie.\n\nCliquez pour restaurer la valeur calculée."
+msgstr ""
+"Ce paramètre est normalement calculé mais il possède actuellement une valeur absolue définie.\n"
+"\n"
+"Cliquez pour restaurer la valeur calculée."
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:128
msgctxt "@label:listbox"
@@ -3547,7 +3594,9 @@ msgctxt "@label:listbox"
msgid ""
"Print Setup disabled\n"
"G-code files cannot be modified"
-msgstr "Configuration de l'impression désactivée\nLes fichiers G-Code ne peuvent pas être modifiés"
+msgstr ""
+"Configuration de l'impression désactivée\n"
+"Les fichiers G-Code ne peuvent pas être modifiés"
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:342
msgctxt "@label Hours and minutes"
@@ -3659,7 +3708,7 @@ msgstr "Aucune imprimante n'est connectée"
#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:139
msgctxt "@label"
msgid "Extruder"
-msgstr "Extrudeuse"
+msgstr "Extrudeur"
#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:120
msgctxt "@tooltip"
@@ -4168,7 +4217,7 @@ msgstr "Nouveau projet"
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:555
msgctxt "@info:question"
msgid "Are you sure you want to start a new project? This will clear the build plate and any unsaved settings."
-msgstr "Êtes-vous sûr(e) de souhaiter lancer un nouveau projet ? Cela supprimera les objets du plateau ainsi que tous paramètres non enregistrés."
+msgstr "Êtes-vous sûr(e) de vouloir commencer un nouveau projet ? Cela supprimera les objets du plateau ainsi que tous paramètres non enregistrés."
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:797
msgctxt "@window:title"
@@ -4193,7 +4242,7 @@ msgstr "Enregistrer le projet"
#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:136
msgctxt "@action:label"
msgid "Extruder %1"
-msgstr "Extrudeuse %1"
+msgstr "Extrudeur %1"
#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:146
msgctxt "@action:label"
@@ -4258,12 +4307,12 @@ msgstr "Générer les supports"
#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:781
msgctxt "@label"
msgid "Generate structures to support parts of the model which have overhangs. Without these structures, such parts would collapse during printing."
-msgstr "Générer des structures pour soutenir les parties du modèle qui possèdent des porte-à-faux. Sans ces structures, ces parties s'effondreront durant l'impression."
+msgstr "Générer des supports pour soutenir les parties du modèle qui possèdent des porte-à-faux. Sans ces supports, ces parties s'effondreront durant l'impression."
#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:799
msgctxt "@label"
msgid "Support Extruder"
-msgstr "Extrudeuse de soutien"
+msgstr "Extrudeur pour matériau support"
#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:851
msgctxt "@label"
@@ -4278,7 +4327,7 @@ msgstr "Adhérence au plateau"
#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:929
msgctxt "@label"
msgid "Enable printing a brim or raft. This will add a flat area around or under your object which is easy to cut off afterwards."
-msgstr "Activez l'impression d'une bordure ou plaquette (Brim/Raft). Cela ajoutera une zone plate autour de ou sous votre objet qui est facile à découper par la suite."
+msgstr "Activez l'impression du Brim ou Raft. Cela ajoutera une zone plate autour de ou sous votre objet qui est facile à retirer par la suite."
#: /home/ruben/Projects/Cura/resources/qml/SidebarSimple.qml:969
msgctxt "@label"
@@ -4500,7 +4549,7 @@ msgstr "Vérifie les mises à jour du firmware."
#: FirmwareUpdateChecker/plugin.json
msgctxt "name"
msgid "Firmware Update Checker"
-msgstr "Vérificateur des mises à jour du firmware"
+msgstr "Vérification des mises à jour du firmware"
#: CuraSolidWorksPlugin/plugin.json
msgctxt "description"
@@ -4560,7 +4609,7 @@ msgstr "Offre la possibilité de lire et d'écrire des profils matériels basés
#: XmlMaterialProfile/plugin.json
msgctxt "name"
msgid "Material Profiles"
-msgstr "Profils matériels"
+msgstr "Profils matériaux"
#: LegacyProfileReader/plugin.json
msgctxt "description"
@@ -4690,7 +4739,7 @@ msgstr "Vous aide à installer un bouton « exporter vers Cura » dans Siemens
#: cura-siemensnx-plugin/plugin.json
msgctxt "name"
msgid "Siemens NX Integration"
-msgstr "Siemens NX Integration"
+msgstr "Intégration Siemens NX"
#: 3MFReader/plugin.json
msgctxt "description"
@@ -4765,17 +4814,17 @@ msgstr "Générateur 3MF"
#: UserAgreementPlugin/plugin.json
msgctxt "description"
msgid "Ask the user once if he/she agrees with our license"
-msgstr "Demander à l'utilisateur une fois s'il appose son accord à notre licence"
+msgstr "Demander à l'utilisateur une fois s'il est d'accord avec les termes de notre licence"
#: UserAgreementPlugin/plugin.json
msgctxt "name"
msgid "UserAgreement"
-msgstr "UserAgreement"
+msgstr "Accord de l'utilisateur"
#: UltimakerMachineActions/plugin.json
msgctxt "description"
msgid "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc)"
-msgstr "Fournit les actions de la machine pour les machines Ultimaker (telles que l'assistant de calibration du plateau, sélection des mises à niveau, etc.)"
+msgstr "Fournit les actions de la machine pour les machines Ultimaker (tels que l'assistant de calibration du plateau, sélection des mises à niveau, etc.)"
#: UltimakerMachineActions/plugin.json
msgctxt "name"
diff --git a/resources/i18n/fr_FR/fdmprinter.def.json.po b/resources/i18n/fr_FR/fdmprinter.def.json.po
index ac292df766..35731b8312 100644
--- a/resources/i18n/fr_FR/fdmprinter.def.json.po
+++ b/resources/i18n/fr_FR/fdmprinter.def.json.po
@@ -1,20 +1,21 @@
-# Cura JSON setting files
-# Copyright (C) 2017 Ultimaker
+# Cura
+# Copyright (C) 2018 Ultimaker
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2017.
+# Ruben Dulek , 2018.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.0\n"
+"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2017-08-02 16:53+0000\n"
-"PO-Revision-Date: 2017-11-30 13:05+0100\n"
+"POT-Creation-Date: 2018-01-29 09:48+0000\n"
+"PO-Revision-Date: 2018-02-13 15:31+0100\n"
"Last-Translator: Bothof \n"
"Language-Team: French\n"
"Language: fr_FR\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: Poedit 2.0.6\n"
#: fdmprinter.def.json
msgctxt "machine_settings label"
@@ -56,7 +57,9 @@ msgctxt "machine_start_gcode description"
msgid ""
"Gcode commands to be executed at the very start - separated by \n"
"."
-msgstr "Commandes Gcode à exécuter au tout début, séparées par \n."
+msgstr ""
+"Commandes Gcode à exécuter au tout début, séparées par \n"
+"."
#: fdmprinter.def.json
msgctxt "machine_end_gcode label"
@@ -68,17 +71,19 @@ msgctxt "machine_end_gcode description"
msgid ""
"Gcode commands to be executed at the very end - separated by \n"
"."
-msgstr "Commandes Gcode à exécuter à la toute fin, séparées par \n."
+msgstr ""
+"Commandes Gcode à exécuter à la toute fin, séparées par \n"
+"."
#: fdmprinter.def.json
msgctxt "material_guid label"
msgid "Material GUID"
-msgstr "GUID matériau"
+msgstr "Identification GUID du matériau"
#: fdmprinter.def.json
msgctxt "material_guid description"
msgid "GUID of the material. This is set automatically. "
-msgstr "GUID du matériau. Cela est configuré automatiquement. "
+msgstr "Identification GUID du matériau. Cela est configuré automatiquement. "
#: fdmprinter.def.json
msgctxt "material_bed_temp_wait label"
@@ -148,7 +153,7 @@ msgstr "Forme du plateau"
#: fdmprinter.def.json
msgctxt "machine_shape description"
msgid "The shape of the build plate without taking unprintable areas into account."
-msgstr "La forme du plateau sans prendre les zones non imprimables en compte."
+msgstr "La forme du plateau sans prendre en compte les zones non imprimables."
#: fdmprinter.def.json
msgctxt "machine_shape option rectangular"
@@ -173,12 +178,12 @@ msgstr "La hauteur (sens Z) de la zone imprimable."
#: fdmprinter.def.json
msgctxt "machine_heated_bed label"
msgid "Has Heated Build Plate"
-msgstr "A un plateau chauffé"
+msgstr "A un plateau chauffant"
#: fdmprinter.def.json
msgctxt "machine_heated_bed description"
msgid "Whether the machine has a heated build plate present."
-msgstr "Si la machine a un plateau chauffé présent."
+msgstr "Si la machine a un plateau chauffant existant."
#: fdmprinter.def.json
msgctxt "machine_center_is_zero label"
@@ -198,7 +203,7 @@ msgstr "Nombre d'extrudeuses"
#: fdmprinter.def.json
msgctxt "machine_extruder_count description"
msgid "Number of extruder trains. An extruder train is the combination of a feeder, bowden tube, and nozzle."
-msgstr "Nombre de trains d'extrudeuse. Un train d'extrudeuse est la combinaison d'un chargeur, d'un tube bowden et d'une buse."
+msgstr "Nombre de systèmes d'extrusion. Un système d'extrusion est la combinaison d'un feeder, d'un tube bowden et d'une buse."
#: fdmprinter.def.json
msgctxt "machine_nozzle_tip_outer_diameter label"
@@ -238,7 +243,7 @@ msgstr "Longueur de la zone chauffée"
#: fdmprinter.def.json
msgctxt "machine_heat_zone_length description"
msgid "The distance from the tip of the nozzle in which heat from the nozzle is transferred to the filament."
-msgstr "Distance depuis la pointe du bec d'impression sur laquelle la chaleur du bec d'impression est transférée au filament."
+msgstr "Distance depuis la pointe de la buse sur laquelle la chaleur de la buse est transférée au filament."
#: fdmprinter.def.json
msgctxt "machine_filament_park_distance label"
@@ -248,7 +253,7 @@ msgstr "Distance de stationnement du filament"
#: fdmprinter.def.json
msgctxt "machine_filament_park_distance description"
msgid "The distance from the tip of the nozzle where to park the filament when an extruder is no longer used."
-msgstr "Distance depuis la pointe du bec sur laquelle stationner le filament lorsqu'une extrudeuse n'est plus utilisée."
+msgstr "Distance depuis la pointe de la buse sur laquelle stationne le filament lorsqu'une extrudeuse n'est plus utilisée."
#: fdmprinter.def.json
msgctxt "machine_nozzle_temp_enabled label"
@@ -263,7 +268,7 @@ msgstr "Contrôler ou non la température depuis Cura. Désactivez cette option
#: fdmprinter.def.json
msgctxt "machine_nozzle_heat_up_speed label"
msgid "Heat up speed"
-msgstr "Vitesse de chauffage"
+msgstr "Vitesse de chauffe"
#: fdmprinter.def.json
msgctxt "machine_nozzle_heat_up_speed description"
@@ -283,7 +288,7 @@ msgstr "La vitesse (°C/s) à laquelle la buse refroidit, sur une moyenne de la
#: fdmprinter.def.json
msgctxt "machine_min_cool_heat_time_window label"
msgid "Minimal Time Standby Temperature"
-msgstr "Durée minimale température de veille"
+msgstr "Température minimale de veille"
#: fdmprinter.def.json
msgctxt "machine_min_cool_heat_time_window description"
@@ -368,12 +373,12 @@ msgstr "Une liste de polygones comportant les zones dans lesquelles la tête d'i
#: fdmprinter.def.json
msgctxt "nozzle_disallowed_areas label"
msgid "Nozzle Disallowed Areas"
-msgstr "Zones interdites au bec d'impression"
+msgstr "Zones interdites à la buse"
#: fdmprinter.def.json
msgctxt "nozzle_disallowed_areas description"
msgid "A list of polygons with areas the nozzle is not allowed to enter."
-msgstr "Une liste de polygones comportant les zones dans lesquelles le bec n'a pas le droit de pénétrer."
+msgstr "Une liste de polygones comportant les zones dans lesquelles la buse n'a pas le droit de pénétrer."
#: fdmprinter.def.json
msgctxt "machine_head_polygon label"
@@ -383,7 +388,7 @@ msgstr "Polygone de la tête de machine"
#: fdmprinter.def.json
msgctxt "machine_head_polygon description"
msgid "A 2D silhouette of the print head (fan caps excluded)."
-msgstr "Une silhouette 2D de la tête d'impression (sans les capuchons du ventilateur)."
+msgstr "Une silhouette 2D de la tête d'impression (sans les carter du ventilateur)."
#: fdmprinter.def.json
msgctxt "machine_head_with_fans_polygon label"
@@ -393,7 +398,7 @@ msgstr "Tête de la machine et polygone du ventilateur"
#: fdmprinter.def.json
msgctxt "machine_head_with_fans_polygon description"
msgid "A 2D silhouette of the print head (fan caps included)."
-msgstr "Une silhouette 2D de la tête d'impression (avec les capuchons du ventilateur)."
+msgstr "Une silhouette 2D de la tête d'impression (avec les carters du ventilateur)."
#: fdmprinter.def.json
msgctxt "gantry_height label"
@@ -408,12 +413,12 @@ msgstr "La différence de hauteur entre la pointe de la buse et le système de p
#: fdmprinter.def.json
msgctxt "machine_nozzle_id label"
msgid "Nozzle ID"
-msgstr "ID buse"
+msgstr "ID de la buse"
#: fdmprinter.def.json
msgctxt "machine_nozzle_id description"
msgid "The nozzle ID for an extruder train, such as \"AA 0.4\" and \"BB 0.8\"."
-msgstr "ID buse pour un train d'extrudeuse, comme « AA 0.4 » et « BB 0.8 »."
+msgstr "ID de la buse pour un système d'extrusion, comme « AA 0.4 » et « BB 0.8 »."
#: fdmprinter.def.json
msgctxt "machine_nozzle_size label"
@@ -428,17 +433,17 @@ msgstr "Le diamètre intérieur de la buse. Modifiez ce paramètre si vous utili
#: fdmprinter.def.json
msgctxt "machine_use_extruder_offset_to_offset_coords label"
msgid "Offset With Extruder"
-msgstr "Décalage avec extrudeuse"
+msgstr "Offset avec extrudeuse"
#: fdmprinter.def.json
msgctxt "machine_use_extruder_offset_to_offset_coords description"
msgid "Apply the extruder offset to the coordinate system."
-msgstr "Appliquer le décalage de l'extrudeuse au système de coordonnées."
+msgstr "Appliquer l'offset de l'extrudeuse au système de coordonnées."
#: fdmprinter.def.json
msgctxt "extruder_prime_pos_z label"
msgid "Extruder Prime Z Position"
-msgstr "Extrudeuse Position d'amorçage Z"
+msgstr "Position d'amorçage en Z de l'extrudeuse"
#: fdmprinter.def.json
msgctxt "extruder_prime_pos_z description"
@@ -598,7 +603,7 @@ msgstr "Tous les paramètres qui influent sur la résolution de l'impression. Ce
#: fdmprinter.def.json
msgctxt "layer_height label"
msgid "Layer Height"
-msgstr "Hauteur de la couche"
+msgstr "Hauteur de couche"
#: fdmprinter.def.json
msgctxt "layer_height description"
@@ -608,7 +613,7 @@ msgstr "La hauteur de chaque couche en mm. Des valeurs plus élevées créent de
#: fdmprinter.def.json
msgctxt "layer_height_0 label"
msgid "Initial Layer Height"
-msgstr "Hauteur de la couche initiale"
+msgstr "Hauteur de couche initiale"
#: fdmprinter.def.json
msgctxt "layer_height_0 description"
@@ -628,12 +633,12 @@ msgstr "Largeur d'une ligne. Généralement, la largeur de chaque ligne doit cor
#: fdmprinter.def.json
msgctxt "wall_line_width label"
msgid "Wall Line Width"
-msgstr "Largeur de ligne de la paroi"
+msgstr "Largeur de ligne de la coque"
#: fdmprinter.def.json
msgctxt "wall_line_width description"
msgid "Width of a single wall line."
-msgstr "Largeur d'une seule ligne de la paroi."
+msgstr "Largeur d'une seule ligne de la paroie."
#: fdmprinter.def.json
msgctxt "wall_line_width_0 label"
@@ -688,7 +693,7 @@ msgstr "Largeur d'une seule ligne de jupe ou de bordure."
#: fdmprinter.def.json
msgctxt "support_line_width label"
msgid "Support Line Width"
-msgstr "Largeur de ligne de support"
+msgstr "Largeur de ligne des supports"
#: fdmprinter.def.json
msgctxt "support_line_width description"
@@ -708,12 +713,12 @@ msgstr "Largeur d'une seule ligne de plafond ou de bas de support."
#: fdmprinter.def.json
msgctxt "support_roof_line_width label"
msgid "Support Roof Line Width"
-msgstr "Largeur de ligne de plafond de support"
+msgstr "Largeur de ligne du toit de support"
#: fdmprinter.def.json
msgctxt "support_roof_line_width description"
msgid "Width of a single support roof line."
-msgstr "Largeur d'une seule ligne de plafond de support."
+msgstr "Largeur d'une seule ligne de toit de support."
#: fdmprinter.def.json
msgctxt "support_bottom_line_width label"
@@ -763,7 +768,7 @@ msgstr "Extrudeuse de paroi"
#: fdmprinter.def.json
msgctxt "wall_extruder_nr description"
msgid "The extruder train used for printing the walls. This is used in multi-extrusion."
-msgstr "Le train d'extrudeuse utilisé pour l'impression des parois. Cela est utilisé en multi-extrusion."
+msgstr "Le système d'extrusion utilisé pour l'impression des parois. Cela est utilisé en multi-extrusion."
#: fdmprinter.def.json
msgctxt "wall_0_extruder_nr label"
@@ -773,7 +778,7 @@ msgstr "Extrudeuse de paroi externe"
#: fdmprinter.def.json
msgctxt "wall_0_extruder_nr description"
msgid "The extruder train used for printing the outer wall. This is used in multi-extrusion."
-msgstr "Le train d'extrudeuse utilisé pour l'impression des parois externes. Cela est utilisé en multi-extrusion."
+msgstr "Le système d'extrusion utilisé pour l'impression des parois externes. Cela est utilisé en multi-extrusion."
#: fdmprinter.def.json
msgctxt "wall_x_extruder_nr label"
@@ -783,7 +788,7 @@ msgstr "Extrudeuse de paroi interne"
#: fdmprinter.def.json
msgctxt "wall_x_extruder_nr description"
msgid "The extruder train used for printing the inner walls. This is used in multi-extrusion."
-msgstr "Le train d'extrudeuse utilisé pour l'impression des parois internes. Cela est utilisé en multi-extrusion."
+msgstr "Le système d'extrusion utilisé pour l'impression des parois internes. Cela est utilisé en multi-extrusion."
#: fdmprinter.def.json
msgctxt "wall_thickness label"
@@ -823,7 +828,7 @@ msgstr "Extrudeuse de couche extérieure de la surface supérieure"
#: fdmprinter.def.json
msgctxt "roofing_extruder_nr description"
msgid "The extruder train used for printing the top most skin. This is used in multi-extrusion."
-msgstr "Le train d'extrudeuse utilisé pour l'impression de la couche extérieure supérieure. Cela est utilisé en multi-extrusion."
+msgstr "Le système d'extrusion utilisé pour l'impression de la couche extérieure supérieure. Cela est utilisé en multi-extrusion."
#: fdmprinter.def.json
msgctxt "roofing_layer_count label"
@@ -843,7 +848,7 @@ msgstr "Extrudeuse du dessus/dessous"
#: fdmprinter.def.json
msgctxt "top_bottom_extruder_nr description"
msgid "The extruder train used for printing the top and bottom skin. This is used in multi-extrusion."
-msgstr "Le train d'extrudeuse utilisé pour l'impression de la couche extérieure du haut et du bas. Cela est utilisé en multi-extrusion."
+msgstr "Le système d'extrusion utilisé pour l'impression de la couche extérieure du haut et du bas. Cela est utilisé en multi-extrusion."
#: fdmprinter.def.json
msgctxt "top_bottom_thickness label"
@@ -958,12 +963,12 @@ msgstr "Une liste de sens de ligne (exprimés en nombres entiers) à utiliser lo
#: fdmprinter.def.json
msgctxt "wall_0_inset label"
msgid "Outer Wall Inset"
-msgstr "Insert de paroi externe"
+msgstr "Enchevêtrement de la paroi externe"
#: fdmprinter.def.json
msgctxt "wall_0_inset description"
msgid "Inset applied to the path of the outer wall. If the outer wall is smaller than the nozzle, and printed after the inner walls, use this offset to get the hole in the nozzle to overlap with the inner walls instead of the outside of the model."
-msgstr "Insert appliqué sur le passage de la paroi externe. Si la paroi externe est plus petite que la buse et imprimée après les parois intérieures, utiliser ce décalage pour que le trou dans la buse chevauche les parois internes et non l'extérieur du modèle."
+msgstr "Enchevêtrement appliqué sur le passage de la paroi externe. Si la paroi externe est plus petite que la buse et imprimée après les parois intérieures, utiliser cet Offset pour que le trou dans la buse chevauche les parois internes et non l'extérieur du modèle."
#: fdmprinter.def.json
msgctxt "optimize_wall_printing_order label"
@@ -1028,12 +1033,12 @@ msgstr "Compenser le débit pour les parties d'une paroi intérieure imprimées
#: fdmprinter.def.json
msgctxt "fill_perimeter_gaps label"
msgid "Fill Gaps Between Walls"
-msgstr "Remplir les trous entre les parois"
+msgstr "Remplir l'espace entre les parois"
#: fdmprinter.def.json
msgctxt "fill_perimeter_gaps description"
msgid "Fills the gaps between walls where no walls fit."
-msgstr "Imprime les remplissages entre les parois lorsqu'aucune paroi ne convient."
+msgstr "Rempli l'espace entre les parois lorsqu'aucune paroi ne convient."
#: fdmprinter.def.json
msgctxt "fill_perimeter_gaps option nowhere"
@@ -1048,12 +1053,12 @@ msgstr "Partout"
#: fdmprinter.def.json
msgctxt "filter_out_tiny_gaps label"
msgid "Filter Out Tiny Gaps"
-msgstr "Filtrer les très petits trous"
+msgstr "Filtrer les petits espaces"
#: fdmprinter.def.json
msgctxt "filter_out_tiny_gaps description"
msgid "Filter out tiny gaps to reduce blobs on outside of model."
-msgstr "Filtrer les très petits trous pour réduire la présence de gouttes à l'extérieur du modèle."
+msgstr "Filtrer les petits espaces pour réduire la présence de gouttes à l'extérieur du modèle."
#: fdmprinter.def.json
msgctxt "fill_outline_gaps label"
@@ -1068,12 +1073,12 @@ msgstr "Imprimer les parties du modèle qui sont horizontalement plus fines que
#: fdmprinter.def.json
msgctxt "xy_offset label"
msgid "Horizontal Expansion"
-msgstr "Vitesse d’impression horizontale"
+msgstr "Expansion horizontale"
#: fdmprinter.def.json
msgctxt "xy_offset description"
msgid "Amount of offset applied to all polygons in each layer. Positive values can compensate for too big holes; negative values can compensate for too small holes."
-msgstr "Le décalage appliqué à tous les polygones dans chaque couche. Une valeur positive peut compenser les trous trop gros ; une valeur négative peut compenser les trous trop petits."
+msgstr "L'offset appliqué à tous les polygones dans chaque couche. Une valeur positive peut compenser les trous trop gros ; une valeur négative peut compenser les trous trop petits."
#: fdmprinter.def.json
msgctxt "xy_offset_layer_0 label"
@@ -1083,7 +1088,7 @@ msgstr "Expansion horizontale de la couche initiale"
#: fdmprinter.def.json
msgctxt "xy_offset_layer_0 description"
msgid "Amount of offset applied to all polygons in the first layer. A negative value can compensate for squishing of the first layer known as \"elephant's foot\"."
-msgstr "Le décalage appliqué à tous les polygones dans la première couche. Une valeur négative peut compenser l'écrasement de la première couche, appelé « patte d'éléphant »."
+msgstr "L'offset appliqué à tous les polygones dans la première couche. Une valeur négative peut compenser l'écrasement de la première couche, appelé « patte d'éléphant »."
#: fdmprinter.def.json
msgctxt "z_seam_type label"
@@ -1093,7 +1098,7 @@ msgstr "Alignement de la jointure en Z"
#: fdmprinter.def.json
msgctxt "z_seam_type description"
msgid "Starting point of each path in a layer. When paths in consecutive layers start at the same point a vertical seam may show on the print. When aligning these near a user specified location, the seam is easiest to remove. When placed randomly the inaccuracies at the paths' start will be less noticeable. When taking the shortest path the print will be quicker."
-msgstr "Point de départ de chaque voie dans une couche. Quand les voies dans les couches consécutives démarrent au même endroit, une jointure verticale peut apparaître sur l'impression. En alignant les points de départ près d'un emplacement défini par l'utilisateur, la jointure sera plus facile à faire disparaître. Lorsqu'elles sont disposées de manière aléatoire, les imprécisions de départ des voies seront moins visibles. En choisissant la voie la plus courte, l'impression se fera plus rapidement."
+msgstr "Point de départ de chaque chemin dans une couche. Quand les chemins dans les couches consécutives démarrent au même endroit, une jointure verticale peut apparaître sur l'impression. En alignant les points de départ près d'un emplacement défini par l'utilisateur, la jointure sera plus facile à faire disparaître. Lorsqu'elles sont disposées de manière aléatoire, les imprécisions de départ des chemins seront moins visibles. En choisissant le chemin le plus court, l'impression se fera plus rapidement."
#: fdmprinter.def.json
msgctxt "z_seam_type option back"
@@ -1178,12 +1183,12 @@ msgstr "Si cette option est activée, les coordonnées de la jointure z sont rel
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic label"
msgid "Ignore Small Z Gaps"
-msgstr "Ignorer les petits trous en Z"
+msgstr "Ignorer les petits espaces en Z"
#: fdmprinter.def.json
msgctxt "skin_no_small_gaps_heuristic description"
msgid "When the model has small vertical gaps, about 5% extra computation time can be spent on generating top and bottom skin in these narrow spaces. In such case, disable the setting."
-msgstr "Quand le modèle présente de petits trous verticaux, environ 5 % de temps de calcul supplémentaire peut être alloué à la génération de couches du dessus et du dessous dans ces espaces étroits. Dans ce cas, désactivez ce paramètre."
+msgstr "Quand le modèle présente de petits espaces verticaux, environ 5 % de temps de calcul supplémentaire peut être alloué à la génération de couches du dessus et du dessous dans ces espaces étroits. Dans ce cas, désactivez ce paramètre."
#: fdmprinter.def.json
msgctxt "skin_outline_count label"
@@ -1198,32 +1203,32 @@ msgstr "Remplace la partie la plus externe du motif du dessus/dessous par un cer
#: fdmprinter.def.json
msgctxt "ironing_enabled label"
msgid "Enable Ironing"
-msgstr "Activer l'étirage"
+msgstr "Activer le lissage"
#: fdmprinter.def.json
msgctxt "ironing_enabled description"
msgid "Go over the top surface one additional time, but without extruding material. This is meant to melt the plastic on top further, creating a smoother surface."
-msgstr "Aller au-dessus de la surface supérieure une fois supplémentaire, mais sans extruder de matériau. Cela signifie de faire fondre le plastique en haut un peu plus, pour créer une surface lisse."
+msgstr "Aller au-dessus de la surface supérieure une fois supplémentaire, mais sans extruder de matériau. Cela signifie de faire fondre le plastique sur les couches supérieures, pour créer une surface lisse."
#: fdmprinter.def.json
msgctxt "ironing_only_highest_layer label"
msgid "Iron Only Highest Layer"
-msgstr "N'étirer que la couche supérieure"
+msgstr "Ne lisser que la couche supérieure"
#: fdmprinter.def.json
msgctxt "ironing_only_highest_layer description"
msgid "Only perform ironing on the very last layer of the mesh. This saves time if the lower layers don't need a smooth surface finish."
-msgstr "N'exécute un étirage que sur l'ultime couche du maillage. Ceci économise du temps si les couches inférieures ne nécessitent pas de fini lisse de surface."
+msgstr "N'exécute un lissage que sur la dernière couche du maillage. Ceci économise du temps si les couches inférieures ne nécessitent pas de finition lissée."
#: fdmprinter.def.json
msgctxt "ironing_pattern label"
msgid "Ironing Pattern"
-msgstr "Motif d'étirage"
+msgstr "Motif de lissage"
#: fdmprinter.def.json
msgctxt "ironing_pattern description"
msgid "The pattern to use for ironing top surfaces."
-msgstr "Le motif à utiliser pour étirer les surfaces supérieures."
+msgstr "Le motif à utiliser pour lisser les surfaces supérieures."
#: fdmprinter.def.json
msgctxt "ironing_pattern option concentric"
@@ -1238,37 +1243,37 @@ msgstr "Zig Zag"
#: fdmprinter.def.json
msgctxt "ironing_line_spacing label"
msgid "Ironing Line Spacing"
-msgstr "Interligne de l'étirage"
+msgstr "Interligne de lissage"
#: fdmprinter.def.json
msgctxt "ironing_line_spacing description"
msgid "The distance between the lines of ironing."
-msgstr "La distance entre les lignes d'étirage."
+msgstr "La distance entre les lignes de lissage"
#: fdmprinter.def.json
msgctxt "ironing_flow label"
msgid "Ironing Flow"
-msgstr "Flux d'étirage"
+msgstr "Flux de lissage"
#: fdmprinter.def.json
msgctxt "ironing_flow description"
msgid "The amount of material, relative to a normal skin line, to extrude during ironing. Keeping the nozzle filled helps filling some of the crevices of the top surface, but too much results in overextrusion and blips on the side of the surface."
-msgstr "La quantité de matériau, relative à une ligne de couche extérieure normale, à extruder pendant l'étirage. Le fait de garder la buse pleine aide à remplir certaines des crevasses de la surface supérieure ; mais si la quantité est trop importante, cela entraînera une surextrusion et l'apparition de coupures sur le côté de la surface."
+msgstr "La quantité de matériau, relative à une ligne de couche extérieure normale, à extruder pendant le lissage. Le fait de garder la buse pleine aide à remplir certaines des crevasses de la surface supérieure ; mais si la quantité est trop importante, cela entraînera une surextrusion et l'apparition de coupures sur le côté de la surface."
#: fdmprinter.def.json
msgctxt "ironing_inset label"
msgid "Ironing Inset"
-msgstr "Insert d'étirage"
+msgstr "Chevauchement du lissage"
#: fdmprinter.def.json
msgctxt "ironing_inset description"
msgid "A distance to keep from the edges of the model. Ironing all the way to the edge of the mesh may result in a jagged edge on your print."
-msgstr "Distance à garder à partir des bords du modèle. Étirer jusqu'au bord de la maille peut entraîner l'apparition d'un bord denté sur votre impression."
+msgstr "Distance à garder à partir des bords du modèle. Lisser jusqu'au bord de la maille peut entraîner l'apparition d'un bord denté sur votre impression."
#: fdmprinter.def.json
msgctxt "speed_ironing label"
msgid "Ironing Speed"
-msgstr "Vitesse d'étirage"
+msgstr "Vitesse de lissage"
#: fdmprinter.def.json
msgctxt "speed_ironing description"
@@ -1278,22 +1283,22 @@ msgstr "La vitesse à laquelle passer sur la surface supérieure."
#: fdmprinter.def.json
msgctxt "acceleration_ironing label"
msgid "Ironing Acceleration"
-msgstr "Accélération d'étirage"
+msgstr "Accélération du lissage"
#: fdmprinter.def.json
msgctxt "acceleration_ironing description"
msgid "The acceleration with which ironing is performed."
-msgstr "L'accélération selon laquelle l'étirage est effectué."
+msgstr "L'accélération selon laquelle le lissage est effectué."
#: fdmprinter.def.json
msgctxt "jerk_ironing label"
msgid "Ironing Jerk"
-msgstr "Saccade d'étirage"
+msgstr "Saccade du lissage"
#: fdmprinter.def.json
msgctxt "jerk_ironing description"
msgid "The maximum instantaneous velocity change while performing ironing."
-msgstr "Le changement instantané maximal de vitesse lors de l'étirage."
+msgstr "Le changement instantané maximal de vitesse lors du lissage."
#: fdmprinter.def.json
msgctxt "infill label"
@@ -1313,7 +1318,7 @@ msgstr "Extrudeuse de remplissage"
#: fdmprinter.def.json
msgctxt "infill_extruder_nr description"
msgid "The extruder train used for printing infill. This is used in multi-extrusion."
-msgstr "Le train d'extrudeuse utilisé pour l'impression du remplissage. Cela est utilisé en multi-extrusion."
+msgstr "Le système d'extrusion utilisé pour l'impression du remplissage. Cela est utilisé en multi-extrusion."
#: fdmprinter.def.json
msgctxt "infill_sparse_density label"
@@ -1338,12 +1343,12 @@ msgstr "Distance entre les lignes de remplissage imprimées. Ce paramètre est c
#: fdmprinter.def.json
msgctxt "infill_pattern label"
msgid "Infill Pattern"
-msgstr "Motif de remplissage"
+msgstr "Motif du remplissage"
#: fdmprinter.def.json
msgctxt "infill_pattern description"
msgid "The pattern of the infill material of the print. The line and zig zag infill swap direction on alternate layers, reducing material cost. The grid, triangle, tri-hexagon, cubic, octet, quarter cubic, cross and concentric patterns are fully printed every layer. Cubic, quarter cubic and octet infill change with every layer to provide a more equal distribution of strength over each direction."
-msgstr "Motif du matériau de remplissage de l'impression. La ligne et le remplissage en zigzag changent de sens à chaque alternance de couche, réduisant ainsi les coûts matériels. Les motifs en grille, en triangle, trihexagonaux, cubiques, octaédriques, quart cubiques et concentriques sont entièrement imprimés sur chaque couche. Les remplissages cubique, quart cubique et octaédrique changent à chaque couche afin d'offrir une répartition plus égale de la solidité dans chaque direction."
+msgstr "Le motif du remplissage de l'impression. La ligne et le remplissage en zigzag changent de sens à chaque alternance de couche, réduisant ainsi les coûts matériels. Les motifs en grille, en triangle, trihexagonaux, cubiques, octaédriques, quart cubiques et concentriques sont entièrement imprimés sur chaque couche. Les remplissages cubique, quart cubique et octaédrique changent à chaque couche afin d'offrir une répartition plus égale de la solidité dans chaque direction."
#: fdmprinter.def.json
msgctxt "infill_pattern option grid"
@@ -1433,7 +1438,7 @@ msgstr "Une liste de sens de ligne (exprimés en nombres entiers) à utiliser. L
#: fdmprinter.def.json
msgctxt "infill_offset_x label"
msgid "Infill X Offset"
-msgstr "Remplissage Décalage X"
+msgstr "Offset Remplissage X"
#: fdmprinter.def.json
msgctxt "infill_offset_x description"
@@ -1443,7 +1448,7 @@ msgstr "Le motif de remplissage est décalé de cette distance sur l'axe X."
#: fdmprinter.def.json
msgctxt "infill_offset_y label"
msgid "Infill Y Offset"
-msgstr "Remplissage Décalage Y"
+msgstr "Remplissage Offset Y"
#: fdmprinter.def.json
msgctxt "infill_offset_y description"
@@ -1658,7 +1663,7 @@ msgstr "Température d’impression par défaut"
#: fdmprinter.def.json
msgctxt "default_material_print_temperature description"
msgid "The default temperature used for printing. This should be the \"base\" temperature of a material. All other print temperatures should use offsets based on this value"
-msgstr "La température par défaut utilisée pour l'impression. Il doit s'agir de la température de « base » d'un matériau. Toutes les autres températures d'impression doivent utiliser des décalages basés sur cette valeur."
+msgstr "La température par défaut utilisée pour l'impression. Il doit s'agir de la température de « base » d'un matériau. Toutes les autres températures d'impression doivent utiliser des offset basés sur cette valeur."
#: fdmprinter.def.json
msgctxt "material_print_temperature label"
@@ -1788,7 +1793,7 @@ msgstr "Rétracter au changement de couche"
#: fdmprinter.def.json
msgctxt "retract_at_layer_change description"
msgid "Retract the filament when the nozzle is moving to the next layer."
-msgstr "Rétracter le filament quand le bec se déplace vers la prochaine couche. "
+msgstr "Rétracter le filament quand la buse se déplace vers la prochaine couche."
#: fdmprinter.def.json
msgctxt "retraction_amount label"
@@ -2543,12 +2548,12 @@ msgstr "déplacement"
#: fdmprinter.def.json
msgctxt "retraction_combing label"
msgid "Combing Mode"
-msgstr "Mode de détours"
+msgstr "Mode detour"
#: fdmprinter.def.json
msgctxt "retraction_combing description"
msgid "Combing keeps the nozzle within already printed areas when traveling. This results in slightly longer travel moves but reduces the need for retractions. If combing is off, the material will retract and the nozzle moves in a straight line to the next point. It is also possible to avoid combing over top/bottom skin areas by combing within the infill only."
-msgstr "Les détours (le 'combing') maintiennent le bec dans les zones déjà imprimées lors des déplacements. Cela résulte en des déplacements légèrement plus longs mais réduit le recours aux rétractions. Si les détours sont désactivés, le matériau se rétractera et le bec se déplacera en ligne droite jusqu'au point suivant. Il est également possible d'éviter les détours sur les zones de la couche du dessus / dessous en effectuant les détours uniquement dans le remplissage."
+msgstr "Les détours (le 'combing') maintiennent la buse dans les zones déjà imprimées lors des déplacements. Cela résulte en des déplacements légèrement plus longs mais réduit le recours aux rétractions. Si les détours sont désactivés, le matériau se rétractera et la buze se déplacera en ligne droite jusqu'au point suivant. Il est également possible d'éviter les détours sur les zones de la couche du dessus / dessous en effectuant les détours uniquement dans le remplissage."
#: fdmprinter.def.json
msgctxt "retraction_combing option off"
@@ -2728,7 +2733,7 @@ msgstr "La durée de couche qui définit la limite entre la vitesse régulière
#: fdmprinter.def.json
msgctxt "cool_fan_speed_0 label"
msgid "Initial Fan Speed"
-msgstr "Vitesse des ventilateurs initiale"
+msgstr "Vitesse initiale des ventilateurs"
#: fdmprinter.def.json
msgctxt "cool_fan_speed_0 description"
@@ -2813,7 +2818,7 @@ msgstr "Extrudeuse de support"
#: fdmprinter.def.json
msgctxt "support_extruder_nr description"
msgid "The extruder train to use for printing the support. This is used in multi-extrusion."
-msgstr "Le train d'extrudeuse à utiliser pour l'impression du support. Cela est utilisé en multi-extrusion."
+msgstr "Le système d'extrusion à utiliser pour l'impression du support. Cela est utilisé en multi-extrusion."
#: fdmprinter.def.json
msgctxt "support_infill_extruder_nr label"
@@ -2823,7 +2828,7 @@ msgstr "Extrudeuse de remplissage du support"
#: fdmprinter.def.json
msgctxt "support_infill_extruder_nr description"
msgid "The extruder train to use for printing the infill of the support. This is used in multi-extrusion."
-msgstr "Le train d'extrudeuse à utiliser pour l'impression du remplissage du support. Cela est utilisé en multi-extrusion."
+msgstr "Le système d'extrusion à utiliser pour l'impression du remplissage du support. Cela est utilisé en multi-extrusion."
#: fdmprinter.def.json
msgctxt "support_extruder_nr_layer_0 label"
@@ -2833,7 +2838,7 @@ msgstr "Extrudeuse de support de la première couche"
#: fdmprinter.def.json
msgctxt "support_extruder_nr_layer_0 description"
msgid "The extruder train to use for printing the first layer of support infill. This is used in multi-extrusion."
-msgstr "Le train d'extrudeuse à utiliser pour l'impression de la première couche de remplissage du support. Cela est utilisé en multi-extrusion."
+msgstr "Le système d'extrusion à utiliser pour l'impression de la première couche de remplissage du support. Cela est utilisé en multi-extrusion."
#: fdmprinter.def.json
msgctxt "support_interface_extruder_nr label"
@@ -2843,7 +2848,7 @@ msgstr "Extrudeuse de l'interface du support"
#: fdmprinter.def.json
msgctxt "support_interface_extruder_nr description"
msgid "The extruder train to use for printing the roofs and floors of the support. This is used in multi-extrusion."
-msgstr "Le train d'extrudeuse à utiliser pour l'impression des plafonds et bas du support. Cela est utilisé en multi-extrusion."
+msgstr "Le système d'extrusion à utiliser pour l'impression des plafonds et bas du support. Cela est utilisé en multi-extrusion."
#: fdmprinter.def.json
msgctxt "support_roof_extruder_nr label"
@@ -2853,7 +2858,7 @@ msgstr "Extrudeuse des plafonds de support"
#: fdmprinter.def.json
msgctxt "support_roof_extruder_nr description"
msgid "The extruder train to use for printing the roofs of the support. This is used in multi-extrusion."
-msgstr "Le train d'extrudeuse à utiliser pour l'impression des plafonds du support. Cela est utilisé en multi-extrusion."
+msgstr "Le système d'extrusion à utiliser pour l'impression des plafonds du support. Cela est utilisé en multi-extrusion."
#: fdmprinter.def.json
msgctxt "support_bottom_extruder_nr label"
@@ -2863,7 +2868,7 @@ msgstr "Extrudeuse des bas de support"
#: fdmprinter.def.json
msgctxt "support_bottom_extruder_nr description"
msgid "The extruder train to use for printing the floors of the support. This is used in multi-extrusion."
-msgstr "Le train d'extrudeuse à utiliser pour l'impression des bas du support. Cela est utilisé en multi-extrusion."
+msgstr "Le système d'extrusion à utiliser pour l'impression des bas du support. Cela est utilisé en multi-extrusion."
#: fdmprinter.def.json
msgctxt "support_type label"
@@ -3078,7 +3083,7 @@ msgstr "Expansion horizontale des supports"
#: fdmprinter.def.json
msgctxt "support_offset description"
msgid "Amount of offset applied to all support polygons in each layer. Positive values can smooth out the support areas and result in more sturdy support."
-msgstr "Le décalage appliqué à tous les polygones pour chaque couche. Une valeur positive peut lisser les zones de support et rendre le support plus solide."
+msgstr "L'offset appliqué à tous les polygones pour chaque couche. Une valeur positive peut lisser les zones de support et rendre le support plus solide."
#: fdmprinter.def.json
msgctxt "support_infill_sparse_thickness label"
@@ -3478,7 +3483,7 @@ msgstr "Extrudeuse d'adhérence du plateau"
#: fdmprinter.def.json
msgctxt "adhesion_extruder_nr description"
msgid "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion."
-msgstr "Le train d'extrudeuse à utiliser pour l'impression de la jupe/la bordure/du radeau. Cela est utilisé en multi-extrusion."
+msgstr "Le système d'extrusion à utiliser pour l'impression de la jupe/la bordure/du radeau. Cela est utilisé en multi-extrusion."
#: fdmprinter.def.json
msgctxt "skirt_line_count label"
@@ -3500,7 +3505,9 @@ msgctxt "skirt_gap description"
msgid ""
"The horizontal distance between the skirt and the first layer of the print.\n"
"This is the minimum distance. Multiple skirt lines will extend outwards from this distance."
-msgstr "La distance horizontale entre la jupe et la première couche de l’impression.\nIl s’agit de la distance minimale séparant la jupe de l’objet. Si la jupe a d’autres lignes, celles-ci s’étendront vers l’extérieur."
+msgstr ""
+"La distance horizontale entre la jupe et la première couche de l’impression.\n"
+"Il s’agit de la distance minimale séparant la jupe de l’objet. Si la jupe a d’autres lignes, celles-ci s’étendront vers l’extérieur."
#: fdmprinter.def.json
msgctxt "skirt_brim_minimal_length label"
@@ -3925,7 +3932,7 @@ msgstr "Compensation du débit : la quantité de matériau extrudée est multip
#: fdmprinter.def.json
msgctxt "prime_tower_wipe_enabled label"
msgid "Wipe Inactive Nozzle on Prime Tower"
-msgstr "Essuyer le bec d'impression inactif sur la tour primaire"
+msgstr "Essuyer la buse d'impression inactif sur la tour primaire"
#: fdmprinter.def.json
msgctxt "prime_tower_wipe_enabled description"
@@ -4665,7 +4672,7 @@ msgstr "Insert en spaghettis"
#: fdmprinter.def.json
msgctxt "spaghetti_inset description"
msgid "The offset from the walls from where the spaghetti infill will be printed."
-msgstr "Le décalage à partir des parois depuis lesquelles le remplissage en spaghettis sera imprimé."
+msgstr "L'offset à partir des parois depuis lesquelles le remplissage en spaghettis sera imprimé."
#: fdmprinter.def.json
msgctxt "spaghetti_flow label"
@@ -4770,7 +4777,7 @@ msgstr "Distance moyenne entre les points ajoutés aléatoirement sur chaque seg
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset label"
msgid "Flow rate compensation max extrusion offset"
-msgstr "Décalage d'extrusion max. pour compensation du débit"
+msgstr "Offset d'extrusion max. pour compensation du débit"
#: fdmprinter.def.json
msgctxt "flow_rate_max_extrusion_offset description"
@@ -4937,7 +4944,9 @@ msgctxt "wireframe_up_half_speed description"
msgid ""
"Distance of an upward move which is extruded with half speed.\n"
"This can cause better adhesion to previous layers, while not heating the material in those layers too much. Only applies to Wire Printing."
-msgstr "Distance d’un déplacement ascendant qui est extrudé à mi-vitesse.\nCela peut permettre une meilleure adhérence aux couches précédentes sans surchauffer le matériau dans ces couches. Uniquement applicable à l'impression filaire."
+msgstr ""
+"Distance d’un déplacement ascendant qui est extrudé à mi-vitesse.\n"
+"Cela peut permettre une meilleure adhérence aux couches précédentes sans surchauffer le matériau dans ces couches. Uniquement applicable à l'impression filaire."
#: fdmprinter.def.json
msgctxt "wireframe_top_jump label"
@@ -5132,7 +5141,7 @@ msgstr "Position z de la maille"
#: fdmprinter.def.json
msgctxt "mesh_position_z description"
msgid "Offset applied to the object in the z direction. With this you can perform what was used to be called 'Object Sink'."
-msgstr "Décalage appliqué à l'objet dans le sens z. Cela vous permet d'exécuter ce que l'on appelait « Affaissement de l'objet »."
+msgstr "Offset appliqué à l'objet dans le sens z. Cela vous permet d'exécuter ce que l'on appelait « Affaissement de l'objet »."
#: fdmprinter.def.json
msgctxt "mesh_rotation_matrix label"
diff --git a/resources/i18n/it_IT/cura.po b/resources/i18n/it_IT/cura.po
index d088670f39..d6f066aa22 100644
--- a/resources/i18n/it_IT/cura.po
+++ b/resources/i18n/it_IT/cura.po
@@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
"POT-Creation-Date: 2018-01-29 09:48+0000\n"
-"PO-Revision-Date: 2018-02-05 13:25+0100\n"
-"Last-Translator: Bothof \n"
+"PO-Revision-Date: 2018-02-13 13:15+0100\n"
+"Last-Translator: Crea-3D \n"
"Language-Team: Italian\n"
"Language: it_IT\n"
"MIME-Version: 1.0\n"
@@ -105,12 +105,12 @@ msgstr "Visualizza registro modifiche"
#: /home/ruben/Projects/Cura/plugins/ProfileFlattener/ProfileFlattener.py:20
msgctxt "@item:inmenu"
msgid "Flatten active settings"
-msgstr "Impostazioni attive profilo appiattito"
+msgstr "Resetta impostazioni attive"
#: /home/ruben/Projects/Cura/plugins/ProfileFlattener/ProfileFlattener.py:32
msgctxt "@info:status"
msgid "Profile has been flattened & activated."
-msgstr "Il profilo è stato appiattito e attivato."
+msgstr "Il profilo è stato resettato e attivato."
#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDevice.py:27
msgctxt "@item:inmenu"
@@ -166,7 +166,7 @@ msgstr "Impossibile avviare un nuovo processo di stampa perché la stampante non
#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1496
msgctxt "@info:title"
msgid "Warning"
-msgstr "Avvertenza"
+msgstr "Attenzione"
#: /home/ruben/Projects/Cura/plugins/USBPrinting/USBPrinterOutputDeviceManager.py:103
msgctxt "@info"
@@ -261,7 +261,7 @@ msgstr "Rimuovi"
#, python-brace-format
msgctxt "@action"
msgid "Eject removable device {0}"
-msgstr "Rimuovi il dispositivo rimovibile {0}"
+msgstr "Espelli il dispositivo rimovibile {0}"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:156
#, python-brace-format
@@ -444,7 +444,7 @@ msgstr "Sei sicuro di voler stampare con la configurazione selezionata?"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:748
msgctxt "@label"
msgid "There is a mismatch between the configuration or calibration of the printer and Cura. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
-msgstr "Le configurazioni o la calibrazione della stampante e di Cura non corrispondono. Per ottenere i migliori risultati, sezionare sempre per i PrintCore e i materiali inseriti nella stampante utilizzata."
+msgstr "Le configurazioni o la calibrazione della stampante e di Cura non corrispondono. Per risultati ottimali, sezionare sempre i PrintCore e i materiali inseriti nella stampante utilizzata."
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:754
msgctxt "@window:title"
@@ -506,7 +506,7 @@ msgstr "Desideri utilizzare la configurazione corrente della tua stampante in Cu
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkPrinterOutputDevice.py:1295
msgctxt "@label"
msgid "The PrintCores and/or materials on your printer differ from those within your current project. For the best result, always slice for the PrintCores and materials that are inserted in your printer."
-msgstr "I PrintCore e/o i materiali sulla stampante differiscono da quelli contenuti nel tuo attuale progetto. Per ottenere i risultati migliori, sezionare sempre per i PrintCore e i materiali inseriti nella stampante utilizzata."
+msgstr "I PrintCore e/o i materiali sulla stampante differiscono da quelli contenuti nel tuo attuale progetto. Per risultati ottimali, sezionare sempre i PrintCore e i materiali inseriti nella stampante utilizzata."
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py:112
msgid "This printer is not set up to host a group of connected Ultimaker 3 printers."
@@ -521,7 +521,7 @@ msgstr "Questa stampante fa da host per un gruppo di {count} stampanti Ultimaker
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py:114
#, python-brace-format
msgid "{printer_name} has finished printing '{job_name}'. Please collect the print and confirm clearing the build plate."
-msgstr "{printer_name} ha terminato la stampa '{job_name}'. Raccogliere la stampa e confermare la liberazione del piano di stampa."
+msgstr "{printer_name} ha terminato la stampa '{job_name}'. Rimuovere la stampa e confermare la pulizia del piano di stampa."
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py:115
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py:533
@@ -579,7 +579,7 @@ msgstr "Stampa finita"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml:282
msgctxt "@label:status"
msgid "Action required"
-msgstr "Richiede un'azione"
+msgstr "Azione richiesta"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py:656
#, python-brace-format
@@ -686,7 +686,7 @@ msgstr "Guida per l’installazione di macro SolidWorks"
#: /home/ruben/Projects/Cura/plugins/SimulationView/__init__.py:14
msgctxt "@item:inlistbox"
msgid "Layer view"
-msgstr "Visualizzazione strato"
+msgstr "Visualizzazione layer"
#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.py:103
msgctxt "@info:status"
@@ -783,7 +783,7 @@ msgstr "Immagine GIF"
#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:299
msgctxt "@info:status"
msgid "Unable to slice with the current material as it is incompatible with the selected machine or configuration."
-msgstr "Impossibile eseguire il sezionamento con il materiale corrente in quanto incompatibile con la macchina o la configurazione selezionata."
+msgstr "Impossibile eseguire lo slicing con il materiale corrente in quanto incompatibile con la macchina o la configurazione selezionata."
#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:299
#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:327
@@ -792,24 +792,24 @@ msgstr "Impossibile eseguire il sezionamento con il materiale corrente in quanto
#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:366
msgctxt "@info:title"
msgid "Unable to slice"
-msgstr "Sezionamento impossibile"
+msgstr "Slicing impossibile"
#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:326
#, python-brace-format
msgctxt "@info:status"
msgid "Unable to slice with the current settings. The following settings have errors: {0}"
-msgstr "Impossibile eseguire il sezionamento con le impostazioni attuali. Le seguenti impostazioni presentano errori: {0}"
+msgstr "Impossibile eseguire lo slicing con le impostazioni attuali. Le seguenti impostazioni presentano errori: {0}"
#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:348
#, python-brace-format
msgctxt "@info:status"
msgid "Unable to slice due to some per-model settings. The following settings have errors on one or more models: {error_labels}"
-msgstr "Impossibile eseguire il sezionamento a causa di alcune impostazioni per modello. Le seguenti impostazioni presentano errori su uno o più modelli: {error_labels}"
+msgstr "Impossibile eseguire lo slicing a causa di alcune impostazioni del modello. Le seguenti impostazioni presentano errori su uno o più modelli: {error_labels}"
#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:356
msgctxt "@info:status"
msgid "Unable to slice because the prime tower or prime position(s) are invalid."
-msgstr "Impossibile eseguire il sezionamento perché la torre di innesco o la posizione di innesco non sono valide."
+msgstr "Impossibile eseguire lo slicing perché la prime tower o la prime position non sono valide."
#: /home/ruben/Projects/Cura/plugins/CuraEngineBackend/CuraEngineBackend.py:365
msgctxt "@info:status"
@@ -843,21 +843,21 @@ msgstr "Installazione"
#: /home/ruben/Projects/Cura/plugins/cura-siemensnx-plugin/Installer.py:43
msgid "Failed to copy Siemens NX plugins files. Please check your UGII_USER_DIR. It is not set to a directory."
-msgstr "Impossibile copiare i file di plugin Siemens NX. Controllare UGII_USER_DIR. Non è assegnato ad alcuna directory."
+msgstr "Impossibile copiare i file dei plugin Siemens NX. Controllare UGII_USER_DIR. Non è assegnato ad alcuna directory."
#: /home/ruben/Projects/Cura/plugins/cura-siemensnx-plugin/Installer.py:50
#: /home/ruben/Projects/Cura/plugins/cura-siemensnx-plugin/Installer.py:59
#: /home/ruben/Projects/Cura/plugins/cura-siemensnx-plugin/Installer.py:81
msgid "Successfully installed Siemens NX Cura plugin."
-msgstr "Installato correttamente plugin Siemens NX Cura."
+msgstr "Siemens NX Cura plugin installato correttamente."
#: /home/ruben/Projects/Cura/plugins/cura-siemensnx-plugin/Installer.py:65
msgid "Failed to copy Siemens NX plugins files. Please check your UGII_USER_DIR."
-msgstr "Impossibile copiare i file di plugin Siemens NX. Controllare UGII_USER_DIR."
+msgstr "Impossibile copiare i file dei plugin Siemens NX. Controllare UGII_USER_DIR."
#: /home/ruben/Projects/Cura/plugins/cura-siemensnx-plugin/Installer.py:85
msgid "Failed to install Siemens NX plugin. Could not set environment variable UGII_USER_DIR for Siemens NX."
-msgstr "Impossibile installare plugin Siemens NX. Impossibile impostare la variabile di ambiente UGII_USER_DIR per Siemens NX."
+msgstr "Impossibile installare il plugin Siemens NX. Impossibile impostare la variabile di ambiente UGII_USER_DIR per Siemens NX."
#: /home/ruben/Projects/Cura/plugins/3MFReader/WorkspaceDialog.py:165
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:590
@@ -887,12 +887,12 @@ msgstr "Ugello"
#, python-brace-format
msgctxt "@info:status"
msgid "Failed to get plugin ID from {0}"
-msgstr "Impossibile ottenere ID plugin da {0}"
+msgstr "Impossibile ottenere ID del plugin da {0}"
#: /home/ruben/Projects/Cura/plugins/PluginBrowser/PluginBrowser.py:153
msgctxt "@info:tile"
msgid "Warning"
-msgstr "Avvertenza"
+msgstr "Attenzione"
#: /home/ruben/Projects/Cura/plugins/PluginBrowser/PluginBrowser.py:191
msgctxt "@window:title"
@@ -912,18 +912,18 @@ msgstr "File G"
#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:321
msgctxt "@info:status"
msgid "Parsing G-code"
-msgstr "Parsing codice G"
+msgstr "Analisi G-code"
#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:323
#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:464
msgctxt "@info:title"
msgid "G-code Details"
-msgstr "Dettagli codice G"
+msgstr "Dettagli G-code"
#: /home/ruben/Projects/Cura/plugins/GCodeReader/FlavorParser.py:462
msgctxt "@info:generic"
msgid "Make sure the g-code is suitable for your printer and printer configuration before sending the file to it. The g-code representation may not be accurate."
-msgstr "Verifica che il codice G sia idoneo alla tua stampante e alla sua configurazione prima di trasmettere il file. La rappresentazione del codice G potrebbe non essere accurata."
+msgstr "Verifica che il G-code sia idoneo alla tua stampante e alla sua configurazione prima di trasmettere il file. La rappresentazione del G-code potrebbe non essere accurata."
#: /home/ruben/Projects/Cura/plugins/CuraProfileWriter/__init__.py:14
#: /home/ruben/Projects/Cura/plugins/CuraProfileReader/__init__.py:14
@@ -1234,7 +1234,7 @@ msgstr "Impossibile individuare posizione"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:81
msgctxt "@title:window"
msgid "Crash Report"
-msgstr "Rapporto su crash"
+msgstr "Rapporto sul crash"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:94
msgctxt "@label crash message"
@@ -1347,13 +1347,13 @@ msgstr "%(width).1f x %(depth).1f x %(height).1f mm"
#, python-brace-format
msgctxt "@info:status"
msgid "Only one G-code file can be loaded at a time. Skipped importing {0}"
-msgstr "È possibile caricare un solo file codice G per volta. Importazione saltata {0}"
+msgstr "È possibile caricare un solo file G-code per volta. Importazione saltata {0}"
#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1426
#, python-brace-format
msgctxt "@info:status"
msgid "Can't open any other file if G-code is loading. Skipped importing {0}"
-msgstr "Impossibile aprire altri file durante il caricamento del codice G. Importazione saltata {0}"
+msgstr "Impossibile aprire altri file durante il caricamento del G-code. Importazione saltata {0}"
#: /home/ruben/Projects/Cura/cura/CuraApplication.py:1495
msgctxt "@info:status"
@@ -1426,7 +1426,7 @@ msgstr "Versione GCode"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:181
msgctxt "@label"
msgid "Printhead Settings"
-msgstr "Impostazioni della testina di stampa"
+msgstr "Impostazioni della testa di stampa"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:191
msgctxt "@label"
@@ -1436,7 +1436,7 @@ msgstr "X min"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:192
msgctxt "@tooltip"
msgid "Distance from the left of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distanza tra il lato sinistro della testina di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testina di stampa durante la stampa \"Uno alla volta\"."
+msgstr "Distanza tra il lato sinistro della testa di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testa di stampa durante la stampa \"Uno alla volta\"."
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:201
msgctxt "@label"
@@ -1446,7 +1446,7 @@ msgstr "Y min"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:202
msgctxt "@tooltip"
msgid "Distance from the front of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distanza tra il lato anteriore della testina di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testina di stampa durante la stampa \"Uno alla volta\"."
+msgstr "Distanza tra il lato anteriore della testa di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testa di stampa durante la stampa \"Uno alla volta\"."
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:211
msgctxt "@label"
@@ -1456,7 +1456,7 @@ msgstr "X max"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:212
msgctxt "@tooltip"
msgid "Distance from the right of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distanza tra il lato destro della testina di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testina di stampa durante la stampa \"Uno alla volta\"."
+msgstr "Distanza tra il lato destro della testa di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testa di stampa durante la stampa \"Uno alla volta\"."
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:221
msgctxt "@label"
@@ -1466,7 +1466,7 @@ msgstr "Y max"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:222
msgctxt "@tooltip"
msgid "Distance from the rear of the printhead to the center of the nozzle. Used to prevent colissions between previous prints and the printhead when printing \"One at a Time\"."
-msgstr "Distanza tra il lato posteriore della testina di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testina di stampa durante la stampa \"Uno alla volta\"."
+msgstr "Distanza tra il lato posteriore della testa di stampa e il centro dell'ugello. Utilizzata per evitare collisioni tra le stampe precedenti e la testa di stampa durante la stampa \"Uno alla volta\"."
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:234
msgctxt "@label"
@@ -1521,7 +1521,7 @@ msgstr "Diametro del materiale compatibile"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:395
msgctxt "@tooltip"
msgid "The nominal diameter of filament supported by the printer. The exact diameter will be overridden by the material and/or the profile."
-msgstr "Diametro nominale del filamento supportato dalla stampante. Il diametro esatto verrà sovrapposto dal materiale e/o dal profilo."
+msgstr "Diametro nominale del filamento supportato dalla stampante. Il diametro esatto verrà sovrascritto dal materiale e/o dal profilo."
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:411
msgctxt "@label"
@@ -1536,12 +1536,12 @@ msgstr "Scostamento Y ugello"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:444
msgctxt "@label"
msgid "Extruder Start Gcode"
-msgstr "Codice G avvio estrusore"
+msgstr "Gcode avvio estrusore"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:462
msgctxt "@label"
msgid "Extruder End Gcode"
-msgstr "Codice G fine estrusore"
+msgstr "Gcode fine estrusore"
#: /home/ruben/Projects/Cura/plugins/ChangeLogPlugin/ChangeLog.qml:18
msgctxt "@label"
@@ -1618,7 +1618,7 @@ msgid ""
"To print directly to your printer over the network, please make sure your printer is connected to the network using a network cable or by connecting your printer to your WIFI network. If you don't connect Cura with your printer, you can still use a USB drive to transfer g-code files to your printer.\n"
"\n"
"Select your printer from the list below:"
-msgstr "Per stampare direttamente sulla stampante in rete, verificare che la stampante desiderata sia collegata alla rete mediante un cavo di rete o mediante collegamento alla rete WIFI. Se si collega Cura alla stampante, è comunque possibile utilizzare una chiavetta USB per trasferire i file codice G alla stampante.\n\nSelezionare la stampante dall’elenco seguente:"
+msgstr "Per stampare direttamente sulla stampante in rete, verificare che la stampante desiderata sia collegata alla rete mediante un cavo di rete o mediante collegamento alla rete WIFI. Se si collega Cura alla stampante, è comunque possibile utilizzare una chiavetta USB per trasferire i file Gcode alla stampante.\n\nSelezionare la stampante dall’elenco seguente:"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:75
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:44
@@ -1715,7 +1715,7 @@ msgstr "OK"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/PrintWindow.qml:24
msgctxt "@title:window"
msgid "Print over network"
-msgstr "Stampa sulla rete"
+msgstr "Stampa tramite rete"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/PrintWindow.qml:92
msgctxt "@action:button"
@@ -1816,7 +1816,7 @@ msgstr "Finisce alle: "
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml:405
msgctxt "@label"
msgid "Clear build plate"
-msgstr "Cancellare piano di stampa"
+msgstr "Pulire piano di stampa"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml:414
msgctxt "@label"
@@ -2054,7 +2054,7 @@ msgstr "Velocità"
#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:144
msgctxt "@label:listbox"
msgid "Layer thickness"
-msgstr "Spessore strato"
+msgstr "Spessore layer"
#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:185
msgctxt "@label"
@@ -2089,7 +2089,7 @@ msgstr "Mostra solo strati superiori"
#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:339
msgctxt "@label"
msgid "Show 5 Detailed Layers On Top"
-msgstr "Mostra 5 strati superiori in dettaglio"
+msgstr "Mostra 5 layer superiori in dettaglio"
#: /home/ruben/Projects/Cura/plugins/SimulationView/SimulationView.qml:350
msgctxt "@label"
@@ -2451,7 +2451,7 @@ msgstr "Seleziona qualsiasi aggiornamento realizzato per questa Ultimaker 2."
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UM2UpgradeSelectionMachineAction.qml:45
msgctxt "@label"
msgid "Olsson Block"
-msgstr "Blocco Olsson"
+msgstr "Olsson Block"
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:27
msgctxt "@title"
@@ -2466,7 +2466,7 @@ msgstr "Per assicurarsi stampe di alta qualità, è ora possibile regolare il pi
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:47
msgctxt "@label"
msgid "For every position; insert a piece of paper under the nozzle and adjust the print build plate height. The print build plate height is right when the paper is slightly gripped by the tip of the nozzle."
-msgstr "Per ciascuna posizione: inserire un pezzo di carta sotto l'ugello e regolare la stampa dell'altezza del piano di stampa. L'altezza del piano di stampa è corretta quando la carta sfiora la punta dell'ugello."
+msgstr "Per ciascuna posizione: inserire un pezzo di carta sotto l'ugello e regolare l'altezza del piano di stampa. L'altezza del piano di stampa è corretta quando la carta sfiora la punta dell'ugello."
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/BedLevelMachineAction.qml:62
msgctxt "@action:button"
@@ -2914,12 +2914,12 @@ msgstr "Visualizza sbalzo"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:344
msgctxt "@info:tooltip"
msgid "Moves the camera so the model is in the center of the view when a model is selected"
-msgstr "Sposta la fotocamera in modo che il modello si trovi al centro della visualizzazione quando è selezionato"
+msgstr "Sposta la camera in modo che il modello si trovi al centro della visualizzazione quando è selezionato"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:349
msgctxt "@action:button"
msgid "Center camera when item is selected"
-msgstr "Centratura fotocamera alla selezione dell'elemento"
+msgstr "Centratura camera alla selezione dell'elemento"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:358
msgctxt "@info:tooltip"
@@ -2929,7 +2929,7 @@ msgstr "Il comportamento dello zoom predefinito di Cura dovrebbe essere invertit
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:363
msgctxt "@action:button"
msgid "Invert the direction of camera zoom."
-msgstr "Inverti la direzione dello zoom della fotocamera."
+msgstr "Inverti la direzione dello zoom della camera."
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:372
msgctxt "@info:tooltip"
@@ -2964,22 +2964,22 @@ msgstr "Rilascia automaticamente i modelli sul piano di stampa"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:416
msgctxt "@info:tooltip"
msgid "Show caution message in gcode reader."
-msgstr "Visualizza il messaggio di avvertimento sul lettore codice G."
+msgstr "Visualizza il messaggio di avvertimento sul lettore gcode."
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:425
msgctxt "@option:check"
msgid "Caution message in gcode reader"
-msgstr "Messaggio di avvertimento sul lettore codice G"
+msgstr "Messaggio di avvertimento sul lettore gcode"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:432
msgctxt "@info:tooltip"
msgid "Should layer be forced into compatibility mode?"
-msgstr "Lo strato deve essere forzato in modalità di compatibilità?"
+msgstr "Il layer deve essere forzato in modalità di compatibilità?"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:437
msgctxt "@option:check"
msgid "Force layer view compatibility mode (restart required)"
-msgstr "Forzare la modalità di compatibilità visualizzazione strato (riavvio necessario)"
+msgstr "Forzare la modalità di compatibilità visualizzazione layer (riavvio necessario)"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:453
msgctxt "@label"
@@ -3109,7 +3109,7 @@ msgstr "I modelli appena caricati devono essere sistemati sul piano di stampa? U
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:699
msgctxt "@option:check"
msgid "Do not arrange objects on load"
-msgstr "Non posizionare oggetti sul carico"
+msgstr "Non posizionare oggetti dopo il caricamento"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:15
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:514
@@ -3154,7 +3154,7 @@ msgstr "Stato:"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:190
msgctxt "@label:MonitorStatus"
msgid "Waiting for someone to clear the build plate"
-msgstr "In attesa di qualcuno che cancelli il piano di stampa"
+msgstr "In attesa che qualcuno liberi il piano di stampa"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:199
msgctxt "@label:MonitorStatus"
@@ -3547,7 +3547,7 @@ msgctxt "@label:listbox"
msgid ""
"Print Setup disabled\n"
"G-code files cannot be modified"
-msgstr "Impostazione di stampa disabilitata\nI file codice G non possono essere modificati"
+msgstr "Impostazione di stampa disabilitata\nI file G-code non possono essere modificati"
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:342
msgctxt "@label Hours and minutes"
@@ -3599,7 +3599,7 @@ msgstr "Impostazione di stampa consigliata
Stampa con le imposta
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:596
msgctxt "@tooltip"
msgid "Custom Print Setup
Print with finegrained control over every last bit of the slicing process."
-msgstr "Impostazione di stampa personalizzata
Stampa con il controllo grana fine su ogni sezione finale del processo di sezionamento."
+msgstr "Impostazione di stampa personalizzata
Stampa con il controllo grana fine su ogni sezione finale del processo di slicing."
#: /home/ruben/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:50
msgctxt "@title:menuitem %1 is the automatically selected material"
@@ -3704,7 +3704,7 @@ msgstr "La temperatura corrente del piano riscaldato."
#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:423
msgctxt "@tooltip of temperature input"
msgid "The temperature to pre-heat the bed to."
-msgstr "La temperatura di preriscaldo del piano."
+msgstr "La temperatura di preriscaldamento del piano."
#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:623
msgctxt "@button Cancel pre-heating"
@@ -3714,7 +3714,7 @@ msgstr "Annulla"
#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:623
msgctxt "@button"
msgid "Pre-heat"
-msgstr "Pre-riscaldo"
+msgstr "Pre-riscaldamento"
#: /home/ruben/Projects/Cura/resources/qml/PrintMonitor.qml:650
msgctxt "@tooltip of pre-heat"
@@ -3925,7 +3925,7 @@ msgstr "Sel&eziona tutti i modelli"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:332
msgctxt "@action:inmenu menubar:edit"
msgid "&Clear Build Plate"
-msgstr "&Cancellare piano di stampa"
+msgstr "&Pulire piano di stampa"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:342
msgctxt "@action:inmenu menubar:file"
@@ -3970,7 +3970,7 @@ msgstr "&Nuovo Progetto..."
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:402
msgctxt "@action:inmenu menubar:help"
msgid "Show Engine &Log..."
-msgstr "M&ostra log motore..."
+msgstr "M&ostra motore log..."
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:410
msgctxt "@action:inmenu menubar:help"
@@ -4010,7 +4010,7 @@ msgstr "Pronto per il sezionamento"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:38
msgctxt "@label:PrintjobStatus"
msgid "Slicing..."
-msgstr "Sezionamento in corso..."
+msgstr "Slicing in corso..."
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:40
msgctxt "@label:PrintjobStatus %1 is target operation"
@@ -4020,7 +4020,7 @@ msgstr "Pronto a %1"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:42
msgctxt "@label:PrintjobStatus"
msgid "Unable to Slice"
-msgstr "Sezionamento impossibile"
+msgstr "Slicing impossibile"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:44
msgctxt "@label:PrintjobStatus"
@@ -4035,7 +4035,7 @@ msgstr "Seziona processo di stampa corrente"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:171
msgctxt "@info:tooltip"
msgid "Cancel slicing process"
-msgstr "Annulla processo di sezionamento"
+msgstr "Annulla processo di slicing"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:183
msgctxt "@label:Printjob"
@@ -4050,7 +4050,7 @@ msgstr "Annulla"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:317
msgctxt "@info:tooltip"
msgid "Select the active output device"
-msgstr "Seleziona l'unità di uscita attiva"
+msgstr "Seleziona l'unità output attiva"
#: /home/ruben/Projects/Cura/resources/qml/OpenFilesIncludingProjectsDialog.qml:19
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:696
@@ -4320,7 +4320,7 @@ msgstr "Importa i modelli"
#: /home/ruben/Projects/Cura/resources/qml/EngineLog.qml:15
msgctxt "@title:window"
msgid "Engine Log"
-msgstr "Log motore"
+msgstr "Motore Log"
#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:245
msgctxt "@label"
@@ -4665,7 +4665,7 @@ msgstr "Lettore di immagine"
#: CuraEngineBackend/plugin.json
msgctxt "description"
msgid "Provides the link to the CuraEngine slicing backend."
-msgstr "Fornisce il collegamento al back-end di sezionamento CuraEngine."
+msgstr "Fornisce il collegamento al back-end di slicing di CuraEngine."
#: CuraEngineBackend/plugin.json
msgctxt "name"
@@ -4725,12 +4725,12 @@ msgstr "Visualizzazione compatta"
#: GCodeReader/plugin.json
msgctxt "description"
msgid "Allows loading and displaying G-code files."
-msgstr "Consente il caricamento e la visualizzazione dei file codice G."
+msgstr "Consente il caricamento e la visualizzazione dei file G-code."
#: GCodeReader/plugin.json
msgctxt "name"
msgid "G-code Reader"
-msgstr "Lettore codice G"
+msgstr "Lettore G-code"
#: CuraProfileWriter/plugin.json
msgctxt "description"
@@ -4944,7 +4944,7 @@ msgstr "Lettore profilo Cura"
#~ msgctxt "@label:status"
#~ msgid "Blocked"
-#~ msgstr "Ostacolato"
+#~ msgstr "Bloccato"
#~ msgctxt "@label:status"
#~ msgid "Can't start print"
@@ -4964,7 +4964,7 @@ msgstr "Lettore profilo Cura"
#~ msgctxt "@info:title"
#~ msgid "Layer View"
-#~ msgstr "Visualizzazione strato"
+#~ msgstr "Visualizzazione layer"
#~ msgctxt "@menuitem"
#~ msgid "Browse plugins"
@@ -5068,7 +5068,7 @@ msgstr "Lettore profilo Cura"
#~ msgctxt "name"
#~ msgid "Layer View"
-#~ msgstr "Visualizzazione strato"
+#~ msgstr "Visualizzazione layer"
#~ msgctxt "@item:inlistbox"
#~ msgid "X-Ray"
@@ -5199,7 +5199,7 @@ msgstr "Lettore profilo Cura"
#~ msgctxt "@label"
#~ msgid "Hotend"
-#~ msgstr "Estremità calda"
+#~ msgstr "Hotend"
#~ msgctxt "@action:button"
#~ msgid "View Mode"
@@ -5335,7 +5335,7 @@ msgstr "Lettore profilo Cura"
#~ msgctxt "@label"
#~ msgid "The print cores and/or materials on your printer differ from those within your current project. For the best result, always slice for the print cores and materials that are inserted in your printer."
-#~ msgstr "I PrintCore e/o i materiali della stampante sono diversi da quelli del progetto corrente. Per ottenere i migliori risultati, sezionare sempre per i PrintCore e i materiali inseriti nella stampante utilizzata."
+#~ msgstr "I PrintCore e/o i materiali della stampante sono diversi da quelli del progetto corrente. Per risultati ottimali, sezionare sempre i PrintCore e i materiali inseriti nella stampante utilizzata."
#~ msgctxt "@label"
#~ msgid "Post Processing"
@@ -5391,11 +5391,11 @@ msgstr "Lettore profilo Cura"
#~ msgctxt "@label"
#~ msgid "Layer View"
-#~ msgstr "Visualizzazione strato"
+#~ msgstr "Visualizzazione layer"
#~ msgctxt "@info:whatsthis"
#~ msgid "Provides the Layer view."
-#~ msgstr "Fornisce la visualizzazione degli strati."
+#~ msgstr "Fornisce la visualizzazione dei layer."
#~ msgctxt "@label"
#~ msgid "Version Upgrade 2.5 to 2.6"
@@ -5435,7 +5435,7 @@ msgstr "Lettore profilo Cura"
#~ msgctxt "@info:whatsthis"
#~ msgid "Provides the link to the CuraEngine slicing backend."
-#~ msgstr "Fornisce il collegamento al back-end di sezionamento CuraEngine."
+#~ msgstr "Fornisce il collegamento al back-end di slicing di CuraEngine."
#~ msgctxt "@label"
#~ msgid "Per Model Settings Tool"
@@ -5463,11 +5463,11 @@ msgstr "Lettore profilo Cura"
#~ msgctxt "@label"
#~ msgid "G-code Reader"
-#~ msgstr "Lettore codice G"
+#~ msgstr "Lettore G-code"
#~ msgctxt "@info:whatsthis"
#~ msgid "Allows loading and displaying G-code files."
-#~ msgstr "Consente il caricamento e la visualizzazione dei file codice G."
+#~ msgstr "Consente il caricamento e la visualizzazione dei file G-code."
#~ msgctxt "@label"
#~ msgid "Cura Profile Writer"
@@ -5736,7 +5736,7 @@ msgstr "Lettore profilo Cura"
#~ msgctxt "@option:check"
#~ msgid "Only display top layer(s) in layer view"
-#~ msgstr "In visualizzazione strato, visualizza solo lo/gli strato/i superiore/i"
+#~ msgstr "In visualizzazione layer, visualizza solo il/i layer(s) superiore/i"
#~ msgctxt "@label"
#~ msgid "Opening files"
diff --git a/resources/i18n/it_IT/fdmprinter.def.json.po b/resources/i18n/it_IT/fdmprinter.def.json.po
index 693c88f543..e5f440e2b2 100644
--- a/resources/i18n/it_IT/fdmprinter.def.json.po
+++ b/resources/i18n/it_IT/fdmprinter.def.json.po
@@ -1,15 +1,15 @@
-# Cura JSON setting files
-# Copyright (C) 2017 Ultimaker
+# Cura
+# Copyright (C) 2018 Ultimaker
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2017.
+# Ruben Dulek , 2018.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.0\n"
+"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2017-08-02 16:53+0000\n"
+"POT-Creation-Date: 2018-01-29 09:48+0000\n"
"PO-Revision-Date: 2017-11-30 13:05+0100\n"
-"Last-Translator: Bothof \n"
+"Last-Translator: Crea-3D \n"
"Language-Team: Italian\n"
"Language: it_IT\n"
"MIME-Version: 1.0\n"
@@ -49,26 +49,26 @@ msgstr "Sceglie se mostrare le diverse varianti di questa macchina, descritte in
#: fdmprinter.def.json
msgctxt "machine_start_gcode label"
msgid "Start GCode"
-msgstr "Codice G avvio"
+msgstr "Avvio GCode"
#: fdmprinter.def.json
msgctxt "machine_start_gcode description"
msgid ""
"Gcode commands to be executed at the very start - separated by \n"
"."
-msgstr "I comandi codice G da eseguire all’avvio, separati da \n."
+msgstr "I comandi del Gcode da eseguire all’avvio, separati da \n."
#: fdmprinter.def.json
msgctxt "machine_end_gcode label"
msgid "End GCode"
-msgstr "Codice G fine"
+msgstr "Fine GCode"
#: fdmprinter.def.json
msgctxt "machine_end_gcode description"
msgid ""
"Gcode commands to be executed at the very end - separated by \n"
"."
-msgstr "I comandi codice G da eseguire alla fine, separati da \n."
+msgstr "I comandi del Gcode da eseguire alla fine, separati da \n."
#: fdmprinter.def.json
msgctxt "material_guid label"
@@ -88,7 +88,7 @@ msgstr "Attendi il riscaldamento del piano di stampa"
#: fdmprinter.def.json
msgctxt "material_bed_temp_wait description"
msgid "Whether to insert a command to wait until the build plate temperature is reached at the start."
-msgstr "Sceglie se inserire un comando per attendere finché la temperatura del piano di stampa non viene raggiunta all’avvio."
+msgstr "Scegli se inserire un comando per attendere finché la temperatura del piano di stampa non viene raggiunta all’avvio."
#: fdmprinter.def.json
msgctxt "material_print_temp_wait label"
@@ -98,7 +98,7 @@ msgstr "Attendi il riscaldamento dell’ugello"
#: fdmprinter.def.json
msgctxt "material_print_temp_wait description"
msgid "Whether to wait until the nozzle temperature is reached at the start."
-msgstr "Sceglie se attendere finché la temperatura dell’ugello non viene raggiunta all’avvio."
+msgstr "Scegli se attendere finché la temperatura dell’ugello non viene raggiunta all’avvio."
#: fdmprinter.def.json
msgctxt "material_print_temp_prepend label"
@@ -108,7 +108,7 @@ msgstr "Includi le temperature del materiale"
#: fdmprinter.def.json
msgctxt "material_print_temp_prepend description"
msgid "Whether to include nozzle temperature commands at the start of the gcode. When the start_gcode already contains nozzle temperature commands Cura frontend will automatically disable this setting."
-msgstr "Sceglie se includere comandi temperatura ugello all’avvio del codice G. Quando start_gcode contiene già comandi temperatura ugello la parte anteriore di Cura disabilita automaticamente questa impostazione."
+msgstr "Scegli se includere comandi temperatura ugello all’avvio del Gcode. Quando start_gcode contiene già comandi temperatura ugello, il frontend di Cura disabilita automaticamente questa impostazione."
#: fdmprinter.def.json
msgctxt "material_bed_temp_prepend label"
@@ -118,7 +118,7 @@ msgstr "Includi temperatura piano di stampa"
#: fdmprinter.def.json
msgctxt "material_bed_temp_prepend description"
msgid "Whether to include build plate temperature commands at the start of the gcode. When the start_gcode already contains build plate temperature commands Cura frontend will automatically disable this setting."
-msgstr "Sceglie se includere comandi temperatura piano di stampa all’avvio del codice G. Quando start_gcode contiene già comandi temperatura piano di stampa la parte anteriore di Cura disabilita automaticamente questa impostazione."
+msgstr "Scegli se includere comandi temperatura piano di stampa all’avvio del gcode. Quando start_gcode contiene già comandi temperatura piano di stampa il frontend di Cura disabilita automaticamente questa impostazione."
#: fdmprinter.def.json
msgctxt "machine_width label"
@@ -183,7 +183,7 @@ msgstr "Indica se la macchina ha un piano di stampa riscaldato."
#: fdmprinter.def.json
msgctxt "machine_center_is_zero label"
msgid "Is Center Origin"
-msgstr "Origine del centro"
+msgstr "Origine al centro"
#: fdmprinter.def.json
msgctxt "machine_center_is_zero description"
@@ -198,7 +198,7 @@ msgstr "Numero di estrusori"
#: fdmprinter.def.json
msgctxt "machine_extruder_count description"
msgid "Number of extruder trains. An extruder train is the combination of a feeder, bowden tube, and nozzle."
-msgstr "Il numero di treni di estrusori. Un treno di estrusori è la combinazione di un alimentatore, un tubo bowden e un ugello."
+msgstr "Il numero dei blocchi di estrusori. Un blocco di estrusori è la combinazione di un alimentatore, un tubo bowden e un ugello."
#: fdmprinter.def.json
msgctxt "machine_nozzle_tip_outer_diameter label"
@@ -218,7 +218,7 @@ msgstr "Lunghezza ugello"
#: fdmprinter.def.json
msgctxt "machine_nozzle_head_distance description"
msgid "The height difference between the tip of the nozzle and the lowest part of the print head."
-msgstr "La differenza di altezza tra la punta dell’ugello e la parte inferiore della testina di stampa."
+msgstr "La differenza di altezza tra la punta dell’ugello e la parte inferiore della testa di stampa."
#: fdmprinter.def.json
msgctxt "machine_nozzle_expansion_angle label"
@@ -293,12 +293,12 @@ msgstr "Il tempo minimo in cui un estrusore deve essere inattivo prima che l’u
#: fdmprinter.def.json
msgctxt "machine_gcode_flavor label"
msgid "Gcode flavour"
-msgstr "Tipo di codice G"
+msgstr "Tipo di Gcode"
#: fdmprinter.def.json
msgctxt "machine_gcode_flavor description"
msgid "The type of gcode to be generated."
-msgstr "Il tipo di codice G da generare."
+msgstr "Il tipo di gcode da generare."
#: fdmprinter.def.json
msgctxt "machine_gcode_flavor option RepRap (Marlin/Sprinter)"
@@ -363,7 +363,7 @@ msgstr "Aree non consentite"
#: fdmprinter.def.json
msgctxt "machine_disallowed_areas description"
msgid "A list of polygons with areas the print head is not allowed to enter."
-msgstr "Un elenco di poligoni con aree alle quali la testina di stampa non può accedere."
+msgstr "Un elenco di poligoni con aree alle quali la testa di stampa non può accedere."
#: fdmprinter.def.json
msgctxt "nozzle_disallowed_areas label"
@@ -378,22 +378,22 @@ msgstr "Un elenco di poligoni con aree alle quali l’ugello non può accedere."
#: fdmprinter.def.json
msgctxt "machine_head_polygon label"
msgid "Machine head polygon"
-msgstr "Poligono testina macchina"
+msgstr "Poligono testa macchina"
#: fdmprinter.def.json
msgctxt "machine_head_polygon description"
msgid "A 2D silhouette of the print head (fan caps excluded)."
-msgstr "Una silhouette 2D della testina di stampa (cappucci ventola esclusi)."
+msgstr "Una silhouette 2D della testa di stampa (coperture ventola escluse)."
#: fdmprinter.def.json
msgctxt "machine_head_with_fans_polygon label"
msgid "Machine head & Fan polygon"
-msgstr "Poligono testina macchina e ventola"
+msgstr "Poligono testa macchina e ventola"
#: fdmprinter.def.json
msgctxt "machine_head_with_fans_polygon description"
msgid "A 2D silhouette of the print head (fan caps included)."
-msgstr "Una silhouette 2D della testina di stampa (cappucci ventola inclusi)."
+msgstr "Una silhouette 2D della testa di stampa (coperture ventola incluse)."
#: fdmprinter.def.json
msgctxt "gantry_height label"
@@ -413,7 +413,7 @@ msgstr "ID ugello"
#: fdmprinter.def.json
msgctxt "machine_nozzle_id description"
msgid "The nozzle ID for an extruder train, such as \"AA 0.4\" and \"BB 0.8\"."
-msgstr "ID ugello per un treno estrusore, come \"AA 0.4\" e \"BB 0.8\"."
+msgstr "ID ugello per un blocco estrusore, come \"AA 0.4\" e \"BB 0.8\"."
#: fdmprinter.def.json
msgctxt "machine_nozzle_size label"
@@ -593,27 +593,27 @@ msgstr "Qualità"
#: fdmprinter.def.json
msgctxt "resolution description"
msgid "All settings that influence the resolution of the print. These settings have a large impact on the quality (and print time)"
-msgstr "Indica tutte le impostazioni che influiscono sulla risoluzione della stampa. Queste impostazioni hanno un elevato impatto sulla qualità (e il tempo di stampa)"
+msgstr "Indica tutte le impostazioni che influiscono sulla risoluzione della stampa. Queste impostazioni hanno un elevato impatto sulla qualità (e sul tempo di stampa)"
#: fdmprinter.def.json
msgctxt "layer_height label"
msgid "Layer Height"
-msgstr "Altezza dello strato"
+msgstr "Altezza del layer"
#: fdmprinter.def.json
msgctxt "layer_height description"
msgid "The height of each layer in mm. Higher values produce faster prints in lower resolution, lower values produce slower prints in higher resolution."
-msgstr "Indica l’altezza di ciascuno strato in mm. Valori più elevati generano stampe più rapide con risoluzione inferiore, valori più bassi generano stampe più lente con risoluzione superiore."
+msgstr "Indica l’altezza di ciascun layer in mm. Valori più elevati generano stampe più rapide con risoluzione inferiore, valori più bassi generano stampe più lente con risoluzione superiore."
#: fdmprinter.def.json
msgctxt "layer_height_0 label"
msgid "Initial Layer Height"
-msgstr "Altezza dello strato iniziale"
+msgstr "Altezza iniziale del layer"
#: fdmprinter.def.json
msgctxt "layer_height_0 description"
msgid "The height of the initial layer in mm. A thicker initial layer makes adhesion to the build plate easier."
-msgstr "Indica l’altezza dello strato iniziale in mm. Uno strato iniziale più spesso facilita l’adesione al piano di stampa."
+msgstr "Indica l’altezza del layer iniziale in mm. Un layer iniziale più spesso facilita l’adesione al piano di stampa."
#: fdmprinter.def.json
msgctxt "line_width label"
@@ -733,17 +733,17 @@ msgstr "Larghezza della linea della torre di innesco"
#: fdmprinter.def.json
msgctxt "prime_tower_line_width description"
msgid "Width of a single prime tower line."
-msgstr "Indica la larghezza di una singola linea della torre di innesco."
+msgstr "Indica la larghezza di una singola linea della prime tower."
#: fdmprinter.def.json
msgctxt "initial_layer_line_width_factor label"
msgid "Initial Layer Line Width"
-msgstr "Larghezza linea strato iniziale"
+msgstr "Larghezza linea layer iniziale"
#: fdmprinter.def.json
msgctxt "initial_layer_line_width_factor description"
msgid "Multiplier of the line width on the first layer. Increasing this could improve bed adhesion."
-msgstr "Moltiplicatore della larghezza della linea del primo strato Il suo aumento potrebbe migliorare l'adesione al piano"
+msgstr "Moltiplicatore della larghezza della linea del primo layer. Il suo aumento potrebbe migliorare l'adesione al piano"
#: fdmprinter.def.json
msgctxt "shell label"
@@ -763,7 +763,7 @@ msgstr "Estrusore pareti"
#: fdmprinter.def.json
msgctxt "wall_extruder_nr description"
msgid "The extruder train used for printing the walls. This is used in multi-extrusion."
-msgstr "Treno estrusore utilizzato per stampare le pareti. Si utilizza nell'estrusione multipla."
+msgstr "Blocco estrusore utilizzato per stampare le pareti. Si utilizza nell'estrusione multipla."
#: fdmprinter.def.json
msgctxt "wall_0_extruder_nr label"
@@ -773,7 +773,7 @@ msgstr "Estrusore parete esterna"
#: fdmprinter.def.json
msgctxt "wall_0_extruder_nr description"
msgid "The extruder train used for printing the outer wall. This is used in multi-extrusion."
-msgstr "Treno estrusore utilizzato per stampare la parete esterna. Si utilizza nell'estrusione multipla."
+msgstr "Blocco estrusore utilizzato per stampare la parete esterna. Si utilizza nell'estrusione multipla."
#: fdmprinter.def.json
msgctxt "wall_x_extruder_nr label"
@@ -783,7 +783,7 @@ msgstr "Estrusore parete interna"
#: fdmprinter.def.json
msgctxt "wall_x_extruder_nr description"
msgid "The extruder train used for printing the inner walls. This is used in multi-extrusion."
-msgstr "Treno estrusore utilizzato per stampare le pareti interne. Si utilizza nell'estrusione multipla."
+msgstr "Blocco estrusore utilizzato per stampare le pareti interne. Si utilizza nell'estrusione multipla."
#: fdmprinter.def.json
msgctxt "wall_thickness label"
@@ -803,7 +803,7 @@ msgstr "Numero delle linee perimetrali"
#: fdmprinter.def.json
msgctxt "wall_line_count description"
msgid "The number of walls. When calculated by the wall thickness, this value is rounded to a whole number."
-msgstr "Indica il numero delle pareti. Quando calcolato mediante lo spessore della parete, il valore viene arrotondato a numero intero."
+msgstr "Indica il numero delle pareti. Se calcolato mediante lo spessore della parete, il valore viene arrotondato a numero intero."
#: fdmprinter.def.json
msgctxt "wall_0_wipe_dist label"
@@ -823,17 +823,17 @@ msgstr "Estrusore rivestimento superficie superiore"
#: fdmprinter.def.json
msgctxt "roofing_extruder_nr description"
msgid "The extruder train used for printing the top most skin. This is used in multi-extrusion."
-msgstr "Treno estrusore utilizzato per stampare il rivestimento più in alto. Si utilizza nell'estrusione multipla."
+msgstr "Blocco estrusore utilizzato per stampare il rivestimento più in alto. Si utilizza nell'estrusione multipla."
#: fdmprinter.def.json
msgctxt "roofing_layer_count label"
msgid "Top Surface Skin Layers"
-msgstr "Strati di rivestimento superficie superiore"
+msgstr "Layer di rivestimento superficie superiore"
#: fdmprinter.def.json
msgctxt "roofing_layer_count description"
msgid "The number of top most skin layers. Usually only one top most layer is sufficient to generate higher quality top surfaces."
-msgstr "Numero degli strati di rivestimento superiori. Solitamente è sufficiente un unico strato di sommità per ottenere superfici superiori di qualità elevata."
+msgstr "Numero dei layers di rivestimento superiori. Solitamente è sufficiente un unico layer di sommità per ottenere superfici superiori di qualità elevata."
#: fdmprinter.def.json
msgctxt "top_bottom_extruder_nr label"
@@ -843,67 +843,67 @@ msgstr "Estrusore superiore/inferiore"
#: fdmprinter.def.json
msgctxt "top_bottom_extruder_nr description"
msgid "The extruder train used for printing the top and bottom skin. This is used in multi-extrusion."
-msgstr "Treno estrusore utilizzato per stampare il rivestimento superiore e quello inferiore. Si utilizza nell'estrusione multipla."
+msgstr "Blocco estrusore utilizzato per stampare il rivestimento superiore e quello inferiore. Si utilizza nell'estrusione multipla."
#: fdmprinter.def.json
msgctxt "top_bottom_thickness label"
msgid "Top/Bottom Thickness"
-msgstr "Spessore dello strato superiore/inferiore"
+msgstr "Spessore del layer superiore/inferiore"
#: fdmprinter.def.json
msgctxt "top_bottom_thickness description"
msgid "The thickness of the top/bottom layers in the print. This value divided by the layer height defines the number of top/bottom layers."
-msgstr "Indica lo spessore degli strati superiore/inferiore nella stampa. Questo valore diviso per la l’altezza dello strato definisce il numero degli strati superiori/inferiori."
+msgstr "Indica lo spessore dei layers superiore/inferiore nella stampa. Questo valore diviso per la l’altezza del layer definisce il numero dei layers superiori/inferiori."
#: fdmprinter.def.json
msgctxt "top_thickness label"
msgid "Top Thickness"
-msgstr "Spessore dello strato superiore"
+msgstr "Spessore del layer superiore"
#: fdmprinter.def.json
msgctxt "top_thickness description"
msgid "The thickness of the top layers in the print. This value divided by the layer height defines the number of top layers."
-msgstr "Indica lo spessore degli strati superiori nella stampa. Questo valore diviso per la l’altezza dello strato definisce il numero degli strati superiori."
+msgstr "Indica lo spessore dei layers superiori nella stampa. Questo valore diviso per la l’altezza del layer definisce il numero dei layers superiori."
#: fdmprinter.def.json
msgctxt "top_layers label"
msgid "Top Layers"
-msgstr "Strati superiori"
+msgstr "Layers superiori"
#: fdmprinter.def.json
msgctxt "top_layers description"
msgid "The number of top layers. When calculated by the top thickness, this value is rounded to a whole number."
-msgstr "Indica il numero degli strati superiori. Quando calcolato mediante lo spessore dello strato superiore, il valore viene arrotondato a numero intero."
+msgstr "Indica il numero dei layers superiori. Se calcolato mediante lo spessore del layer superiore, il valore viene arrotondato a numero intero."
#: fdmprinter.def.json
msgctxt "bottom_thickness label"
msgid "Bottom Thickness"
-msgstr "Spessore degli strati inferiori"
+msgstr "Spessore dei layers inferiori"
#: fdmprinter.def.json
msgctxt "bottom_thickness description"
msgid "The thickness of the bottom layers in the print. This value divided by the layer height defines the number of bottom layers."
-msgstr "Indica lo spessore degli strati inferiori nella stampa. Questo valore diviso per la l’altezza dello strato definisce il numero degli strati inferiori."
+msgstr "Indica lo spessore dei layers inferiori nella stampa. Questo valore diviso per la l’altezza del layer definisce il numero dei layers inferiori."
#: fdmprinter.def.json
msgctxt "bottom_layers label"
msgid "Bottom Layers"
-msgstr "Strati inferiori"
+msgstr "Layers inferiori"
#: fdmprinter.def.json
msgctxt "bottom_layers description"
msgid "The number of bottom layers. When calculated by the bottom thickness, this value is rounded to a whole number."
-msgstr "Indica il numero degli strati inferiori. Quando calcolato mediante lo spessore dello strato inferiore, il valore viene arrotondato a numero intero."
+msgstr "Indica il numero dei layers inferiori. Quando calcolato mediante lo spessore del layer inferiore, il valore viene arrotondato a numero intero."
#: fdmprinter.def.json
msgctxt "top_bottom_pattern label"
msgid "Top/Bottom Pattern"
-msgstr "Configurazione dello strato superiore/inferiore"
+msgstr "Configurazione del layer superiore/inferiore"
#: fdmprinter.def.json
msgctxt "top_bottom_pattern description"
msgid "The pattern of the top/bottom layers."
-msgstr "Indica la configurazione degli strati superiori/inferiori."
+msgstr "Indica la configurazione dei layers superiori/inferiori."
#: fdmprinter.def.json
msgctxt "top_bottom_pattern option lines"
@@ -923,12 +923,12 @@ msgstr "Zig Zag"
#: fdmprinter.def.json
msgctxt "top_bottom_pattern_0 label"
msgid "Bottom Pattern Initial Layer"
-msgstr "Strato iniziale configurazione inferiore"
+msgstr "Layer iniziale configurazione inferiore"
#: fdmprinter.def.json
msgctxt "top_bottom_pattern_0 description"
msgid "The pattern on the bottom of the print on the first layer."
-msgstr "La configurazione al fondo della stampa sul primo strato."
+msgstr "La configurazione al fondo della stampa sul primo layer."
#: fdmprinter.def.json
msgctxt "top_bottom_pattern_0 option lines"
@@ -953,7 +953,7 @@ msgstr "Direzioni delle linee superiori/inferiori"
#: fdmprinter.def.json
msgctxt "skin_angles description"
msgid "A list of integer line directions to use when the top/bottom layers use the lines or zig zag pattern. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the traditional default angles (45 and 135 degrees)."
-msgstr "Un elenco di direzioni linee intere da usare quando gli strati superiori/inferiori utilizzano le linee o la configurazione zig zag. Gli elementi dall’elenco sono utilizzati in sequenza con il progredire degli strati e, al raggiungimento della fine dell’elenco, la sequenza ricomincia dall’inizio. Le voci elencate sono separate da virgole e l’intero elenco è racchiuso tra parentesi quadre. L’elenco predefinito è vuoto, vale a dire che utilizza i valori angolari predefiniti (45 e 135 gradi)."
+msgstr "Un elenco di direzioni linee intere da usare quando i layers superiori/inferiori utilizzano le linee o la configurazione zig zag. Gli elementi dall’elenco sono utilizzati in sequenza con il progredire dei layers e, al raggiungimento della fine dell’elenco, la sequenza ricomincia dall’inizio. Le voci elencate sono separate da virgole e l’intero elenco è racchiuso tra parentesi quadre. L’elenco predefinito è vuoto, vale a dire che utilizza i valori angolari predefiniti (45 e 135 gradi)."
#: fdmprinter.def.json
msgctxt "wall_0_inset label"
@@ -1073,17 +1073,17 @@ msgstr "Espansione orizzontale"
#: fdmprinter.def.json
msgctxt "xy_offset description"
msgid "Amount of offset applied to all polygons in each layer. Positive values can compensate for too big holes; negative values can compensate for too small holes."
-msgstr "Determina l'entità di offset (o estensione dello strato) applicata a tutti i poligoni su ciascuno strato. I valori positivi possono compensare fori troppo estesi; i valori negativi possono compensare fori troppo piccoli."
+msgstr "Determina l'entità di offset (o estensione del layer) applicata a tutti i poligoni su ciascun layer. I valori positivi possono compensare fori troppo estesi; i valori negativi possono compensare fori troppo piccoli."
#: fdmprinter.def.json
msgctxt "xy_offset_layer_0 label"
msgid "Initial Layer Horizontal Expansion"
-msgstr "Espansione orizzontale dello strato iniziale"
+msgstr "Espansione orizzontale del layer iniziale"
#: fdmprinter.def.json
msgctxt "xy_offset_layer_0 description"
msgid "Amount of offset applied to all polygons in the first layer. A negative value can compensate for squishing of the first layer known as \"elephant's foot\"."
-msgstr "È l'entità di offset (estensione dello strato) applicata a tutti i poligoni di supporto in ciascuno strato. Un valore negativo può compensare lo schiacciamento del primo strato noto come \"zampa di elefante\"."
+msgstr "È l'entità di offset (estensione del layer) applicata a tutti i poligoni di supporto in ciascun layer. Un valore negativo può compensare lo schiacciamento del primo layer noto come \"zampa di elefante\"."
#: fdmprinter.def.json
msgctxt "z_seam_type label"
@@ -1093,7 +1093,7 @@ msgstr "Allineamento delle giunzioni a Z"
#: fdmprinter.def.json
msgctxt "z_seam_type description"
msgid "Starting point of each path in a layer. When paths in consecutive layers start at the same point a vertical seam may show on the print. When aligning these near a user specified location, the seam is easiest to remove. When placed randomly the inaccuracies at the paths' start will be less noticeable. When taking the shortest path the print will be quicker."
-msgstr "Punto di partenza di ogni percorso nell'ambito di uno strato. Quando i percorsi in strati consecutivi iniziano nello stesso punto, sulla stampa può apparire una linea di giunzione verticale. Se si allineano in prossimità di una posizione specificata dall’utente, la linea di giunzione può essere rimossa più facilmente. Se disposti in modo casuale, le imprecisioni in corrispondenza dell'inizio del percorso saranno meno evidenti. Prendendo il percorso più breve la stampa sarà più veloce."
+msgstr "Punto di partenza di ogni percorso nell'ambito di un layer. Quando i percorsi in layers consecutivi iniziano nello stesso punto, sulla stampa può apparire una linea di giunzione verticale. Se si allineano in prossimità di una posizione specificata dall’utente, la linea di giunzione può essere rimossa più facilmente. Se disposti in modo casuale, le imprecisioni in corrispondenza dell'inizio del percorso saranno meno evidenti. Prendendo il percorso più breve la stampa sarà più veloce."
#: fdmprinter.def.json
msgctxt "z_seam_type option back"
@@ -1123,7 +1123,7 @@ msgstr "Giunzione Z X"
#: fdmprinter.def.json
msgctxt "z_seam_x description"
msgid "The X coordinate of the position near where to start printing each part in a layer."
-msgstr "La coordinata X della posizione in prossimità della quale si innesca all’avvio della stampa di ciascuna parte in uno strato."
+msgstr "La coordinata X della posizione in prossimità della quale si innesca all’avvio della stampa di ciascuna parte in un layer."
#: fdmprinter.def.json
msgctxt "z_seam_y label"
@@ -1133,7 +1133,7 @@ msgstr "Giunzione Z Y"
#: fdmprinter.def.json
msgctxt "z_seam_y description"
msgid "The Y coordinate of the position near where to start printing each part in a layer."
-msgstr "La coordinata Y della posizione in prossimità della quale si innesca all’avvio della stampa di ciascuna parte in uno strato."
+msgstr "La coordinata Y della posizione in prossimità della quale si innesca all’avvio della stampa di ciascuna parte in un layer."
#: fdmprinter.def.json
msgctxt "z_seam_corner label"
@@ -1208,12 +1208,12 @@ msgstr "Ulteriore passaggio sopra la superficie superiore, senza estrusione di m
#: fdmprinter.def.json
msgctxt "ironing_only_highest_layer label"
msgid "Iron Only Highest Layer"
-msgstr "Stiramento del solo strato più elevato"
+msgstr "Stiramento del solo layer più elevato"
#: fdmprinter.def.json
msgctxt "ironing_only_highest_layer description"
msgid "Only perform ironing on the very last layer of the mesh. This saves time if the lower layers don't need a smooth surface finish."
-msgstr "Effettua lo stiramento solo dell'ultimissimo strato della maglia. È possibile quindi risparmiare tempo se gli strati inferiori non richiedono una finitura con superficie liscia."
+msgstr "Effettua lo stiramento solo dell'ultimissimo layer della maglia. È possibile quindi risparmiare tempo se i layers inferiori non richiedono una finitura con superficie liscia."
#: fdmprinter.def.json
msgctxt "ironing_pattern label"
@@ -1313,7 +1313,7 @@ msgstr "Estrusore riempimento"
#: fdmprinter.def.json
msgctxt "infill_extruder_nr description"
msgid "The extruder train used for printing infill. This is used in multi-extrusion."
-msgstr "Treno estrusore utilizzato per stampare il riempimento. Si utilizza nell'estrusione multipla."
+msgstr "Blocco estrusore utilizzato per stampare il riempimento. Si utilizza nell'estrusione multipla."
#: fdmprinter.def.json
msgctxt "infill_sparse_density label"
@@ -1343,7 +1343,7 @@ msgstr "Configurazione di riempimento"
#: fdmprinter.def.json
msgctxt "infill_pattern description"
msgid "The pattern of the infill material of the print. The line and zig zag infill swap direction on alternate layers, reducing material cost. The grid, triangle, tri-hexagon, cubic, octet, quarter cubic, cross and concentric patterns are fully printed every layer. Cubic, quarter cubic and octet infill change with every layer to provide a more equal distribution of strength over each direction."
-msgstr "Configurazione del materiale di riempimento della stampa. Il riempimento a linea e a zig zag cambia direzione su strati alternati, riducendo il costo del materiale. Le configurazioni a griglia, a triangolo, tri-esagonali, cubiche, ottagonali, a quarto di cubo, incrociate e concentriche sono stampate completamente su ogni strato. Le configurazioni cubiche, a quarto di cubo e ottagonali variano per ciascuno strato per garantire una più uniforme distribuzione della forza in ogni direzione."
+msgstr "Configurazione del materiale di riempimento della stampa. Il riempimento a linea e a zig zag cambia direzione su strati alternati, riducendo il costo del materiale. Le configurazioni a griglia, a triangolo, tri-esagonali, cubiche, ottagonali, a quarto di cubo, incrociate e concentriche sono stampate completamente su ogni layer. Le configurazioni cubiche, a quarto di cubo e ottagonali variano per ciascun layer per garantire una più uniforme distribuzione della forza in ogni direzione."
#: fdmprinter.def.json
msgctxt "infill_pattern option grid"
@@ -1428,7 +1428,7 @@ msgstr "Direzioni delle linee di riempimento"
#: fdmprinter.def.json
msgctxt "infill_angles description"
msgid "A list of integer line directions to use. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the traditional default angles (45 and 135 degrees for the lines and zig zag patterns and 45 degrees for all other patterns)."
-msgstr "Un elenco di direzioni linee intere. Gli elementi dall’elenco sono utilizzati in sequenza con il progredire degli strati e, al raggiungimento della fine dell’elenco, la sequenza ricomincia dall’inizio. Le voci elencate sono separate da virgole e l’intero elenco è racchiuso tra parentesi quadre. L’elenco predefinito è vuoto, vale a dire che utilizza i valori angolari predefiniti (45 e 135 gradi per le linee e la configurazione zig zag e 45 gradi per tutte le altre configurazioni)."
+msgstr "Un elenco di direzioni linee intere. Gli elementi dall’elenco sono utilizzati in sequenza con il progredire dei layers e, al raggiungimento della fine dell’elenco, la sequenza ricomincia dall’inizio. Le voci elencate sono separate da virgole e l’intero elenco è racchiuso tra parentesi quadre. L’elenco predefinito è vuoto, vale a dire che utilizza i valori angolari predefiniti (45 e 135 gradi per le linee e la configurazione zig zag e 45 gradi per tutte le altre configurazioni)."
#: fdmprinter.def.json
msgctxt "infill_offset_x label"
@@ -1513,12 +1513,12 @@ msgstr "Indica la distanza di uno spostamento inserito dopo ogni linea di riempi
#: fdmprinter.def.json
msgctxt "infill_sparse_thickness label"
msgid "Infill Layer Thickness"
-msgstr "Spessore dello strato di riempimento"
+msgstr "Spessore del layer di riempimento"
#: fdmprinter.def.json
msgctxt "infill_sparse_thickness description"
msgid "The thickness per layer of infill material. This value should always be a multiple of the layer height and is otherwise rounded."
-msgstr "Indica lo spessore per strato di materiale di riempimento. Questo valore deve sempre essere un multiplo dell’altezza dello strato e in caso contrario viene arrotondato."
+msgstr "Indica lo spessore per layer di materiale di riempimento. Questo valore deve sempre essere un multiplo dell’altezza del layer e in caso contrario viene arrotondato."
#: fdmprinter.def.json
msgctxt "gradual_infill_steps label"
@@ -1593,7 +1593,7 @@ msgstr "Larghezza massima delle aree di rivestimento inferiore che è possibile
#: fdmprinter.def.json
msgctxt "expand_skins_expand_distance label"
msgid "Skin Expand Distance"
-msgstr "Distanza prolunga rivestimento esterno"
+msgstr "Distanza espansione rivestimento esterno"
#: fdmprinter.def.json
msgctxt "expand_skins_expand_distance description"
@@ -1603,7 +1603,7 @@ msgstr "Distanza per cui i rivestimenti si estendono nel riempimento. Valori mag
#: fdmprinter.def.json
msgctxt "top_skin_expand_distance label"
msgid "Top Skin Expand Distance"
-msgstr "Distanza prolunga rivestimento superiore"
+msgstr "Distanza espansione rivestimento superiore"
#: fdmprinter.def.json
msgctxt "top_skin_expand_distance description"
@@ -1613,7 +1613,7 @@ msgstr "Distanza per cui i rivestimenti superiori si estendono nel riempimento.
#: fdmprinter.def.json
msgctxt "bottom_skin_expand_distance label"
msgid "Bottom Skin Expand Distance"
-msgstr "Distanza prolunga rivestimento inferiore"
+msgstr "Distanza espansione rivestimento inferiore"
#: fdmprinter.def.json
msgctxt "bottom_skin_expand_distance description"
@@ -1623,7 +1623,7 @@ msgstr "Distanza per cui i rivestimenti inferiori si estendono nel riempimento.
#: fdmprinter.def.json
msgctxt "max_skin_angle_for_expansion label"
msgid "Maximum Skin Angle for Expansion"
-msgstr "Angolo massimo rivestimento esterno per prolunga"
+msgstr "Angolo massimo rivestimento esterno per espansione"
#: fdmprinter.def.json
msgctxt "max_skin_angle_for_expansion description"
@@ -1633,7 +1633,7 @@ msgstr "Per le superfici inferiori e/o superiori dell’oggetto con un angolo ma
#: fdmprinter.def.json
msgctxt "min_skin_width_for_expansion label"
msgid "Minimum Skin Width for Expansion"
-msgstr "Larghezza minima rivestimento esterno per prolunga"
+msgstr "Larghezza minima rivestimento esterno per espansione"
#: fdmprinter.def.json
msgctxt "min_skin_width_for_expansion description"
@@ -1673,12 +1673,12 @@ msgstr "Indica la temperatura usata per la stampa."
#: fdmprinter.def.json
msgctxt "material_print_temperature_layer_0 label"
msgid "Printing Temperature Initial Layer"
-msgstr "Temperatura di stampa Strato iniziale"
+msgstr "Temperatura di stampa layer iniziale"
#: fdmprinter.def.json
msgctxt "material_print_temperature_layer_0 description"
msgid "The temperature used for printing the first layer. Set at 0 to disable special handling of the initial layer."
-msgstr "Indica la temperatura usata per la stampa del primo strato. Impostare a 0 per disabilitare la manipolazione speciale dello strato iniziale."
+msgstr "Indica la temperatura usata per la stampa del primo layer. Impostare a 0 per disabilitare la manipolazione speciale del layer iniziale."
#: fdmprinter.def.json
msgctxt "material_initial_print_temperature label"
@@ -1723,12 +1723,12 @@ msgstr "Indica la temperatura usata per il piano di stampa riscaldato. Se è 0,
#: fdmprinter.def.json
msgctxt "material_bed_temperature_layer_0 label"
msgid "Build Plate Temperature Initial Layer"
-msgstr "Temperatura piano di stampa Strato iniziale"
+msgstr "Temperatura piano di stampa Layer iniziale"
#: fdmprinter.def.json
msgctxt "material_bed_temperature_layer_0 description"
msgid "The temperature used for the heated build plate at the first layer."
-msgstr "Indica la temperatura usata per il piano di stampa riscaldato per il primo strato."
+msgstr "Indica la temperatura usata per il piano di stampa riscaldato per il primo layer."
#: fdmprinter.def.json
msgctxt "material_diameter label"
@@ -1783,12 +1783,12 @@ msgstr "Ritrae il filamento quando l'ugello si sta muovendo su un'area non stamp
#: fdmprinter.def.json
msgctxt "retract_at_layer_change label"
msgid "Retract at Layer Change"
-msgstr "Retrazione al cambio strato"
+msgstr "Retrazione al cambio layer"
#: fdmprinter.def.json
msgctxt "retract_at_layer_change description"
msgid "Retract the filament when the nozzle is moving to the next layer."
-msgstr "Ritrae il filamento quando l'ugello si sta muovendo allo strato successivo. "
+msgstr "Ritrae il filamento quando l'ugello si sta muovendo al layer successivo. "
#: fdmprinter.def.json
msgctxt "retraction_amount label"
@@ -2053,12 +2053,12 @@ msgstr "Velocità alla quale viene stampata la parte inferiore del supporto. La
#: fdmprinter.def.json
msgctxt "speed_prime_tower label"
msgid "Prime Tower Speed"
-msgstr "Velocità della torre di innesco"
+msgstr "Velocità della Prime Tower"
#: fdmprinter.def.json
msgctxt "speed_prime_tower description"
msgid "The speed at which the prime tower is printed. Printing the prime tower slower can make it more stable when the adhesion between the different filaments is suboptimal."
-msgstr "Indica la velocità alla quale è stampata la torre di innesco. La stampa della torre di innesco a una velocità inferiore può renderla maggiormente stabile quando l’adesione tra i diversi filamenti non è ottimale."
+msgstr "Indica la velocità alla quale è stampata la Prime Tower. La stampa della Prime Tower a una velocità inferiore può renderla maggiormente stabile quando l’adesione tra i diversi filamenti non è ottimale."
#: fdmprinter.def.json
msgctxt "speed_travel label"
@@ -2073,32 +2073,32 @@ msgstr "Indica la velocità alla quale vengono effettuati gli spostamenti."
#: fdmprinter.def.json
msgctxt "speed_layer_0 label"
msgid "Initial Layer Speed"
-msgstr "Velocità di stampa dello strato iniziale"
+msgstr "Velocità di stampa del layer iniziale"
#: fdmprinter.def.json
msgctxt "speed_layer_0 description"
msgid "The speed for the initial layer. A lower value is advised to improve adhesion to the build plate."
-msgstr "Indica la velocità per lo strato iniziale. Un valore inferiore è consigliabile per migliorare l’adesione al piano di stampa."
+msgstr "Indica la velocità per il layer iniziale. Un valore inferiore è consigliabile per migliorare l’adesione al piano di stampa."
#: fdmprinter.def.json
msgctxt "speed_print_layer_0 label"
msgid "Initial Layer Print Speed"
-msgstr "Velocità di stampa strato iniziale"
+msgstr "Velocità di stampa layer iniziale"
#: fdmprinter.def.json
msgctxt "speed_print_layer_0 description"
msgid "The speed of printing for the initial layer. A lower value is advised to improve adhesion to the build plate."
-msgstr "Indica la velocità di stampa per lo strato iniziale. Un valore inferiore è consigliabile per migliorare l’adesione al piano di stampa."
+msgstr "Indica la velocità di stampa per il layer iniziale. Un valore inferiore è consigliabile per migliorare l’adesione al piano di stampa."
#: fdmprinter.def.json
msgctxt "speed_travel_layer_0 label"
msgid "Initial Layer Travel Speed"
-msgstr "Velocità di spostamento dello strato iniziale"
+msgstr "Velocità di spostamento del layer iniziale"
#: fdmprinter.def.json
msgctxt "speed_travel_layer_0 description"
msgid "The speed of travel moves in the initial layer. A lower value is advised to prevent pulling previously printed parts away from the build plate. The value of this setting can automatically be calculated from the ratio between the Travel Speed and the Print Speed."
-msgstr "Indica la velocità di spostamento per lo strato iniziale. Un valore inferiore è consigliabile per evitare di rimuovere le parti precedentemente stampate dal piano di stampa. Il valore di questa impostazione può essere calcolato automaticamente dal rapporto tra la velocità di spostamento e la velocità di stampa."
+msgstr "Indica la velocità di spostamento del layer iniziale. Un valore inferiore è consigliabile per evitare di rimuovere le parti precedentemente stampate dal piano di stampa. Il valore di questa impostazione può essere calcolato automaticamente dal rapporto tra la velocità di spostamento e la velocità di stampa."
#: fdmprinter.def.json
msgctxt "skirt_brim_speed label"
@@ -2123,12 +2123,12 @@ msgstr "Indica la velocità massima di spostamento del piano di stampa. L’impo
#: fdmprinter.def.json
msgctxt "speed_slowdown_layers label"
msgid "Number of Slower Layers"
-msgstr "Numero di strati stampati a velocità inferiore"
+msgstr "Numero di layers stampati a velocità inferiore"
#: fdmprinter.def.json
msgctxt "speed_slowdown_layers description"
msgid "The first few layers are printed slower than the rest of the model, to get better adhesion to the build plate and improve the overall success rate of prints. The speed is gradually increased over these layers."
-msgstr "I primi strati vengono stampati più lentamente rispetto al resto del modello, per ottenere una migliore adesione al piano di stampa ed ottimizzare nel complesso la percentuale di successo delle stampe. La velocità aumenta gradualmente nel corso di esecuzione degli strati successivi."
+msgstr "I primi layers vengono stampati più lentamente rispetto al resto del modello, per ottenere una migliore adesione al piano di stampa ed ottimizzare nel complesso la percentuale di successo delle stampe. La velocità aumenta gradualmente nel corso di esecuzione dei layers successivi."
#: fdmprinter.def.json
msgctxt "speed_equalize_flow_enabled label"
@@ -2283,12 +2283,12 @@ msgstr "Accelerazione alla quale vengono stampate le parti inferiori del support
#: fdmprinter.def.json
msgctxt "acceleration_prime_tower label"
msgid "Prime Tower Acceleration"
-msgstr "Accelerazione della torre di innesco"
+msgstr "Accelerazione della Prime Tower"
#: fdmprinter.def.json
msgctxt "acceleration_prime_tower description"
msgid "The acceleration with which the prime tower is printed."
-msgstr "Indica l’accelerazione con cui viene stampata la torre di innesco."
+msgstr "Indica l’accelerazione con cui viene stampata la Prime Tower."
#: fdmprinter.def.json
msgctxt "acceleration_travel label"
@@ -2303,32 +2303,32 @@ msgstr "Indica l’accelerazione alla quale vengono effettuati gli spostamenti."
#: fdmprinter.def.json
msgctxt "acceleration_layer_0 label"
msgid "Initial Layer Acceleration"
-msgstr "Accelerazione dello strato iniziale"
+msgstr "Accelerazione del layer iniziale"
#: fdmprinter.def.json
msgctxt "acceleration_layer_0 description"
msgid "The acceleration for the initial layer."
-msgstr "Indica l’accelerazione dello strato iniziale."
+msgstr "Indica l’accelerazione del layer iniziale."
#: fdmprinter.def.json
msgctxt "acceleration_print_layer_0 label"
msgid "Initial Layer Print Acceleration"
-msgstr "Accelerazione di stampa strato iniziale"
+msgstr "Accelerazione di stampa layer iniziale"
#: fdmprinter.def.json
msgctxt "acceleration_print_layer_0 description"
msgid "The acceleration during the printing of the initial layer."
-msgstr "Indica l’accelerazione durante la stampa dello strato iniziale."
+msgstr "Indica l’accelerazione durante la stampa del layer iniziale."
#: fdmprinter.def.json
msgctxt "acceleration_travel_layer_0 label"
msgid "Initial Layer Travel Acceleration"
-msgstr "Accelerazione spostamenti dello strato iniziale"
+msgstr "Accelerazione spostamenti del layer iniziale"
#: fdmprinter.def.json
msgctxt "acceleration_travel_layer_0 description"
msgid "The acceleration for travel moves in the initial layer."
-msgstr "Indica l’accelerazione degli spostamenti dello strato iniziale."
+msgstr "Indica l’accelerazione degli spostamenti del layer iniziale."
#: fdmprinter.def.json
msgctxt "acceleration_skirt_brim label"
@@ -2338,7 +2338,7 @@ msgstr "Accelerazione skirt/brim"
#: fdmprinter.def.json
msgctxt "acceleration_skirt_brim description"
msgid "The acceleration with which the skirt and brim are printed. Normally this is done with the initial layer acceleration, but sometimes you might want to print the skirt or brim at a different acceleration."
-msgstr "Indica l’accelerazione alla quale sono stampati lo skirt ed il brim. Normalmente questa operazione viene svolta all’accelerazione dello strato iniziale, ma a volte è possibile che si desideri stampare lo skirt o il brim ad un’accelerazione diversa."
+msgstr "Indica l’accelerazione alla quale sono stampati lo skirt ed il brim. Normalmente questa operazione viene svolta all’accelerazione del layer iniziale, ma a volte è possibile che si desideri stampare lo skirt o il brim ad un’accelerazione diversa."
#: fdmprinter.def.json
msgctxt "jerk_enabled label"
@@ -2348,7 +2348,7 @@ msgstr "Abilita controllo jerk"
#: fdmprinter.def.json
msgctxt "jerk_enabled description"
msgid "Enables adjusting the jerk of print head when the velocity in the X or Y axis changes. Increasing the jerk can reduce printing time at the cost of print quality."
-msgstr "Abilita la regolazione del jerk della testina di stampa quando la velocità nell’asse X o Y cambia. Aumentando il jerk il tempo di stampa si riduce a discapito della qualità di stampa."
+msgstr "Abilita la regolazione del jerk della testa di stampa quando la velocità nell’asse X o Y cambia. Aumentando il jerk il tempo di stampa si riduce a discapito della qualità di stampa."
#: fdmprinter.def.json
msgctxt "jerk_print label"
@@ -2358,7 +2358,7 @@ msgstr "Jerk stampa"
#: fdmprinter.def.json
msgctxt "jerk_print description"
msgid "The maximum instantaneous velocity change of the print head."
-msgstr "Indica il cambio della velocità istantanea massima della testina di stampa."
+msgstr "Indica il cambio della velocità istantanea massima della testa di stampa."
#: fdmprinter.def.json
msgctxt "jerk_infill label"
@@ -2408,7 +2408,7 @@ msgstr "Jerk del rivestimento superficie superiore"
#: fdmprinter.def.json
msgctxt "jerk_roofing description"
msgid "The maximum instantaneous velocity change with which top surface skin layers are printed."
-msgstr "Indica la variazione di velocità istantanea massima con cui vengono stampati gli strati rivestimento superficie superiore."
+msgstr "Indica la variazione di velocità istantanea massima con cui vengono stampati i layers rivestimento superficie superiore."
#: fdmprinter.def.json
msgctxt "jerk_topbottom label"
@@ -2418,7 +2418,7 @@ msgstr "Jerk strato superiore/inferiore"
#: fdmprinter.def.json
msgctxt "jerk_topbottom description"
msgid "The maximum instantaneous velocity change with which top/bottom layers are printed."
-msgstr "Indica il cambio della velocità istantanea massima con cui vengono stampati gli strati superiore/inferiore."
+msgstr "Indica il cambio della velocità istantanea massima con cui vengono stampati i layers superiore/inferiore."
#: fdmprinter.def.json
msgctxt "jerk_support label"
@@ -2473,12 +2473,12 @@ msgstr "Indica la variazione della velocità istantanea massima con cui vengono
#: fdmprinter.def.json
msgctxt "jerk_prime_tower label"
msgid "Prime Tower Jerk"
-msgstr "Jerk della torre di innesco"
+msgstr "Jerk della Prime Tower"
#: fdmprinter.def.json
msgctxt "jerk_prime_tower description"
msgid "The maximum instantaneous velocity change with which the prime tower is printed."
-msgstr "Indica il cambio della velocità istantanea massima con cui viene stampata la torre di innesco del supporto."
+msgstr "Indica il cambio della velocità istantanea massima con cui viene stampata la Prime Tower del supporto."
#: fdmprinter.def.json
msgctxt "jerk_travel label"
@@ -2493,32 +2493,32 @@ msgstr "Indica il cambio della velocità istantanea massima con cui vengono effe
#: fdmprinter.def.json
msgctxt "jerk_layer_0 label"
msgid "Initial Layer Jerk"
-msgstr "Jerk dello strato iniziale"
+msgstr "Jerk del layer iniziale"
#: fdmprinter.def.json
msgctxt "jerk_layer_0 description"
msgid "The print maximum instantaneous velocity change for the initial layer."
-msgstr "Indica il cambio della velocità istantanea massima dello strato iniziale."
+msgstr "Indica il cambio della velocità istantanea massima del layer iniziale."
#: fdmprinter.def.json
msgctxt "jerk_print_layer_0 label"
msgid "Initial Layer Print Jerk"
-msgstr "Jerk di stampa strato iniziale"
+msgstr "Jerk di stampa layer iniziale"
#: fdmprinter.def.json
msgctxt "jerk_print_layer_0 description"
msgid "The maximum instantaneous velocity change during the printing of the initial layer."
-msgstr "Indica il cambio della velocità istantanea massima durante la stampa dello strato iniziale."
+msgstr "Indica il cambio della velocità istantanea massima durante la stampa del layer iniziale."
#: fdmprinter.def.json
msgctxt "jerk_travel_layer_0 label"
msgid "Initial Layer Travel Jerk"
-msgstr "Jerk spostamenti dello strato iniziale"
+msgstr "Jerk spostamenti del layer iniziale"
#: fdmprinter.def.json
msgctxt "jerk_travel_layer_0 description"
msgid "The acceleration for travel moves in the initial layer."
-msgstr "Indica l’accelerazione degli spostamenti dello strato iniziale."
+msgstr "Indica l’accelerazione degli spostamenti del layer iniziale."
#: fdmprinter.def.json
msgctxt "jerk_skirt_brim label"
@@ -2598,22 +2598,22 @@ msgstr "La distanza tra l’ugello e le parti già stampate quando si effettua l
#: fdmprinter.def.json
msgctxt "start_layers_at_same_position label"
msgid "Start Layers with the Same Part"
-msgstr "Avvio strati con la stessa parte"
+msgstr "Avvio layers con la stessa parte"
#: fdmprinter.def.json
msgctxt "start_layers_at_same_position description"
msgid "In each layer start with printing the object near the same point, so that we don't start a new layer with printing the piece which the previous layer ended with. This makes for better overhangs and small parts, but increases printing time."
-msgstr "In ciascuno strato inizia la stampa dell’oggetto vicino allo stesso punto, in modo che non si inizia un nuovo strato con la stampa del pezzo con cui è terminato lo strato precedente. Questo consente di ottenere migliori sovrapposizioni e parti piccole, ma aumenta il tempo di stampa."
+msgstr "In ciascun layer inizia la stampa dell’oggetto vicino allo stesso punto, in modo che non si inizi un nuovo layer con la stampa del pezzo con cui è terminato il layer precedente. Questo consente di ottenere migliori sovrapposizioni e parti piccole, ma aumenta il tempo di stampa."
#: fdmprinter.def.json
msgctxt "layer_start_x label"
msgid "Layer Start X"
-msgstr "Avvio strato X"
+msgstr "Avvio layer X"
#: fdmprinter.def.json
msgctxt "layer_start_x description"
msgid "The X coordinate of the position near where to find the part to start printing each layer."
-msgstr "La coordinata X della posizione in prossimità della quale si trova la parte per avviare la stampa di ciascuno strato."
+msgstr "La coordinata X della posizione in prossimità della quale si trova la parte per avviare la stampa di ciascun layer."
#: fdmprinter.def.json
msgctxt "layer_start_y label"
@@ -2623,7 +2623,7 @@ msgstr "Avvio strato Y"
#: fdmprinter.def.json
msgctxt "layer_start_y description"
msgid "The Y coordinate of the position near where to find the part to start printing each layer."
-msgstr "La coordinata Y della posizione in prossimità della quale si trova la parte per avviare la stampa di ciascuno strato."
+msgstr "La coordinata Y della posizione in prossimità della quale si trova la parte per avviare la stampa di ciascun layer."
#: fdmprinter.def.json
msgctxt "retraction_hop_enabled label"
@@ -2683,7 +2683,7 @@ msgstr "Abilitazione raffreddamento stampa"
#: fdmprinter.def.json
msgctxt "cool_fan_enabled description"
msgid "Enables the print cooling fans while printing. The fans improve print quality on layers with short layer times and bridging / overhangs."
-msgstr "Abilita le ventole di raffreddamento durante la stampa. Le ventole migliorano la qualità di stampa sugli strati con tempi per strato più brevi e ponti/sbalzi."
+msgstr "Abilita le ventole di raffreddamento durante la stampa. Le ventole migliorano la qualità di stampa sui layers con tempi per layer più brevi e ponti/sbalzi."
#: fdmprinter.def.json
msgctxt "cool_fan_speed label"
@@ -2703,7 +2703,7 @@ msgstr "Velocità regolare della ventola"
#: fdmprinter.def.json
msgctxt "cool_fan_speed_min description"
msgid "The speed at which the fans spin before hitting the threshold. When a layer prints faster than the threshold, the fan speed gradually inclines towards the maximum fan speed."
-msgstr "Indica la velocità alla quale ruotano le ventole prima di raggiungere la soglia. Quando uno strato viene stampato a una velocità superiore alla soglia, la velocità della ventola tende gradualmente verso la velocità massima della ventola."
+msgstr "Indica la velocità alla quale ruotano le ventole prima di raggiungere la soglia. Quando un layer viene stampato a una velocità superiore alla soglia, la velocità della ventola tende gradualmente verso la velocità massima della ventola."
#: fdmprinter.def.json
msgctxt "cool_fan_speed_max label"
@@ -2713,7 +2713,7 @@ msgstr "Velocità massima della ventola"
#: fdmprinter.def.json
msgctxt "cool_fan_speed_max description"
msgid "The speed at which the fans spin on the minimum layer time. The fan speed gradually increases between the regular fan speed and maximum fan speed when the threshold is hit."
-msgstr "Indica la velocità di rotazione della ventola al tempo minimo per strato. La velocità della ventola aumenta gradualmente tra la velocità regolare della ventola e la velocità massima della ventola quando viene raggiunta la soglia."
+msgstr "Indica la velocità di rotazione della ventola al tempo minimo per layer. La velocità della ventola aumenta gradualmente tra la velocità regolare della ventola e la velocità massima della ventola quando viene raggiunta la soglia."
#: fdmprinter.def.json
msgctxt "cool_min_layer_time_fan_speed_max label"
@@ -2723,7 +2723,7 @@ msgstr "Soglia velocità regolare/massima della ventola"
#: fdmprinter.def.json
msgctxt "cool_min_layer_time_fan_speed_max description"
msgid "The layer time which sets the threshold between regular fan speed and maximum fan speed. Layers that print slower than this time use regular fan speed. For faster layers the fan speed gradually increases towards the maximum fan speed."
-msgstr "Indica il tempo per strato che definisce la soglia tra la velocità regolare e quella massima della ventola. Gli strati che vengono stampati a una velocità inferiore a questo valore utilizzano una velocità regolare della ventola. Per gli strati stampati più velocemente la velocità della ventola aumenta gradualmente verso la velocità massima della ventola."
+msgstr "Indica il tempo per layer che definisce la soglia tra la velocità regolare e quella massima della ventola. Gli strati che vengono stampati a una velocità inferiore a questo valore utilizzano una velocità regolare della ventola. Per i layers stampati più velocemente la velocità della ventola aumenta gradualmente verso la velocità massima della ventola."
#: fdmprinter.def.json
msgctxt "cool_fan_speed_0 label"
@@ -2733,7 +2733,7 @@ msgstr "Velocità iniziale della ventola"
#: fdmprinter.def.json
msgctxt "cool_fan_speed_0 description"
msgid "The speed at which the fans spin at the start of the print. In subsequent layers the fan speed is gradually increased up to the layer corresponding to Regular Fan Speed at Height."
-msgstr "La velocità di rotazione della ventola all’inizio della stampa. Negli strati successivi la velocità della ventola aumenta gradualmente da zero fino allo strato corrispondente alla velocità regolare in altezza."
+msgstr "La velocità di rotazione della ventola all’inizio della stampa. Nei layers successivi la velocità della ventola aumenta gradualmente da zero fino allo strato corrispondente alla velocità regolare in altezza."
#: fdmprinter.def.json
msgctxt "cool_fan_full_at_height label"
@@ -2743,27 +2743,27 @@ msgstr "Velocità regolare della ventola in altezza"
#: fdmprinter.def.json
msgctxt "cool_fan_full_at_height description"
msgid "The height at which the fans spin on regular fan speed. At the layers below the fan speed gradually increases from Initial Fan Speed to Regular Fan Speed."
-msgstr "Indica l’altezza alla quale la ventola ruota alla velocità regolare. Agli strati stampati a velocità inferiore la velocità della ventola aumenta gradualmente dalla velocità iniziale a quella regolare."
+msgstr "Indica l’altezza alla quale la ventola ruota alla velocità regolare. ai layers stampati a velocità inferiore la velocità della ventola aumenta gradualmente dalla velocità iniziale a quella regolare."
#: fdmprinter.def.json
msgctxt "cool_fan_full_layer label"
msgid "Regular Fan Speed at Layer"
-msgstr "Velocità regolare della ventola in corrispondenza dello strato"
+msgstr "Velocità regolare della ventola in corrispondenza del layer"
#: fdmprinter.def.json
msgctxt "cool_fan_full_layer description"
msgid "The layer at which the fans spin on regular fan speed. If regular fan speed at height is set, this value is calculated and rounded to a whole number."
-msgstr "Indica lo strato in corrispondenza del quale la ventola ruota alla velocità regolare. Se è impostata la velocità regolare in altezza, questo valore viene calcolato e arrotondato a un numero intero."
+msgstr "Indica il layer in corrispondenza del quale la ventola ruota alla velocità regolare. Se è impostata la velocità regolare in altezza, questo valore viene calcolato e arrotondato a un numero intero."
#: fdmprinter.def.json
msgctxt "cool_min_layer_time label"
msgid "Minimum Layer Time"
-msgstr "Tempo minimo per strato"
+msgstr "Tempo minimo per layer"
#: fdmprinter.def.json
msgctxt "cool_min_layer_time description"
msgid "The minimum time spent in a layer. This forces the printer to slow down, to at least spend the time set here in one layer. This allows the printed material to cool down properly before printing the next layer. Layers may still take shorter than the minimal layer time if Lift Head is disabled and if the Minimum Speed would otherwise be violated."
-msgstr "Indica il tempo minimo dedicato a uno strato. Questo forza la stampante a rallentare, per impiegare almeno il tempo impostato qui per uno strato. Questo consente il corretto raffreddamento del materiale stampato prima di procedere alla stampa dello strato successivo. La stampa degli strati potrebbe richiedere un tempo inferiore al minimo se la funzione Sollevamento della testina è disabilitata e se la velocità minima non viene rispettata."
+msgstr "Indica il tempo minimo dedicato a un layer. Questo forza la stampante a rallentare, per impiegare almeno il tempo impostato qui per un layer. Questo consente il corretto raffreddamento del materiale stampato prima di procedere alla stampa del layer successivo. La stampa dei layers potrebbe richiedere un tempo inferiore al minimo se la funzione Sollevamento della testina è disabilitata e se la velocità minima non viene rispettata."
#: fdmprinter.def.json
msgctxt "cool_min_speed label"
@@ -2773,7 +2773,7 @@ msgstr "Velocità minima"
#: fdmprinter.def.json
msgctxt "cool_min_speed description"
msgid "The minimum print speed, despite slowing down due to the minimum layer time. When the printer would slow down too much, the pressure in the nozzle would be too low and result in bad print quality."
-msgstr "Indica la velocità minima di stampa, a prescindere dal rallentamento per il tempo minimo per strato. Quando la stampante rallenta eccessivamente, la pressione nell’ugello risulta insufficiente con conseguente scarsa qualità di stampa."
+msgstr "Indica la velocità minima di stampa, a prescindere dal rallentamento per il tempo minimo per layer. Quando la stampante rallenta eccessivamente, la pressione nell’ugello risulta insufficiente con conseguente scarsa qualità di stampa."
#: fdmprinter.def.json
msgctxt "cool_lift_head label"
@@ -2783,7 +2783,7 @@ msgstr "Sollevamento della testina"
#: fdmprinter.def.json
msgctxt "cool_lift_head description"
msgid "When the minimum speed is hit because of minimum layer time, lift the head away from the print and wait the extra time until the minimum layer time is reached."
-msgstr "Quando viene raggiunta la velocità minima per il tempo minimo per strato, sollevare la testina dalla stampa e attendere il tempo supplementare fino al raggiungimento del valore per tempo minimo per strato."
+msgstr "Quando viene raggiunta la velocità minima per il tempo minimo per layer, sollevare la testina dalla stampa e attendere il tempo supplementare fino al raggiungimento del valore per tempo minimo per layer."
#: fdmprinter.def.json
msgctxt "support label"
@@ -2813,7 +2813,7 @@ msgstr "Estrusore del supporto"
#: fdmprinter.def.json
msgctxt "support_extruder_nr description"
msgid "The extruder train to use for printing the support. This is used in multi-extrusion."
-msgstr "Il treno estrusore utilizzato per la stampa del supporto. Utilizzato nell’estrusione multipla."
+msgstr "Il blocco estrusore utilizzato per la stampa del supporto. Utilizzato nell’estrusione multipla."
#: fdmprinter.def.json
msgctxt "support_infill_extruder_nr label"
@@ -2823,17 +2823,17 @@ msgstr "Estrusore riempimento del supporto"
#: fdmprinter.def.json
msgctxt "support_infill_extruder_nr description"
msgid "The extruder train to use for printing the infill of the support. This is used in multi-extrusion."
-msgstr "Il treno estrusore utilizzato per la stampa del riempimento del supporto. Utilizzato nell’estrusione multipla."
+msgstr "Il blocco estrusore utilizzato per la stampa del riempimento del supporto. Utilizzato nell’estrusione multipla."
#: fdmprinter.def.json
msgctxt "support_extruder_nr_layer_0 label"
msgid "First Layer Support Extruder"
-msgstr "Estrusore del supporto primo strato"
+msgstr "Estrusore del supporto primo layer"
#: fdmprinter.def.json
msgctxt "support_extruder_nr_layer_0 description"
msgid "The extruder train to use for printing the first layer of support infill. This is used in multi-extrusion."
-msgstr "Il treno estrusore utilizzato per la stampa del primo strato del riempimento del supporto. Utilizzato nell’estrusione multipla."
+msgstr "Il blocco estrusore utilizzato per la stampa del primo layer del riempimento del supporto. Utilizzato nell’estrusione multipla."
#: fdmprinter.def.json
msgctxt "support_interface_extruder_nr label"
@@ -2843,7 +2843,7 @@ msgstr "Estrusore interfaccia del supporto"
#: fdmprinter.def.json
msgctxt "support_interface_extruder_nr description"
msgid "The extruder train to use for printing the roofs and floors of the support. This is used in multi-extrusion."
-msgstr "Treno estrusore utilizzato per la stampa delle parti superiori e inferiori del supporto. Utilizzato nell’estrusione multipla."
+msgstr "Blocco estrusore utilizzato per la stampa delle parti superiori e inferiori del supporto. Utilizzato nell’estrusione multipla."
#: fdmprinter.def.json
msgctxt "support_roof_extruder_nr label"
@@ -2853,7 +2853,7 @@ msgstr "Estrusore parte superiore del supporto"
#: fdmprinter.def.json
msgctxt "support_roof_extruder_nr description"
msgid "The extruder train to use for printing the roofs of the support. This is used in multi-extrusion."
-msgstr "Treno estrusore utilizzato per la stampa delle parti superiori del supporto. Utilizzato nell’estrusione multipla."
+msgstr "Blocco estrusore utilizzato per la stampa delle parti superiori del supporto. Utilizzato nell’estrusione multipla."
#: fdmprinter.def.json
msgctxt "support_bottom_extruder_nr label"
@@ -2863,7 +2863,7 @@ msgstr "Estrusore parte inferiore del supporto"
#: fdmprinter.def.json
msgctxt "support_bottom_extruder_nr description"
msgid "The extruder train to use for printing the floors of the support. This is used in multi-extrusion."
-msgstr "Treno estrusore utilizzato per la stampa delle parti inferiori del supporto. Utilizzato nell’estrusione multipla."
+msgstr "Blocco estrusore utilizzato per la stampa delle parti inferiori del supporto. Utilizzato nell’estrusione multipla."
#: fdmprinter.def.json
msgctxt "support_type label"
@@ -3083,12 +3083,12 @@ msgstr "È l'entità di offset (estensione dello strato) applicato a tutti i pol
#: fdmprinter.def.json
msgctxt "support_infill_sparse_thickness label"
msgid "Support Infill Layer Thickness"
-msgstr "Spessore dello strato di riempimento di supporto"
+msgstr "Spessore dello layer di riempimento di supporto"
#: fdmprinter.def.json
msgctxt "support_infill_sparse_thickness description"
msgid "The thickness per layer of support infill material. This value should always be a multiple of the layer height and is otherwise rounded."
-msgstr "Indica lo spessore per strato del materiale di riempimento del supporto. Questo valore deve sempre essere un multiplo dell’altezza dello strato e in caso contrario viene arrotondato."
+msgstr "Indica lo spessore per layer del materiale di riempimento del supporto. Questo valore deve sempre essere un multiplo dell’altezza del layer e in caso contrario viene arrotondato."
#: fdmprinter.def.json
msgctxt "gradual_support_infill_steps label"
@@ -3168,7 +3168,7 @@ msgstr "Spessore parte inferiore del supporto"
#: fdmprinter.def.json
msgctxt "support_bottom_height description"
msgid "The thickness of the support floors. This controls the number of dense layers that are printed on top of places of a model on which support rests."
-msgstr "Indica lo spessore delle parti inferiori del supporto. Questo controlla il numero di strati fitti stampati sulla sommità dei punti di un modello su cui appoggia un supporto."
+msgstr "Indica lo spessore delle parti inferiori del supporto. Questo controlla il numero di layers fitti stampati sulla sommità dei punti di un modello su cui appoggia un supporto."
#: fdmprinter.def.json
msgctxt "support_interface_skip_height label"
@@ -3398,7 +3398,7 @@ msgstr "Maglia supporto di discesa"
#: fdmprinter.def.json
msgctxt "support_mesh_drop_down description"
msgid "Make support everywhere below the support mesh, so that there's no overhang in the support mesh."
-msgstr "Rappresenta il supporto ovunque sotto la maglia di supporto, in modo che in questa non vi siano punti a sbalzo."
+msgstr "Genera supporti ovunque sotto la maglia di supporto, in modo che in questa non vi siano punti a sbalzo."
#: fdmprinter.def.json
msgctxt "platform_adhesion label"
@@ -3478,7 +3478,7 @@ msgstr "Estrusore adesione piano di stampa"
#: fdmprinter.def.json
msgctxt "adhesion_extruder_nr description"
msgid "The extruder train to use for printing the skirt/brim/raft. This is used in multi-extrusion."
-msgstr "Il treno estrusore utilizzato per la stampa dello skirt/brim/raft. Utilizzato nell’estrusione multipla."
+msgstr "Il blocco estrusore utilizzato per la stampa dello skirt/brim/raft. Utilizzato nell’estrusione multipla."
#: fdmprinter.def.json
msgctxt "skirt_line_count label"
@@ -3570,37 +3570,37 @@ msgstr "Traferro del raft"
#: fdmprinter.def.json
msgctxt "raft_airgap description"
msgid "The gap between the final raft layer and the first layer of the model. Only the first layer is raised by this amount to lower the bonding between the raft layer and the model. Makes it easier to peel off the raft."
-msgstr "È l'interstizio tra lo strato di raft finale ed il primo strato del modello. Solo il primo strato viene sollevato di questo valore per ridurre l'adesione fra lo strato di raft e il modello. Ciò rende più facile rimuovere il raft."
+msgstr "È l'interstizio tra il layer del raft finale ed il primo layer del modello. Solo il primo layer viene sollevato di questo valore per ridurre l'adesione fra lo strato di raft e il modello. Ciò rende più facile rimuovere il raft."
#: fdmprinter.def.json
msgctxt "layer_0_z_overlap label"
msgid "Initial Layer Z Overlap"
-msgstr "Z Sovrapposizione Primo Strato"
+msgstr "Z Sovrapposizione Primo Layer"
#: fdmprinter.def.json
msgctxt "layer_0_z_overlap description"
msgid "Make the first and second layer of the model overlap in the Z direction to compensate for the filament lost in the airgap. All models above the first model layer will be shifted down by this amount."
-msgstr "Effettua il primo e secondo strato di sovrapposizione modello nella direzione Z per compensare il filamento perso nel traferro. Tutti i modelli sopra il primo strato del modello saranno spostati verso il basso di questa quantità."
+msgstr "Effettua il primo e secondo layer di sovrapposizione modello nella direzione Z per compensare il filamento perso nel vuoto. Tutti i modelli sopra il primo layer del modello saranno spostati verso il basso di questa quantità."
#: fdmprinter.def.json
msgctxt "raft_surface_layers label"
msgid "Raft Top Layers"
-msgstr "Strati superiori del raft"
+msgstr "Layers superiori del raft"
#: fdmprinter.def.json
msgctxt "raft_surface_layers description"
msgid "The number of top layers on top of the 2nd raft layer. These are fully filled layers that the model sits on. 2 layers result in a smoother top surface than 1."
-msgstr "Numero di strati sulla parte superiore del secondo strato del raft. Si tratta di strati completamente riempiti su cui poggia il modello. 2 strati danno come risultato una superficie superiore più levigata rispetto ad 1 solo strato."
+msgstr "Numero di layers sulla parte superiore del secondo layer del raft. Si tratta di layers completamente riempiti su cui poggia il modello. 2 layers danno come risultato una superficie superiore più levigata rispetto ad 1 solo layer."
#: fdmprinter.def.json
msgctxt "raft_surface_thickness label"
msgid "Raft Top Layer Thickness"
-msgstr "Spessore dello strato superiore del raft"
+msgstr "Spessore del layer superiore del raft"
#: fdmprinter.def.json
msgctxt "raft_surface_thickness description"
msgid "Layer thickness of the top raft layers."
-msgstr "È lo spessore degli strati superiori del raft."
+msgstr "È lo spessore dei layers superiori del raft."
#: fdmprinter.def.json
msgctxt "raft_surface_line_width label"
@@ -3625,17 +3625,17 @@ msgstr "Indica la distanza tra le linee che costituiscono la maglia superiore de
#: fdmprinter.def.json
msgctxt "raft_interface_thickness label"
msgid "Raft Middle Thickness"
-msgstr "Spessore dello strato intermedio del raft"
+msgstr "Spessore del layer intermedio del raft"
#: fdmprinter.def.json
msgctxt "raft_interface_thickness description"
msgid "Layer thickness of the middle raft layer."
-msgstr "È lo spessore dello strato intermedio del raft."
+msgstr "È lo spessore del layer intermedio del raft."
#: fdmprinter.def.json
msgctxt "raft_interface_line_width label"
msgid "Raft Middle Line Width"
-msgstr "Larghezza delle linee dello strato intermedio del raft"
+msgstr "Larghezza delle linee del layer intermedio del raft"
#: fdmprinter.def.json
msgctxt "raft_interface_line_width description"
@@ -3645,12 +3645,12 @@ msgstr "Indica la larghezza delle linee dello strato intermedio del raft. Una ma
#: fdmprinter.def.json
msgctxt "raft_interface_line_spacing label"
msgid "Raft Middle Spacing"
-msgstr "Spaziatura dello strato intermedio del raft"
+msgstr "Spaziatura del layer intermedio del raft"
#: fdmprinter.def.json
msgctxt "raft_interface_line_spacing description"
msgid "The distance between the raft lines for the middle raft layer. The spacing of the middle should be quite wide, while being dense enough to support the top raft layers."
-msgstr "Indica la distanza fra le linee dello strato intermedio del raft. La spaziatura dello strato intermedio deve essere abbastanza ampia, ma al tempo stesso sufficientemente fitta da sostenere gli strati superiori del raft."
+msgstr "Indica la distanza fra le linee del layer intermedio del raft. La spaziatura del layer intermedio deve essere abbastanza ampia, ma al tempo stesso sufficientemente fitta da sostenere i layers superiori del raft."
#: fdmprinter.def.json
msgctxt "raft_base_thickness label"
@@ -3660,17 +3660,17 @@ msgstr "Spessore della base del raft"
#: fdmprinter.def.json
msgctxt "raft_base_thickness description"
msgid "Layer thickness of the base raft layer. This should be a thick layer which sticks firmly to the printer build plate."
-msgstr "Indica lo spessore dello strato di base del raft. Questo strato deve essere spesso per aderire saldamente al piano di stampa."
+msgstr "Indica lo spessore del layer di base del raft. Questo layer deve essere spesso per aderire saldamente al piano di stampa."
#: fdmprinter.def.json
msgctxt "raft_base_line_width label"
msgid "Raft Base Line Width"
-msgstr "Larghezza delle linee dello strato di base del raft"
+msgstr "Larghezza delle linee del layer di base del raft"
#: fdmprinter.def.json
msgctxt "raft_base_line_width description"
msgid "Width of the lines in the base raft layer. These should be thick lines to assist in build plate adhesion."
-msgstr "Indica la larghezza delle linee dello strato di base del raft. Le linee di questo strato devono essere spesse per favorire l'adesione al piano di stampa."
+msgstr "Indica la larghezza delle linee del layer di base del raft. Le linee di questo layer devono essere spesse per favorire l'adesione al piano di stampa."
#: fdmprinter.def.json
msgctxt "raft_base_line_spacing label"
@@ -3680,7 +3680,7 @@ msgstr "Spaziatura delle linee del raft"
#: fdmprinter.def.json
msgctxt "raft_base_line_spacing description"
msgid "The distance between the raft lines for the base raft layer. Wide spacing makes for easy removal of the raft from the build plate."
-msgstr "Indica la distanza tra le linee che costituiscono lo strato di base del raft. Un'ampia spaziatura favorisce la rimozione del raft dal piano di stampa."
+msgstr "Indica la distanza tra le linee che costituiscono il layer di base del raft. Un'ampia spaziatura favorisce la rimozione del raft dal piano di stampa."
#: fdmprinter.def.json
msgctxt "raft_speed label"
@@ -3700,7 +3700,7 @@ msgstr "Velocità di stampa parte superiore del raft"
#: fdmprinter.def.json
msgctxt "raft_surface_speed description"
msgid "The speed at which the top raft layers are printed. These should be printed a bit slower, so that the nozzle can slowly smooth out adjacent surface lines."
-msgstr "Indica la velocità alla quale sono stampati gli strati superiori del raft. La stampa di questi strati deve avvenire un po' più lentamente, in modo da consentire all'ugello di levigare lentamente le linee superficiali adiacenti."
+msgstr "Indica la velocità alla quale sono stampati i layers superiori del raft. La stampa di questi layers deve avvenire un po' più lentamente, in modo da consentire all'ugello di levigare lentamente le linee superficiali adiacenti."
#: fdmprinter.def.json
msgctxt "raft_interface_speed label"
@@ -3710,7 +3710,7 @@ msgstr "Velocità di stampa raft intermedio"
#: fdmprinter.def.json
msgctxt "raft_interface_speed description"
msgid "The speed at which the middle raft layer is printed. This should be printed quite slowly, as the volume of material coming out of the nozzle is quite high."
-msgstr "Indica la velocità alla quale viene stampato lo strato intermedio del raft. La sua stampa deve avvenire molto lentamente, considerato che il volume di materiale che fuoriesce dall'ugello è piuttosto elevato."
+msgstr "Indica la velocità alla quale viene stampato il layer intermedio del raft. La sua stampa deve avvenire molto lentamente, considerato che il volume di materiale che fuoriesce dall'ugello è piuttosto elevato."
#: fdmprinter.def.json
msgctxt "raft_base_speed label"
@@ -3740,7 +3740,7 @@ msgstr "Accelerazione di stampa parte superiore del raft"
#: fdmprinter.def.json
msgctxt "raft_surface_acceleration description"
msgid "The acceleration with which the top raft layers are printed."
-msgstr "Indica l’accelerazione alla quale vengono stampati gli strati superiori del raft."
+msgstr "Indica l’accelerazione alla quale vengono stampati i layers superiori del raft."
#: fdmprinter.def.json
msgctxt "raft_interface_acceleration label"
@@ -3750,7 +3750,7 @@ msgstr "Accelerazione di stampa raft intermedio"
#: fdmprinter.def.json
msgctxt "raft_interface_acceleration description"
msgid "The acceleration with which the middle raft layer is printed."
-msgstr "Indica l’accelerazione con cui viene stampato lo strato intermedio del raft."
+msgstr "Indica l’accelerazione con cui viene stampato il layer intermedio del raft."
#: fdmprinter.def.json
msgctxt "raft_base_acceleration label"
@@ -3760,7 +3760,7 @@ msgstr "Accelerazione di stampa della base del raft"
#: fdmprinter.def.json
msgctxt "raft_base_acceleration description"
msgid "The acceleration with which the base raft layer is printed."
-msgstr "Indica l’accelerazione con cui viene stampato lo strato di base del raft."
+msgstr "Indica l’accelerazione con cui viene stampato il layer di base del raft."
#: fdmprinter.def.json
msgctxt "raft_jerk label"
@@ -3780,7 +3780,7 @@ msgstr "Jerk di stampa parte superiore del raft"
#: fdmprinter.def.json
msgctxt "raft_surface_jerk description"
msgid "The jerk with which the top raft layers are printed."
-msgstr "Indica il jerk al quale vengono stampati gli strati superiori del raft."
+msgstr "Indica il jerk al quale vengono stampati i layers superiori del raft."
#: fdmprinter.def.json
msgctxt "raft_interface_jerk label"
@@ -3790,7 +3790,7 @@ msgstr "Jerk di stampa raft intermedio"
#: fdmprinter.def.json
msgctxt "raft_interface_jerk description"
msgid "The jerk with which the middle raft layer is printed."
-msgstr "Indica il jerk con cui viene stampato lo strato intermedio del raft."
+msgstr "Indica il jerk con cui viene stampato il layer intermedio del raft."
#: fdmprinter.def.json
msgctxt "raft_base_jerk label"
@@ -3800,7 +3800,7 @@ msgstr "Jerk di stampa della base del raft"
#: fdmprinter.def.json
msgctxt "raft_base_jerk description"
msgid "The jerk with which the base raft layer is printed."
-msgstr "Indica il jerk con cui viene stampato lo strato di base del raft."
+msgstr "Indica il jerk con cui viene stampato il layer di base del raft."
#: fdmprinter.def.json
msgctxt "raft_fan_speed label"
@@ -3820,7 +3820,7 @@ msgstr "Velocità della ventola per la parte superiore del raft"
#: fdmprinter.def.json
msgctxt "raft_surface_fan_speed description"
msgid "The fan speed for the top raft layers."
-msgstr "Indica la velocità di rotazione della ventola per gli strati superiori del raft."
+msgstr "Indica la velocità di rotazione della ventola per i layers superiori del raft."
#: fdmprinter.def.json
msgctxt "raft_interface_fan_speed label"
@@ -3830,7 +3830,7 @@ msgstr "Velocità della ventola per il raft intermedio"
#: fdmprinter.def.json
msgctxt "raft_interface_fan_speed description"
msgid "The fan speed for the middle raft layer."
-msgstr "Indica la velocità di rotazione della ventola per gli strati intermedi del raft."
+msgstr "Indica la velocità di rotazione della ventola per i layers intermedi del raft."
#: fdmprinter.def.json
msgctxt "raft_base_fan_speed label"
@@ -3840,7 +3840,7 @@ msgstr "Velocità della ventola per la base del raft"
#: fdmprinter.def.json
msgctxt "raft_base_fan_speed description"
msgid "The fan speed for the base raft layer."
-msgstr "Indica la velocità di rotazione della ventola per lo strato di base del raft."
+msgstr "Indica la velocità di rotazione della ventola per il layer di base del raft."
#: fdmprinter.def.json
msgctxt "dual label"
@@ -3855,7 +3855,7 @@ msgstr "Indica le impostazioni utilizzate per la stampa con estrusori multipli."
#: fdmprinter.def.json
msgctxt "prime_tower_enable label"
msgid "Enable Prime Tower"
-msgstr "Abilitazione torre di innesco"
+msgstr "Abilitazione Prime Tower"
#: fdmprinter.def.json
msgctxt "prime_tower_enable description"
@@ -3865,57 +3865,57 @@ msgstr "Stampa una torre accanto alla stampa che serve per innescare il material
#: fdmprinter.def.json
msgctxt "prime_tower_size label"
msgid "Prime Tower Size"
-msgstr "Dimensioni torre di innesco"
+msgstr "Dimensioni Prime Tower"
#: fdmprinter.def.json
msgctxt "prime_tower_size description"
msgid "The width of the prime tower."
-msgstr "Indica la larghezza della torre di innesco."
+msgstr "Indica la larghezza della Prime Tower."
#: fdmprinter.def.json
msgctxt "prime_tower_min_volume label"
msgid "Prime Tower Minimum Volume"
-msgstr "Volume minimo torre di innesco"
+msgstr "Volume minimo Prime Tower"
#: fdmprinter.def.json
msgctxt "prime_tower_min_volume description"
msgid "The minimum volume for each layer of the prime tower in order to purge enough material."
-msgstr "Il volume minimo per ciascuno strato della torre di innesco per scaricare materiale a sufficienza."
+msgstr "Il volume minimo per ciascun layer della Prime Tower per scaricare materiale a sufficienza."
#: fdmprinter.def.json
msgctxt "prime_tower_wall_thickness label"
msgid "Prime Tower Thickness"
-msgstr "Spessore torre di innesco"
+msgstr "Spessore Prime Tower"
#: fdmprinter.def.json
msgctxt "prime_tower_wall_thickness description"
msgid "The thickness of the hollow prime tower. A thickness larger than half the Prime Tower Minimum Volume will result in a dense prime tower."
-msgstr "Lo spessore della torre di innesco cava. Uno spessore superiore alla metà del volume minimo della torre di innesco genera una torre di innesco densa."
+msgstr "Lo spessore della Prime Tower cava. Uno spessore superiore alla metà del volume minimo della Prime Tower genera una torre di innesco densa."
#: fdmprinter.def.json
msgctxt "prime_tower_position_x label"
msgid "Prime Tower X Position"
-msgstr "Posizione X torre di innesco"
+msgstr "Posizione X Prime Tower"
#: fdmprinter.def.json
msgctxt "prime_tower_position_x description"
msgid "The x coordinate of the position of the prime tower."
-msgstr "Indica la coordinata X della posizione della torre di innesco."
+msgstr "Indica la coordinata X della posizione della Prime Tower."
#: fdmprinter.def.json
msgctxt "prime_tower_position_y label"
msgid "Prime Tower Y Position"
-msgstr "Posizione Y torre di innesco"
+msgstr "Posizione Y Prime Tower"
#: fdmprinter.def.json
msgctxt "prime_tower_position_y description"
msgid "The y coordinate of the position of the prime tower."
-msgstr "Indica la coordinata Y della posizione della torre di innesco."
+msgstr "Indica la coordinata Y della posizione della Prime Tower."
#: fdmprinter.def.json
msgctxt "prime_tower_flow label"
msgid "Prime Tower Flow"
-msgstr "Flusso torre di innesco"
+msgstr "Flusso Prime Tower"
#: fdmprinter.def.json
msgctxt "prime_tower_flow description"
@@ -3925,17 +3925,17 @@ msgstr "Determina la compensazione del flusso: la quantità di materiale estruso
#: fdmprinter.def.json
msgctxt "prime_tower_wipe_enabled label"
msgid "Wipe Inactive Nozzle on Prime Tower"
-msgstr "Ugello pulitura inattiva sulla torre di innesco"
+msgstr "Ugello pulitura inattiva sulla Prime Tower"
#: fdmprinter.def.json
msgctxt "prime_tower_wipe_enabled description"
msgid "After printing the prime tower with one nozzle, wipe the oozed material from the other nozzle off on the prime tower."
-msgstr "Dopo la stampa della torre di innesco con un ugello, pulisce il materiale fuoriuscito dall’altro ugello sulla torre di innesco."
+msgstr "Dopo la stampa della Prime Tower con un ugello, pulisce il materiale fuoriuscito dall’altro ugello sulla Prime Tower."
#: fdmprinter.def.json
msgctxt "dual_pre_wipe label"
msgid "Wipe Nozzle After Switch"
-msgstr "Ugello pulitura dopo commutazione"
+msgstr "Pulitura ugello dopo commutazione"
#: fdmprinter.def.json
msgctxt "dual_pre_wipe description"
@@ -3945,12 +3945,12 @@ msgstr "Dopo la commutazione dell’estrusore, pulire il materiale fuoriuscito d
#: fdmprinter.def.json
msgctxt "prime_tower_purge_volume label"
msgid "Prime Tower Purge Volume"
-msgstr "Volume di scarico torre di innesco"
+msgstr "Volume di scarico Prime Tower"
#: fdmprinter.def.json
msgctxt "prime_tower_purge_volume description"
msgid "Amount of filament to be purged when wiping on the prime tower. Purging is useful for compensating the filament lost by oozing during inactivity of the nozzle."
-msgstr "Quantità di filamento da scaricare durante la pulizia della torre di innesco. Lo scarico è utile per compensare il filamento perso per colatura durante l'inattività dell'ugello."
+msgstr "Quantità di filamento da scaricare durante la pulizia della Prime Tower. Lo scarico è utile per compensare il filamento perso per colatura durante l'inattività dell'ugello."
#: fdmprinter.def.json
msgctxt "ooze_shield_enabled label"
@@ -4090,7 +4090,7 @@ msgstr "Sequenza di stampa"
#: fdmprinter.def.json
msgctxt "print_sequence description"
msgid "Whether to print all models one layer at a time or to wait for one model to finish, before moving on to the next. One at a time mode is only possible if all models are separated in such a way that the whole print head can move in between and all models are lower than the distance between the nozzle and the X/Y axes."
-msgstr "Indica se stampare tutti i modelli uno strato alla volta o se attendere di terminare un modello prima di passare al successivo. La modalità 'uno per volta' è possibile solo se tutti i modelli sono separati in modo tale che l'intera testina di stampa possa muoversi tra di essi e se tutti i modelli sono più bassi della distanza tra l'ugello e gli assi X/Y."
+msgstr "Indica se stampare tutti i modelli uno layer alla volta o se attendere di terminare un modello prima di passare al successivo. La modalità 'uno per volta' è possibile solo se tutti i modelli sono separati in modo tale che l'intera testa di stampa possa muoversi tra di essi e se tutti i modelli sono più bassi della distanza tra l'ugello e gli assi X/Y."
#: fdmprinter.def.json
msgctxt "print_sequence option all_at_once"
@@ -4245,7 +4245,7 @@ msgstr "Estrusione relativa"
#: fdmprinter.def.json
msgctxt "relative_extrusion description"
msgid "Use relative extrusion rather than absolute extrusion. Using relative E-steps makes for easier post-processing of the Gcode. However, it's not supported by all printers and it may produce very slight deviations in the amount of deposited material compared to absolute E-steps. Irrespective of this setting, the extrusion mode will always be set to absolute before any Gcode script is output."
-msgstr "Utilizza l'estrusione relativa invece di quella assoluta. L'utilizzo di fasi E relative facilita la post-elaborazione del codice G. Tuttavia, questa impostazione non è supportata da tutte le stampanti e può causare deviazioni molto piccole nella quantità di materiale depositato rispetto alle fasi E assolute. Indipendentemente da questa impostazione, la modalità estrusione sarà sempre impostata su assoluta prima che venga generato uno script in codice G."
+msgstr "Utilizza l'estrusione relativa invece di quella assoluta. L'utilizzo di fasi E relative facilita la post-elaborazione del Gcode. Tuttavia, questa impostazione non è supportata da tutte le stampanti e può causare deviazioni molto piccole nella quantità di materiale depositato rispetto agli E-steps assoluti. Indipendentemente da questa impostazione, la modalità estrusione sarà sempre impostata su assoluta prima che venga generato uno script Gcode."
#: fdmprinter.def.json
msgctxt "experimental label"
@@ -4380,7 +4380,7 @@ msgstr "Configurazione del rivestimento superficie superiore"
#: fdmprinter.def.json
msgctxt "roofing_pattern description"
msgid "The pattern of the top most layers."
-msgstr "Configurazione degli strati superiori."
+msgstr "Configurazione dei layers superiori."
#: fdmprinter.def.json
msgctxt "roofing_pattern option lines"
@@ -4405,7 +4405,7 @@ msgstr "Direzioni linea rivestimento superficie superiore"
#: fdmprinter.def.json
msgctxt "roofing_angles description"
msgid "A list of integer line directions to use when the top surface skin layers use the lines or zig zag pattern. Elements from the list are used sequentially as the layers progress and when the end of the list is reached, it starts at the beginning again. The list items are separated by commas and the whole list is contained in square brackets. Default is an empty list which means use the traditional default angles (45 and 135 degrees)."
-msgstr "Un elenco di direzioni linee intere da usare quando gli strati rivestimento superficie superiore utilizzano le linee o la configurazione zig zag. Gli elementi dall’elenco sono utilizzati in sequenza con il progredire degli strati e, al raggiungimento della fine dell’elenco, la sequenza ricomincia dall’inizio. Le voci elencate sono separate da virgole e l’intero elenco è racchiuso tra parentesi quadre. L’elenco predefinito è vuoto, vale a dire che utilizza i valori angolari predefiniti (45 e 135 gradi)."
+msgstr "Un elenco di direzioni linee intere da usare quando i layers rivestimento superficie superiore utilizzano le linee o la configurazione zig zag. Gli elementi dall’elenco sono utilizzati in sequenza con il progredire dei layers e, al raggiungimento della fine dell’elenco, la sequenza ricomincia dall’inizio. Le voci elencate sono separate da virgole e l’intero elenco è racchiuso tra parentesi quadre. L’elenco predefinito è vuoto, vale a dire che utilizza i valori angolari predefiniti (45 e 135 gradi)."
#: fdmprinter.def.json
msgctxt "infill_enable_travel_optimization label"
@@ -4425,7 +4425,7 @@ msgstr "Temperatura automatica"
#: fdmprinter.def.json
msgctxt "material_flow_dependent_temperature description"
msgid "Change the temperature for each layer automatically with the average flow speed of that layer."
-msgstr "Modifica automaticamente la temperatura per ciascuno strato con la velocità media del flusso per tale strato."
+msgstr "Modifica automaticamente la temperatura per ciascun layer con la velocità media del flusso per tale strato."
#: fdmprinter.def.json
msgctxt "material_flow_temp_graph label"
@@ -4925,7 +4925,7 @@ msgstr "Ritardo tra due segmenti orizzontali WP"
#: fdmprinter.def.json
msgctxt "wireframe_flat_delay description"
msgid "Delay time between two horizontal segments. Introducing such a delay can cause better adhesion to previous layers at the connection points, while too long delays cause sagging. Only applies to Wire Printing."
-msgstr "Indica il tempo di ritardo tra due segmenti orizzontali. Introducendo un tale ritardo si può ottenere una migliore adesione agli strati precedenti in corrispondenza dei punti di collegamento, mentre ritardi troppo prolungati provocano cedimenti. Applicabile solo alla funzione Wire Printing."
+msgstr "Indica il tempo di ritardo tra due segmenti orizzontali. Introducendo un tale ritardo si può ottenere una migliore adesione ai layers precedenti in corrispondenza dei punti di collegamento, mentre ritardi troppo prolungati provocano cedimenti. Applicabile solo alla funzione Wire Printing."
#: fdmprinter.def.json
msgctxt "wireframe_up_half_speed label"
@@ -4947,7 +4947,7 @@ msgstr "Dimensione dei nodi WP"
#: fdmprinter.def.json
msgctxt "wireframe_top_jump description"
msgid "Creates a small knot at the top of an upward line, so that the consecutive horizontal layer has a better chance to connect to it. Only applies to Wire Printing."
-msgstr "Crea un piccolo nodo alla sommità di una linea verticale verso l'alto, in modo che lo strato orizzontale consecutivo abbia una migliore possibilità di collegarsi ad essa. Applicabile solo alla funzione Wire Printing."
+msgstr "Crea un piccolo nodo alla sommità di una linea verticale verso l'alto, in modo che il layer orizzontale consecutivo abbia una migliore possibilità di collegarsi ad essa. Applicabile solo alla funzione Wire Printing."
#: fdmprinter.def.json
msgctxt "wireframe_fall_down label"
@@ -4977,7 +4977,7 @@ msgstr "Strategia WP"
#: fdmprinter.def.json
msgctxt "wireframe_strategy description"
msgid "Strategy for making sure two consecutive layers connect at each connection point. Retraction lets the upward lines harden in the right position, but may cause filament grinding. A knot can be made at the end of an upward line to heighten the chance of connecting to it and to let the line cool; however, it may require slow printing speeds. Another strategy is to compensate for the sagging of the top of an upward line; however, the lines won't always fall down as predicted."
-msgstr "Strategia per garantire il collegamento di due strati consecutivi ad ogni punto di connessione. La retrazione consente l'indurimento delle linee verticali verso l'alto nella giusta posizione, ma può causare la deformazione del filamento. È possibile realizzare un nodo all'estremità di una linea verticale verso l'alto per accrescere la possibilità di collegamento e lasciarla raffreddare; tuttavia ciò può richiedere velocità di stampa ridotte. Un'altra strategia consiste nel compensare il cedimento della parte superiore di una linea verticale verso l'alto; tuttavia le linee non sempre ricadono come previsto."
+msgstr "Strategia per garantire il collegamento di due layers consecutivi ad ogni punto di connessione. La retrazione consente l'indurimento delle linee verticali verso l'alto nella giusta posizione, ma può causare la deformazione del filamento. È possibile realizzare un nodo all'estremità di una linea verticale verso l'alto per accrescere la possibilità di collegamento e lasciarla raffreddare; tuttavia ciò può richiedere velocità di stampa ridotte. Un'altra strategia consiste nel compensare il cedimento della parte superiore di una linea verticale verso l'alto; tuttavia le linee non sempre ricadono come previsto."
#: fdmprinter.def.json
msgctxt "wireframe_strategy option compensate"
@@ -5047,42 +5047,42 @@ msgstr "Indica la distanza tra l'ugello e le linee diagonali verso il basso. Un
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_enabled label"
msgid "Use adaptive layers"
-msgstr "Uso di strati adattivi"
+msgstr "Uso di layers adattivi"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_enabled description"
msgid "Adaptive layers computes the layer heights depending on the shape of the model."
-msgstr "Gli strati adattivi calcolano l’altezza degli strati in base alla forma del modello."
+msgstr "I layers adattivi calcolano l’altezza dei layers in base alla forma del modello."
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation label"
msgid "Adaptive layers maximum variation"
-msgstr "Variazione massima strati adattivi"
+msgstr "Variazione massima layers adattivi"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation description"
msgid "The maximum allowed height different from the base layer height in mm."
-msgstr "La differenza di altezza massima rispetto all’altezza dello strato di base in mm."
+msgstr "La differenza di altezza massima rispetto all’altezza del layer di base in mm."
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation_step label"
msgid "Adaptive layers variation step size"
-msgstr "Dimensione variazione strati adattivi"
+msgstr "Dimensione variazione layers adattivi"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation_step description"
msgid "The difference in height of the next layer height compared to the previous one."
-msgstr "La differenza in altezza dello strato successivo rispetto al precedente."
+msgstr "La differenza in altezza del layer successivo rispetto al precedente."
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold label"
msgid "Adaptive layers threshold"
-msgstr "Soglia strati adattivi"
+msgstr "Soglia layers adattivi"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold description"
msgid "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer."
-msgstr "Soglia per l’utilizzo o meno di uno strato di dimensioni minori. Questo numero è confrontato al valore dell’inclinazione più ripida di uno strato."
+msgstr "Soglia per l’utilizzo o meno di un layer di dimensioni minori. Questo numero è confrontato al valore dell’inclinazione più ripida di un layer."
#: fdmprinter.def.json
msgctxt "command_line_settings label"
@@ -5092,7 +5092,7 @@ msgstr "Impostazioni riga di comando"
#: fdmprinter.def.json
msgctxt "command_line_settings description"
msgid "Settings which are only used if CuraEngine isn't called from the Cura frontend."
-msgstr "Impostazioni utilizzate solo se CuraEngine non è chiamato dalla parte anteriore di Cura."
+msgstr "Impostazioni utilizzate solo se CuraEngine non è chiamato dal frontend di Cura."
#: fdmprinter.def.json
msgctxt "center_object label"
@@ -5170,7 +5170,7 @@ msgstr "Matrice di rotazione da applicare al modello quando caricato dal file."
#~ msgctxt "infill_pattern description"
#~ msgid "The pattern of the infill material of the print. The line and zig zag infill swap direction on alternate layers, reducing material cost. The grid, triangle, cubic, octet, quarter cubic and concentric patterns are fully printed every layer. Cubic, quarter cubic and octet infill change with every layer to provide a more equal distribution of strength over each direction."
-#~ msgstr "Configurazione del materiale di riempimento della stampa. Il riempimento a linea e zig zag su strati alternati riduce il costo del materiale. Le configurazioni a griglia, triangolo, a cubo, ottagonale, a quarto di cubo e concentrica comportano la stampa completa in ogni strato. Il riempimento a cubi, a quarto di cubo e a ottagonale cambia a ogni strato per consentire una distribuzione più uniforme della resistenza in ogni direzione."
+#~ msgstr "Configurazione del materiale di riempimento della stampa. Il riempimento a linea e zig zag su layers alternati riduce il costo del materiale. Le configurazioni a griglia, triangolo, a cubo, ottagonale, a quarto di cubo e concentrica comportano la stampa completa in ogni layer. Il riempimento a cubi, a quarto di cubo e a ottagonale cambia a ogni layer per consentire una distribuzione più uniforme della resistenza in ogni direzione."
#~ msgctxt "zig_zaggify_infill description"
#~ msgid "Connect the ends where the infill pattern meets the inner wall using a lines which follows the shape of the inner wall. Enabling this setting can make the infill adhere to the walls better and reduces the effects on infill on the quality of vertical surfaces. Disabling this setting reduces the amount of material used."
@@ -5186,19 +5186,19 @@ msgstr "Matrice di rotazione da applicare al modello quando caricato dal file."
#~ msgctxt "z_offset_layer_0 label"
#~ msgid "Initial Layer Z Offset"
-#~ msgstr "Scostamento Z strato iniziale"
+#~ msgstr "Scostamento Z layer iniziale"
#~ msgctxt "z_offset_layer_0 description"
#~ msgid "The extruder is offset from the normal height of the first layer by this amount. It can be positive (raised) or negative (lowered). Some filament types adhere to the build plate better if the extruder is raised slightly."
-#~ msgstr "L'estrusore viene posizionato ad una distanza dall'altezza normale del primo strato pari al valore indicato. Questo scostamento può essere positivo (più in alto) o negativo (più in basso). Alcuni tipi di filamento aderiscono meglio al piano di stampa se l'estrusore viene leggermente sollevato."
+#~ msgstr "L'estrusore viene posizionato ad una distanza dall'altezza normale del primo layer pari al valore indicato. Questo scostamento può essere positivo (più in alto) o negativo (più in basso). Alcuni tipi di filamento aderiscono meglio al piano di stampa se l'estrusore viene leggermente sollevato."
#~ msgctxt "z_offset_taper_layers label"
#~ msgid "Z Offset Taper Layers"
-#~ msgstr "Scostamento Z strati di rastremazione"
+#~ msgstr "Scostamento Z layers di rastremazione"
#~ msgctxt "z_offset_taper_layers description"
#~ msgid "When non-zero, the Z offset is reduced to 0 over that many layers. A value of 0 means that the Z offset remains constant for all the layers in the print."
-#~ msgstr "Se diverso da zero, lo scostamento Z viene ridotto a 0 entro il numero di strati indicato. Un valore di 0 indica che lo scostamento Z rimane costante per tutti gli strati di stampa."
+#~ msgstr "Se diverso da zero, lo scostamento Z viene ridotto a 0 entro il numero di layers indicato. Un valore di 0 indica che lo scostamento Z rimane costante per tutti i layers di stampa."
#~ msgctxt "raft_smoothing description"
#~ msgid "This setting control how much inner corners in the raft outline are rounded. Inward corners are rounded to a semi circle with a radius equal to the value given here. This setting also removes holes in the raft outline which are smaller than such a circle."
@@ -5206,7 +5206,7 @@ msgstr "Matrice di rotazione da applicare al modello quando caricato dal file."
#~ msgctxt "infill_pattern description"
#~ msgid "The pattern of the infill material of the print. The line and zig zag infill swap direction on alternate layers, reducing material cost. The grid, triangle, cubic, tetrahedral and concentric patterns are fully printed every layer. Cubic and tetrahedral infill change with every layer to provide a more equal distribution of strength over each direction."
-#~ msgstr "Indica la configurazione del materiale di riempimento della stampa. Il riempimento a linea e a zig zag cambia direzione su strati alternati, riducendo il costo del materiale. Le configurazioni a griglia, triangolo, cubo, tetraedriche e concentriche sono stampate completamente su ogni strato. Il riempimento delle configurazioni cubiche e tetraedriche cambia ad ogni strato per fornire una distribuzione più uniforme della forza su ciascuna direzione."
+#~ msgstr "Indica la configurazione del materiale di riempimento della stampa. Il riempimento a linea e a zig zag cambia direzione su layers alternati, riducendo il costo del materiale. Le configurazioni a griglia, triangolo, cubo, tetraedriche e concentriche sono stampate completamente su ogni layers. Il riempimento delle configurazioni cubiche e tetraedriche cambia ad ogni strato per fornire una distribuzione più uniforme della forza su ciascuna direzione."
#~ msgctxt "infill_pattern option tetrahedral"
#~ msgid "Tetrahedral"
@@ -5214,27 +5214,27 @@ msgstr "Matrice di rotazione da applicare al modello quando caricato dal file."
#~ msgctxt "expand_skins_into_infill label"
#~ msgid "Expand Skins Into Infill"
-#~ msgstr "Prolunga rivestimenti esterni nel riempimento"
+#~ msgstr "Estende rivestimenti esterni nel riempimento"
#~ msgctxt "expand_skins_into_infill description"
#~ msgid "Expand skin areas of top and/or bottom skin of flat surfaces. By default, skins stop under the wall lines that surround infill but this can lead to holes appearing when the infill density is low. This setting extends the skins beyond the wall lines so that the infill on the next layer rests on skin."
-#~ msgstr "Prolunga le aree di rivestimento esterno superiori e/o inferiori delle superfici piatte. Per default, i rivestimenti esterni si interrompono sotto le linee delle pareti circostanti il riempimento, ma questo può generare la comparsa di fori quando la densità del riempimento è bassa. Questa impostazione prolunga i rivestimenti esterni oltre le linee delle pareti in modo che il riempimento sullo strato successivo appoggi sul rivestimento esterno."
+#~ msgstr "Estende le aree di rivestimento esterno superiori e/o inferiori delle superfici piatte. Per default, i rivestimenti esterni si interrompono sotto le linee delle pareti circostanti il riempimento, ma questo può generare la comparsa di fori quando la densità del riempimento è bassa. Questa impostazione prolunga i rivestimenti esterni oltre le linee delle pareti in modo che il riempimento sullo strato successivo appoggi sul rivestimento esterno."
#~ msgctxt "expand_upper_skins label"
#~ msgid "Expand Top Skins Into Infill"
-#~ msgstr "Prolunga rivestimenti esterni superiori nel riempimento"
+#~ msgstr "Estendi rivestimenti esterni superiori nel riempimento"
#~ msgctxt "expand_upper_skins description"
#~ msgid "Expand the top skin areas (areas with air above) so that they support infill above."
-#~ msgstr "Prolunga le aree di rivestimento esterno superiori (aree con aria al di sopra) in modo che supportino il riempimento sovrastante."
+#~ msgstr "Estendi le aree di rivestimento esterno superiori (aree con aria al di sopra) in modo che supportino il riempimento sovrastante."
#~ msgctxt "expand_lower_skins label"
#~ msgid "Expand Bottom Skins Into Infill"
-#~ msgstr "Prolunga rivestimenti esterni inferiori nel riempimento"
+#~ msgstr "Estendi rivestimenti esterni inferiori nel riempimento"
#~ msgctxt "expand_lower_skins description"
#~ msgid "Expand the bottom skin areas (areas with air below) so that they are anchored by the infill layers above and below."
-#~ msgstr "Prolunga aree rivestimento esterno inferiori (aree con aria al di sotto) in modo che siano ancorate dagli strati di riempimento sovrastanti e sottostanti."
+#~ msgstr "Estendi aree rivestimento esterno inferiori (aree con aria al di sotto) in modo che siano ancorate dai layers di riempimento sovrastanti e sottostanti."
#~ msgctxt "expand_skins_expand_distance description"
#~ msgid "The distance the skins are expanded into the infill. The default distance is enough to bridge the gap between the infill lines and will stop holes appearing in the skin where it meets the wall when the infill density is low. A smaller distance will often be sufficient."
@@ -5330,19 +5330,19 @@ msgstr "Matrice di rotazione da applicare al modello quando caricato dal file."
#~ msgctxt "expand_upper_skins label"
#~ msgid "Expand Upper Skins"
-#~ msgstr "Prolunga rivestimenti esterni superiori"
+#~ msgstr "Estendi rivestimenti esterni superiori"
#~ msgctxt "expand_upper_skins description"
#~ msgid "Expand upper skin areas (areas with air above) so that they support infill above."
-#~ msgstr "Prolunga le aree di rivestimento esterno superiori (aree con aria al di sopra) in modo che supportino il riempimento sovrastante."
+#~ msgstr "Estendi le aree di rivestimento esterno superiori (aree con aria al di sopra) in modo che supportino il riempimento sovrastante."
#~ msgctxt "expand_lower_skins label"
#~ msgid "Expand Lower Skins"
-#~ msgstr "Prolunga rivestimenti esterni inferiori"
+#~ msgstr "Estendi rivestimenti esterni inferiori"
#~ msgctxt "expand_lower_skins description"
#~ msgid "Expand lower skin areas (areas with air below) so that they are anchored by the infill layers above and below."
-#~ msgstr "Prolunga aree rivestimento esterno inferiori (aree con aria al di sotto) in modo che siano ancorate dagli strati di riempimento sovrastanti e sottostanti."
+#~ msgstr "Estendi aree rivestimento esterno inferiori (aree con aria al di sotto) in modo che siano ancorate dagli strati di riempimento sovrastanti e sottostanti."
#~ msgctxt "speed_support_interface description"
#~ msgid "The speed at which the roofs and bottoms of support are printed. Printing the them at lower speeds can improve overhang quality."
@@ -5366,7 +5366,7 @@ msgstr "Matrice di rotazione da applicare al modello quando caricato dal file."
#~ msgctxt "support_interface_extruder_nr description"
#~ msgid "The extruder train to use for printing the roofs and bottoms of the support. This is used in multi-extrusion."
-#~ msgstr "Il treno estrusore utilizzato per la stampa delle parti superiori e inferiori del supporto. Utilizzato nell’estrusione multipla."
+#~ msgstr "Il blocco estrusore utilizzato per la stampa delle parti superiori e inferiori del supporto. Utilizzato nell’estrusione multipla."
#~ msgctxt "support_bottom_stair_step_height description"
#~ msgid "The height of the steps of the stair-like bottom of support resting on the model. A low value makes the support harder to remove, but too high values can lead to unstable support structures."
@@ -5374,11 +5374,11 @@ msgstr "Matrice di rotazione da applicare al modello quando caricato dal file."
#~ msgctxt "support_bottom_height label"
#~ msgid "Support Bottom Thickness"
-#~ msgstr "Spessore degli strati inferiori del supporto"
+#~ msgstr "Spessore dei layers inferiori del supporto"
#~ msgctxt "support_bottom_height description"
#~ msgid "The thickness of the support bottoms. This controls the number of dense layers are printed on top of places of a model on which support rests."
-#~ msgstr "Indica lo spessore degli strati inferiori del supporto. Questo controlla il numero di strati fitti stampati sulla sommità dei punti di un modello su cui appoggia un supporto."
+#~ msgstr "Indica lo spessore dei layers inferiori del supporto. Questo controlla il numero di slayers fitti stampati sulla sommità dei punti di un modello su cui appoggia un supporto."
#~ msgctxt "support_interface_skip_height description"
#~ msgid "When checking where there's model above the support, take steps of the given height. Lower values will slice slower, while higher values may cause normal support to be printed in some places where there should have been support interface."
diff --git a/resources/i18n/ja_JP/cura.po b/resources/i18n/ja_JP/cura.po
index 1900ec980f..11e6f08883 100644
--- a/resources/i18n/ja_JP/cura.po
+++ b/resources/i18n/ja_JP/cura.po
@@ -8,15 +8,15 @@ msgstr ""
"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
"POT-Creation-Date: 2018-01-29 09:48+0000\n"
-"PO-Revision-Date: 2018-02-05 13:25+0100\n"
-"Last-Translator: Bothof \n"
+"PO-Revision-Date: 2018-02-10 04:58+0900\n"
+"Last-Translator: Brule \n"
"Language-Team: Japanese\n"
"Language: ja_JP\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Poedit 1.8.7.1\n"
+"X-Generator: Poedit 2.0.4\n"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:26
msgctxt "@action"
@@ -634,7 +634,10 @@ msgid ""
"Found no models inside your drawing. Could you please check it's content again and make sure one part or assembly is inside?\n"
"\n"
" Thanks!."
-msgstr "図面の中にモデルが見つかりません。中身を確認し、パートかアセンブリーが中に入っていることを確認してください。\n\n 再確認をお願いします。"
+msgstr ""
+"図面の中にモデルが見つかりません。中身を確認し、パートかアセンブリーが中に入っていることを確認してください。\n"
+"\n"
+" 再確認をお願いします。"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksReader.py:595
msgctxt "@info:status"
@@ -642,7 +645,10 @@ msgid ""
"Found more then one part or assembly inside your drawing. We currently only support drawings with exactly one part or assembly inside.\n"
"\n"
"Sorry!"
-msgstr "図面の中にパートかアセンブリーが2個以上見つかりました。今のところ、本製品はパートかアセンブリーが1個の図面のみに対応しています。\n\n申し訳ありません。"
+msgstr ""
+"図面の中にパートかアセンブリーが2個以上見つかりました。今のところ、本製品はパートかアセンブリーが1個の図面のみに対応しています。\n"
+"\n"
+"申し訳ありません。"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:25
msgctxt "@item:inlistbox"
@@ -667,7 +673,12 @@ msgid ""
"\n"
"With kind regards\n"
" - Thomas Karl Pietrowski"
-msgstr "お客様へ\nシステム上に正規のソリッドワークスがインストールされていません。つまり、ソリッドワークスがインストールされていないか、有効なライセンスが存在しません。ソリッドワークスだけを問題なく使用できるようになっているか確認するか、自社のIT部門にご相談ください。\n\nお願いいたします。\n - Thomas Karl Pietrowski"
+msgstr ""
+"お客様へ\n"
+"システム上に正規のソリッドワークスがインストールされていません。つまり、ソリッドワークスがインストールされていないか、有効なライセンスが存在しません。ソリッドワークスだけを問題なく使用できるようになっているか確認するか、自社のIT部門にご相談ください。\n"
+"\n"
+"お願いいたします。\n"
+" - Thomas Karl Pietrowski"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:57
msgctxt "@info:status"
@@ -677,7 +688,12 @@ msgid ""
"\n"
"With kind regards\n"
" - Thomas Karl Pietrowski"
-msgstr "お客様へ\nこのプラグインは現在Windows以外のOSで実行されています。このプラグインは、ソリッドワークスがインストールされたWindowsでしか動作しません。有効なライセンスも必要です。ソリッドワークスがインストールされたWindowsマシンにこのプラグインをインストールしてください。\n\nお願いいたします。\n - Thomas Karl Pietrowski"
+msgstr ""
+"お客様へ\n"
+"このプラグインは現在Windows以外のOSで実行されています。このプラグインは、ソリッドワークスがインストールされたWindowsでしか動作しません。有効なライセンスも必要です。ソリッドワークスがインストールされたWindowsマシンにこのプラグインをインストールしてください。\n"
+"\n"
+"お願いいたします。\n"
+" - Thomas Karl Pietrowski"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksDialogHandler.py:70
msgid "Configure"
@@ -751,7 +767,9 @@ msgctxt "@info:status"
msgid ""
"Could not export using \"{}\" quality!\n"
"Felt back to \"{}\"."
-msgstr "\"{}\"品質を使用したエクスポートができませんでした!\n\"{}\"になりました。"
+msgstr ""
+"\"{}\"品質を使用したエクスポートができませんでした!\n"
+"\"{}\"になりました。"
#: /home/ruben/Projects/Cura/plugins/GCodeProfileReader/__init__.py:14
#: /home/ruben/Projects/Cura/plugins/GCodeReader/__init__.py:14
@@ -1246,7 +1264,10 @@ msgid ""
"A fatal error has occurred. Please send us this Crash Report to fix the problem
\n"
" Please use the \"Send report\" button to post a bug report automatically to our servers
\n"
" "
-msgstr "致命的なエラーが発生しました。問題解決のためこのクラッシュレポートを送信してください
\n 「レポート送信」ボタンを使用してバグレポートが自動的に当社サーバーに送られるようにしてください
\n "
+msgstr ""
+"致命的なエラーが発生しました。問題解決のためこのクラッシュレポートを送信してください
\n"
+" 「レポート送信」ボタンを使用してバグレポートが自動的に当社サーバーに送られるようにしてください
\n"
+" "
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:102
msgctxt "@title:groupbox"
@@ -1932,7 +1953,9 @@ msgctxt "@action:button"
msgid ""
"Open the directory\n"
"with macro and icon"
-msgstr "ディレクトリーを開きます\n(マクロとアイコンで)"
+msgstr ""
+"ディレクトリーを開きます\n"
+"(マクロとアイコンで)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:160
msgctxt "@description:label"
@@ -2426,7 +2449,10 @@ msgid ""
"This plugin contains a license.\n"
"You need to accept this license to install this plugin.\n"
"Do you agree with the terms below?"
-msgstr "このプラグインにはライセンスが含まれています。\nこのプラグインをインストールするにはこのライセンスに同意する必要があります。\n下の利用規約に同意しますか?"
+msgstr ""
+"このプラグインにはライセンスが含まれています。\n"
+"このプラグインをインストールするにはこのライセンスに同意する必要があります。\n"
+"下の利用規約に同意しますか?"
#: /home/ruben/Projects/Cura/plugins/PluginBrowser/PluginBrowser.qml:242
msgctxt "@action:button"
@@ -2555,10 +2581,9 @@ msgid "Not connected"
msgstr "プリンターにつながっていません。"
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:99
-#, fuzzy
msgctxt "@label"
msgid "Min endstop X: "
-msgstr "エンドストップ X:"
+msgstr "最小エンドストップ X:"
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:109
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:130
@@ -2577,16 +2602,14 @@ msgid "Not checked"
msgstr "チェックされていません。"
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:120
-#, fuzzy
msgctxt "@label"
msgid "Min endstop Y: "
-msgstr "エンドストップ Y:"
+msgstr "最小エンドストップ Y:"
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:141
-#, fuzzy
msgctxt "@label"
msgid "Min endstop Z: "
-msgstr "エンドストップ Z:"
+msgstr "最小エンドストップ Z:"
#: /home/ruben/Projects/Cura/plugins/UltimakerMachineActions/UMOCheckupMachineAction.qml:163
msgctxt "@label"
@@ -3470,7 +3493,9 @@ msgid ""
"Some setting/override values are different from the values stored in the profile.\n"
"\n"
"Click to open the profile manager."
-msgstr "いくらかの設定プロファイルにある値とことなる場合無効にします。\nプロファイルマネージャーをクリックして開いてください。"
+msgstr ""
+"いくらかの設定プロファイルにある値とことなる場合無効にします。\n"
+"プロファイルマネージャーをクリックして開いてください。"
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingView.qml:150
msgctxt "@label:textbox"
@@ -3508,7 +3533,9 @@ msgid ""
"Some hidden settings use values different from their normal calculated value.\n"
"\n"
"Click to make these settings visible."
-msgstr "いくらかの非表示設定は通常の計算された値と異なる値を使用します。\n表示されるようにクリックしてください。"
+msgstr ""
+"いくらかの非表示設定は通常の計算された値と異なる値を使用します。\n"
+"表示されるようにクリックしてください。"
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:61
msgctxt "@label Header for list of settings."
@@ -3536,7 +3563,9 @@ msgid ""
"This setting has a value that is different from the profile.\n"
"\n"
"Click to restore the value of the profile."
-msgstr "この設定にプロファイルと異なった値があります。\nプロファイルの値を戻すためにクリックしてください。"
+msgstr ""
+"この設定にプロファイルと異なった値があります。\n"
+"プロファイルの値を戻すためにクリックしてください。"
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:288
msgctxt "@label"
@@ -3544,7 +3573,9 @@ msgid ""
"This setting is normally calculated, but it currently has an absolute value set.\n"
"\n"
"Click to restore the calculated value."
-msgstr "このセッティングは通常計算されます、今は絶対値に固定されています。\n計算された値に変更するためにクリックを押してください。"
+msgstr ""
+"このセッティングは通常計算されます、今は絶対値に固定されています。\n"
+"計算された値に変更するためにクリックを押してください。"
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:128
msgctxt "@label:listbox"
@@ -3556,7 +3587,9 @@ msgctxt "@label:listbox"
msgid ""
"Print Setup disabled\n"
"G-code files cannot be modified"
-msgstr "プリントセットアップが無効\nG-codeファイルを修正することができません。"
+msgstr ""
+"プリントセットアップが無効\n"
+"G-codeファイルを修正することができません。"
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:342
msgctxt "@label Hours and minutes"
diff --git a/resources/i18n/ja_JP/fdmprinter.def.json.po b/resources/i18n/ja_JP/fdmprinter.def.json.po
index ca796d5a56..25c3b58fe3 100644
--- a/resources/i18n/ja_JP/fdmprinter.def.json.po
+++ b/resources/i18n/ja_JP/fdmprinter.def.json.po
@@ -1,14 +1,14 @@
-# Cura JSON setting files
-# Copyright (C) 2017 Ultimaker
+# Cura
+# Copyright (C) 2018 Ultimaker
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2017.
+# Ruben Dulek , 2018.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.0\n"
+"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2017-08-02 16:53+0000\n"
-"PO-Revision-Date: 2017-11-30 13:05+0100\n"
+"POT-Creation-Date: 2018-01-29 09:48+0000\n"
+"PO-Revision-Date: 2018-02-10 05:04+0900\n"
"Last-Translator: Brule\n"
"Language-Team: Brule\n"
"Language: ja_JP\n"
@@ -62,7 +62,9 @@ msgctxt "machine_start_gcode description"
msgid ""
"Gcode commands to be executed at the very start - separated by \n"
"."
-msgstr "Gcodeのコマンドは −で始まり\nで区切られます。"
+msgstr ""
+"Gcodeのコマンドは −で始まり\n"
+"で区切られます。"
#: fdmprinter.def.json
msgctxt "machine_end_gcode label"
@@ -75,7 +77,9 @@ msgctxt "machine_end_gcode description"
msgid ""
"Gcode commands to be executed at the very end - separated by \n"
"."
-msgstr "Gcodeのコマンドは −で始まり\nで区切られます。"
+msgstr ""
+"Gcodeのコマンドは −で始まり\n"
+"で区切られます。"
#: fdmprinter.def.json
msgctxt "material_guid label"
@@ -1175,7 +1179,9 @@ msgstr "ZシームX"
#: fdmprinter.def.json
msgctxt "z_seam_x description"
msgid "The X coordinate of the position near where to start printing each part in a layer."
-msgstr "レイヤー内の各印刷を開始するX座\n標の位置。"
+msgstr ""
+"レイヤー内の各印刷を開始するX座\n"
+"標の位置。"
#: fdmprinter.def.json
msgctxt "z_seam_y label"
@@ -1630,7 +1636,9 @@ msgstr "インフィル優先"
#: fdmprinter.def.json
msgctxt "infill_before_walls description"
msgid "Print the infill before printing the walls. Printing the walls first may lead to more accurate walls, but overhangs print worse. Printing the infill first leads to sturdier walls, but the infill pattern might sometimes show through the surface."
-msgstr "壁より前にインフィルをプリントします はじめに壁をプリントするとより精密な壁になりますが、オーバーハングのプリントは悪化します\nはじめにインフィルをプリントすると丈夫な壁になりますが、インフィルの模様が時折表面から透けて表れます"
+msgstr ""
+"壁より前にインフィルをプリントします はじめに壁をプリントするとより精密な壁になりますが、オーバーハングのプリントは悪化します\n"
+"はじめにインフィルをプリントすると丈夫な壁になりますが、インフィルの模様が時折表面から透けて表れます"
#: fdmprinter.def.json
msgctxt "min_infill_area label"
@@ -3544,7 +3552,7 @@ msgstr "密着性"
#: fdmprinter.def.json
msgctxt "prime_blob_enable label"
msgid "Enable Prime Blob"
-msgstr "プライムボルブを有効にする"
+msgstr "プライムブロブを有効にする"
# msgstr "プライムブロブを有効にする"
#: fdmprinter.def.json
@@ -3636,7 +3644,9 @@ msgctxt "skirt_gap description"
msgid ""
"The horizontal distance between the skirt and the first layer of the print.\n"
"This is the minimum distance. Multiple skirt lines will extend outwards from this distance."
-msgstr "スカートと印刷の最初の層の間の水平距離。\nこれは最小距離です。複数のスカートラインがこの距離から外側に展開されます。"
+msgstr ""
+"スカートと印刷の最初の層の間の水平距離。\n"
+"これは最小距離です。複数のスカートラインがこの距離から外側に展開されます。"
#: fdmprinter.def.json
msgctxt "skirt_brim_minimal_length label"
diff --git a/resources/i18n/pl_PL/cura.po b/resources/i18n/pl_PL/cura.po
index 7cf338b1e7..c612eefc13 100644
--- a/resources/i18n/pl_PL/cura.po
+++ b/resources/i18n/pl_PL/cura.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: Cura 3.0\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
"POT-Creation-Date: 2017-08-02 16:53+0000\n"
-"PO-Revision-Date: 2017-11-22 16:19+0100\n"
+"PO-Revision-Date: 2018-02-10 14:24+0100\n"
"Last-Translator: 'Jaguś' Paweł Jagusiak and Andrzej 'anraf1001' Rafalski\n"
"Language-Team: reprapy.pl\n"
"Language: pl_PL\n"
@@ -16,7 +16,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Poedit 2.0.4\n"
+"X-Generator: Poedit 2.0.6\n"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:26
msgctxt "@action"
@@ -189,7 +189,7 @@ msgstr "Oprogramowanie Drukarki"
#: /home/ruben/Projects/Cura/plugins/PrepareStage/__init__.py:12
msgctxt "@item:inmenu"
msgid "Prepare"
-msgstr ""
+msgstr "Przygotuj"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:23
msgctxt "@action:button Preceded by 'Ready to'."
@@ -562,7 +562,7 @@ msgstr "Otwiera interfejs zadań druku w przeglądarce."
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:239
msgctxt "@label Printer name"
msgid "Unknown"
-msgstr ""
+msgstr "Nieznana"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py:505
#, python-brace-format
@@ -597,7 +597,7 @@ msgstr "Połącz przez sieć"
#: /home/ruben/Projects/Cura/plugins/MonitorStage/__init__.py:12
msgctxt "@item:inmenu"
msgid "Monitor"
-msgstr ""
+msgstr "Monitor"
#: /home/ruben/Projects/Cura/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py:66
#, python-brace-format
@@ -624,7 +624,7 @@ msgstr "Nie można uzyskać dostępu do informacji o aktualizacji"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksReader.py:579
msgctxt "@info:status"
msgid "SolidWorks reported errors, while opening your file. We recommend to solve these issues inside SolidWorks itself."
-msgstr ""
+msgstr "SolidWorks zgłosił błędy podczas otwierania twojego pliku. Zalecamy rozwiązanie tego problemu w samym SolidWorksie."
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksReader.py:591
msgctxt "@info:status"
@@ -633,6 +633,9 @@ msgid ""
"\n"
" Thanks!."
msgstr ""
+"Nie znaleziono modeli wewnątrz twojego rysunku. Czy mógłbyś sprawdzić jego zawartość ponownie i upewnić się, że znajduje się tam jedna część lub złożenie?\n"
+"\n"
+"Dziękuję!."
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksReader.py:595
msgctxt "@info:status"
@@ -641,6 +644,9 @@ msgid ""
"\n"
"Sorry!"
msgstr ""
+"Znaleziono więcej niż jedną część lub złożenie wewnątrz rysunku. Obecnie obsługujemy tylko rysunki z dokładnie jedną częścią lub złożeniem.\n"
+"\n"
+"Przepraszamy!"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:25
msgctxt "@item:inlistbox"
@@ -655,7 +661,7 @@ msgstr "Plik złożenia SolidWorks"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:33
msgctxt "@item:inlistbox"
msgid "SolidWorks drawing file"
-msgstr ""
+msgstr "Plik rysunku SolidWorks"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:48
msgctxt "@info:status"
@@ -666,6 +672,11 @@ msgid ""
"With kind regards\n"
" - Thomas Karl Pietrowski"
msgstr ""
+"Szanowny kliencie,\n"
+"Nie mogliśmy znaleźć poprawnej instalacji SolidWorks w twoim systemie. To oznacza, że albo nie masz zainstalowanego SolidWorks, albo nie masz ważnej licencji. Proszę upewnić się, że uruchomiony SolidWorks działa bez żadnych problemów i/lub skontaktuj się z ICT.\n"
+"\n"
+"Z wyrazami szacunku,\n"
+" - Thomas Karl Pietrowski"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:57
msgctxt "@info:status"
@@ -676,6 +687,10 @@ msgid ""
"With kind regards\n"
" - Thomas Karl Pietrowski"
msgstr ""
+"Szanowny kliencie,\n"
+"Używasz aktualnie tego pluginu na innym systemie niż Windows. Ten plugin działa tylko w Windows razem z zainstalowanym SolidWorks, włączając w to poprawną licencję. Proszę zainstalować ten plugin na maszynie z systemem Windows z zainstalowanym SolidWorks.\n"
+"Z wyrazami szacunku,\n"
+" - Thomas Karl Pietrowski"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksDialogHandler.py:70
msgid "Configure"
@@ -683,7 +698,7 @@ msgstr "Konfiguruj"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksDialogHandler.py:71
msgid "Installation guide for SolidWorks macro"
-msgstr ""
+msgstr "Instalacja poradnika dla skrótów SolidWorks"
#: /home/ruben/Projects/Cura/plugins/SimulationView/__init__.py:14
msgctxt "@item:inlistbox"
@@ -707,7 +722,7 @@ msgstr "Modyfikuj G-Code"
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:43
msgctxt "@info"
msgid "Cura collects anonymized usage statistics."
-msgstr ""
+msgstr "Cura zbiera anonimowe dane statystyczne."
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:46
msgctxt "@info:title"
@@ -717,22 +732,22 @@ msgstr "Zbieranie Danych"
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:48
msgctxt "@action:button"
msgid "Allow"
-msgstr ""
+msgstr "Zezwól"
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:49
msgctxt "@action:tooltip"
msgid "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing."
-msgstr ""
+msgstr "Zezwól Cura na wysyłanie anonimowych danych statystycznych, aby pomóc w wyborze przyszłych usprawnień Cura. Część twoich ustawień i preferencji jest wysyłana, a także wersja Cury i kod modelu który tniesz."
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:50
msgctxt "@action:button"
msgid "Disable"
-msgstr ""
+msgstr "Wyłącz"
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:51
msgctxt "@action:tooltip"
msgid "Don't allow Cura to send anonymized usage statistics. You can enable it again in the preferences."
-msgstr ""
+msgstr "Nie zezwalaj Cura na wysyłanie anonimowych danych statystycznych. Możesz to włączyć ponownie w preferencjach."
#: /home/ruben/Projects/Cura/plugins/LegacyProfileReader/__init__.py:14
msgctxt "@item:inlistbox"
@@ -742,7 +757,7 @@ msgstr "Profile Cura 15.04 "
#: /home/ruben/Projects/Cura/plugins/CuraBlenderPlugin/__init__.py:15
msgctxt "@item:inlistbox"
msgid "Blender file"
-msgstr ""
+msgstr "Plik Blender"
#: /home/ruben/Projects/Cura/plugins/CuraBlenderPlugin/CadIntegrationUtils/CommonReader.py:199
msgctxt "@info:status"
@@ -750,6 +765,8 @@ msgid ""
"Could not export using \"{}\" quality!\n"
"Felt back to \"{}\"."
msgstr ""
+"Nie można wyeksportować używając \"{}\" jakości!\n"
+"Powrócono do \"{}\"."
#: /home/ruben/Projects/Cura/plugins/GCodeProfileReader/__init__.py:14
#: /home/ruben/Projects/Cura/plugins/GCodeReader/__init__.py:14
@@ -936,12 +953,12 @@ msgstr "Profile Cura"
#: /home/ruben/Projects/Cura/plugins/CuraPrintProfileCreator/__init__.py:12
msgctxt "@item:inmenu"
msgid "Profile Assistant"
-msgstr ""
+msgstr "Asystent Profilu"
#: /home/ruben/Projects/Cura/plugins/CuraPrintProfileCreator/__init__.py:17
msgctxt "@item:inlistbox"
msgid "Profile Assistant"
-msgstr ""
+msgstr "Asystent Profilu"
#: /home/ruben/Projects/Cura/plugins/3MFWriter/__init__.py:30
msgctxt "@item:inlistbox"
@@ -1139,13 +1156,13 @@ msgstr "Nie udało się zaimportować profilu z {0}: or !"
msgid "This profile {0} contains incorrect data, could not import it."
-msgstr ""
+msgstr "Ten profil {0} zawiera błędne dane, nie można go zaimportować."
#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:240
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags or !"
msgid "The machine defined in profile {0} doesn't match with your current machine, could not import it."
-msgstr ""
+msgstr "Maszyna zdefiniowana w profilu {0} nie zgadza się z obecnie wybraną maszyną, nie można zaimportować."
#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:274
#, python-brace-format
@@ -1157,7 +1174,7 @@ msgstr "Profil zaimportowany {0}"
#, python-brace-format
msgctxt "@info:status"
msgid "File {0} does not contain any valid profile."
-msgstr ""
+msgstr "Plik {0} nie zawiera żadnego poprawnego profilu."
#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:280
#, python-brace-format
@@ -1185,7 +1202,7 @@ msgstr "Nie można znaleźć typu jakości {0} dla bieżącej konfiguracji."
#, python-brace-format
msgctxt "@label"
msgid "Group #{group_nr}"
-msgstr ""
+msgstr "Grupa #{group_nr}"
#: /home/ruben/Projects/Cura/cura/BuildVolume.py:100
msgctxt "@info:status"
@@ -1236,7 +1253,7 @@ msgstr "Nie można Znaleźć Lokalizacji"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:81
msgctxt "@title:window"
msgid "Crash Report"
-msgstr "Raport awarii"
+msgstr "Raport Błędu"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:94
msgctxt "@label crash message"
@@ -1245,6 +1262,9 @@ msgid ""
" Please use the \"Send report\" button to post a bug report automatically to our servers
\n"
" "
msgstr ""
+"Wystąpił błąd krytyczny. Proszę wysłać do nas ten Raport Błędu, aby rozwiązać ten problem
\n"
+" Proszę użyć przycisku \"Wyślij raport\" aby wysłać raport automatycznie na nasze serwery
\n"
+" "
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:102
msgctxt "@title:groupbox"
@@ -1259,32 +1279,32 @@ msgstr "Nieznany"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:112
msgctxt "@label Cura version number"
msgid "Cura version"
-msgstr ""
+msgstr "Wersja Cura"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:113
msgctxt "@label Type of platform"
msgid "Platform"
-msgstr ""
+msgstr "Platforma"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:114
msgctxt "@label"
msgid "Qt version"
-msgstr ""
+msgstr "Wersja Qt"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:115
msgctxt "@label"
msgid "PyQt version"
-msgstr ""
+msgstr "Wersja PyQt"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:116
msgctxt "@label OpenGL version"
msgid "OpenGL"
-msgstr ""
+msgstr "OpenGL"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:133
msgctxt "@label"
msgid "not yet initialised
"
-msgstr ""
+msgstr "jeszcze nie uruchomiono
"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:136
#, python-brace-format
@@ -1307,7 +1327,7 @@ msgstr "- OpenGL Renderer: {renderer}
"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:147
msgctxt "@title:groupbox"
msgid "Error traceback"
-msgstr ""
+msgstr "Śledzenie błedu"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:214
msgctxt "@title:groupbox"
@@ -1518,7 +1538,7 @@ msgstr "Rozmiar dyszy"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:393
msgctxt "@label"
msgid "Compatible material diameter"
-msgstr ""
+msgstr "Kompatybilna średnica materiału"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:395
msgctxt "@tooltip"
@@ -1663,12 +1683,12 @@ msgstr "Rodzaj"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:233
msgctxt "@label Printer name"
msgid "Ultimaker 3"
-msgstr ""
+msgstr "Ultimaker 3"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:236
msgctxt "@label Printer name"
msgid "Ultimaker 3 Extended"
-msgstr ""
+msgstr "Ultimaker 3 Extended"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:252
msgctxt "@label"
@@ -1735,7 +1755,7 @@ msgstr "%1 nie została ustawiona do hostowania grupy podłączonych drukarek Ul
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/ClusterMonitorItem.qml:55
msgctxt "@label link to connect manager"
msgid "Add/Remove printers"
-msgstr ""
+msgstr "Dodaj/Usuń drukarki"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/OpenPanelButton.qml:14
msgctxt "@info:tooltip"
@@ -1775,7 +1795,7 @@ msgstr "Utracone połączenie z drukarką"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml:47
msgctxt "@label Printer status"
msgid "Unknown"
-msgstr ""
+msgstr "Nieznany"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml:257
msgctxt "@label:status"
@@ -1871,62 +1891,62 @@ msgstr "Uaktywnij konfigurację"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:21
msgctxt "@title:window"
msgid "SolidWorks: Export wizard"
-msgstr ""
+msgstr "SolidWorks: Kreator eksportu"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:45
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:140
msgctxt "@action:label"
msgid "Quality:"
-msgstr ""
+msgstr "Jakość:"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:78
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:179
msgctxt "@option:curaSolidworksStlQuality"
msgid "Fine (3D-printing)"
-msgstr ""
+msgstr "Dobra (druk 3D)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:79
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:180
msgctxt "@option:curaSolidworksStlQuality"
msgid "Coarse (3D-printing)"
-msgstr ""
+msgstr "Słaba (druk 3D)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:80
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:181
msgctxt "@option:curaSolidworksStlQuality"
msgid "Fine (SolidWorks)"
-msgstr ""
+msgstr "Dobra (SolidWorks)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:81
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:182
msgctxt "@option:curaSolidworksStlQuality"
msgid "Coarse (SolidWorks)"
-msgstr ""
+msgstr "Słaba (Solidworks)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:94
msgctxt "@text:window"
msgid "Show this dialog again"
-msgstr ""
+msgstr "Pokaż to okno ponownie"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:104
msgctxt "@action:button"
msgid "Continue"
-msgstr ""
+msgstr "Kontynuuj"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:116
msgctxt "@action:button"
msgid "Abort"
-msgstr ""
+msgstr "Przerwij"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:21
msgctxt "@title:window"
msgid "How to install Cura SolidWorks macro"
-msgstr ""
+msgstr "Jak zainstalować skróty SolidWorks dla Cura"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:62
msgctxt "@description:label"
msgid "Steps:"
-msgstr ""
+msgstr "Kroki:"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:140
msgctxt "@action:button"
@@ -1934,101 +1954,103 @@ msgid ""
"Open the directory\n"
"with macro and icon"
msgstr ""
+"Otwórz folder\n"
+"ze skrótem i ikoną"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:160
msgctxt "@description:label"
msgid "Instructions:"
-msgstr ""
+msgstr "Instrukcje:"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:202
msgctxt "@action:playpause"
msgid "Play"
-msgstr ""
+msgstr "Odtwórz"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:206
msgctxt "@action:playpause"
msgid "Pause"
-msgstr ""
+msgstr "Zatrzymaj"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:268
msgctxt "@action:button"
msgid "Previous Step"
-msgstr ""
+msgstr "Poprzedni Krok"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:283
msgctxt "@action:button"
msgid "Done"
-msgstr ""
+msgstr "Zrobione"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:287
msgctxt "@action:button"
msgid "Next Step"
-msgstr ""
+msgstr "Następny Krok"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:21
msgctxt "@title:window"
msgid "SolidWorks plugin: Configuration"
-msgstr ""
+msgstr "Plugin SolidWorks: Konfiguracja"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:39
msgctxt "@title:tab"
msgid "Conversion settings"
-msgstr ""
+msgstr "Konwersja ustawień"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:66
msgctxt "@label"
msgid "First choice:"
-msgstr ""
+msgstr "Pierwszy wybór:"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:86
msgctxt "@text:menu"
msgid "Latest installed version (Recommended)"
-msgstr ""
+msgstr "Ostatnio zainstalowana wersja (Rekomendowana)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:95
msgctxt "@text:menu"
msgid "Default version"
-msgstr ""
+msgstr "Domyślna wersja"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:193
msgctxt "@label"
msgid "Show wizard before opening SolidWorks files"
-msgstr ""
+msgstr "Pokaż konfigurator przed otworzeniem plików SolidWorks"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:203
msgctxt "@label"
msgid "Automatically rotate opened file into normed orientation"
-msgstr ""
+msgstr "Automatycznie obracaj otworzone pliki do unormowanej pozycji"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:210
msgctxt "@title:tab"
msgid "Installation(s)"
-msgstr ""
+msgstr "Instalacja(-e)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:284
msgctxt "@label"
msgid "COM service found"
-msgstr ""
+msgstr "Usługa COM znaleziona"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:295
msgctxt "@label"
msgid "Executable found"
-msgstr ""
+msgstr "Znaleziono plik wykonywalny"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:306
msgctxt "@label"
msgid "COM starting"
-msgstr ""
+msgstr "Uruchamianie COM"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:317
msgctxt "@label"
msgid "Revision number"
-msgstr ""
+msgstr "Numer wydania"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:328
msgctxt "@label"
msgid "Functions available"
-msgstr ""
+msgstr "Dostępne funkcje"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:341
#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:264
@@ -2214,32 +2236,32 @@ msgstr "Wygładzanie"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:38
msgctxt "@label"
msgid "Mesh Type"
-msgstr ""
+msgstr "Typ siatki"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:69
msgctxt "@label"
msgid "Normal model"
-msgstr ""
+msgstr "Normalny model"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:76
msgctxt "@label"
msgid "Print as support"
-msgstr ""
+msgstr "Drukuj jako podpora"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:84
msgctxt "@label"
msgid "Don't support overlap with other models"
-msgstr ""
+msgstr "Nie wspieraj nałożeń z innymi modelami"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:92
msgctxt "@label"
msgid "Modify settings for overlap with other models"
-msgstr ""
+msgstr "Modyfikuj ustawienia nakładania z innymi modelami"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:100
msgctxt "@label"
msgid "Modify settings for infill of other models"
-msgstr ""
+msgstr "Modyfikuj ustawienia wypełnienia innych modeli"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:333
msgctxt "@action:button"
@@ -3099,27 +3121,27 @@ msgstr "Wyślij (anonimowe) informacje o drukowaniu"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:674
msgctxt "@label"
msgid "Experimental"
-msgstr ""
+msgstr "Eksperymentalne"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:680
msgctxt "@info:tooltip"
msgid "Use multi build plate functionality"
-msgstr ""
+msgstr "Użyj funkcji wielu pól roboczych"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:685
msgctxt "@option:check"
msgid "Use multi build plate functionality (restart required)"
-msgstr ""
+msgstr "Użyj funkcji wielu pól roboczych (wymagany restart)"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:694
msgctxt "@info:tooltip"
msgid "Should newly loaded models be arranged on the build plate? Used in conjunction with multi build plate (EXPERIMENTAL)"
-msgstr ""
+msgstr "Czy nowo załadowane modele powinny zostać rozłożone na platformie roboczej? Używane w połączeniu z multi platformą roboczą (EKSPERYMENTALNE)"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:699
msgctxt "@option:check"
msgid "Do not arrange objects on load"
-msgstr ""
+msgstr "Nie układaj obiektów podczas ładowania"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:15
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:514
@@ -3532,7 +3554,7 @@ msgstr "Pod wpływem"
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:156
msgctxt "@label"
msgid "This setting is always shared between all extruders. Changing it here will change the value for all extruders."
-msgstr ""
+msgstr "To ustawienie jest dzielone pomiędzy wszystkimi ekstruderami. Zmiana tutaj spowoduje zmianę dla wszystkich ekstruderów."
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:159
msgctxt "@label"
@@ -3583,7 +3605,7 @@ msgstr "00godz. 00min."
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:359
msgctxt "@tooltip"
msgid "Time specification"
-msgstr ""
+msgstr "Specyfikacja czasu"
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:441
msgctxt "@label"
@@ -3640,12 +3662,12 @@ msgstr "&Widok"
#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:37
msgctxt "@action:inmenu menubar:view"
msgid "&Camera position"
-msgstr ""
+msgstr "&Pozycja kamery"
#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:52
msgctxt "@action:inmenu menubar:view"
msgid "&Build plate"
-msgstr ""
+msgstr "&Pole robocze"
#: /home/ruben/Projects/Cura/resources/qml/Menus/NozzleMenu.qml:40
msgctxt "@title:menuitem %1 is the nozzle currently loaded in the printer"
@@ -3815,27 +3837,27 @@ msgstr "&Zamknij"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:114
msgctxt "@action:inmenu menubar:view"
msgid "&3D View"
-msgstr ""
+msgstr "&Widok 3D"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:121
msgctxt "@action:inmenu menubar:view"
msgid "&Front View"
-msgstr ""
+msgstr "&Widok z przodu"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:128
msgctxt "@action:inmenu menubar:view"
msgid "&Top View"
-msgstr ""
+msgstr "&Widok z góry"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:135
msgctxt "@action:inmenu menubar:view"
msgid "&Left Side View"
-msgstr ""
+msgstr "&Widok z lewej strony"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:142
msgctxt "@action:inmenu menubar:view"
msgid "&Right Side View"
-msgstr ""
+msgstr "&Widok z prawej strony"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:149
msgctxt "@action:inmenu"
@@ -3961,7 +3983,7 @@ msgstr "Przeładuj wszystkie modele"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models To All Build Plates"
-msgstr ""
+msgstr "Rozłóż Wszystkie Modele na Wszystkie Platformy Robocze."
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:358
msgctxt "@action:inmenu menubar:edit"
@@ -4021,7 +4043,7 @@ msgstr "Zainstalowane wtyczki..."
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:438
msgctxt "@action:inmenu menubar:view"
msgid "Expand/Collapse Sidebar"
-msgstr ""
+msgstr "Rozłóż/Schowaj Pasek Boczny"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:26
msgctxt "@label:PrintjobStatus"
@@ -4056,12 +4078,12 @@ msgstr "Cięcie niedostępne"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:171
msgctxt "@info:tooltip"
msgid "Slice current printjob"
-msgstr ""
+msgstr "Potnij aktualny wydruk"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:171
msgctxt "@info:tooltip"
msgid "Cancel slicing process"
-msgstr ""
+msgstr "Przerwij proces cięcia"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:183
msgctxt "@label:Printjob"
@@ -4117,7 +4139,7 @@ msgstr "Zapisz &jako..."
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:139
msgctxt "@title:menu menubar:file"
msgid "Save &Project..."
-msgstr ""
+msgstr "Zapisz &Project..."
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:162
msgctxt "@title:menu menubar:toplevel"
@@ -4356,7 +4378,7 @@ msgstr "Materiał"
#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:352
msgctxt "@label"
msgid "Check compatibility"
-msgstr ""
+msgstr "Sprawdź kompatybilność"
#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:372
msgctxt "@tooltip"
@@ -4366,17 +4388,17 @@ msgstr "Kliknij, aby sprawdzić zgodność materiału na Ultimaker.com."
#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:211
msgctxt "@option:check"
msgid "See only current build plate"
-msgstr ""
+msgstr "Pokaż tylko aktualną platformę roboczą"
#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:227
msgctxt "@action:button"
msgid "Arrange to all build plates"
-msgstr ""
+msgstr "Rozłóż na wszystkich platformach roboczych"
#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:247
msgctxt "@action:button"
msgid "Arrange current build plate"
-msgstr ""
+msgstr "Rozłóż na obecnej platformie roboczej"
#: MachineSettingsAction/plugin.json
msgctxt "description"
@@ -4471,22 +4493,22 @@ msgstr "Drukowanie USB"
#: PrepareStage/plugin.json
msgctxt "description"
msgid "Provides a prepare stage in Cura."
-msgstr ""
+msgstr "Zapewnia etap przygotowania w Cura."
#: PrepareStage/plugin.json
msgctxt "name"
msgid "Prepare Stage"
-msgstr ""
+msgstr "Etap Przygotowania"
#: CuraLiveScriptingPlugin/plugin.json
msgctxt "description"
msgid "Provides an edit window for direct script editing."
-msgstr ""
+msgstr "Zapewnia okno edycji dla bezpośredniego edytowania skryptów."
#: CuraLiveScriptingPlugin/plugin.json
msgctxt "name"
msgid "Live scripting tool"
-msgstr ""
+msgstr "Narzędzie pisania skryptów na żywo."
#: RemovableDriveOutputDevice/plugin.json
msgctxt "description"
@@ -4511,12 +4533,12 @@ msgstr "Połączenie Sieciowe UM3"
#: MonitorStage/plugin.json
msgctxt "description"
msgid "Provides a monitor stage in Cura."
-msgstr ""
+msgstr "Zapewnia etap monitorowania w Cura."
#: MonitorStage/plugin.json
msgctxt "name"
msgid "Monitor Stage"
-msgstr ""
+msgstr "Etap Monitorowania"
#: FirmwareUpdateChecker/plugin.json
msgctxt "description"
@@ -4531,7 +4553,7 @@ msgstr "Sprawdzacz Aktualizacji Oprogramowania"
#: CuraSolidWorksPlugin/plugin.json
msgctxt "description"
msgid "Gives you the possibility to open certain files using SolidWorks itself. Conversion is done by this plugin and additional optimizations."
-msgstr ""
+msgstr "Daje Tobie możliwość otwierania plików używają samego SolidWorks. Konwersja jest wykonywana przez ten plugin i dodatkowo optymalizowana."
#: CuraSolidWorksPlugin/plugin.json
msgctxt "name"
@@ -4601,12 +4623,12 @@ msgstr "Czytnik Profili Starszej Cura"
#: CuraBlenderPlugin/plugin.json
msgctxt "description"
msgid "Helps to open Blender files directly in Cura."
-msgstr ""
+msgstr "Pomaga w otwieraniu plików Blender bezpośrednio w Cura."
#: CuraBlenderPlugin/plugin.json
msgctxt "name"
msgid "Blender Integration (experimental)"
-msgstr ""
+msgstr "Integracja z Blenderem (eksperymentalny)"
#: GCodeProfileReader/plugin.json
msgctxt "description"
@@ -4771,12 +4793,12 @@ msgstr "Cura Profile Writer"
#: CuraPrintProfileCreator/plugin.json
msgctxt "description"
msgid "Allows material manufacturers to create new material and quality profiles using a drop-in UI."
-msgstr ""
+msgstr "Pozwala twórcą materiałów na tworzenie nowych profili materiałów i jakości używając rozwijanego menu."
#: CuraPrintProfileCreator/plugin.json
msgctxt "name"
msgid "Print Profile Assistant"
-msgstr ""
+msgstr "Asystent Profilów Druku"
#: 3MFWriter/plugin.json
msgctxt "description"
diff --git a/resources/i18n/pl_PL/fdmprinter.def.json.po b/resources/i18n/pl_PL/fdmprinter.def.json.po
index 5d886b3789..989967bd75 100644
--- a/resources/i18n/pl_PL/fdmprinter.def.json.po
+++ b/resources/i18n/pl_PL/fdmprinter.def.json.po
@@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: Cura 3.0\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
"POT-Creation-Date: 2017-08-02 16:53+0000\n"
-"PO-Revision-Date: 2017-11-22 19:41+0100\n"
+"PO-Revision-Date: 2018-02-10 14:03+0100\n"
"Last-Translator: 'Jaguś' Paweł Jagusiak and Andrzej 'anraf1001' Rafalski\n"
"Language-Team: reprapy.pl\n"
"Language: pl_PL\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.0.4\n"
+"X-Generator: Poedit 2.0.6\n"
#: fdmprinter.def.json
msgctxt "machine_settings label"
@@ -353,12 +353,12 @@ msgstr "Repetier"
#: fdmprinter.def.json
msgctxt "machine_firmware_retract label"
msgid "Firmware Retraction"
-msgstr ""
+msgstr "Retrakcja Programowa"
#: fdmprinter.def.json
msgctxt "machine_firmware_retract description"
msgid "Whether to use firmware retract commands (G10/G11) instead of using the E property in G1 commands to retract the material."
-msgstr ""
+msgstr "Używaj komend retrakcji (G10/G11) zamiast używać współrzędną E w komendzie G1, aby wycofać materiał."
#: fdmprinter.def.json
msgctxt "machine_disallowed_areas label"
@@ -1053,12 +1053,12 @@ msgstr "Wszędzie"
#: fdmprinter.def.json
msgctxt "filter_out_tiny_gaps label"
msgid "Filter Out Tiny Gaps"
-msgstr ""
+msgstr "Filtruj Małe Luki"
#: fdmprinter.def.json
msgctxt "filter_out_tiny_gaps description"
msgid "Filter out tiny gaps to reduce blobs on outside of model."
-msgstr ""
+msgstr "Filtruj małe luki, aby zredukować bloby na zewnątrz modelu."
#: fdmprinter.def.json
msgctxt "fill_outline_gaps label"
@@ -1443,7 +1443,7 @@ msgstr "Przesunięcie Wypełn. w Osi X"
#: fdmprinter.def.json
msgctxt "infill_offset_x description"
msgid "The infill pattern is moved this distance along the X axis."
-msgstr ""
+msgstr "Wzór wypełnienia jest przesunięty o tę odległość wzdłuż osi X."
#: fdmprinter.def.json
msgctxt "infill_offset_y label"
@@ -1453,7 +1453,7 @@ msgstr "Przesunięcie Wypełn. w Osi Y"
#: fdmprinter.def.json
msgctxt "infill_offset_y description"
msgid "The infill pattern is moved this distance along the Y axis."
-msgstr ""
+msgstr "Wzór wypełnienia jest przesunięty o tę odległość wzdłuż osi Y."
#: fdmprinter.def.json
msgctxt "sub_div_rad_add label"
@@ -1473,7 +1473,7 @@ msgstr "Procent Nałożenia Wypełn."
#: fdmprinter.def.json
msgctxt "infill_overlap description"
msgid "The amount of overlap between the infill and the walls as a percentage of the infill line width. A slight overlap allows the walls to connect firmly to the infill."
-msgstr ""
+msgstr "Ilość nałożenia pomiędzy wypełnieniem i ścianami w procentach szerokości linii wypełnienia. Delikatne nałożenie pozwala na lepsze połączenie ścian z wypełnieniem."
#: fdmprinter.def.json
msgctxt "infill_overlap_mm label"
@@ -1493,7 +1493,7 @@ msgstr "Procent Nakładania się Skóry"
#: fdmprinter.def.json
msgctxt "skin_overlap description"
msgid "The amount of overlap between the skin and the walls as a percentage of the skin line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall."
-msgstr ""
+msgstr "Ilość nałożenia pomiędzy skórą a ścianami w procentach szerokości linii skóry. Delikatne nałożenie pozawala na lepsze połączenie się ścian ze skórą. Jest to procent średniej szerokości linii skóry i wewnętrznej ściany."
#: fdmprinter.def.json
msgctxt "skin_overlap_mm label"
@@ -1723,7 +1723,7 @@ msgstr "Temperatura Stołu"
#: fdmprinter.def.json
msgctxt "material_bed_temperature description"
msgid "The temperature used for the heated build plate. If this is 0, the bed temperature will not be adjusted."
-msgstr ""
+msgstr "Temperatura stosowana dla podgrzewanej platformy roboczej. Jeżeli jest ustawione 0, temperatura stołu nie będzie ustawiona."
#: fdmprinter.def.json
msgctxt "material_bed_temperature_layer_0 label"
@@ -4267,82 +4267,82 @@ msgstr "eksperymentalne!"
#: fdmprinter.def.json
msgctxt "support_tree_enable label"
msgid "Tree Support"
-msgstr ""
+msgstr "Drzewne Podpory"
#: fdmprinter.def.json
msgctxt "support_tree_enable description"
msgid "Generate a tree-like support with branches that support your print. This may reduce material usage and print time, but greatly increases slicing time."
-msgstr ""
+msgstr "Generuj drzewiaste podpory z gałęziami podpierającymi wydruk. Może to zredukować zużycie materiału i czas wydruku, ale bardzo zwiększa czas cięcia."
#: fdmprinter.def.json
msgctxt "support_tree_angle label"
msgid "Tree Support Branch Angle"
-msgstr ""
+msgstr "Kąt Gałęzi Drzewnej Podpory"
#: fdmprinter.def.json
msgctxt "support_tree_angle description"
msgid "The angle of the branches. Use a lower angle to make them more vertical and more stable. Use a higher angle to be able to have more reach."
-msgstr ""
+msgstr "Kąt gałęzi. Użyj mniejszego kąta, aby były bardziej pionowe i stabilne. Użyj większego kąta, aby mieć większy zasięg."
#: fdmprinter.def.json
msgctxt "support_tree_branch_distance label"
msgid "Tree Support Branch Distance"
-msgstr ""
+msgstr "Odległość Gałęzi Drzewiastej Podpory"
#: fdmprinter.def.json
msgctxt "support_tree_branch_distance description"
msgid "How far apart the branches need to be when they touch the model. Making this distance small will cause the tree support to touch the model at more points, causing better overhang but making support harder to remove."
-msgstr ""
+msgstr "W jakich odległościach powinny znajdować się gałęzie kiedy dotykają modelu. Mały dystans spowoduje więcej punktów podparcia, co da lepsze nawisy, ale utrudni usuwanie podpór."
#: fdmprinter.def.json
msgctxt "support_tree_branch_diameter label"
msgid "Tree Support Branch Diameter"
-msgstr ""
+msgstr "Średnica Gałęzi Drzewiastej Podpory"
#: fdmprinter.def.json
msgctxt "support_tree_branch_diameter description"
msgid "The diameter of the thinnest branches of tree support. Thicker branches are more sturdy. Branches towards the base will be thicker than this."
-msgstr ""
+msgstr "Średnica najcieńszej gałęzi drzewiastej podpory. Grubsze gałęzie są bardziej sztywne. Gałęzie bliżej podłoża będą grubsze od tego."
#: fdmprinter.def.json
msgctxt "support_tree_branch_diameter_angle label"
msgid "Tree Support Branch Diameter Angle"
-msgstr ""
+msgstr "Kąt Średnicy Gałęzi Drzewiastej Podpory"
#: fdmprinter.def.json
msgctxt "support_tree_branch_diameter_angle description"
msgid "The angle of the branches' diameter as they gradually become thicker towards the bottom. An angle of 0 will cause the branches to have uniform thickness over their length. A bit of an angle can increase stability of the tree support."
-msgstr ""
+msgstr "Kąt średnicy gałęzi, które stają się grubsze bliżej podłoża. Kąt 0 spowoduje równą grubość na całej długości gałęzi. Delikatny kąt może spowodować lepszą stabilność podpór."
#: fdmprinter.def.json
msgctxt "support_tree_collision_resolution label"
msgid "Tree Support Collision Resolution"
-msgstr ""
+msgstr "Rozdzielczość Kolizji Drzewiastej Podpory"
#: fdmprinter.def.json
msgctxt "support_tree_collision_resolution description"
msgid "Resolution to compute collisions with to avoid hitting the model. Setting this lower will produce more accurate trees that fail less often, but increases slicing time dramatically."
-msgstr ""
+msgstr "Rozdzielczość przeliczania kolizji, aby unikać zderzeń z modelem. Ustawienie niższej wartości spowoduje bardziej dokładne drzewa, które rzadziej zawodzą, ale zwiększa to drastycznie czas cięcia."
#: fdmprinter.def.json
msgctxt "support_tree_wall_thickness label"
msgid "Tree Support Wall Thickness"
-msgstr ""
+msgstr "Grubość Ściany Drzewiastej Podpory"
#: fdmprinter.def.json
msgctxt "support_tree_wall_thickness description"
msgid "The thickness of the walls of the branches of tree support. Thicker walls take longer to print but don't fall over as easily."
-msgstr ""
+msgstr "Grubość ścian gałęzi drzewiastej podpory. Grubsze ściany drukują się dłużej, ale nie odpadają tak łatwo."
#: fdmprinter.def.json
msgctxt "support_tree_wall_count label"
msgid "Tree Support Wall Line Count"
-msgstr ""
+msgstr "Liczba Linii Ściany Drzewiastej Podpory"
#: fdmprinter.def.json
msgctxt "support_tree_wall_count description"
msgid "The number of walls of the branches of tree support. Thicker walls take longer to print but don't fall over as easily."
-msgstr ""
+msgstr "Liczba ścian gałęzi drzewiastej podpory. Grubsze ściany drukują się dłużej , ale nie odpadają tak łatwo."
#: fdmprinter.def.json
msgctxt "slicing_tolerance label"
@@ -4417,12 +4417,12 @@ msgstr "Lista całkowitych kierunków linii używana kiedy skóra górnej powier
#: fdmprinter.def.json
msgctxt "infill_enable_travel_optimization label"
msgid "Infill Travel Optimization"
-msgstr ""
+msgstr "Optymalizacja Ruchów Jałowych Wypełnienia"
#: fdmprinter.def.json
msgctxt "infill_enable_travel_optimization description"
msgid "When enabled, the order in which the infill lines are printed is optimized to reduce the distance travelled. The reduction in travel time achieved very much depends on the model being sliced, infill pattern, density, etc. Note that, for some models that have many small areas of infill, the time to slice the model may be greatly increased."
-msgstr ""
+msgstr "Kiedy włączone, kolejność drukowania linii wypełnienia jest optymalizowana tak, aby zredukować odległości ruchów jałowych. Osiągnięta redukcja czasu ruchów jałowych zależy od ciętego modelu, wzory wypełnienia, gęstości itd. Zauważ, że dla niektórych modeli, które mają małe obszary wypełnienia, czas ciecia modelu może się bardzo wydłużyć."
#: fdmprinter.def.json
msgctxt "material_flow_dependent_temperature label"
@@ -5056,42 +5056,42 @@ msgstr "Odległość między dyszą a liniami skierowanymi w dół. Większe prz
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_enabled label"
msgid "Use adaptive layers"
-msgstr ""
+msgstr "Użyj zmiennych warstw"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_enabled description"
msgid "Adaptive layers computes the layer heights depending on the shape of the model."
-msgstr ""
+msgstr "Zmienne warstwy obliczają wysokości warstw w zależności od kształtu modelu."
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation label"
msgid "Adaptive layers maximum variation"
-msgstr ""
+msgstr "Maks. zmiana zmiennych warstw"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation description"
msgid "The maximum allowed height different from the base layer height in mm."
-msgstr ""
+msgstr "Maksymalna dozwolona różnica wysokości od podstawowej wysokości warstwy w mm."
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation_step label"
msgid "Adaptive layers variation step size"
-msgstr ""
+msgstr "Krok zmian zmiennych warstw"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation_step description"
msgid "The difference in height of the next layer height compared to the previous one."
-msgstr ""
+msgstr "Różnica w wysokości pomiędzy następną wysokością warstwy i poprzednią."
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold label"
msgid "Adaptive layers threshold"
-msgstr ""
+msgstr "Opóźnienie zmiennych warstw"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold description"
msgid "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer."
-msgstr ""
+msgstr "Opóźnienie w wyborze, czy użyć mniejszej warstwy, czy nie. Ta liczba jest porównywana do najbardziej stromego nachylenia na warstwie."
#: fdmprinter.def.json
msgctxt "command_line_settings label"
diff --git a/resources/i18n/pt_BR/cura.po b/resources/i18n/pt_BR/cura.po
index 947ee3416d..9000a6ff35 100644
--- a/resources/i18n/pt_BR/cura.po
+++ b/resources/i18n/pt_BR/cura.po
@@ -1,14 +1,14 @@
# Cura
-# Copyright (C) 2017 Ultimaker
+# Copyright (C) 2018 Ultimaker
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2017.
+# Ruben Dulek , 2018.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.0\n"
+"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2017-08-02 16:53+0000\n"
-"PO-Revision-Date: 2017-12-04 10:20-0300\n"
+"POT-Creation-Date: 2018-01-29 09:48+0000\n"
+"PO-Revision-Date: 2018-02-12 10:20-0300\n"
"Last-Translator: Cláudio Sampaio \n"
"Language-Team: Cláudio Sampaio and CoderSquirrel \n"
"Language: pt_BR\n"
@@ -188,7 +188,7 @@ msgstr "Firmware da Impressora"
#: /home/ruben/Projects/Cura/plugins/PrepareStage/__init__.py:12
msgctxt "@item:inmenu"
msgid "Prepare"
-msgstr ""
+msgstr "Preparar"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:23
msgctxt "@action:button Preceded by 'Ready to'."
@@ -561,7 +561,7 @@ msgstr "Abrir a interface de trabalhos de impressão em seu navegador."
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:239
msgctxt "@label Printer name"
msgid "Unknown"
-msgstr ""
+msgstr "Desconhecida"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py:505
#, python-brace-format
@@ -596,7 +596,7 @@ msgstr "Conectar pela rede"
#: /home/ruben/Projects/Cura/plugins/MonitorStage/__init__.py:12
msgctxt "@item:inmenu"
msgid "Monitor"
-msgstr ""
+msgstr "Monitor"
#: /home/ruben/Projects/Cura/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py:66
#, python-brace-format
@@ -623,7 +623,7 @@ msgstr "Não foi possível acessar informação de atualização."
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksReader.py:579
msgctxt "@info:status"
msgid "SolidWorks reported errors, while opening your file. We recommend to solve these issues inside SolidWorks itself."
-msgstr ""
+msgstr "O SolidWorks relatou problemas ao abrir seu arquivo. Recomendamos resolver tais problemas dentro do próprio SolidWorks."
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksReader.py:591
msgctxt "@info:status"
@@ -632,6 +632,9 @@ msgid ""
"\n"
" Thanks!."
msgstr ""
+"Não foram encontrados modelos dentro de seu desenho. Poderia verificar seu conteúdo novamente e se assegurar que uma parte ou montagem está incluída?\n"
+"\n"
+" Obrigado!."
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksReader.py:595
msgctxt "@info:status"
@@ -640,6 +643,9 @@ msgid ""
"\n"
"Sorry!"
msgstr ""
+"Foi encontrado mais de uma parte ou montagem dentro de seu desenho. Atualmente só suportamos desenhos com exatamente uma parte ou montagem dentro.\n"
+"\n"
+"Desculpe!"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:25
msgctxt "@item:inlistbox"
@@ -654,7 +660,7 @@ msgstr "Arquivo de montagem de SolidWorks"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:33
msgctxt "@item:inlistbox"
msgid "SolidWorks drawing file"
-msgstr ""
+msgstr "Arquivo de desenho do SolidWorks"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:48
msgctxt "@info:status"
@@ -665,6 +671,11 @@ msgid ""
"With kind regards\n"
" - Thomas Karl Pietrowski"
msgstr ""
+"Caro cliente,\n"
+"Não foi encontrada uma intalação válida de SolidWorks no seu sistema. Isso significa que ou o SolidWorks não está instalado ou você nào tem licença válida. Por favor se assegure que rodar o Solidworks funciona sem problemas e/ou contate seu suporte.\n"
+"\n"
+"Atenciosamente\n"
+" - Thomas Karl Pietrowski"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:57
msgctxt "@info:status"
@@ -675,6 +686,11 @@ msgid ""
"With kind regards\n"
" - Thomas Karl Pietrowski"
msgstr ""
+"Caro cliente,\n"
+"Você está no momento rodando este complemento em um sistema operacional diferente de Windows. Este complemento só funcionará no Windows com o SolidWorks instalado e com licença válida. Por favor instale este complemento em uma máquina Windows com o SolidWorks instalado.\n"
+"\n"
+"Atenciosamente\n"
+" - Thomas Karl Pietrowski"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksDialogHandler.py:70
msgid "Configure"
@@ -682,7 +698,7 @@ msgstr "Configure"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksDialogHandler.py:71
msgid "Installation guide for SolidWorks macro"
-msgstr ""
+msgstr "Guia de Instalação para macro do SolidWorks"
#: /home/ruben/Projects/Cura/plugins/SimulationView/__init__.py:14
msgctxt "@item:inlistbox"
@@ -706,7 +722,7 @@ msgstr "Modificar G-Code"
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:43
msgctxt "@info"
msgid "Cura collects anonymized usage statistics."
-msgstr ""
+msgstr "O Cura coleta estatísticas anônimas de uso."
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:46
msgctxt "@info:title"
@@ -716,22 +732,22 @@ msgstr "Coletando Dados"
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:48
msgctxt "@action:button"
msgid "Allow"
-msgstr ""
+msgstr "Permitir"
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:49
msgctxt "@action:tooltip"
msgid "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing."
-msgstr ""
+msgstr "Permite que o Cura envie estatísticas anônimas de uso para ajudar a priorizar futuras melhorias ao software. Algumas de suas preferências e ajustes são enviados junto à versão atual do Cura e um hash dos modelos que estão sendo fatiados."
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:50
msgctxt "@action:button"
msgid "Disable"
-msgstr ""
+msgstr "Desabilitar"
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:51
msgctxt "@action:tooltip"
msgid "Don't allow Cura to send anonymized usage statistics. You can enable it again in the preferences."
-msgstr ""
+msgstr "Não permitir que o Cura envie estatísticas anônimas de uso. Você pode habilitar novamente nas preferências."
#: /home/ruben/Projects/Cura/plugins/LegacyProfileReader/__init__.py:14
msgctxt "@item:inlistbox"
@@ -741,7 +757,7 @@ msgstr "Perfis do Cura 15.04"
#: /home/ruben/Projects/Cura/plugins/CuraBlenderPlugin/__init__.py:15
msgctxt "@item:inlistbox"
msgid "Blender file"
-msgstr ""
+msgstr "Arquivo do Blender"
#: /home/ruben/Projects/Cura/plugins/CuraBlenderPlugin/CadIntegrationUtils/CommonReader.py:199
msgctxt "@info:status"
@@ -749,6 +765,8 @@ msgid ""
"Could not export using \"{}\" quality!\n"
"Felt back to \"{}\"."
msgstr ""
+"Não foi possível exportar usando qualidade \"{}\"!\n"
+"Foi usada a \"{}\"."
#: /home/ruben/Projects/Cura/plugins/GCodeProfileReader/__init__.py:14
#: /home/ruben/Projects/Cura/plugins/GCodeReader/__init__.py:14
@@ -935,12 +953,12 @@ msgstr "Perfil do Cura"
#: /home/ruben/Projects/Cura/plugins/CuraPrintProfileCreator/__init__.py:12
msgctxt "@item:inmenu"
msgid "Profile Assistant"
-msgstr ""
+msgstr "Assistente de Perfil"
#: /home/ruben/Projects/Cura/plugins/CuraPrintProfileCreator/__init__.py:17
msgctxt "@item:inlistbox"
msgid "Profile Assistant"
-msgstr ""
+msgstr "Assistente de Perfil"
#: /home/ruben/Projects/Cura/plugins/3MFWriter/__init__.py:30
msgctxt "@item:inlistbox"
@@ -1138,13 +1156,13 @@ msgstr "Falha ao importa perfil de {0}: {1} or !"
msgid "This profile {0} contains incorrect data, could not import it."
-msgstr ""
+msgstr "Este perfil {0} contém dados incorretos, não foi possível importá-lo."
#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:240
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags or !"
msgid "The machine defined in profile {0} doesn't match with your current machine, could not import it."
-msgstr ""
+msgstr "A máquina definida no perfil {0} não corresponde à sua máquina atual, não foi possível importá-lo."
#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:274
#, python-brace-format
@@ -1156,7 +1174,7 @@ msgstr "Perfil {0} importado com sucesso"
#, python-brace-format
msgctxt "@info:status"
msgid "File {0} does not contain any valid profile."
-msgstr ""
+msgstr "Arquivo {0} não contém nenhum perfil válido."
#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:280
#, python-brace-format
@@ -1184,7 +1202,7 @@ msgstr "Não foi possível encontrar tipo de qualidade {0} para a configuração
#, python-brace-format
msgctxt "@label"
msgid "Group #{group_nr}"
-msgstr ""
+msgstr "Grupo #{group_nr}"
#: /home/ruben/Projects/Cura/cura/BuildVolume.py:100
msgctxt "@info:status"
@@ -1244,6 +1262,9 @@ msgid ""
" Please use the \"Send report\" button to post a bug report automatically to our servers
\n"
" "
msgstr ""
+"Um erro fatal ocorreu. Por favor nos envie este Relatório de Erro para consertar o problema
\n"
+" Por favor use o botão \"Enviar relatório\" para publicar um relatório de erro automaticamente nos nossos servidores
\n"
+" "
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:102
msgctxt "@title:groupbox"
@@ -1258,32 +1279,32 @@ msgstr "Desconhecida"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:112
msgctxt "@label Cura version number"
msgid "Cura version"
-msgstr ""
+msgstr "Versão do Cura"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:113
msgctxt "@label Type of platform"
msgid "Platform"
-msgstr ""
+msgstr "Plataforma"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:114
msgctxt "@label"
msgid "Qt version"
-msgstr ""
+msgstr "Versão do Qt"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:115
msgctxt "@label"
msgid "PyQt version"
-msgstr ""
+msgstr "Versão do PyQt"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:116
msgctxt "@label OpenGL version"
msgid "OpenGL"
-msgstr ""
+msgstr "OpenGL"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:133
msgctxt "@label"
msgid "not yet initialised
"
-msgstr ""
+msgstr "ainda não inicializado
"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:136
#, python-brace-format
@@ -1306,7 +1327,7 @@ msgstr "- Renderizador da OpenGL: {renderer}
"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:147
msgctxt "@title:groupbox"
msgid "Error traceback"
-msgstr ""
+msgstr "Traceback do erro"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:214
msgctxt "@title:groupbox"
@@ -1517,7 +1538,7 @@ msgstr "Tamanho do bico"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:393
msgctxt "@label"
msgid "Compatible material diameter"
-msgstr ""
+msgstr "Diâmetro de material compatível"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:395
msgctxt "@tooltip"
@@ -1662,12 +1683,12 @@ msgstr "Tipo"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:233
msgctxt "@label Printer name"
msgid "Ultimaker 3"
-msgstr ""
+msgstr "Ultimaker 3"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:236
msgctxt "@label Printer name"
msgid "Ultimaker 3 Extended"
-msgstr ""
+msgstr "Ultimaker 3 Extended"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:252
msgctxt "@label"
@@ -1734,7 +1755,7 @@ msgstr "%1 não está configurada para hospedar um grupo de impressora Ultimaker
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/ClusterMonitorItem.qml:55
msgctxt "@label link to connect manager"
msgid "Add/Remove printers"
-msgstr ""
+msgstr "Adicionar/Remover impressoras"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/OpenPanelButton.qml:14
msgctxt "@info:tooltip"
@@ -1774,7 +1795,7 @@ msgstr "A conexão à impressora foi perdida"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml:47
msgctxt "@label Printer status"
msgid "Unknown"
-msgstr ""
+msgstr "Desconhecido"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml:257
msgctxt "@label:status"
@@ -1870,62 +1891,62 @@ msgstr "Ativar Configuração"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:21
msgctxt "@title:window"
msgid "SolidWorks: Export wizard"
-msgstr ""
+msgstr "SolidWorks: Assistente de Exportação"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:45
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:140
msgctxt "@action:label"
msgid "Quality:"
-msgstr ""
+msgstr "Qualidade"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:78
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:179
msgctxt "@option:curaSolidworksStlQuality"
msgid "Fine (3D-printing)"
-msgstr ""
+msgstr "Fina (impressão-3D)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:79
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:180
msgctxt "@option:curaSolidworksStlQuality"
msgid "Coarse (3D-printing)"
-msgstr ""
+msgstr "Baixa"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:80
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:181
msgctxt "@option:curaSolidworksStlQuality"
msgid "Fine (SolidWorks)"
-msgstr ""
+msgstr "Fina (SolidWorks)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:81
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:182
msgctxt "@option:curaSolidworksStlQuality"
msgid "Coarse (SolidWorks)"
-msgstr ""
+msgstr "Baixa (SolidWorks)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:94
msgctxt "@text:window"
msgid "Show this dialog again"
-msgstr ""
+msgstr "Mostrar este diálogo novamente"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:104
msgctxt "@action:button"
msgid "Continue"
-msgstr ""
+msgstr "Continuar"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:116
msgctxt "@action:button"
msgid "Abort"
-msgstr ""
+msgstr "Abortar"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:21
msgctxt "@title:window"
msgid "How to install Cura SolidWorks macro"
-msgstr ""
+msgstr "Como instalar a macro de SolidWorks do Cura"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:62
msgctxt "@description:label"
msgid "Steps:"
-msgstr ""
+msgstr "Passos:"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:140
msgctxt "@action:button"
@@ -1933,101 +1954,103 @@ msgid ""
"Open the directory\n"
"with macro and icon"
msgstr ""
+"Abrir o diretório\n"
+"com a macro e o ícone"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:160
msgctxt "@description:label"
msgid "Instructions:"
-msgstr ""
+msgstr "Instruções:"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:202
msgctxt "@action:playpause"
msgid "Play"
-msgstr ""
+msgstr "Tocar"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:206
msgctxt "@action:playpause"
msgid "Pause"
-msgstr ""
+msgstr "Pausar"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:268
msgctxt "@action:button"
msgid "Previous Step"
-msgstr ""
+msgstr "Passo Anterior"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:283
msgctxt "@action:button"
msgid "Done"
-msgstr ""
+msgstr "Finalizado"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:287
msgctxt "@action:button"
msgid "Next Step"
-msgstr ""
+msgstr "Passo Seguinte"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:21
msgctxt "@title:window"
msgid "SolidWorks plugin: Configuration"
-msgstr ""
+msgstr "Complemento do SolidWorks: Configuração"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:39
msgctxt "@title:tab"
msgid "Conversion settings"
-msgstr ""
+msgstr "Ajustes de conversão"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:66
msgctxt "@label"
msgid "First choice:"
-msgstr ""
+msgstr "Primeira escolha:"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:86
msgctxt "@text:menu"
msgid "Latest installed version (Recommended)"
-msgstr ""
+msgstr "Última versão instalada (Recomendado)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:95
msgctxt "@text:menu"
msgid "Default version"
-msgstr ""
+msgstr "Versão default"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:193
msgctxt "@label"
msgid "Show wizard before opening SolidWorks files"
-msgstr ""
+msgstr "Mostrar o assistente antes de abrir arquivos do SolidWorks"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:203
msgctxt "@label"
msgid "Automatically rotate opened file into normed orientation"
-msgstr ""
+msgstr "Rotacionar automaticamente o arquivo aberto em orientação normalizada"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:210
msgctxt "@title:tab"
msgid "Installation(s)"
-msgstr ""
+msgstr "Instalações"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:284
msgctxt "@label"
msgid "COM service found"
-msgstr ""
+msgstr "Serviço COM encontrado"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:295
msgctxt "@label"
msgid "Executable found"
-msgstr ""
+msgstr "Executável encontrado"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:306
msgctxt "@label"
msgid "COM starting"
-msgstr ""
+msgstr "COM iniciando"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:317
msgctxt "@label"
msgid "Revision number"
-msgstr ""
+msgstr "Número de revisão"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:328
msgctxt "@label"
msgid "Functions available"
-msgstr ""
+msgstr "Funções disponíveis"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:341
#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:264
@@ -2213,32 +2236,32 @@ msgstr "Suavização"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:38
msgctxt "@label"
msgid "Mesh Type"
-msgstr ""
+msgstr "Tipo de Malha"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:69
msgctxt "@label"
msgid "Normal model"
-msgstr ""
+msgstr "Modelo normal"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:76
msgctxt "@label"
msgid "Print as support"
-msgstr ""
+msgstr "Imprimir como suporte"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:84
msgctxt "@label"
msgid "Don't support overlap with other models"
-msgstr ""
+msgstr "Não suportar sobreposição com outros modelos"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:92
msgctxt "@label"
msgid "Modify settings for overlap with other models"
-msgstr ""
+msgstr "Modificar ajustes para sobrepor com outros modelos"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:100
msgctxt "@label"
msgid "Modify settings for infill of other models"
-msgstr ""
+msgstr "Modificar ajustes para preenchimento de outros modelos"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:333
msgctxt "@action:button"
@@ -3098,27 +3121,27 @@ msgstr "Enviar informação (anônima) de impressão."
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:674
msgctxt "@label"
msgid "Experimental"
-msgstr ""
+msgstr "Experimental"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:680
msgctxt "@info:tooltip"
msgid "Use multi build plate functionality"
-msgstr ""
+msgstr "Usar funcionalidade de plataforma múltipla de impressão"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:685
msgctxt "@option:check"
msgid "Use multi build plate functionality (restart required)"
-msgstr ""
+msgstr "Usar funcionalidade de plataforma múltipla de impressão (reinício requerido)"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:694
msgctxt "@info:tooltip"
msgid "Should newly loaded models be arranged on the build plate? Used in conjunction with multi build plate (EXPERIMENTAL)"
-msgstr ""
+msgstr "Novos modelos carregados devem ser posicionados na plataforma de impressão? Usado em conjunção com plataforma múltipla de impressão (EXPERIMENTAL)"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:699
msgctxt "@option:check"
msgid "Do not arrange objects on load"
-msgstr ""
+msgstr "Não posicionar objetos ao carregar."
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:15
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:514
@@ -3531,7 +3554,7 @@ msgstr "Afetado Por"
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:156
msgctxt "@label"
msgid "This setting is always shared between all extruders. Changing it here will change the value for all extruders."
-msgstr ""
+msgstr "Este ajuste é sempre compartilhado entre todos os extrusores. Modificá-lo aqui mudará o valor para todos."
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:159
msgctxt "@label"
@@ -3580,7 +3603,7 @@ msgstr "00h 00min"
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:359
msgctxt "@tooltip"
msgid "Time specification"
-msgstr ""
+msgstr "Especificação de tempo"
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:441
msgctxt "@label"
@@ -3637,12 +3660,12 @@ msgstr "&Ver"
#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:37
msgctxt "@action:inmenu menubar:view"
msgid "&Camera position"
-msgstr ""
+msgstr "Posição da &câmera"
#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:52
msgctxt "@action:inmenu menubar:view"
msgid "&Build plate"
-msgstr ""
+msgstr "Plataforma de Impressão (&B)"
#: /home/ruben/Projects/Cura/resources/qml/Menus/NozzleMenu.qml:40
msgctxt "@title:menuitem %1 is the nozzle currently loaded in the printer"
@@ -3797,7 +3820,7 @@ msgstr "A<ernar Tela Cheia"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:86
msgctxt "@action:inmenu menubar:edit"
msgid "&Undo"
-msgstr "Des&fazer"
+msgstr "Desfazer (&U)"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:96
msgctxt "@action:inmenu menubar:edit"
@@ -3807,32 +3830,32 @@ msgstr "&Refazer"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:106
msgctxt "@action:inmenu menubar:file"
msgid "&Quit"
-msgstr "&Sair"
+msgstr "Sair (&Q)"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:114
msgctxt "@action:inmenu menubar:view"
msgid "&3D View"
-msgstr ""
+msgstr "Visão &3D"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:121
msgctxt "@action:inmenu menubar:view"
msgid "&Front View"
-msgstr ""
+msgstr "Visão &Frontal"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:128
msgctxt "@action:inmenu menubar:view"
msgid "&Top View"
-msgstr ""
+msgstr "Visão Superior (&T)"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:135
msgctxt "@action:inmenu menubar:view"
msgid "&Left Side View"
-msgstr ""
+msgstr "Visão do Lado Esquerdo (&L)"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:142
msgctxt "@action:inmenu menubar:view"
msgid "&Right Side View"
-msgstr ""
+msgstr "Visão do Lado Direito (&R)"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:149
msgctxt "@action:inmenu"
@@ -3857,7 +3880,7 @@ msgstr "Administrar Materiais..."
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:177
msgctxt "@action:inmenu menubar:profile"
msgid "&Update profile with current settings/overrides"
-msgstr "&Atualizar perfil com valores e sobrepujanças atuais"
+msgstr "At&ualizar perfil com valores e sobrepujanças atuais"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:185
msgctxt "@action:inmenu menubar:profile"
@@ -3887,7 +3910,7 @@ msgstr "Relatar um &Bug"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:226
msgctxt "@action:inmenu menubar:help"
msgid "&About..."
-msgstr "S&obre..."
+msgstr "Sobre (&A)..."
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:233
msgctxt "@action:inmenu menubar:edit"
@@ -3948,17 +3971,17 @@ msgstr "&Selecionar Todos Os Modelos"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:332
msgctxt "@action:inmenu menubar:edit"
msgid "&Clear Build Plate"
-msgstr "&Esvaziar a mesa de impressão"
+msgstr "Esvaziar a Mesa de Impressão (&C)"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:342
msgctxt "@action:inmenu menubar:file"
msgid "Re&load All Models"
-msgstr "&Recarregar Todos Os Modelos"
+msgstr "Recarregar Todos Os Mode&los"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models To All Build Plates"
-msgstr ""
+msgstr "Posicionar Todos os Modelos em Todas as Plataformas de Impressão"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:358
msgctxt "@action:inmenu menubar:edit"
@@ -3983,7 +4006,7 @@ msgstr "Remover as &Transformações de Todos Os Modelos"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:387
msgctxt "@action:inmenu menubar:file"
msgid "&Open File(s)..."
-msgstr "Abrir Arquiv&os(s)..."
+msgstr "Abrir Arquiv&o(s)..."
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:395
msgctxt "@action:inmenu menubar:file"
@@ -3993,7 +4016,7 @@ msgstr "&Novo Projeto..."
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:402
msgctxt "@action:inmenu menubar:help"
msgid "Show Engine &Log..."
-msgstr "&Exibir o Registro do Motor de Fatiamento..."
+msgstr "Exibir o Registro do Motor de Fatiamento (&L)..."
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:410
msgctxt "@action:inmenu menubar:help"
@@ -4018,7 +4041,7 @@ msgstr "Complementos instalados..."
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:438
msgctxt "@action:inmenu menubar:view"
msgid "Expand/Collapse Sidebar"
-msgstr ""
+msgstr "Expandir/Encolher Barra Lateral"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:26
msgctxt "@label:PrintjobStatus"
@@ -4053,12 +4076,12 @@ msgstr "Fatiamento indisponível"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:171
msgctxt "@info:tooltip"
msgid "Slice current printjob"
-msgstr ""
+msgstr "Fatiar trabalho de impressão atual"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:171
msgctxt "@info:tooltip"
msgid "Cancel slicing process"
-msgstr ""
+msgstr "Cancelar processo de fatiamento"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:183
msgctxt "@label:Printjob"
@@ -4099,7 +4122,7 @@ msgstr "Ultimaker Cura"
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:102
msgctxt "@title:menu menubar:toplevel"
msgid "&File"
-msgstr "&Arquivo"
+msgstr "Arquivo (&F)"
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:119
msgctxt "@action:inmenu menubar:file"
@@ -4114,7 +4137,7 @@ msgstr "S&alvar Como..."
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:139
msgctxt "@title:menu menubar:file"
msgid "Save &Project..."
-msgstr ""
+msgstr "Salvar &Projeto..."
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:162
msgctxt "@title:menu menubar:toplevel"
@@ -4353,7 +4376,7 @@ msgstr "Material"
#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:352
msgctxt "@label"
msgid "Check compatibility"
-msgstr ""
+msgstr "Verificar compatibilidade"
#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:372
msgctxt "@tooltip"
@@ -4363,17 +4386,17 @@ msgstr "Clique para verificar a compatibilidade do material em Ultimaker.com."
#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:211
msgctxt "@option:check"
msgid "See only current build plate"
-msgstr ""
+msgstr "Ver somente a plataforma de impressão atual"
#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:227
msgctxt "@action:button"
msgid "Arrange to all build plates"
-msgstr ""
+msgstr "Posicionar em todas as plataformas de impressão"
#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:247
msgctxt "@action:button"
msgid "Arrange current build plate"
-msgstr ""
+msgstr "Reposicionar a plataforma de impressão atual"
#: MachineSettingsAction/plugin.json
msgctxt "description"
@@ -4468,22 +4491,22 @@ msgstr "Impressão USB"
#: PrepareStage/plugin.json
msgctxt "description"
msgid "Provides a prepare stage in Cura."
-msgstr ""
+msgstr "Provê um estágio de preparação no Cura."
#: PrepareStage/plugin.json
msgctxt "name"
msgid "Prepare Stage"
-msgstr ""
+msgstr "Estágio de Preparação"
#: CuraLiveScriptingPlugin/plugin.json
msgctxt "description"
msgid "Provides an edit window for direct script editing."
-msgstr ""
+msgstr "Provê uma janela de edição para edição direta de script."
#: CuraLiveScriptingPlugin/plugin.json
msgctxt "name"
msgid "Live scripting tool"
-msgstr ""
+msgstr "Ferramenta de scripting integrada"
#: RemovableDriveOutputDevice/plugin.json
msgctxt "description"
@@ -4508,12 +4531,12 @@ msgstr "Conexão de Rede UM3"
#: MonitorStage/plugin.json
msgctxt "description"
msgid "Provides a monitor stage in Cura."
-msgstr ""
+msgstr "Provê um estágio de monitor no Cura."
#: MonitorStage/plugin.json
msgctxt "name"
msgid "Monitor Stage"
-msgstr ""
+msgstr "Estágio de Monitor"
#: FirmwareUpdateChecker/plugin.json
msgctxt "description"
@@ -4528,7 +4551,7 @@ msgstr "Verificador de Atualizações de Firmware"
#: CuraSolidWorksPlugin/plugin.json
msgctxt "description"
msgid "Gives you the possibility to open certain files using SolidWorks itself. Conversion is done by this plugin and additional optimizations."
-msgstr ""
+msgstr "Te dá a possibilidade de abrir certos arquivos usando o SolidWorks. A conversão é feita por este plugin junto com personalizações adicionais."
#: CuraSolidWorksPlugin/plugin.json
msgctxt "name"
@@ -4598,12 +4621,12 @@ msgstr "Leitor de Perfis de Cura Legado"
#: CuraBlenderPlugin/plugin.json
msgctxt "description"
msgid "Helps to open Blender files directly in Cura."
-msgstr ""
+msgstr "Ajuda a abrir arquivos do Blender diretamente no Cura."
#: CuraBlenderPlugin/plugin.json
msgctxt "name"
msgid "Blender Integration (experimental)"
-msgstr ""
+msgstr "Integração ao Blender (experimental)"
#: GCodeProfileReader/plugin.json
msgctxt "description"
@@ -4768,12 +4791,12 @@ msgstr "Gravador de Perfis do Cura"
#: CuraPrintProfileCreator/plugin.json
msgctxt "description"
msgid "Allows material manufacturers to create new material and quality profiles using a drop-in UI."
-msgstr ""
+msgstr "Permite que fabricantes de material criem novos perfis de material e qualidade usando uma interface drop-in."
#: CuraPrintProfileCreator/plugin.json
msgctxt "name"
msgid "Print Profile Assistant"
-msgstr ""
+msgstr "Assistente de Perfil de Impressão"
#: 3MFWriter/plugin.json
msgctxt "description"
diff --git a/resources/i18n/pt_BR/fdmextruder.def.json.po b/resources/i18n/pt_BR/fdmextruder.def.json.po
index a7609a1ceb..ad86d46edc 100644
--- a/resources/i18n/pt_BR/fdmextruder.def.json.po
+++ b/resources/i18n/pt_BR/fdmextruder.def.json.po
@@ -1,11 +1,11 @@
-# Cura JSON setting files
-# Copyright (C) 2017 Ultimaker
+# Cura
+# Copyright (C) 2018 Ultimaker
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2017.
+# Ruben Dulek , 2018.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.0\n"
+"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
"POT-Creation-Date: 2017-08-02 16:53+0000\n"
"PO-Revision-Date: 2017-12-04 09:00-0300\n"
diff --git a/resources/i18n/pt_BR/fdmprinter.def.json.po b/resources/i18n/pt_BR/fdmprinter.def.json.po
index 5e2889e0e6..d42015f67c 100644
--- a/resources/i18n/pt_BR/fdmprinter.def.json.po
+++ b/resources/i18n/pt_BR/fdmprinter.def.json.po
@@ -1,14 +1,14 @@
-# Cura JSON setting files
-# Copyright (C) 2017 Ultimaker
+# Cura
+# Copyright (C) 2018 Ultimaker
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2017.
+# Ruben Dulek , 2018.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.0\n"
+"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2017-08-02 16:53+0000\n"
-"PO-Revision-Date: 2017-12-04 10:20-0300\n"
+"POT-Creation-Date: 2018-01-29 09:48+0000\n"
+"PO-Revision-Date: 2018-02-13 02:20-0300\n"
"Last-Translator: Cláudio Sampaio \n"
"Language-Team: Cláudio Sampaio and CoderSquirrel \n"
"Language: pt_BR\n"
@@ -353,12 +353,12 @@ msgstr "Repetier"
#: fdmprinter.def.json
msgctxt "machine_firmware_retract label"
msgid "Firmware Retraction"
-msgstr ""
+msgstr "Retração de Firmware"
#: fdmprinter.def.json
msgctxt "machine_firmware_retract description"
msgid "Whether to use firmware retract commands (G10/G11) instead of using the E property in G1 commands to retract the material."
-msgstr ""
+msgstr "Usar ou não comandos de retração de firmware (G10/G11) ao invés de usar a propriedade E dos comandos G1 para retrair o material."
#: fdmprinter.def.json
msgctxt "machine_disallowed_areas label"
@@ -1053,12 +1053,12 @@ msgstr "Em todos os lugares"
#: fdmprinter.def.json
msgctxt "filter_out_tiny_gaps label"
msgid "Filter Out Tiny Gaps"
-msgstr ""
+msgstr "Filtrar Pequenas Lacunas"
#: fdmprinter.def.json
msgctxt "filter_out_tiny_gaps description"
msgid "Filter out tiny gaps to reduce blobs on outside of model."
-msgstr ""
+msgstr "Filtrar (rempver) pequenas lacunas para reduzir bolhas no exterior do modelo."
#: fdmprinter.def.json
msgctxt "fill_outline_gaps label"
@@ -1443,7 +1443,7 @@ msgstr "Deslocamento X do Preenchimento"
#: fdmprinter.def.json
msgctxt "infill_offset_x description"
msgid "The infill pattern is moved this distance along the X axis."
-msgstr ""
+msgstr "O padrão de preenchimento é movido por esta distância no eixo X."
#: fdmprinter.def.json
msgctxt "infill_offset_y label"
@@ -1453,7 +1453,7 @@ msgstr "Deslocamento do Preenchimento Y"
#: fdmprinter.def.json
msgctxt "infill_offset_y description"
msgid "The infill pattern is moved this distance along the Y axis."
-msgstr ""
+msgstr "O padrão de preenchimento é movido por esta distância no eixo Y."
#: fdmprinter.def.json
msgctxt "sub_div_rad_add label"
@@ -1473,7 +1473,7 @@ msgstr "Porcentagem de Sobreposição do Preenchimento"
#: fdmprinter.def.json
msgctxt "infill_overlap description"
msgid "The amount of overlap between the infill and the walls as a percentage of the infill line width. A slight overlap allows the walls to connect firmly to the infill."
-msgstr ""
+msgstr "A quantidade de sobreposição entre o preenchimento e as paredes como uma porcentagem da largura de extrusão de preenchimento. Uma leve sobreposição permite que as paredes se conectem firmemente ao preenchimento."
#: fdmprinter.def.json
msgctxt "infill_overlap_mm label"
@@ -1483,7 +1483,7 @@ msgstr "Sobreposição de Preenchimento"
#: fdmprinter.def.json
msgctxt "infill_overlap_mm description"
msgid "The amount of overlap between the infill and the walls. A slight overlap allows the walls to connect firmly to the infill."
-msgstr "Medida de sobreposição entre o preenchimento e as paredes. Uma leve sobreposição permite que as paredes fiquem firememente aderidas ao preenchimento."
+msgstr "A quantidade de sobreposição entre o preenchimento e as paredes. Uma leve sobreposição permite que as paredes se conectem firmemente ao preenchimento."
#: fdmprinter.def.json
msgctxt "skin_overlap label"
@@ -1493,7 +1493,7 @@ msgstr "Porcentagem de Sobreposição do Contorno"
#: fdmprinter.def.json
msgctxt "skin_overlap description"
msgid "The amount of overlap between the skin and the walls as a percentage of the skin line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall."
-msgstr ""
+msgstr "A quantidade de sobreposição entre o contorno e as paredes como uma porcentagem da largura de extrusão do contorno. Uma leve sobreposição permite que as paredes se conectem firmemente ao contorno. É uma porcentagem das larguras de extrusão médias das linhas de contorno e a parede mais interna."
#: fdmprinter.def.json
msgctxt "skin_overlap_mm label"
@@ -1503,7 +1503,7 @@ msgstr "Sobreposição do Contorno"
#: fdmprinter.def.json
msgctxt "skin_overlap_mm description"
msgid "The amount of overlap between the skin and the walls. A slight overlap allows the walls to connect firmly to the skin."
-msgstr "Medida de sobreposição entre o contorno e as paredes. Uma ligeira sobreposição permite às paredes ficarem firmemente aderidas ao contorno."
+msgstr "A quantidade de sobreposição entre o contorno e as paredes. Uma leve sobreposição permite às paredes ficarem firmemente aderidas ao contorno."
#: fdmprinter.def.json
msgctxt "infill_wipe_dist label"
@@ -1723,7 +1723,7 @@ msgstr "Temperatura da Mesa de Impressão"
#: fdmprinter.def.json
msgctxt "material_bed_temperature description"
msgid "The temperature used for the heated build plate. If this is 0, the bed temperature will not be adjusted."
-msgstr ""
+msgstr "A temperatura usada para a plataforma de impressão aquecida. Se for 0, a temperatura da mesa não será ajustada."
#: fdmprinter.def.json
msgctxt "material_bed_temperature_layer_0 label"
@@ -4267,82 +4267,82 @@ msgstr "experimental!"
#: fdmprinter.def.json
msgctxt "support_tree_enable label"
msgid "Tree Support"
-msgstr ""
+msgstr "Suporte de Árvore"
#: fdmprinter.def.json
msgctxt "support_tree_enable description"
msgid "Generate a tree-like support with branches that support your print. This may reduce material usage and print time, but greatly increases slicing time."
-msgstr ""
+msgstr "Gera um suporte em árvore com galhos que apóiam sua impressão. Isto pode reduzir uso de material e tempo de impressão, mas aumenta bastante o tempo de fatiamento."
#: fdmprinter.def.json
msgctxt "support_tree_angle label"
msgid "Tree Support Branch Angle"
-msgstr ""
+msgstr "Ângulo do Galho do Suporte em Árvore"
#: fdmprinter.def.json
msgctxt "support_tree_angle description"
msgid "The angle of the branches. Use a lower angle to make them more vertical and more stable. Use a higher angle to be able to have more reach."
-msgstr ""
+msgstr "Ô angulo dos galhos. Use um ângulo menor para torná-los mais verticais e mais estáveis. Use um ângulo maior para aumentar o alcance."
#: fdmprinter.def.json
msgctxt "support_tree_branch_distance label"
msgid "Tree Support Branch Distance"
-msgstr ""
+msgstr "Distância dos Galhos do Suporte em Árvore"
#: fdmprinter.def.json
msgctxt "support_tree_branch_distance description"
msgid "How far apart the branches need to be when they touch the model. Making this distance small will cause the tree support to touch the model at more points, causing better overhang but making support harder to remove."
-msgstr ""
+msgstr "Quão distantes os galhos precisam estar quando tocam o modelo. Tornar esta distância pequena fará com que o suporte em árvore toque o modelo em mais pontos, permitindo maior sustentação mas tornando o suporte mais difícil de remover."
#: fdmprinter.def.json
msgctxt "support_tree_branch_diameter label"
msgid "Tree Support Branch Diameter"
-msgstr ""
+msgstr "Diâmetro de Galho do Suporte em Árvore"
#: fdmprinter.def.json
msgctxt "support_tree_branch_diameter description"
msgid "The diameter of the thinnest branches of tree support. Thicker branches are more sturdy. Branches towards the base will be thicker than this."
-msgstr ""
+msgstr "O diâmetro dos galhos mais finos do suporte em árvore. Galhos mais grossos são mais resistentes. Galhos na direção da base serão mais grossos que essa medida."
#: fdmprinter.def.json
msgctxt "support_tree_branch_diameter_angle label"
msgid "Tree Support Branch Diameter Angle"
-msgstr ""
+msgstr "Ângulo do Diâmetro do Galho do Suporte em Árvore"
#: fdmprinter.def.json
msgctxt "support_tree_branch_diameter_angle description"
msgid "The angle of the branches' diameter as they gradually become thicker towards the bottom. An angle of 0 will cause the branches to have uniform thickness over their length. A bit of an angle can increase stability of the tree support."
-msgstr ""
+msgstr "O ângulo do diâmetro dos galhos enquanto se tornam gradualmente mais grossos na direção da base. Um ângulo de 0 fará com que os galhos tenham grossura uniforme no seu comrpimento. Um ângulo levemente maior que zero pode aumentar a estabilidade do suporte em árvore."
#: fdmprinter.def.json
msgctxt "support_tree_collision_resolution label"
msgid "Tree Support Collision Resolution"
-msgstr ""
+msgstr "Resolução de Colisão do Suporte em Árvore"
#: fdmprinter.def.json
msgctxt "support_tree_collision_resolution description"
msgid "Resolution to compute collisions with to avoid hitting the model. Setting this lower will produce more accurate trees that fail less often, but increases slicing time dramatically."
-msgstr ""
+msgstr "Resolução para computar colisões com a qual evitar tocar o modelo. Ajustar valor mais baixos produzirá árvore mais precisas que falharão menos, mas aumentará o tempo de fatiamento dramaticamente."
#: fdmprinter.def.json
msgctxt "support_tree_wall_thickness label"
msgid "Tree Support Wall Thickness"
-msgstr ""
+msgstr "Espessura de Parede do Suporte em Árvore"
#: fdmprinter.def.json
msgctxt "support_tree_wall_thickness description"
msgid "The thickness of the walls of the branches of tree support. Thicker walls take longer to print but don't fall over as easily."
-msgstr ""
+msgstr "A espessura das paredes dos galhos do suporte em árvore. Paredes mais espessas tomarão mais tempo pra imprimir mas não tombarão facilmente."
#: fdmprinter.def.json
msgctxt "support_tree_wall_count label"
msgid "Tree Support Wall Line Count"
-msgstr ""
+msgstr "Número de Filetes da Parede do Suporte em Árvore"
#: fdmprinter.def.json
msgctxt "support_tree_wall_count description"
msgid "The number of walls of the branches of tree support. Thicker walls take longer to print but don't fall over as easily."
-msgstr ""
+msgstr "O número de filetes da parede dos galhos do suporte em árvore. Paredes mais espessas tomarão mais tempo pra imprimir mas não tombarão facilmente."
#: fdmprinter.def.json
msgctxt "slicing_tolerance label"
@@ -4417,12 +4417,12 @@ msgstr "Uma lista de direções inteiras de filete a usar quando as camadas supe
#: fdmprinter.def.json
msgctxt "infill_enable_travel_optimization label"
msgid "Infill Travel Optimization"
-msgstr ""
+msgstr "Otimização de Percurso de Preenchimento"
#: fdmprinter.def.json
msgctxt "infill_enable_travel_optimization description"
msgid "When enabled, the order in which the infill lines are printed is optimized to reduce the distance travelled. The reduction in travel time achieved very much depends on the model being sliced, infill pattern, density, etc. Note that, for some models that have many small areas of infill, the time to slice the model may be greatly increased."
-msgstr ""
+msgstr "Quando habilitado, a ordem em que os filetes de preenchimento são impressos é otimizada para reduzir a distância percorrida. A redução em tempo de percurso conseguida depende bastante do modelo sendo fatiado, do padrão de preenchimento, da densidade, etc. Note que, para alguns modelos que têm áreas bem pequenas de preenchimento, o tempo de fatiamento pode ser aumentado bastante."
#: fdmprinter.def.json
msgctxt "material_flow_dependent_temperature label"
@@ -5056,42 +5056,42 @@ msgstr "Distância entre o bico e os filetes descendentes horizontais. Espaços
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_enabled label"
msgid "Use adaptive layers"
-msgstr ""
+msgstr "Usar camadas adaptativas"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_enabled description"
msgid "Adaptive layers computes the layer heights depending on the shape of the model."
-msgstr ""
+msgstr "Camadas adaptativas fazem a computação das alturas de camada depender da forma do modelo."
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation label"
msgid "Adaptive layers maximum variation"
-msgstr ""
+msgstr "Variação máxima das camadas adaptativas"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation description"
msgid "The maximum allowed height different from the base layer height in mm."
-msgstr ""
+msgstr "A dferença de altura máxima permitida da altura de camada base permitida, em mm."
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation_step label"
msgid "Adaptive layers variation step size"
-msgstr ""
+msgstr "Tamanho de passo da variaçã das camadas adaptativas"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation_step description"
msgid "The difference in height of the next layer height compared to the previous one."
-msgstr ""
+msgstr "A diferença em tamanho da próxima camada comparada à anterior."
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold label"
msgid "Adaptive layers threshold"
-msgstr ""
+msgstr "Limite das camadas adaptativas"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold description"
msgid "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer."
-msgstr ""
+msgstr "Limite até onde se usa uma camada menor ou não. Este número é comparado à tangente da ladeira mais vertical da camada."
#: fdmprinter.def.json
msgctxt "command_line_settings label"
diff --git a/resources/i18n/zh_TW/cura.po b/resources/i18n/zh_TW/cura.po
index b884b13a19..0a1c5e9294 100644
--- a/resources/i18n/zh_TW/cura.po
+++ b/resources/i18n/zh_TW/cura.po
@@ -1,22 +1,22 @@
# Cura
-# Copyright (C) 2017 Ultimaker
+# Copyright (C) 2018 Ultimaker
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2017.
+# Ruben Dulek , 2018.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.1\n"
+"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2017-08-02 16:53+0000\n"
-"PO-Revision-Date: 2017-11-28 23:48+0800\n"
+"POT-Creation-Date: 2018-01-29 16:53+0000\n"
+"PO-Revision-Date: 2018-02-04 11:18+0800\n"
"Last-Translator: Zhang Heh Ji \n"
-"Language-Team: TEAM\n"
+"Language-Team: Zhang Heh Ji \n"
"Language: zh_TW\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
-"X-Generator: Poedit 2.0.4\n"
+"X-Generator: Poedit 2.0.6\n"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.py:26
msgctxt "@action"
@@ -189,7 +189,7 @@ msgstr "印表機韌體"
#: /home/ruben/Projects/Cura/plugins/PrepareStage/__init__.py:12
msgctxt "@item:inmenu"
msgid "Prepare"
-msgstr ""
+msgstr "準備"
#: /home/ruben/Projects/Cura/plugins/RemovableDriveOutputDevice/RemovableDriveOutputDevice.py:23
msgctxt "@action:button Preceded by 'Ready to'."
@@ -562,7 +562,7 @@ msgstr "使用瀏覽器開啟列印作業介面。"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:239
msgctxt "@label Printer name"
msgid "Unknown"
-msgstr ""
+msgstr "未知"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/NetworkClusterPrinterOutputDevice.py:505
#, python-brace-format
@@ -597,7 +597,7 @@ msgstr "透過網路連接"
#: /home/ruben/Projects/Cura/plugins/MonitorStage/__init__.py:12
msgctxt "@item:inmenu"
msgid "Monitor"
-msgstr ""
+msgstr "監控"
#: /home/ruben/Projects/Cura/plugins/FirmwareUpdateChecker/FirmwareUpdateCheckerJob.py:66
#, python-brace-format
@@ -624,7 +624,7 @@ msgstr "無法存取更新資訊。"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksReader.py:579
msgctxt "@info:status"
msgid "SolidWorks reported errors, while opening your file. We recommend to solve these issues inside SolidWorks itself."
-msgstr ""
+msgstr "SolidWorks 在開啟檔案時回報了錯誤。建議在 SolidWorks 內部解決這些問題。"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksReader.py:591
msgctxt "@info:status"
@@ -633,6 +633,9 @@ msgid ""
"\n"
" Thanks!."
msgstr ""
+"在你的繪圖找不到模型。請你再次檢查它的內容並確認裡面有一個零件或組件。\n"
+"\n"
+"謝謝。"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksReader.py:595
msgctxt "@info:status"
@@ -641,6 +644,9 @@ msgid ""
"\n"
"Sorry!"
msgstr ""
+"在你的繪圖找到了超過一個的零件或組件。我們目前只支援一個零件或組件的繪圖。\n"
+"\n"
+"抱歉!"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:25
msgctxt "@item:inlistbox"
@@ -655,7 +661,7 @@ msgstr "SolidWorks 組件檔案"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:33
msgctxt "@item:inlistbox"
msgid "SolidWorks drawing file"
-msgstr ""
+msgstr "SolidWorks 繪圖檔案"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:48
msgctxt "@info:status"
@@ -666,6 +672,11 @@ msgid ""
"With kind regards\n"
" - Thomas Karl Pietrowski"
msgstr ""
+"親愛的客戶,\n"
+"我們無法在您的系統上找到有效安裝的 SolidWorks。這表示未安裝 SolidWorks,或者您沒有擁有有效的授權。請確認 SolidWorks 本身是可以正常執行的,或是聯絡您的技術部門處理。\n"
+"\n"
+"順頌 時祺\n"
+" - Thomas Karl Pietrowski"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/__init__.py:57
msgctxt "@info:status"
@@ -676,6 +687,11 @@ msgid ""
"With kind regards\n"
" - Thomas Karl Pietrowski"
msgstr ""
+"親愛的客戶,\n"
+"您目前正在 Windows 以外的作業系統上執行此外掛。此外掛只能在有安裝有效授權 SolidWorks 的 Windows 上執行。請在有安裝 SolidWorks 的 windows 電腦上安裝此外掛。\n"
+"\n"
+"順頌 時祺\n"
+" - Thomas Karl Pietrowski"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksDialogHandler.py:70
msgid "Configure"
@@ -683,7 +699,7 @@ msgstr "設定"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksDialogHandler.py:71
msgid "Installation guide for SolidWorks macro"
-msgstr ""
+msgstr "SolidWorks 巨集的安裝指南"
# Added manually to fix a string that was changed after string freeze.
#: /home/ruben/Projects/Cura/plugins/SimulationView/__init__.py:14
@@ -708,7 +724,7 @@ msgstr "修改 G-Code 檔案"
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:43
msgctxt "@info"
msgid "Cura collects anonymized usage statistics."
-msgstr ""
+msgstr "Cura 以匿名方式蒐集使用狀況統計資料。"
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:46
msgctxt "@info:title"
@@ -718,22 +734,22 @@ msgstr "收集資料中"
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:48
msgctxt "@action:button"
msgid "Allow"
-msgstr ""
+msgstr "允許"
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:49
msgctxt "@action:tooltip"
msgid "Allow Cura to send anonymized usage statistics to help prioritize future improvements to Cura. Some of your preferences and settings are sent, the Cura version and a hash of the models you're slicing."
-msgstr ""
+msgstr "允許 Cura 以匿名方式傳送使用狀況統計資料,用來協助 Cura 的未來改善工作。你的部份偏好設定和參數,Cura 的版本及你切片模型的雜湊值會被傳送。"
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:50
msgctxt "@action:button"
msgid "Disable"
-msgstr ""
+msgstr "關閉"
#: /home/ruben/Projects/Cura/plugins/SliceInfoPlugin/SliceInfo.py:51
msgctxt "@action:tooltip"
msgid "Don't allow Cura to send anonymized usage statistics. You can enable it again in the preferences."
-msgstr ""
+msgstr "不允許 Cura 傳送匿名的使用狀況統計資料。你可以在偏好設定中再次啟用此功能。"
#: /home/ruben/Projects/Cura/plugins/LegacyProfileReader/__init__.py:14
msgctxt "@item:inlistbox"
@@ -743,7 +759,7 @@ msgstr "Cura 15.04 列印參數"
#: /home/ruben/Projects/Cura/plugins/CuraBlenderPlugin/__init__.py:15
msgctxt "@item:inlistbox"
msgid "Blender file"
-msgstr ""
+msgstr "Blender 檔案"
#: /home/ruben/Projects/Cura/plugins/CuraBlenderPlugin/CadIntegrationUtils/CommonReader.py:199
msgctxt "@info:status"
@@ -751,6 +767,8 @@ msgid ""
"Could not export using \"{}\" quality!\n"
"Felt back to \"{}\"."
msgstr ""
+"無法使用 \"{}\" 品質導出!\n"
+"覆蓋回 \"{}\"。"
#: /home/ruben/Projects/Cura/plugins/GCodeProfileReader/__init__.py:14
#: /home/ruben/Projects/Cura/plugins/GCodeReader/__init__.py:14
@@ -937,12 +955,12 @@ msgstr "Cura 列印參數"
#: /home/ruben/Projects/Cura/plugins/CuraPrintProfileCreator/__init__.py:12
msgctxt "@item:inmenu"
msgid "Profile Assistant"
-msgstr ""
+msgstr "參數助手"
#: /home/ruben/Projects/Cura/plugins/CuraPrintProfileCreator/__init__.py:17
msgctxt "@item:inlistbox"
msgid "Profile Assistant"
-msgstr ""
+msgstr "參數助手"
#: /home/ruben/Projects/Cura/plugins/3MFWriter/__init__.py:30
msgctxt "@item:inlistbox"
@@ -1140,13 +1158,13 @@ msgstr "無法從 {0} 匯入列印參數:{1} or !"
msgid "This profile {0} contains incorrect data, could not import it."
-msgstr ""
+msgstr "此列印參數 {0} 含有錯誤的資料,無法導入。"
#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:240
#, python-brace-format
msgctxt "@info:status Don't translate the XML tags or !"
msgid "The machine defined in profile {0} doesn't match with your current machine, could not import it."
-msgstr ""
+msgstr "列印參數 {0} 中的機器設定與你目前的機器不相符,無法導入。"
#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:274
#, python-brace-format
@@ -1158,7 +1176,7 @@ msgstr "已成功匯入列印參數 {0}"
#, python-brace-format
msgctxt "@info:status"
msgid "File {0} does not contain any valid profile."
-msgstr ""
+msgstr "檔案 {0} 內未含有效的列印參數。"
#: /home/ruben/Projects/Cura/cura/Settings/CuraContainerRegistry.py:280
#, python-brace-format
@@ -1186,7 +1204,7 @@ msgstr "無法為目前設定找到品質類型 {0}。"
#, python-brace-format
msgctxt "@label"
msgid "Group #{group_nr}"
-msgstr ""
+msgstr "群組 #{group_nr}"
#: /home/ruben/Projects/Cura/cura/BuildVolume.py:100
msgctxt "@info:status"
@@ -1246,6 +1264,9 @@ msgid ""
" Please use the \"Send report\" button to post a bug report automatically to our servers
\n"
" "
msgstr ""
+"發生致命錯誤。請將錯誤報告傳送給我們以便修正此問題。
\n"
+" 請使用\"送出報告\"按鈕自動發送一份問題報告給我們的伺服器
\n"
+" "
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:102
msgctxt "@title:groupbox"
@@ -1260,32 +1281,32 @@ msgstr "未知"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:112
msgctxt "@label Cura version number"
msgid "Cura version"
-msgstr ""
+msgstr "Cura 版本"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:113
msgctxt "@label Type of platform"
msgid "Platform"
-msgstr ""
+msgstr "平台"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:114
msgctxt "@label"
msgid "Qt version"
-msgstr ""
+msgstr "Qt 版本"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:115
msgctxt "@label"
msgid "PyQt version"
-msgstr ""
+msgstr "PyQt 版本"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:116
msgctxt "@label OpenGL version"
msgid "OpenGL"
-msgstr ""
+msgstr "OpenGL"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:133
msgctxt "@label"
msgid "not yet initialised
"
-msgstr ""
+msgstr "尚未初始化
"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:136
#, python-brace-format
@@ -1308,7 +1329,7 @@ msgstr "- OpenGL 渲染器:{renderer}
"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:147
msgctxt "@title:groupbox"
msgid "Error traceback"
-msgstr ""
+msgstr "錯誤追溯"
#: /home/ruben/Projects/Cura/cura/CrashHandler.py:214
msgctxt "@title:groupbox"
@@ -1519,7 +1540,7 @@ msgstr "噴頭孔徑"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:393
msgctxt "@label"
msgid "Compatible material diameter"
-msgstr ""
+msgstr "相容的耗材直徑"
#: /home/ruben/Projects/Cura/plugins/MachineSettingsAction/MachineSettingsAction.qml:395
msgctxt "@tooltip"
@@ -1664,12 +1685,12 @@ msgstr "類型"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:233
msgctxt "@label Printer name"
msgid "Ultimaker 3"
-msgstr ""
+msgstr "Ultimaker 3"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:236
msgctxt "@label Printer name"
msgid "Ultimaker 3 Extended"
-msgstr ""
+msgstr "Ultimaker 3 Extended"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/DiscoverUM3Action.qml:252
msgctxt "@label"
@@ -1736,7 +1757,7 @@ msgstr "%1 未設定成管理一組連線的 Ultimaker 3 印表機的主機"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/ClusterMonitorItem.qml:55
msgctxt "@label link to connect manager"
msgid "Add/Remove printers"
-msgstr ""
+msgstr "新增/移除印表機"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/OpenPanelButton.qml:14
msgctxt "@info:tooltip"
@@ -1776,7 +1797,7 @@ msgstr "與印表機的連接中斷"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml:47
msgctxt "@label Printer status"
msgid "Unknown"
-msgstr ""
+msgstr "未知"
#: /home/ruben/Projects/Cura/plugins/UM3NetworkPrinting/PrinterInfoBlock.qml:257
msgctxt "@label:status"
@@ -1872,62 +1893,62 @@ msgstr "啟用設定"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:21
msgctxt "@title:window"
msgid "SolidWorks: Export wizard"
-msgstr ""
+msgstr "SolidWorks: 導出精靈"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:45
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:140
msgctxt "@action:label"
msgid "Quality:"
-msgstr ""
+msgstr "品質:"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:78
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:179
msgctxt "@option:curaSolidworksStlQuality"
msgid "Fine (3D-printing)"
-msgstr ""
+msgstr "精細 (3D-printing)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:79
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:180
msgctxt "@option:curaSolidworksStlQuality"
msgid "Coarse (3D-printing)"
-msgstr ""
+msgstr "粗糙 (3D-printing)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:80
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:181
msgctxt "@option:curaSolidworksStlQuality"
msgid "Fine (SolidWorks)"
-msgstr ""
+msgstr "精細 (SolidWorks)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:81
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:182
msgctxt "@option:curaSolidworksStlQuality"
msgid "Coarse (SolidWorks)"
-msgstr ""
+msgstr "粗糙 (SolidWorks)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:94
msgctxt "@text:window"
msgid "Show this dialog again"
-msgstr ""
+msgstr "再次顯示這個對話框"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:104
msgctxt "@action:button"
msgid "Continue"
-msgstr ""
+msgstr "繼續"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksWizard.qml:116
msgctxt "@action:button"
msgid "Abort"
-msgstr ""
+msgstr "取消"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:21
msgctxt "@title:window"
msgid "How to install Cura SolidWorks macro"
-msgstr ""
+msgstr "如何安裝 Cura SolidWorks 巨集"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:62
msgctxt "@description:label"
msgid "Steps:"
-msgstr ""
+msgstr "步驟:"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:140
msgctxt "@action:button"
@@ -1935,101 +1956,103 @@ msgid ""
"Open the directory\n"
"with macro and icon"
msgstr ""
+"使用巨集和圖示\n"
+"開啟目錄"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:160
msgctxt "@description:label"
msgid "Instructions:"
-msgstr ""
+msgstr "操作說明:"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:202
msgctxt "@action:playpause"
msgid "Play"
-msgstr ""
+msgstr "播放"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:206
msgctxt "@action:playpause"
msgid "Pause"
-msgstr ""
+msgstr "暫停"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:268
msgctxt "@action:button"
msgid "Previous Step"
-msgstr ""
+msgstr "前一步"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:283
msgctxt "@action:button"
msgid "Done"
-msgstr ""
+msgstr "完成"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksMacroTutorial.qml:287
msgctxt "@action:button"
msgid "Next Step"
-msgstr ""
+msgstr "下一步"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:21
msgctxt "@title:window"
msgid "SolidWorks plugin: Configuration"
-msgstr ""
+msgstr "SolidWorks 外掛:設定"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:39
msgctxt "@title:tab"
msgid "Conversion settings"
-msgstr ""
+msgstr "轉換設定"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:66
msgctxt "@label"
msgid "First choice:"
-msgstr ""
+msgstr "第一選擇:"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:86
msgctxt "@text:menu"
msgid "Latest installed version (Recommended)"
-msgstr ""
+msgstr "最新安裝的版本(建議)"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:95
msgctxt "@text:menu"
msgid "Default version"
-msgstr ""
+msgstr "預設的版本"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:193
msgctxt "@label"
msgid "Show wizard before opening SolidWorks files"
-msgstr ""
+msgstr "開啟 SolidWorks 檔案時顯示精靈"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:203
msgctxt "@label"
msgid "Automatically rotate opened file into normed orientation"
-msgstr ""
+msgstr "自動將開啟的檔案旋轉到正常方向"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:210
msgctxt "@title:tab"
msgid "Installation(s)"
-msgstr ""
+msgstr "安裝"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:284
msgctxt "@label"
msgid "COM service found"
-msgstr ""
+msgstr "找到 COM 服務"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:295
msgctxt "@label"
msgid "Executable found"
-msgstr ""
+msgstr "找到可執行檔案"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:306
msgctxt "@label"
msgid "COM starting"
-msgstr ""
+msgstr "COM 啟動中"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:317
msgctxt "@label"
msgid "Revision number"
-msgstr ""
+msgstr "版本號碼"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:328
msgctxt "@label"
msgid "Functions available"
-msgstr ""
+msgstr "可用功能"
#: /home/ruben/Projects/Cura/plugins/CuraSolidWorksPlugin/SolidWorksConfiguration.qml:341
#: /home/ruben/Projects/Cura/resources/qml/WorkspaceSummaryDialog.qml:264
@@ -2215,32 +2238,32 @@ msgstr "平滑"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:38
msgctxt "@label"
msgid "Mesh Type"
-msgstr ""
+msgstr "網格類型"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:69
msgctxt "@label"
msgid "Normal model"
-msgstr ""
+msgstr "普通模型"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:76
msgctxt "@label"
msgid "Print as support"
-msgstr ""
+msgstr "做為支撐"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:84
msgctxt "@label"
msgid "Don't support overlap with other models"
-msgstr ""
+msgstr "不支援與其他模型重疊"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:92
msgctxt "@label"
msgid "Modify settings for overlap with other models"
-msgstr ""
+msgstr "修改其他模型的重疊設定"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:100
msgctxt "@label"
msgid "Modify settings for infill of other models"
-msgstr ""
+msgstr "修改其他模型的填充設定"
#: /home/ruben/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:333
msgctxt "@action:button"
@@ -2742,7 +2765,7 @@ msgstr "保留"
#: /home/ruben/Projects/Cura/resources/qml/DiscardOrKeepProfileChangesDialog.qml:222
msgctxt "@action:button"
msgid "Create New Profile"
-msgstr "創建新的列印參數"
+msgstr "建立新的列印參數"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialView.qml:44
msgctxt "@title"
@@ -3098,27 +3121,27 @@ msgstr "(匿名)發送列印資訊"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:674
msgctxt "@label"
msgid "Experimental"
-msgstr ""
+msgstr "實驗功能"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:680
msgctxt "@info:tooltip"
msgid "Use multi build plate functionality"
-msgstr ""
+msgstr "使用多列印平台功能"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:685
msgctxt "@option:check"
msgid "Use multi build plate functionality (restart required)"
-msgstr ""
+msgstr "使用多列印平台功能(需重啟軟體)"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:694
msgctxt "@info:tooltip"
msgid "Should newly loaded models be arranged on the build plate? Used in conjunction with multi build plate (EXPERIMENTAL)"
-msgstr ""
+msgstr "新載入的模型要擺放在列印平台上嗎?必需與多列印平台功能一起使用(實驗功能)"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/GeneralPage.qml:699
msgctxt "@option:check"
msgid "Do not arrange objects on load"
-msgstr ""
+msgstr "載入時不要擺放物件"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MachinesPage.qml:15
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:514
@@ -3189,7 +3212,7 @@ msgstr "自訂列印參數"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:64
msgctxt "@label"
msgid "Create"
-msgstr "創建"
+msgstr "建立"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:80
msgctxt "@label"
@@ -3246,7 +3269,7 @@ msgstr "重命名列印參數"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:271
msgctxt "@title:window"
msgid "Create Profile"
-msgstr "創建列印參數"
+msgstr "建立列印參數"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/ProfilesPage.qml:285
msgctxt "@title:window"
@@ -3287,7 +3310,7 @@ msgstr "印表機:%1"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:150
msgctxt "@action:button"
msgid "Create"
-msgstr "創建"
+msgstr "建立"
#: /home/ruben/Projects/Cura/resources/qml/Preferences/MaterialsPage.qml:160
msgctxt "@action:button"
@@ -3531,7 +3554,7 @@ msgstr "影響因素"
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:156
msgctxt "@label"
msgid "This setting is always shared between all extruders. Changing it here will change the value for all extruders."
-msgstr ""
+msgstr "這個設定是所有擠出機共用的。修改它會同時更動到所有擠出機的值。"
#: /home/ruben/Projects/Cura/resources/qml/Settings/SettingItem.qml:159
msgctxt "@label"
@@ -3582,7 +3605,7 @@ msgstr "00 小時 00 分"
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:359
msgctxt "@tooltip"
msgid "Time specification"
-msgstr ""
+msgstr "時間規格"
#: /home/ruben/Projects/Cura/resources/qml/Sidebar.qml:441
msgctxt "@label"
@@ -3639,12 +3662,12 @@ msgstr "檢視(&V)"
#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:37
msgctxt "@action:inmenu menubar:view"
msgid "&Camera position"
-msgstr ""
+msgstr "視角位置(&C)"
#: /home/ruben/Projects/Cura/resources/qml/Menus/ViewMenu.qml:52
msgctxt "@action:inmenu menubar:view"
msgid "&Build plate"
-msgstr ""
+msgstr "列印平台(&B)"
#: /home/ruben/Projects/Cura/resources/qml/Menus/NozzleMenu.qml:40
msgctxt "@title:menuitem %1 is the nozzle currently loaded in the printer"
@@ -3812,27 +3835,27 @@ msgstr "退出(&Q)"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:114
msgctxt "@action:inmenu menubar:view"
msgid "&3D View"
-msgstr ""
+msgstr "立體圖(&3)"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:121
msgctxt "@action:inmenu menubar:view"
msgid "&Front View"
-msgstr ""
+msgstr "前視圖(&F)"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:128
msgctxt "@action:inmenu menubar:view"
msgid "&Top View"
-msgstr ""
+msgstr "上視圖(&T)"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:135
msgctxt "@action:inmenu menubar:view"
msgid "&Left Side View"
-msgstr ""
+msgstr "左視圖(&L)"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:142
msgctxt "@action:inmenu menubar:view"
msgid "&Right Side View"
-msgstr ""
+msgstr "右視圖(&R)"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:149
msgctxt "@action:inmenu"
@@ -3867,7 +3890,7 @@ msgstr "捨棄目前更改(&D)"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:197
msgctxt "@action:inmenu menubar:profile"
msgid "&Create profile from current settings/overrides..."
-msgstr "從目前設定 / 覆寫值創建列印參數(&C)…"
+msgstr "從目前設定 / 覆寫值建立列印參數(&C)…"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:203
msgctxt "@action:inmenu menubar:profile"
@@ -3955,17 +3978,17 @@ msgstr "重新載入所有模型(&L)"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:351
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models To All Build Plates"
-msgstr ""
+msgstr "將所有模型排列到所有列印平台上"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:358
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange All Models"
-msgstr "編位所有的模型"
+msgstr "排列所有模型"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:366
msgctxt "@action:inmenu menubar:edit"
msgid "Arrange Selection"
-msgstr "為所選模型編位"
+msgstr "排列所選模型"
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:373
msgctxt "@action:inmenu menubar:edit"
@@ -4015,7 +4038,7 @@ msgstr "安裝外掛..."
#: /home/ruben/Projects/Cura/resources/qml/Actions.qml:438
msgctxt "@action:inmenu menubar:view"
msgid "Expand/Collapse Sidebar"
-msgstr ""
+msgstr "展開/收合側邊欄"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:26
msgctxt "@label:PrintjobStatus"
@@ -4050,12 +4073,12 @@ msgstr "切片無法使用"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:171
msgctxt "@info:tooltip"
msgid "Slice current printjob"
-msgstr ""
+msgstr "對目前列印工作進行切片"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:171
msgctxt "@info:tooltip"
msgid "Cancel slicing process"
-msgstr ""
+msgstr "取消進行中的切片程序"
#: /home/ruben/Projects/Cura/resources/qml/SaveButton.qml:183
msgctxt "@label:Printjob"
@@ -4111,7 +4134,7 @@ msgstr "另存為(&A)…"
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:139
msgctxt "@title:menu menubar:file"
msgid "Save &Project..."
-msgstr ""
+msgstr "儲存專案...(&P)"
#: /home/ruben/Projects/Cura/resources/qml/Cura.qml:162
msgctxt "@title:menu menubar:toplevel"
@@ -4349,7 +4372,7 @@ msgstr "耗材"
#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:352
msgctxt "@label"
msgid "Check compatibility"
-msgstr ""
+msgstr "檢查相容性"
#: /home/ruben/Projects/Cura/resources/qml/SidebarHeader.qml:372
msgctxt "@tooltip"
@@ -4359,17 +4382,17 @@ msgstr "點擊查看 Ultimaker.com 上的耗材相容性。"
#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:211
msgctxt "@option:check"
msgid "See only current build plate"
-msgstr ""
+msgstr "只顯示目前的列印平台"
#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:227
msgctxt "@action:button"
msgid "Arrange to all build plates"
-msgstr ""
+msgstr "擺放到所有的列印平台"
#: /home/ruben/Projects/Cura/resources/qml/ObjectsList.qml:247
msgctxt "@action:button"
msgid "Arrange current build plate"
-msgstr ""
+msgstr "擺放到目前的列印平台"
#: MachineSettingsAction/plugin.json
msgctxt "description"
@@ -4444,7 +4467,7 @@ msgstr "更新日誌"
#: ProfileFlattener/plugin.json
msgctxt "description"
msgid "Create a flattend quality changes profile."
-msgstr "創建一份合併品質變化列印參數。"
+msgstr "建立一份合併品質變化列印參數。"
#: ProfileFlattener/plugin.json
msgctxt "name"
@@ -4464,22 +4487,22 @@ msgstr "USB 連線列印"
#: PrepareStage/plugin.json
msgctxt "description"
msgid "Provides a prepare stage in Cura."
-msgstr ""
+msgstr "在 cura 提供一個準備介面。"
#: PrepareStage/plugin.json
msgctxt "name"
msgid "Prepare Stage"
-msgstr ""
+msgstr "準備介面"
#: CuraLiveScriptingPlugin/plugin.json
msgctxt "description"
msgid "Provides an edit window for direct script editing."
-msgstr ""
+msgstr "提供一個直接編輯描述檔的編輯視窗。"
#: CuraLiveScriptingPlugin/plugin.json
msgctxt "name"
msgid "Live scripting tool"
-msgstr ""
+msgstr "即時描述檔工具"
#: RemovableDriveOutputDevice/plugin.json
msgctxt "description"
@@ -4504,12 +4527,12 @@ msgstr "UM3 網路連接"
#: MonitorStage/plugin.json
msgctxt "description"
msgid "Provides a monitor stage in Cura."
-msgstr ""
+msgstr "在 cura 提供一個監控介面。"
#: MonitorStage/plugin.json
msgctxt "name"
msgid "Monitor Stage"
-msgstr ""
+msgstr "監控介面"
#: FirmwareUpdateChecker/plugin.json
msgctxt "description"
@@ -4524,7 +4547,7 @@ msgstr "韌體更新檢查"
#: CuraSolidWorksPlugin/plugin.json
msgctxt "description"
msgid "Gives you the possibility to open certain files using SolidWorks itself. Conversion is done by this plugin and additional optimizations."
-msgstr ""
+msgstr "讓你可以使用 SolidWorks 開啟某些檔案。此外掛會完成轉換和最佳化的工作。"
#: CuraSolidWorksPlugin/plugin.json
msgctxt "name"
@@ -4594,12 +4617,12 @@ msgstr "舊版 Cura 列印參數讀取器"
#: CuraBlenderPlugin/plugin.json
msgctxt "description"
msgid "Helps to open Blender files directly in Cura."
-msgstr ""
+msgstr "協助你直接在 Cura 中打開 Blender 檔案。"
#: CuraBlenderPlugin/plugin.json
msgctxt "name"
msgid "Blender Integration (experimental)"
-msgstr ""
+msgstr "Blender 整合(實驗功能)"
#: GCodeProfileReader/plugin.json
msgctxt "description"
@@ -4764,12 +4787,12 @@ msgstr "Cura 列印參數寫入器"
#: CuraPrintProfileCreator/plugin.json
msgctxt "description"
msgid "Allows material manufacturers to create new material and quality profiles using a drop-in UI."
-msgstr ""
+msgstr "允許耗材製造商使用下拉式 UI 建立新的耗材和品質設定參數。"
#: CuraPrintProfileCreator/plugin.json
msgctxt "name"
msgid "Print Profile Assistant"
-msgstr ""
+msgstr "列印參數設定助手"
#: 3MFWriter/plugin.json
msgctxt "description"
diff --git a/resources/i18n/zh_TW/fdmprinter.def.json.po b/resources/i18n/zh_TW/fdmprinter.def.json.po
index 7c9d882750..a20c882f5d 100644
--- a/resources/i18n/zh_TW/fdmprinter.def.json.po
+++ b/resources/i18n/zh_TW/fdmprinter.def.json.po
@@ -1,21 +1,21 @@
# Cura JSON setting files
-# Copyright (C) 2017 Ultimaker
+# Copyright (C) 2018 Ultimaker
# This file is distributed under the same license as the Cura package.
-# Ruben Dulek , 2017.
+# Ruben Dulek , 2018.
#
msgid ""
msgstr ""
-"Project-Id-Version: Cura 3.1\n"
+"Project-Id-Version: Cura 3.2\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
-"POT-Creation-Date: 2017-08-02 16:53+0000\n"
-"PO-Revision-Date: 2017-11-25 00:31+0800\n"
+"POT-Creation-Date: 2018-01-29 16:53+0000\n"
+"PO-Revision-Date: 2018-02-01 20:58+0800\n"
"Last-Translator: Zhang Heh Ji \n"
-"Language-Team: TEAM\n"
+"Language-Team: Zhang Heh Ji \n"
"Language: zh_TW\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Generator: Poedit 2.0.4\n"
+"X-Generator: Poedit 2.0.6\n"
#: fdmprinter.def.json
msgctxt "machine_settings label"
@@ -353,12 +353,12 @@ msgstr "Repetier"
#: fdmprinter.def.json
msgctxt "machine_firmware_retract label"
msgid "Firmware Retraction"
-msgstr ""
+msgstr "韌體回抽"
#: fdmprinter.def.json
msgctxt "machine_firmware_retract description"
msgid "Whether to use firmware retract commands (G10/G11) instead of using the E property in G1 commands to retract the material."
-msgstr ""
+msgstr "是否使用韌體回抽命令(G10/G11)取代 G1 命令的 E 參數來回抽線材。"
#: fdmprinter.def.json
msgctxt "machine_disallowed_areas label"
@@ -1053,12 +1053,12 @@ msgstr "全部填充"
#: fdmprinter.def.json
msgctxt "filter_out_tiny_gaps label"
msgid "Filter Out Tiny Gaps"
-msgstr ""
+msgstr "濾除微小間隙"
#: fdmprinter.def.json
msgctxt "filter_out_tiny_gaps description"
msgid "Filter out tiny gaps to reduce blobs on outside of model."
-msgstr ""
+msgstr "濾除微小間隙以減少模型外側的斑點 。"
#: fdmprinter.def.json
msgctxt "fill_outline_gaps label"
@@ -1443,7 +1443,7 @@ msgstr "填充 X 軸偏移"
#: fdmprinter.def.json
msgctxt "infill_offset_x description"
msgid "The infill pattern is moved this distance along the X axis."
-msgstr ""
+msgstr "填充樣式在 X 軸方向平移此距離。"
#: fdmprinter.def.json
msgctxt "infill_offset_y label"
@@ -1453,7 +1453,7 @@ msgstr "填充 Y 軸偏移"
#: fdmprinter.def.json
msgctxt "infill_offset_y description"
msgid "The infill pattern is moved this distance along the Y axis."
-msgstr ""
+msgstr "填充樣式在 Y 軸方向平移此距離。"
#: fdmprinter.def.json
msgctxt "sub_div_rad_add label"
@@ -1473,7 +1473,7 @@ msgstr "填充重疊百分比"
#: fdmprinter.def.json
msgctxt "infill_overlap description"
msgid "The amount of overlap between the infill and the walls as a percentage of the infill line width. A slight overlap allows the walls to connect firmly to the infill."
-msgstr ""
+msgstr "填充與牆壁的重疊量佔填充線寬的百分比。輕微的重疊能讓填充與牆壁牢固地連接。"
#: fdmprinter.def.json
msgctxt "infill_overlap_mm label"
@@ -1493,7 +1493,7 @@ msgstr "表層重疊百分比"
#: fdmprinter.def.json
msgctxt "skin_overlap description"
msgid "The amount of overlap between the skin and the walls as a percentage of the skin line width. A slight overlap allows the walls to connect firmly to the skin. This is a percentage of the average line widths of the skin lines and the innermost wall."
-msgstr ""
+msgstr "表層與牆壁的重疊量佔表層線寬的百分比。輕微的重疊能讓填充與表層牢固地連接。這是表層線寬和最內層牆壁線寬平均的百分比。"
#: fdmprinter.def.json
msgctxt "skin_overlap_mm label"
@@ -1723,7 +1723,7 @@ msgstr "列印平台溫度"
#: fdmprinter.def.json
msgctxt "material_bed_temperature description"
msgid "The temperature used for the heated build plate. If this is 0, the bed temperature will not be adjusted."
-msgstr ""
+msgstr "設定列印平台的溫度。如果設定為 0,就不會加熱列印平台。"
#: fdmprinter.def.json
msgctxt "material_bed_temperature_layer_0 label"
@@ -4267,82 +4267,82 @@ msgstr "實驗性!"
#: fdmprinter.def.json
msgctxt "support_tree_enable label"
msgid "Tree Support"
-msgstr ""
+msgstr "樹狀支撐"
#: fdmprinter.def.json
msgctxt "support_tree_enable description"
msgid "Generate a tree-like support with branches that support your print. This may reduce material usage and print time, but greatly increases slicing time."
-msgstr ""
+msgstr "產生帶有樹枝樹狀支撐結構支撐你的模型。這可能可以減少耗材的使用和列印的時間,但會大大的增加切片時間。"
#: fdmprinter.def.json
msgctxt "support_tree_angle label"
msgid "Tree Support Branch Angle"
-msgstr ""
+msgstr "樹狀支撐樹枝角度"
#: fdmprinter.def.json
msgctxt "support_tree_angle description"
msgid "The angle of the branches. Use a lower angle to make them more vertical and more stable. Use a higher angle to be able to have more reach."
-msgstr ""
+msgstr "樹枝的角度。使用較小的角度讓樹枝較垂直且較平穩。使用較大的角度則可以支撐較大的範圍。"
#: fdmprinter.def.json
msgctxt "support_tree_branch_distance label"
msgid "Tree Support Branch Distance"
-msgstr ""
+msgstr "樹狀支撐樹枝距離"
#: fdmprinter.def.json
msgctxt "support_tree_branch_distance description"
msgid "How far apart the branches need to be when they touch the model. Making this distance small will cause the tree support to touch the model at more points, causing better overhang but making support harder to remove."
-msgstr ""
+msgstr "樹支與模型接觸的點與點之間的間隔距離。較小的距離會讓支撐和模型有較多的接觸點,會有較佳的懸垂但支撐也較難移除。"
#: fdmprinter.def.json
msgctxt "support_tree_branch_diameter label"
msgid "Tree Support Branch Diameter"
-msgstr ""
+msgstr "樹狀支撐樹枝直徑"
#: fdmprinter.def.json
msgctxt "support_tree_branch_diameter description"
msgid "The diameter of the thinnest branches of tree support. Thicker branches are more sturdy. Branches towards the base will be thicker than this."
-msgstr ""
+msgstr "樹狀支撐中最細樹枝的直徑。越粗的樹枝越堅固。底部的樹枝會比這更粗。"
#: fdmprinter.def.json
msgctxt "support_tree_branch_diameter_angle label"
msgid "Tree Support Branch Diameter Angle"
-msgstr ""
+msgstr "樹狀支撐樹枝外徑角度"
#: fdmprinter.def.json
msgctxt "support_tree_branch_diameter_angle description"
msgid "The angle of the branches' diameter as they gradually become thicker towards the bottom. An angle of 0 will cause the branches to have uniform thickness over their length. A bit of an angle can increase stability of the tree support."
-msgstr ""
+msgstr "樹枝向底部逐漸變粗時,外徑變化的角度。設為 0 可讓整條樹枝的粗細一致, 而有點角度可增加樹狀支撐的穩定性。"
#: fdmprinter.def.json
msgctxt "support_tree_collision_resolution label"
msgid "Tree Support Collision Resolution"
-msgstr ""
+msgstr "樹狀支撐碰撞計算精度"
#: fdmprinter.def.json
msgctxt "support_tree_collision_resolution description"
msgid "Resolution to compute collisions with to avoid hitting the model. Setting this lower will produce more accurate trees that fail less often, but increases slicing time dramatically."
-msgstr ""
+msgstr "計算避免碰撞模型的計算精度。設定較低的值可產生較精確的樹狀支撐,這樣的支撐問題較少但會嚴重的增加切片所需的時間。"
#: fdmprinter.def.json
msgctxt "support_tree_wall_thickness label"
msgid "Tree Support Wall Thickness"
-msgstr ""
+msgstr "樹狀支撐牆厚"
#: fdmprinter.def.json
msgctxt "support_tree_wall_thickness description"
msgid "The thickness of the walls of the branches of tree support. Thicker walls take longer to print but don't fall over as easily."
-msgstr ""
+msgstr "樹狀支撐樹枝的牆壁厚度。較厚的牆壁需要花較長的時間列印,但較不易倒下。"
#: fdmprinter.def.json
msgctxt "support_tree_wall_count label"
msgid "Tree Support Wall Line Count"
-msgstr ""
+msgstr "樹狀支撐牆壁線條數量"
#: fdmprinter.def.json
msgctxt "support_tree_wall_count description"
msgid "The number of walls of the branches of tree support. Thicker walls take longer to print but don't fall over as easily."
-msgstr ""
+msgstr "樹狀支撐樹枝牆壁的圈數。較厚的牆壁需要花較長的時間列印,但較不易倒下。"
#: fdmprinter.def.json
msgctxt "slicing_tolerance label"
@@ -4417,12 +4417,12 @@ msgstr "當頂部表層採用線條或鋸齒狀的列印樣式時使用的整數
#: fdmprinter.def.json
msgctxt "infill_enable_travel_optimization label"
msgid "Infill Travel Optimization"
-msgstr ""
+msgstr "填充空跑最佳化"
#: fdmprinter.def.json
msgctxt "infill_enable_travel_optimization description"
msgid "When enabled, the order in which the infill lines are printed is optimized to reduce the distance travelled. The reduction in travel time achieved very much depends on the model being sliced, infill pattern, density, etc. Note that, for some models that have many small areas of infill, the time to slice the model may be greatly increased."
-msgstr ""
+msgstr "當功能啟用時,填充線條的列印順序會對降低空跑距離做最佳化。所能減少的空跑時間取決於模型、填充樣式、填充密度等。請注意,對於有很多小型填充區域的模型,切片時間可能會大量增加。"
#: fdmprinter.def.json
msgctxt "material_flow_dependent_temperature label"
@@ -5056,42 +5056,42 @@ msgstr "噴頭和水平下行線之間的距離。較大的間隙會讓斜下行
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_enabled label"
msgid "Use adaptive layers"
-msgstr ""
+msgstr "使用適應層高"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_enabled description"
msgid "Adaptive layers computes the layer heights depending on the shape of the model."
-msgstr ""
+msgstr "適應層高會依據模型的形狀計算列印的層高。"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation label"
msgid "Adaptive layers maximum variation"
-msgstr ""
+msgstr "適應層高最大變化量"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation description"
msgid "The maximum allowed height different from the base layer height in mm."
-msgstr ""
+msgstr "允許與層高基礎值相差的最大值(以毫米為單位)。"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation_step label"
msgid "Adaptive layers variation step size"
-msgstr ""
+msgstr "適應層高變化幅度"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_variation_step description"
msgid "The difference in height of the next layer height compared to the previous one."
-msgstr ""
+msgstr "下一列印層與前一列印層的層高差。"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold label"
msgid "Adaptive layers threshold"
-msgstr ""
+msgstr "適應層高門檻值"
#: fdmprinter.def.json
msgctxt "adaptive_layer_height_threshold description"
msgid "Threshold whether to use a smaller layer or not. This number is compared to the tan of the steepest slope in a layer."
-msgstr ""
+msgstr "決定是否使用較小層高的門檻值。此值會與一層中最陡坡度的 tan 值做比較。"
#: fdmprinter.def.json
msgctxt "command_line_settings label"
diff --git a/resources/meshes/artemis_platform.stl b/resources/meshes/artemis_platform.stl
new file mode 100644
index 0000000000..bf7c8ecb0d
Binary files /dev/null and b/resources/meshes/artemis_platform.stl differ
diff --git a/resources/meshes/neva.stl b/resources/meshes/neva.stl
new file mode 100644
index 0000000000..72ec185bd9
Binary files /dev/null and b/resources/meshes/neva.stl differ
diff --git a/resources/meshes/rostock_platform.stl b/resources/meshes/rostock_platform.stl
new file mode 100644
index 0000000000..7db5520d1c
Binary files /dev/null and b/resources/meshes/rostock_platform.stl differ
diff --git a/resources/preset_setting_visibility_groups/advanced.cfg b/resources/preset_setting_visibility_groups/advanced.cfg
index 3bbe0ce065..e68ee787f5 100644
--- a/resources/preset_setting_visibility_groups/advanced.cfg
+++ b/resources/preset_setting_visibility_groups/advanced.cfg
@@ -8,120 +8,71 @@ weight = 2
layer_height
layer_height_0
line_width
+wall_line_width
+wall_line_width_0
+wall_line_width_x
+skin_line_width
+infill_line_width
+initial_layer_line_width_factor
[shell]
wall_extruder_nr
+wall_0_extruder_nr
+wall_x_extruder_nr
wall_thickness
-wall_0_wipe_dist
-roofing_extruder_nr
-roofing_layer_count
+wall_line_count
top_bottom_extruder_nr
top_bottom_thickness
-top_bottom_pattern
-top_bottom_pattern_0
-skin_angles
-wall_0_inset
+top_thickness
+top_layers
+bottom_thickness
+bottom_layers
optimize_wall_printing_order
-outer_inset_first
-alternate_extra_perimeter
-travel_compensate_overlapping_walls_enabled
fill_perimeter_gaps
-filter_out_tiny_gaps
-fill_outline_gaps
xy_offset
-xy_offset_layer_0
-z_seam_type
-z_seam_x
-z_seam_y
-z_seam_corner
-z_seam_relative
-skin_no_small_gaps_heuristic
-skin_outline_count
ironing_enabled
-ironing_only_highest_layer
-ironing_pattern
-ironing_line_spacing
-ironing_flow
-ironing_inset
-speed_ironing
-acceleration_ironing
-jerk_ironing
[infill]
infill_extruder_nr
infill_sparse_density
+infill_line_distance
infill_pattern
-zig_zaggify_infill
-infill_angles
-infill_offset_x
-infill_offset_y
-sub_div_rad_add
infill_overlap
-skin_overlap
-infill_wipe_dist
infill_sparse_thickness
gradual_infill_steps
-gradual_infill_step_height
-infill_before_walls
-min_infill_area
-skin_preshrink
-expand_skins_expand_distance
-max_skin_angle_for_expansion
[material]
-default_material_print_temperature
material_print_temperature
material_print_temperature_layer_0
material_initial_print_temperature
material_final_print_temperature
-material_extrusion_cool_down_speed
-default_material_bed_temperature
material_bed_temperature
material_bed_temperature_layer_0
-material_diameter
-material_adhesion_tendency
-material_surface_energy
-material_flow
retraction_enable
retract_at_layer_change
retraction_amount
retraction_speed
-retraction_extra_prime_amount
-retraction_min_travel
-retraction_count_max
-retraction_extrusion_window
material_standby_temperature
-switch_extruder_retraction_amount
-switch_extruder_retraction_speeds
[speed]
speed_print
+speed_infill
+speed_wall
+speed_wall_0
+speed_wall_x
+speed_topbottom
+speed_support
+speed_prime_tower
speed_travel
speed_layer_0
skirt_brim_speed
-max_feedrate_z_override
-speed_slowdown_layers
-speed_equalize_flow_enabled
-speed_equalize_flow_max
acceleration_enabled
-acceleration_print
-acceleration_travel
-acceleration_layer_0
-acceleration_skirt_brim
jerk_enabled
-jerk_print
-jerk_travel
-jerk_layer_0
-jerk_skirt_brim
[travel]
retraction_combing
-travel_retract_before_outer_wall
travel_avoid_other_parts
travel_avoid_distance
-start_layers_at_same_position
-layer_start_x
-layer_start_y
retraction_hop_enabled
retraction_hop_only_when_collides
retraction_hop
@@ -130,9 +81,12 @@ retraction_hop_after_extruder_switch
[cooling]
cool_fan_enabled
cool_fan_speed
+cool_fan_speed_min
+cool_fan_speed_max
cool_min_layer_time_fan_speed_max
cool_fan_speed_0
cool_fan_full_at_height
+cool_fan_full_layer
cool_min_layer_time
cool_min_speed
cool_lift_head
@@ -140,115 +94,45 @@ cool_lift_head
[support]
support_enable
support_extruder_nr
+support_infill_extruder_nr
+support_extruder_nr_layer_0
+support_interface_extruder_nr
support_type
support_angle
support_pattern
-support_connect_zigzags
support_infill_rate
-support_z_distance
-support_xy_distance
-support_xy_overrides_z
-support_xy_distance_overhang
-support_bottom_stair_step_height
-support_bottom_stair_step_width
-support_join_distance
support_offset
support_infill_sparse_thickness
gradual_support_infill_steps
gradual_support_infill_step_height
support_interface_enable
-support_interface_height
-support_interface_skip_height
-support_interface_density
-support_interface_pattern
-support_use_towers
-support_tower_diameter
-support_minimal_diameter
-support_tower_roof_angle
-support_mesh_drop_down
+support_roof_enable
+support_bottom_enable
[platform_adhesion]
prime_blob_enable
-extruder_prime_pos_x
-extruder_prime_pos_y
adhesion_type
adhesion_extruder_nr
skirt_line_count
-skirt_gap
-skirt_brim_minimal_length
brim_width
+brim_line_count
brim_outside_only
-raft_margin
-raft_smoothing
-raft_airgap
-layer_0_z_overlap
-raft_surface_layers
-raft_surface_thickness
-raft_surface_line_width
-raft_surface_line_spacing
-raft_interface_thickness
-raft_interface_line_width
-raft_interface_line_spacing
-raft_base_thickness
-raft_base_line_width
-raft_base_line_spacing
-raft_speed
-raft_acceleration
-raft_jerk
-raft_fan_speed
[dual]
prime_tower_enable
-prime_tower_size
-prime_tower_min_volume
prime_tower_position_x
prime_tower_position_y
-prime_tower_flow
-prime_tower_wipe_enabled
-dual_pre_wipe
prime_tower_purge_volume
-ooze_shield_enabled
-ooze_shield_angle
-ooze_shield_dist
[meshfix]
-meshfix_union_all
-meshfix_union_all_remove_holes
-meshfix_extensive_stitching
-meshfix_keep_open_polygons
-multiple_mesh_overlap
-carve_multiple_volumes
-alternate_carve_order
-remove_empty_first_layers
[blackmagic]
print_sequence
-infill_mesh
-infill_mesh_order
-cutting_mesh
-mold_enabled
-mold_width
-mold_roof_height
-mold_angle
-support_mesh
-anti_overhang_mesh
magic_mesh_surface_mode
magic_spiralize
smooth_spiralized_contours
-relative_extrusion
[experimental]
-infill_enable_travel_optimization
-material_flow_dependent_temperature
-material_flow_temp_graph
-meshfix_maximum_resolution
-roofing_angles
-roofing_pattern
-slicing_tolerance
-support_tree_angle
-support_tree_branch_diameter
-support_tree_branch_diameter_angle
-support_tree_branch_distance
-support_tree_collision_resolution
-support_tree_enable
-support_tree_wall_thickness
+conical_overhang_enabled
+support_conical_enabled
+adaptive_layer_height_enabled
diff --git a/resources/preset_setting_visibility_groups/basic.cfg b/resources/preset_setting_visibility_groups/basic.cfg
index 062feb9189..4196a3a9e7 100644
--- a/resources/preset_setting_visibility_groups/basic.cfg
+++ b/resources/preset_setting_visibility_groups/basic.cfg
@@ -9,30 +9,28 @@ layer_height
[shell]
wall_thickness
+wall_line_count
top_bottom_thickness
-z_seam_x
-z_seam_y
+top_thickness
+top_layers
+bottom_thickness
+bottom_layers
+xy_offset
[infill]
infill_sparse_density
-gradual_infill_steps
+infill_pattern
[material]
material_print_temperature
material_bed_temperature
-material_diameter
-material_flow
retraction_enable
[speed]
speed_print
-speed_travel
-acceleration_print
-acceleration_travel
-jerk_print
-jerk_travel
[travel]
+retraction_hop_enabled
[cooling]
cool_fan_enabled
@@ -41,26 +39,20 @@ cool_fan_enabled
support_enable
support_extruder_nr
support_type
+support_angle
[platform_adhesion]
+prime_blob_enable
adhesion_type
adhesion_extruder_nr
-brim_width
-raft_airgap
-layer_0_z_overlap
-raft_surface_layers
[dual]
prime_tower_enable
-prime_tower_size
prime_tower_position_x
prime_tower_position_y
[meshfix]
[blackmagic]
-print_sequence
-infill_mesh
-cutting_mesh
-[experimental]
\ No newline at end of file
+[experimental]
diff --git a/resources/preset_setting_visibility_groups/expert.cfg b/resources/preset_setting_visibility_groups/expert.cfg
index 1be5ca7804..d6989f8b26 100644
--- a/resources/preset_setting_visibility_groups/expert.cfg
+++ b/resources/preset_setting_visibility_groups/expert.cfg
@@ -8,15 +8,33 @@ weight = 3
layer_height
layer_height_0
line_width
+wall_line_width
+wall_line_width_0
+wall_line_width_x
+skin_line_width
+infill_line_width
+skirt_brim_line_width
+support_line_width
+support_interface_line_width
+support_roof_line_width
+support_bottom_line_width
+prime_tower_line_width
+initial_layer_line_width_factor
[shell]
wall_extruder_nr
+wall_0_extruder_nr
+wall_x_extruder_nr
wall_thickness
+wall_line_count
wall_0_wipe_dist
-roofing_extruder_nr
roofing_layer_count
top_bottom_extruder_nr
top_bottom_thickness
+top_thickness
+top_layers
+bottom_thickness
+bottom_layers
top_bottom_pattern
top_bottom_pattern_0
skin_angles
@@ -25,6 +43,8 @@ optimize_wall_printing_order
outer_inset_first
alternate_extra_perimeter
travel_compensate_overlapping_walls_enabled
+travel_compensate_overlapping_walls_0_enabled
+travel_compensate_overlapping_walls_x_enabled
fill_perimeter_gaps
filter_out_tiny_gaps
fill_outline_gaps
@@ -50,6 +70,7 @@ jerk_ironing
[infill]
infill_extruder_nr
infill_sparse_density
+infill_line_distance
infill_pattern
zig_zaggify_infill
infill_angles
@@ -57,7 +78,9 @@ infill_offset_x
infill_offset_y
sub_div_rad_add
infill_overlap
+infill_overlap_mm
skin_overlap
+skin_overlap_mm
infill_wipe_dist
infill_sparse_thickness
gradual_infill_steps
@@ -65,8 +88,13 @@ gradual_infill_step_height
infill_before_walls
min_infill_area
skin_preshrink
+top_skin_preshrink
+bottom_skin_preshrink
expand_skins_expand_distance
+top_skin_expand_distance
+bottom_skin_expand_distance
max_skin_angle_for_expansion
+min_skin_width_for_expansion
[material]
default_material_print_temperature
@@ -82,10 +110,13 @@ material_diameter
material_adhesion_tendency
material_surface_energy
material_flow
+material_flow_layer_0
retraction_enable
retract_at_layer_change
retraction_amount
retraction_speed
+retraction_retract_speed
+retraction_prime_speed
retraction_extra_prime_amount
retraction_min_travel
retraction_count_max
@@ -93,11 +124,25 @@ retraction_extrusion_window
material_standby_temperature
switch_extruder_retraction_amount
switch_extruder_retraction_speeds
+switch_extruder_retraction_speed
+switch_extruder_prime_speed
[speed]
speed_print
+speed_infill
+speed_wall
+speed_wall_0
+speed_wall_x
+speed_roofing
+speed_topbottom
+speed_support
+speed_support_infill
+speed_support_interface
+speed_prime_tower
speed_travel
speed_layer_0
+speed_print_layer_0
+speed_travel_layer_0
skirt_brim_speed
max_feedrate_z_override
speed_slowdown_layers
@@ -105,13 +150,37 @@ speed_equalize_flow_enabled
speed_equalize_flow_max
acceleration_enabled
acceleration_print
+acceleration_infill
+acceleration_wall
+acceleration_wall_0
+acceleration_wall_x
+acceleration_roofing
+acceleration_topbottom
+acceleration_support
+acceleration_support_infill
+acceleration_support_interface
+acceleration_prime_tower
acceleration_travel
acceleration_layer_0
+acceleration_print_layer_0
+acceleration_travel_layer_0
acceleration_skirt_brim
jerk_enabled
jerk_print
+jerk_infill
+jerk_wall
+jerk_wall_0
+jerk_wall_x
+jerk_roofing
+jerk_topbottom
+jerk_support
+jerk_support_infill
+jerk_support_interface
+jerk_prime_tower
jerk_travel
jerk_layer_0
+jerk_print_layer_0
+jerk_travel_layer_0
jerk_skirt_brim
[travel]
@@ -130,9 +199,12 @@ retraction_hop_after_extruder_switch
[cooling]
cool_fan_enabled
cool_fan_speed
+cool_fan_speed_min
+cool_fan_speed_max
cool_min_layer_time_fan_speed_max
cool_fan_speed_0
cool_fan_full_at_height
+cool_fan_full_layer
cool_min_layer_time
cool_min_speed
cool_lift_head
@@ -140,12 +212,21 @@ cool_lift_head
[support]
support_enable
support_extruder_nr
+support_infill_extruder_nr
+support_extruder_nr_layer_0
+support_interface_extruder_nr
+support_roof_extruder_nr
+support_bottom_extruder_nr
support_type
support_angle
support_pattern
+zig_zaggify_support
support_connect_zigzags
support_infill_rate
+support_line_distance
support_z_distance
+support_top_distance
+support_bottom_distance
support_xy_distance
support_xy_overrides_z
support_xy_distance_overhang
@@ -157,9 +238,15 @@ support_infill_sparse_thickness
gradual_support_infill_steps
gradual_support_infill_step_height
support_interface_enable
+support_roof_enable
+support_bottom_enable
support_interface_height
+support_roof_height
+support_bottom_height
support_interface_skip_height
support_interface_density
+support_roof_density
+support_bottom_density
support_interface_pattern
support_use_towers
support_tower_diameter
@@ -169,19 +256,17 @@ support_mesh_drop_down
[platform_adhesion]
prime_blob_enable
-extruder_prime_pos_x
-extruder_prime_pos_y
adhesion_type
adhesion_extruder_nr
skirt_line_count
skirt_gap
skirt_brim_minimal_length
brim_width
+brim_line_count
brim_outside_only
raft_margin
raft_smoothing
raft_airgap
-layer_0_z_overlap
raft_surface_layers
raft_surface_thickness
raft_surface_line_width
@@ -199,8 +284,10 @@ raft_fan_speed
[dual]
prime_tower_enable
+prime_tower_circular
prime_tower_size
prime_tower_min_volume
+prime_tower_wall_thickness
prime_tower_position_x
prime_tower_position_y
prime_tower_flow
@@ -238,8 +325,25 @@ smooth_spiralized_contours
relative_extrusion
[experimental]
+support_tree_enable
+support_tree_angle
+support_tree_branch_distance
+support_tree_branch_diameter
+support_tree_branch_diameter_angle
+support_tree_collision_resolution
+support_tree_wall_thickness
+support_tree_wall_count
+slicing_tolerance
+roofing_line_width
+roofing_pattern
+roofing_angles
+infill_enable_travel_optimization
+material_flow_dependent_temperature
+material_flow_temp_graph
+meshfix_maximum_resolution
support_skip_some_zags
support_skip_zag_per_mm
+support_zag_skip_count
draft_shield_enabled
draft_shield_dist
draft_shield_height_limitation
@@ -267,19 +371,34 @@ infill_hollow
magic_fuzzy_skin_enabled
magic_fuzzy_skin_thickness
magic_fuzzy_skin_point_density
+magic_fuzzy_skin_point_dist
flow_rate_max_extrusion_offset
flow_rate_extrusion_offset_factor
-infill_enable_travel_optimization
-material_flow_dependent_temperature
-material_flow_temp_graph
-meshfix_maximum_resolution
-roofing_angles
-roofing_pattern
-slicing_tolerance
-support_tree_angle
-support_tree_branch_diameter
-support_tree_branch_diameter_angle
-support_tree_branch_distance
-support_tree_collision_resolution
-support_tree_enable
-support_tree_wall_thickness
+wireframe_enabled
+wireframe_height
+wireframe_roof_inset
+wireframe_printspeed
+wireframe_printspeed_bottom
+wireframe_printspeed_up
+wireframe_printspeed_down
+wireframe_printspeed_flat
+wireframe_flow
+wireframe_flow_connection
+wireframe_flow_flat
+wireframe_top_delay
+wireframe_bottom_delay
+wireframe_flat_delay
+wireframe_up_half_speed
+wireframe_top_jump
+wireframe_fall_down
+wireframe_drag_along
+wireframe_strategy
+wireframe_straight_before_down
+wireframe_roof_fall_down
+wireframe_roof_drag_along
+wireframe_roof_outer_delay
+wireframe_nozzle_clearance
+adaptive_layer_height_enabled
+adaptive_layer_height_variation
+adaptive_layer_height_variation_step
+adaptive_layer_height_threshold
diff --git a/resources/qml/AboutDialog.qml b/resources/qml/AboutDialog.qml
index 36cebe594a..5d3b1d1544 100644
--- a/resources/qml/AboutDialog.qml
+++ b/resources/qml/AboutDialog.qml
@@ -117,7 +117,7 @@ UM.Dialog
{
projectsModel.append({ name:"Cura", description: catalog.i18nc("@label", "Graphical user interface"), license: "LGPLv3", url: "https://github.com/Ultimaker/Cura" });
projectsModel.append({ name:"Uranium", description: catalog.i18nc("@label", "Application framework"), license: "LGPLv3", url: "https://github.com/Ultimaker/Uranium" });
- projectsModel.append({ name:"CuraEngine", description: catalog.i18nc("@label", "GCode generator"), license: "AGPLv3", url: "https://github.com/Ultimaker/CuraEngine" });
+ projectsModel.append({ name:"CuraEngine", description: catalog.i18nc("@label", "G-code generator"), license: "AGPLv3", url: "https://github.com/Ultimaker/CuraEngine" });
projectsModel.append({ name:"libArcus", description: catalog.i18nc("@label", "Interprocess communication library"), license: "LGPLv3", url: "https://github.com/Ultimaker/libArcus" });
projectsModel.append({ name:"Python", description: catalog.i18nc("@label", "Programming language"), license: "Python", url: "http://python.org/" });
@@ -134,8 +134,9 @@ UM.Dialog
projectsModel.append({ name:"Clipper", description: catalog.i18nc("@label", "Polygon clipping library"), license: "Boost", url: "http://www.angusj.com/delphi/clipper.php" });
projectsModel.append({ name:"Requests", description: catalog.i18nc("@Label", "Python HTTP library"), license: "GPL", url: "http://docs.python-requests.org" });
- projectsModel.append({ name:"Open Sans", description: catalog.i18nc("@label", "Font"), license: "Apache 2.0", url: "https://fonts.google.com/specimen/Open+Sans" });
+ projectsModel.append({ name:"Noto Sans", description: catalog.i18nc("@label", "Font"), license: "Apache 2.0", url: "https://www.google.com/get/noto/" });
projectsModel.append({ name:"Font-Awesome-SVG-PNG", description: catalog.i18nc("@label", "SVG icons"), license: "SIL OFL 1.1", url: "https://github.com/encharm/Font-Awesome-SVG-PNG" });
+ projectsModel.append({ name:"AppImageKit", description: catalog.i18nc("@label", "Linux cross-distribution application deployment"), license: "MIT", url: "https://github.com/AppImage/AppImageKit" });
}
}
}
@@ -149,4 +150,3 @@ UM.Dialog
onClicked: base.visible = false;
}
}
-
diff --git a/resources/qml/Actions.qml b/resources/qml/Actions.qml
index 05ff5050e9..7002711614 100644
--- a/resources/qml/Actions.qml
+++ b/resources/qml/Actions.qml
@@ -69,7 +69,6 @@ Item
property alias configureSettingVisibility: configureSettingVisibilityAction
property alias browsePlugins: browsePluginsAction
- property alias configurePlugins: configurePluginsAction
UM.I18nCatalog{id: catalog; name:"cura"}
@@ -173,7 +172,7 @@ Item
Action
{
id: updateProfileAction;
- enabled: !Cura.MachineManager.stacksHaveErrors && Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId)
+ enabled: !Cura.MachineManager.stacksHaveErrors && Cura.MachineManager.hasUserSettings && Cura.MachineManager.activeQualityChangesGroup != null
text: catalog.i18nc("@action:inmenu menubar:profile","&Update profile with current settings/overrides");
onTriggered: Cura.ContainerManager.updateQualityChanges();
}
@@ -237,6 +236,16 @@ Item
onTriggered: CuraActions.deleteSelection();
}
+ Action //Also add backspace as the same function as delete because on Macintosh keyboards the button called "delete" is actually a backspace, and the user expects it to function as a delete.
+ {
+ id: backspaceSelectionAction
+ text: catalog.i18ncp("@action:inmenu menubar:edit", "Delete &Selected Model", "Delete &Selected Models", UM.Selection.selectionCount)
+ enabled: UM.Controller.toolsEnabled && UM.Selection.hasSelection
+ iconName: "edit-delete"
+ shortcut: StandardKey.Backspace
+ onTriggered: CuraActions.deleteSelection()
+ }
+
Action
{
id: centerSelectionAction;
@@ -425,13 +434,6 @@ Item
iconName: "plugins_browse"
}
- Action
- {
- id: configurePluginsAction
- text: catalog.i18nc("@action:menu", "Installed plugins...");
- iconName: "plugins_configure"
- }
-
Action
{
id: expandSidebarAction;
diff --git a/resources/qml/Cura.qml b/resources/qml/Cura.qml
index 6f649a7273..c81281f0d7 100644
--- a/resources/qml/Cura.qml
+++ b/resources/qml/Cura.qml
@@ -190,24 +190,42 @@ UM.MainWindow
model: Cura.ExtrudersModel { simpleNames: true }
Menu {
title: model.name
- visible: machineExtruderCount.properties.value > 1
NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: Cura.MachineManager.hasVariants; extruderIndex: index }
MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: Cura.MachineManager.hasMaterials; extruderIndex: index }
- ProfileMenu { title: catalog.i18nc("@title:menu", "&Profile"); }
- MenuSeparator { }
+ MenuSeparator
+ {
+ visible: Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials
+ }
+
+ MenuItem
+ {
+ text: catalog.i18nc("@action:inmenu", "Set as Active Extruder")
+ onTriggered: Cura.MachineManager.setExtruderIndex(model.index)
+ }
+
+ MenuItem
+ {
+ text: catalog.i18nc("@action:inmenu", "Enable Extruder")
+ onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true)
+ visible: !Cura.MachineManager.getExtruder(model.index).isEnabled
+ }
+
+ MenuItem
+ {
+ text: catalog.i18nc("@action:inmenu", "Disable Extruder")
+ onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false)
+ visible: Cura.MachineManager.getExtruder(model.index).isEnabled
+ }
- MenuItem { text: catalog.i18nc("@action:inmenu", "Set as Active Extruder"); onTriggered: Cura.ExtruderManager.setActiveExtruderIndex(model.index) }
}
onObjectAdded: settingsMenu.insertItem(index, object)
onObjectRemoved: settingsMenu.removeItem(object)
}
BuildplateMenu { title: catalog.i18nc("@title:menu", "&Build plate"); visible: Cura.MachineManager.hasVariantBuildplates }
- NozzleMenu { title: Cura.MachineManager.activeDefinitionVariantsName; visible: machineExtruderCount.properties.value <= 1 && Cura.MachineManager.hasVariants }
- MaterialMenu { title: catalog.i18nc("@title:menu", "&Material"); visible: machineExtruderCount.properties.value <= 1 && Cura.MachineManager.hasMaterials }
- ProfileMenu { title: catalog.i18nc("@title:menu", "&Profile"); visible: machineExtruderCount.properties.value <= 1 }
+ ProfileMenu { title: catalog.i18nc("@title:menu", "&Profile"); }
MenuSeparator { }
@@ -254,7 +272,6 @@ UM.MainWindow
title: catalog.i18nc("@title:menu menubar:toplevel", "P&lugins")
MenuItem { action: Cura.Actions.browsePlugins }
- MenuItem { action: Cura.Actions.configurePlugins }
}
Menu
@@ -477,6 +494,14 @@ UM.MainWindow
collapseSidebarAnimation.start();
}
}
+
+ MouseArea
+ {
+ visible: UM.Controller.activeStage.sidebarComponent != ""
+ anchors.fill: parent
+ acceptedButtons: Qt.AllButtons
+ onWheel: wheel.accepted = true
+ }
}
UM.MessageStack
@@ -484,7 +509,7 @@ UM.MainWindow
anchors
{
horizontalCenter: parent.horizontalCenter
- horizontalCenterOffset: -(UM.Theme.getSize("sidebar").width/ 2)
+ horizontalCenterOffset: -(Math.round(UM.Theme.getSize("sidebar").width / 2))
top: parent.verticalCenter;
bottom: parent.bottom;
}
@@ -518,6 +543,9 @@ UM.MainWindow
insertPage(4, catalog.i18nc("@title:tab", "Profiles"), Qt.resolvedUrl("Preferences/ProfilesPage.qml"));
+ // Remove plug-ins page because we will use the shiny new plugin browser:
+ removePage(5);
+
//Force refresh
setPage(0);
}
@@ -629,17 +657,6 @@ UM.MainWindow
}
}
- // show the installed plugins page in the preferences dialog
- Connections
- {
- target: Cura.Actions.configurePlugins
- onTriggered:
- {
- preferences.visible = true
- preferences.setPage(5)
- }
- }
-
UM.ExtensionModel {
id: curaExtensions
}
diff --git a/resources/qml/DiscardOrKeepProfileChangesDialog.qml b/resources/qml/DiscardOrKeepProfileChangesDialog.qml
index 915a11fde2..afa9fda0bd 100644
--- a/resources/qml/DiscardOrKeepProfileChangesDialog.qml
+++ b/resources/qml/DiscardOrKeepProfileChangesDialog.qml
@@ -7,7 +7,7 @@ import QtQuick.Dialogs 1.2
import QtQuick.Window 2.1
import UM 1.2 as UM
-import Cura 1.1 as Cura
+import Cura 1.0 as Cura
UM.Dialog
{
diff --git a/resources/qml/ExtruderButton.qml b/resources/qml/ExtruderButton.qml
index 9212c705f7..2c1b80047e 100644
--- a/resources/qml/ExtruderButton.qml
+++ b/resources/qml/ExtruderButton.qml
@@ -19,7 +19,7 @@ Button
iconSource: UM.Theme.getIcon("extruder_button")
checked: Cura.ExtruderManager.selectedObjectExtruders.indexOf(extruder.id) != -1
- enabled: UM.Selection.hasSelection
+ enabled: UM.Selection.hasSelection && extruder.stack.isEnabled
property color customColor: base.hovered ? UM.Theme.getColor("button_hover") : UM.Theme.getColor("button");
@@ -65,7 +65,7 @@ Button
width: UM.Theme.getSize("extruder_button_material").width
height: UM.Theme.getSize("extruder_button_material").height
- radius: width / 2
+ radius: Math.round(width / 2)
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("extruder_button_material_border")
diff --git a/resources/qml/JobSpecs.qml b/resources/qml/JobSpecs.qml
index c701e5ebf4..04e8ec397f 100644
--- a/resources/qml/JobSpecs.qml
+++ b/resources/qml/JobSpecs.qml
@@ -94,7 +94,7 @@ Item {
{
id: printJobTextfield
anchors.right: printJobPencilIcon.left
- anchors.rightMargin: Math.floor(UM.Theme.getSize("default_margin").width/2)
+ anchors.rightMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
height: UM.Theme.getSize("jobspecs_line").height
width: Math.max(__contentWidth + UM.Theme.getSize("default_margin").width, 50)
maximumLength: 120
diff --git a/resources/qml/Menus/BuildplateMenu.qml b/resources/qml/Menus/BuildplateMenu.qml
index 4b85aa9e93..b924aa0879 100644
--- a/resources/qml/Menus/BuildplateMenu.qml
+++ b/resources/qml/Menus/BuildplateMenu.qml
@@ -1,8 +1,8 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.2
-import QtQuick.Controls 1.1
+import QtQuick 2.7
+import QtQuick.Controls 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
@@ -12,28 +12,22 @@ Menu
id: menu
title: "Build plate"
+ property var buildPlateModel: CuraApplication.getBuildPlateModel()
+
Instantiator
{
- id: buildplateInstantiator
- model: UM.InstanceContainersModel
- {
- filter:
- {
- "type": "variant",
- "hardware_type": "buildplate",
- "definition": Cura.MachineManager.activeDefinitionId //Only show variants of this machine
- }
- }
+ model: menu.buildPlateModel
+
MenuItem {
text: model.name
checkable: true
- checked: model.id == Cura.MachineManager.globalVariantId
+ checked: model.name == Cura.MachineManager.globalVariantName
exclusiveGroup: group
- onTriggered:
- {
- Cura.MachineManager.setActiveVariantBuildplate(model.id);
+ onTriggered: {
+ Cura.MachineManager.setGlobalVariant(model.container_node);
}
}
+
onObjectAdded: menu.insertItem(index, object)
onObjectRemoved: menu.removeItem(object)
}
diff --git a/resources/qml/Menus/ContextMenu.qml b/resources/qml/Menus/ContextMenu.qml
index b5f51f4d63..83302f9463 100644
--- a/resources/qml/Menus/ContextMenu.qml
+++ b/resources/qml/Menus/ContextMenu.qml
@@ -7,7 +7,7 @@ import QtQuick.Dialogs 1.2
import QtQuick.Window 2.1
import UM 1.2 as UM
-import Cura 1.2 as Cura
+import Cura 1.0 as Cura
Menu
{
@@ -15,6 +15,8 @@ Menu
property bool shouldShowExtruders: machineExtruderCount.properties.value > 1;
+ property var multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel()
+
// Selection-related actions.
MenuItem { action: Cura.Actions.centerSelection; }
MenuItem { action: Cura.Actions.deleteSelection; }
@@ -45,13 +47,13 @@ Menu
Instantiator
{
- model: Cura.BuildPlateModel
+ model: base.multiBuildPlateModel
MenuItem {
enabled: UM.Selection.hasSelection
- text: Cura.BuildPlateModel.getItem(index).name;
- onTriggered: CuraActions.setBuildPlateForSelection(Cura.BuildPlateModel.getItem(index).buildPlateNumber);
+ text: base.multiBuildPlateModel.getItem(index).name;
+ onTriggered: CuraActions.setBuildPlateForSelection(base.multiBuildPlateModel.getItem(index).buildPlateNumber);
checkable: true
- checked: Cura.BuildPlateModel.selectionBuildPlates.indexOf(Cura.BuildPlateModel.getItem(index).buildPlateNumber) != -1;
+ checked: base.multiBuildPlateModel.selectionBuildPlates.indexOf(base.multiBuildPlateModel.getItem(index).buildPlateNumber) != -1;
visible: UM.Preferences.getValue("cura/use_multi_build_plate")
}
onObjectAdded: base.insertItem(index, object);
@@ -62,7 +64,7 @@ Menu
enabled: UM.Selection.hasSelection
text: "New build plate";
onTriggered: {
- CuraActions.setBuildPlateForSelection(Cura.BuildPlateModel.maxBuildPlate + 1);
+ CuraActions.setBuildPlateForSelection(base.multiBuildPlateModel.maxBuildPlate + 1);
checked = false;
}
checkable: true
diff --git a/resources/qml/Menus/MaterialMenu.qml b/resources/qml/Menus/MaterialMenu.qml
index 3d04649f11..d81e0c86c3 100644
--- a/resources/qml/Menus/MaterialMenu.qml
+++ b/resources/qml/Menus/MaterialMenu.qml
@@ -1,8 +1,8 @@
// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.2
-import QtQuick.Controls 1.1
+import QtQuick 2.7
+import QtQuick.Controls 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
@@ -13,64 +13,6 @@ Menu
title: "Material"
property int extruderIndex: 0
- property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
- property bool isClusterPrinter:
- {
- if(Cura.MachineManager.printerOutputDevices.length == 0)
- {
- return false;
- }
- var clusterSize = Cura.MachineManager.printerOutputDevices[0].clusterSize;
- // This is not a cluster printer or the cluster it is just one printer
- if(clusterSize == undefined || clusterSize == 1)
- {
- return false;
- }
- return true;
- }
-
- UM.SettingPropertyProvider
- {
- id: materialDiameterProvider
-
- containerStackId: Cura.ExtruderManager.activeExtruderStackId
- key: "material_diameter"
- watchedProperties: [ "value" ]
- storeIndex: 5
- }
-
- MenuItem
- {
- id: automaticMaterial
- text:
- {
- if(visible)
- {
- var materialName = Cura.MachineManager.printerOutputDevices[0].materialNames[extruderIndex];
- return catalog.i18nc("@title:menuitem %1 is the automatically selected material", "Automatic: %1").arg(materialName);
- }
- return "";
- }
- visible: printerConnected && Cura.MachineManager.printerOutputDevices[0].materialNames != undefined && Cura.MachineManager.printerOutputDevices[0].materialNames.length > extruderIndex && !isClusterPrinter
- onTriggered:
- {
- var materialId = Cura.MachineManager.printerOutputDevices[0].materialIds[extruderIndex];
- var items = materialsModel.items;
- for(var i in items)
- {
- if (items[i]["metadata"]["GUID"] == materialId)
- {
- Cura.MachineManager.setActiveMaterial(items[i].id);
- break;
- }
- }
- }
- }
-
- MenuSeparator
- {
- visible: automaticMaterial.visible
- }
Instantiator
{
@@ -79,16 +21,11 @@ Menu
{
text: model.name
checkable: true
- checked: model.id == Cura.MachineManager.allActiveMaterialIds[Cura.ExtruderManager.extruderIds[extruderIndex]]
+ checked: model.root_material_id == Cura.MachineManager.currentRootMaterialId[extruderIndex]
exclusiveGroup: group
onTriggered:
{
- // This workaround is done because of the application menus for materials and variants for multiextrusion printers.
- // The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI.
- var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex;
- Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex);
- Cura.MachineManager.setActiveMaterial(model.id);
- Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex);
+ Cura.MachineManager.setMaterial(extruderIndex, model.container_node);
}
}
onObjectAdded: menu.insertItem(index, object)
@@ -126,12 +63,8 @@ Menu
exclusiveGroup: group
onTriggered:
{
- // This workaround is done because of the application menus for materials and variants for multiextrusion printers.
- // The extruder menu would always act on the correspoding extruder only, instead of acting on the extruder selected in the UI.
var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex;
- Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex);
- Cura.MachineManager.setActiveMaterial(model.id);
- Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex);
+ Cura.MachineManager.setMaterial(activeExtruderIndex, model.container_node);
}
}
onObjectAdded: brandMaterialsMenu.insertItem(index, object)
@@ -146,24 +79,16 @@ Menu
onObjectRemoved: menu.removeItem(object)
}
- ListModel
+ Cura.GenericMaterialsModel
{
id: genericMaterialsModel
- Component.onCompleted: populateMenuModels()
+ extruderPosition: menu.extruderIndex
}
- ListModel
+ Cura.BrandMaterialsModel
{
id: brandModel
- }
-
- //: Model used to populate the brandModel
- Cura.MaterialsModel
- {
- id: materialsModel
- filter: materialFilter()
- onModelReset: populateMenuModels()
- onDataChanged: populateMenuModels()
+ extruderPosition: menu.extruderIndex
}
ExclusiveGroup { id: group }
@@ -171,80 +96,4 @@ Menu
MenuSeparator { }
MenuItem { action: Cura.Actions.manageMaterials }
-
- function materialFilter()
- {
- var result = { "type": "material", "approximate_diameter": Math.round(materialDiameterProvider.properties.value).toString() };
- if(Cura.MachineManager.filterMaterialsByMachine)
- {
- result.definition = Cura.MachineManager.activeQualityDefinitionId;
- if(Cura.MachineManager.hasVariants)
- {
- result.variant = Cura.MachineManager.activeQualityVariantId;
- }
- }
- else
- {
- result.definition = "fdmprinter";
- result.compatible = true; //NB: Only checks for compatibility in global version of material, but we don't have machine-specific materials anyway.
- }
- return result;
- }
-
- function populateMenuModels()
- {
- // Create a structure of unique brands and their material-types
- genericMaterialsModel.clear()
- brandModel.clear();
-
- var items = materialsModel.items;
- var materialsByBrand = {};
- for (var i in items) {
- var brandName = items[i]["metadata"]["brand"];
- var materialName = items[i]["metadata"]["material"];
-
- if (brandName == "Generic")
- {
- // Add to top section
- var materialId = items[i].id;
- genericMaterialsModel.append({
- id: materialId,
- name: items[i].name
- });
- }
- else
- {
- // Add to per-brand, per-material menu
- if (!materialsByBrand.hasOwnProperty(brandName))
- {
- materialsByBrand[brandName] = {};
- }
- if (!materialsByBrand[brandName].hasOwnProperty(materialName))
- {
- materialsByBrand[brandName][materialName] = [];
- }
- materialsByBrand[brandName][materialName].push({
- id: items[i].id,
- name: items[i].name
- });
- }
- }
-
- for (var brand in materialsByBrand)
- {
- var materialsByBrandModel = [];
- var materials = materialsByBrand[brand];
- for (var material in materials)
- {
- materialsByBrandModel.push({
- name: material,
- colors: materials[material]
- })
- }
- brandModel.append({
- name: brand,
- materials: materialsByBrandModel
- });
- }
- }
}
diff --git a/resources/qml/Menus/NozzleMenu.qml b/resources/qml/Menus/NozzleMenu.qml
index 81db20a79d..43f3b79dd4 100644
--- a/resources/qml/Menus/NozzleMenu.qml
+++ b/resources/qml/Menus/NozzleMenu.qml
@@ -1,8 +1,8 @@
// Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.2
-import QtQuick.Controls 1.1
+import QtQuick 2.7
+import QtQuick.Controls 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
@@ -13,89 +13,31 @@ Menu
title: "Nozzle"
property int extruderIndex: 0
- property bool printerConnected: Cura.MachineManager.printerOutputDevices.length != 0
- property bool isClusterPrinter:
- {
- if(Cura.MachineManager.printerOutputDevices.length == 0)
- {
- return false;
- }
- var clusterSize = Cura.MachineManager.printerOutputDevices[0].clusterSize;
- // This is not a cluster printer or the cluster it is just one printer
- if(clusterSize == undefined || clusterSize == 1)
- {
- return false;
- }
- return true;
- }
- MenuItem
+ Cura.NozzleModel
{
- id: automaticNozzle
- text:
- {
- if(visible)
- {
- var nozzleName = Cura.MachineManager.printerOutputDevices[0].hotendIds[extruderIndex];
- return catalog.i18nc("@title:menuitem %1 is the nozzle currently loaded in the printer", "Automatic: %1").arg(nozzleName);
- }
- return "";
- }
- visible: printerConnected && Cura.MachineManager.printerOutputDevices[0].hotendIds != undefined && Cura.MachineManager.printerOutputDevices[0].hotendIds.length > extruderIndex && !isClusterPrinter
- onTriggered:
- {
- var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex;
- Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex);
- var hotendId = Cura.MachineManager.printerOutputDevices[0].hotendIds[extruderIndex];
- var itemIndex = nozzleInstantiator.model.find("name", hotendId);
- if(itemIndex > -1)
- {
- Cura.MachineManager.setActiveVariant(nozzleInstantiator.model.getItem(itemIndex).id);
- }
- Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex);
- }
- }
-
- MenuSeparator
- {
- visible: automaticNozzle.visible
+ id: nozzleModel
}
Instantiator
{
- id: nozzleInstantiator
- model: UM.InstanceContainersModel
- {
- filter:
- {
- var filter_dict =
- {
- "type": "variant",
- "definition": Cura.MachineManager.activeQualityDefinitionId //Only show variants of this machine
- }
- if (Cura.MachineManager.hasVariantBuildplates)
- {
- filter_dict["hardware_type"] = "nozzle"
- }
+ model: nozzleModel
- return filter_dict
- }
- }
- MenuItem {
- text: model.name
+ MenuItem
+ {
+ text: model.hotend_name
checkable: true
- checked: model.id == Cura.MachineManager.allActiveVariantIds[Cura.ExtruderManager.extruderIds[extruderIndex]]
+ checked: {
+ return Cura.MachineManager.activeVariantNames[extruderIndex] == model.hotend_name
+ }
exclusiveGroup: group
- onTriggered:
- {
- var activeExtruderIndex = Cura.ExtruderManager.activeExtruderIndex;
- Cura.ExtruderManager.setActiveExtruderIndex(extruderIndex);
- Cura.MachineManager.setActiveVariant(model.id);
- Cura.ExtruderManager.setActiveExtruderIndex(activeExtruderIndex);
+ onTriggered: {
+ Cura.MachineManager.setVariantGroup(menu.extruderIndex, model.container_node);
}
}
- onObjectAdded: menu.insertItem(index, object)
- onObjectRemoved: menu.removeItem(object)
+
+ onObjectAdded: menu.insertItem(index, object);
+ onObjectRemoved: menu.removeItem(object);
}
ExclusiveGroup { id: group }
diff --git a/resources/qml/Menus/ProfileMenu.qml b/resources/qml/Menus/ProfileMenu.qml
index f543bb36eb..5b9a5a3b73 100644
--- a/resources/qml/Menus/ProfileMenu.qml
+++ b/resources/qml/Menus/ProfileMenu.qml
@@ -1,8 +1,8 @@
-// Copyright (c) 2016 Ultimaker B.V.
+// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.2
-import QtQuick.Controls 1.1
+import QtQuick 2.7
+import QtQuick.Controls 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
@@ -13,15 +13,17 @@ Menu
Instantiator
{
- model: Cura.ProfilesModel
+ model: Cura.QualityProfilesDropDownMenuModel
MenuItem
{
- text: (model.layer_height != "") ? model.name + " - " + model.layer_height : model.name
+ text: (model.layer_height != "") ? model.name + " - " + model.layer_height + model.layer_height_unit : model.name
checkable: true
- checked: Cura.MachineManager.activeQualityId == model.id
+ checked: Cura.MachineManager.activeQualityOrQualityChangesName == model.name
exclusiveGroup: group
- onTriggered: Cura.MachineManager.setActiveQuality(model.id)
+ onTriggered: {
+ Cura.MachineManager.setQualityGroup(model.quality_group)
+ }
visible: model.available
}
@@ -32,24 +34,28 @@ Menu
MenuSeparator
{
id: customSeparator
- visible: Cura.UserProfilesModel.rowCount > 0
+ visible: Cura.CustomQualityProfilesDropDownMenuModel.rowCount > 0
}
Instantiator
{
id: customProfileInstantiator
- model: Cura.UserProfilesModel
+ model: Cura.CustomQualityProfilesDropDownMenuModel
+
+ Connections
{
- onModelReset: customSeparator.visible = rowCount() > 0
+ target: Cura.CustomQualityProfilesDropDownMenuModel
+ onModelReset: customSeparator.visible = Cura.CustomQualityProfilesDropDownMenuModel.rowCount() > 0
}
MenuItem
{
text: model.name
- checkable: true
- checked: Cura.MachineManager.activeQualityChangesId == model.id
+ checkable: model.available
+ enabled: model.available
+ checked: Cura.MachineManager.activeQualityOrQualityChangesName == model.name
exclusiveGroup: group
- onTriggered: Cura.MachineManager.setActiveQuality(model.id)
+ onTriggered: Cura.MachineManager.setQualityChangesGroup(model.quality_changes_group)
}
onObjectAdded:
@@ -73,23 +79,4 @@ Menu
MenuItem { action: Cura.Actions.resetProfile }
MenuSeparator { }
MenuItem { action: Cura.Actions.manageProfiles }
-
- function getFilter(initial_conditions)
- {
- var result = initial_conditions;
-
- if(Cura.MachineManager.filterQualityByMachine)
- {
- result.definition = Cura.MachineManager.activeQualityDefinitionId;
- if(Cura.MachineManager.hasMaterials)
- {
- result.material = Cura.MachineManager.activeQualityMaterialId;
- }
- }
- else
- {
- result.definition = "fdmprinter"
- }
- return result
- }
}
diff --git a/resources/qml/Menus/ViewMenu.qml b/resources/qml/Menus/ViewMenu.qml
index afc80dd314..6bbb0b1e2e 100644
--- a/resources/qml/Menus/ViewMenu.qml
+++ b/resources/qml/Menus/ViewMenu.qml
@@ -5,7 +5,7 @@ import QtQuick 2.2
import QtQuick.Controls 1.1
import UM 1.2 as UM
-import Cura 1.2 as Cura
+import Cura 1.0 as Cura
Menu
{
@@ -13,6 +13,8 @@ Menu
id: base
enabled: !PrintInformation.preSliced
+ property var multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel()
+
// main views
Instantiator
{
@@ -53,12 +55,12 @@ Menu
visible: UM.Preferences.getValue("cura/use_multi_build_plate")
Instantiator
{
- model: Cura.BuildPlateModel
+ model: base.multiBuildPlateModel
MenuItem {
- text: Cura.BuildPlateModel.getItem(index).name;
- onTriggered: Cura.SceneController.setActiveBuildPlate(Cura.BuildPlateModel.getItem(index).buildPlateNumber);
+ text: base.multiBuildPlateModel.getItem(index).name;
+ onTriggered: Cura.SceneController.setActiveBuildPlate(base.multiBuildPlateModel.getItem(index).buildPlateNumber);
checkable: true;
- checked: Cura.BuildPlateModel.getItem(index).buildPlateNumber == Cura.BuildPlateModel.activeBuildPlate;
+ checked: base.multiBuildPlateModel.getItem(index).buildPlateNumber == base.multiBuildPlateModel.activeBuildPlate;
exclusiveGroup: buildPlateGroup;
visible: UM.Preferences.getValue("cura/use_multi_build_plate")
}
diff --git a/resources/qml/MonitorButton.qml b/resources/qml/MonitorButton.qml
index 0e9728da3d..c3ae200464 100644
--- a/resources/qml/MonitorButton.qml
+++ b/resources/qml/MonitorButton.qml
@@ -225,7 +225,7 @@ Item
width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width;
height: UM.Theme.getSize("progressbar").height;
anchors.top: statusLabel.bottom;
- anchors.topMargin: UM.Theme.getSize("sidebar_margin").height / 4;
+ anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 4);
anchors.left: parent.left;
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width;
}
diff --git a/resources/qml/ObjectsList.qml b/resources/qml/ObjectsList.qml
index 9fd2ab1ca7..8c8eaa16ae 100644
--- a/resources/qml/ObjectsList.qml
+++ b/resources/qml/ObjectsList.qml
@@ -8,7 +8,7 @@ import QtQuick.Layouts 1.1
import QtQuick.Dialogs 1.1
import UM 1.3 as UM
-import Cura 1.2 as Cura
+import Cura 1.0 as Cura
import "Menus"
@@ -31,14 +31,16 @@ Rectangle
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
- property bool collapsed: true;
+ property bool collapsed: true
+
+ property var multiBuildPlateModel: CuraApplication.getMultiBuildPlateModel()
SystemPalette { id: palette }
Button {
id: collapseButton
anchors.top: parent.top
- anchors.topMargin: Math.floor(UM.Theme.getSize("default_margin").height + (UM.Theme.getSize("layerview_row").height - UM.Theme.getSize("default_margin").height) / 2)
+ anchors.topMargin: Math.round(UM.Theme.getSize("default_margin").height + (UM.Theme.getSize("layerview_row").height - UM.Theme.getSize("default_margin").height) / 2)
anchors.right: parent.right
anchors.rightMargin: UM.Theme.getSize("default_margin").width
@@ -67,7 +69,7 @@ Rectangle
Rectangle
{
height: childrenRect.height
- color: Cura.BuildPlateModel.getItem(index).buildPlateNumber == Cura.BuildPlateModel.activeBuildPlate ? palette.highlight : index % 2 ? palette.base : palette.alternateBase
+ color: multiBuildPlateModel.getItem(index).buildPlateNumber == multiBuildPlateModel.activeBuildPlate ? palette.highlight : index % 2 ? palette.base : palette.alternateBase
width: parent.width
Label
{
@@ -75,8 +77,8 @@ Rectangle
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("default_margin").width
width: parent.width - 2 * UM.Theme.getSize("default_margin").width - 30
- text: Cura.BuildPlateModel.getItem(index) ? Cura.BuildPlateModel.getItem(index).name : "";
- color: Cura.BuildPlateModel.activeBuildPlate == index ? palette.highlightedText : palette.text
+ text: multiBuildPlateModel.getItem(index) ? multiBuildPlateModel.getItem(index).name : "";
+ color: multiBuildPlateModel.activeBuildPlate == index ? palette.highlightedText : palette.text
elide: Text.ElideRight
}
@@ -118,13 +120,12 @@ Rectangle
ListView
{
id: buildPlateListView
- model: Cura.BuildPlateModel
+ model: multiBuildPlateModel
width: parent.width
delegate: buildPlateDelegate
}
}
-
Component {
id: objectDelegate
Rectangle
@@ -200,7 +201,6 @@ Rectangle
}
}
-
CheckBox
{
id: filterBuildPlateCheckbox
@@ -260,6 +260,4 @@ Rectangle
}
action: Cura.Actions.arrangeAll;
}
-
-
}
diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml
index ac5cacdbf6..1c7b2bcf7c 100644
--- a/resources/qml/Preferences/GeneralPage.qml
+++ b/resources/qml/Preferences/GeneralPage.qml
@@ -413,7 +413,7 @@ UM.PreferencesPage
width: childrenRect.width;
height: childrenRect.height;
- text: catalog.i18nc("@info:tooltip","Show caution message in gcode reader.")
+ text: catalog.i18nc("@info:tooltip","Show caution message in g-code reader.")
CheckBox
{
@@ -422,7 +422,7 @@ UM.PreferencesPage
checked: boolCheck(UM.Preferences.getValue("gcodereader/show_caution"))
onClicked: UM.Preferences.setValue("gcodereader/show_caution", checked)
- text: catalog.i18nc("@option:check","Caution message in gcode reader");
+ text: catalog.i18nc("@option:check","Caution message in g-code reader");
}
}
diff --git a/resources/qml/Preferences/MachinesPage.qml b/resources/qml/Preferences/MachinesPage.qml
index 889dfa8d5b..62e5ef98b4 100644
--- a/resources/qml/Preferences/MachinesPage.qml
+++ b/resources/qml/Preferences/MachinesPage.qml
@@ -1,13 +1,14 @@
// Copyright (c) 2016 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.1
-import QtQuick.Controls 1.1
+import QtQuick 2.7
+import QtQuick.Controls 1.4
import QtQuick.Window 2.1
import UM 1.2 as UM
import Cura 1.0 as Cura
+
UM.ManagementPage
{
id: base;
diff --git a/resources/qml/Preferences/MaterialView.qml b/resources/qml/Preferences/MaterialView.qml
index b2307fe4f6..d2f653e650 100644
--- a/resources/qml/Preferences/MaterialView.qml
+++ b/resources/qml/Preferences/MaterialView.qml
@@ -1,8 +1,8 @@
// Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.1
-import QtQuick.Controls 1.3
+import QtQuick 2.7
+import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.2
import UM 1.2 as UM
@@ -12,7 +12,10 @@ TabView
{
id: base
- property QtObject properties;
+ property QtObject materialManager: CuraApplication.getMaterialManager()
+
+ property QtObject properties
+ property var currentMaterialNode: null
property bool editingEnabled: false;
property string currency: UM.Preferences.getValue("cura/currency") ? UM.Preferences.getValue("cura/currency") : "€"
@@ -27,18 +30,36 @@ TabView
property bool reevaluateLinkedMaterials: false
property string linkedMaterialNames:
{
- if (reevaluateLinkedMaterials)
- {
+ if (reevaluateLinkedMaterials) {
reevaluateLinkedMaterials = false;
}
- if(!base.containerId || !base.editingEnabled)
- {
+ if (!base.containerId || !base.editingEnabled) {
+ return ""
+ }
+ var linkedMaterials = Cura.ContainerManager.getLinkedMaterials(base.currentMaterialNode);
+ if (linkedMaterials.length <= 1) {
return ""
}
- var linkedMaterials = Cura.ContainerManager.getLinkedMaterials(base.containerId);
return linkedMaterials.join(", ");
}
+ function getApproximateDiameter(diameter) {
+ return Math.round(diameter);
+ }
+
+ // This trick makes sure to make all fields lose focus so their onEditingFinished will be triggered
+ // and modified values will be saved. This can happen when a user changes a value and then closes the
+ // dialog directly.
+ //
+ // Please note that somehow this callback is ONLY triggered when visible is false.
+ onVisibleChanged:
+ {
+ if (!visible)
+ {
+ base.focus = false;
+ }
+ }
+
Tab
{
title: catalog.i18nc("@title", "Information")
@@ -65,6 +86,34 @@ TabView
width: base.width
property real rowHeight: textField.height + UM.Theme.getSize("default_lining").height
+ MessageDialog
+ {
+ id: confirmDiameterChangeDialog
+
+ icon: StandardIcon.Question;
+ title: catalog.i18nc("@title:window", "Confirm Diameter Change")
+ text: catalog.i18nc("@label (%1 is object name)", "The new material diameter is set to %1 mm, which is not compatible to the current machine. Do you wish to continue?".arg(new_diameter_value))
+ standardButtons: StandardButton.Yes | StandardButton.No
+ modality: Qt.ApplicationModal
+
+ property var new_diameter_value: null;
+ property var old_diameter_value: null;
+ property var old_approximate_diameter_value: null;
+
+ onYes:
+ {
+ Cura.ContainerManager.setContainerProperty(base.containerId, "material_diameter", "value", new_diameter_value);
+ base.setMetaDataEntry("approximate_diameter", old_approximate_diameter_value, getApproximateDiameter(new_diameter_value).toString());
+ base.setMetaDataEntry("properties/diameter", properties.diameter, new_diameter_value);
+ }
+
+ onNo:
+ {
+ properties.diameter = old_diameter_value;
+ diameterSpinBox.value = properties.diameter;
+ }
+ }
+
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Display Name") }
ReadOnlyTextField
{
@@ -80,33 +129,33 @@ TabView
{
id: textField;
width: scrollView.columnWidth;
- text: properties.supplier;
+ text: properties.brand;
readOnly: !base.editingEnabled;
- onEditingFinished: base.updateMaterialSupplier(properties.supplier, text)
+ onEditingFinished: base.updateMaterialBrand(properties.brand, text)
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Material Type") }
ReadOnlyTextField
{
width: scrollView.columnWidth;
- text: properties.material_type;
+ text: properties.material;
readOnly: !base.editingEnabled;
- onEditingFinished: base.updateMaterialType(properties.material_type, text)
+ onEditingFinished: base.updateMaterialType(properties.material, text)
}
Label { width: scrollView.columnWidth; height: parent.rowHeight; verticalAlignment: Qt.AlignVCenter; text: catalog.i18nc("@label", "Color") }
Row {
width: scrollView.columnWidth
height: parent.rowHeight
- spacing: Math.floor(UM.Theme.getSize("default_margin").width/2)
+ spacing: Math.round(UM.Theme.getSize("default_margin").width / 2)
// color indicator square
Rectangle {
id: colorSelector
color: properties.color_code
- width: Math.floor(colorLabel.height * 0.75)
- height: Math.floor(colorLabel.height * 0.75)
+ width: Math.round(colorLabel.height * 0.75)
+ height: Math.round(colorLabel.height * 0.75)
border.width: UM.Theme.getSize("default_lining").height
anchors.verticalCenter: parent.verticalCenter
@@ -172,14 +221,20 @@ TabView
// which derive from the same base_file
var old_diameter = Cura.ContainerManager.getContainerProperty(base.containerId, "material_diameter", "value").toString();
var old_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter");
- base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, Math.round(value).toString());
- base.setMetaDataEntry("properties/diameter", properties.diameter, value);
- var new_approximate_diameter = Cura.ContainerManager.getContainerMetaDataEntry(base.containerId, "approximate_diameter");
- if (Cura.MachineManager.filterMaterialsByMachine && new_approximate_diameter != Cura.MachineManager.activeMachine.approximateMaterialDiameter)
+ var new_approximate_diameter = getApproximateDiameter(value);
+ if (Cura.MachineManager.filterMaterialsByMachine && new_approximate_diameter != Cura.ExtruderManager.getActiveExtruderStack().approximateMaterialDiameter)
{
- Cura.MaterialManager.showMaterialWarningMessage(base.containerId, old_diameter);
+ confirmDiameterChangeDialog.old_diameter_value = old_diameter;
+ confirmDiameterChangeDialog.new_diameter_value = value;
+ confirmDiameterChangeDialog.old_approximate_diameter_value = old_approximate_diameter;
+
+ confirmDiameterChangeDialog.open()
+ }
+ else {
+ Cura.ContainerManager.setContainerProperty(base.containerId, "material_diameter", "value", value);
+ base.setMetaDataEntry("approximate_diameter", old_approximate_diameter, getApproximateDiameter(value).toString());
+ base.setMetaDataEntry("properties/diameter", properties.diameter, value);
}
- Cura.ContainerManager.setContainerProperty(base.containerId, "material_diameter", "value", value);
}
onValueChanged: updateCostPerMeter()
}
@@ -251,7 +306,7 @@ TabView
visible: base.linkedMaterialNames != ""
onClicked:
{
- Cura.ContainerManager.unlinkMaterial(base.containerId)
+ Cura.ContainerManager.unlinkMaterial(base.currentMaterialNode)
base.reevaluateLinkedMaterials = true
}
}
@@ -357,8 +412,20 @@ TabView
onEditingFinished: materialPropertyProvider.setPropertyValue("value", value)
}
- UM.ContainerPropertyProvider { id: materialPropertyProvider; containerId: base.containerId; watchedProperties: [ "value" ]; key: model.key }
- UM.ContainerPropertyProvider { id: machinePropertyProvider; containerId: Cura.MachineManager.activeDefinitionId; watchedProperties: [ "value" ]; key: model.key }
+ UM.ContainerPropertyProvider
+ {
+ id: materialPropertyProvider
+ containerId: base.containerId
+ watchedProperties: [ "value" ]
+ key: model.key
+ }
+ UM.ContainerPropertyProvider
+ {
+ id: machinePropertyProvider
+ containerId: Cura.MachineManager.activeDefinitionId
+ watchedProperties: [ "value" ]
+ key: model.key
+ }
}
}
}
@@ -405,9 +472,12 @@ TabView
// Tiny convenience function to check if a value really changed before trying to set it.
function setMetaDataEntry(entry_name, old_value, new_value) {
if (old_value != new_value) {
- Cura.ContainerManager.setContainerMetaDataEntry(base.containerId, entry_name, new_value)
+ Cura.ContainerManager.setContainerMetaDataEntry(base.currentMaterialNode, entry_name, new_value)
// make sure the UI properties are updated as well since we don't re-fetch the entire model here
- properties[entry_name] = new_value
+ // When the entry_name is something like properties/diameter, we take the last part of the entry_name
+ var list = entry_name.split("/")
+ var key = list[list.length - 1]
+ properties[key] = new_value
}
}
@@ -439,26 +509,25 @@ TabView
// update the display name of the material
function updateMaterialDisplayName (old_name, new_name) {
-
// don't change when new name is the same
if (old_name == new_name) {
return
}
// update the values
- Cura.ContainerManager.setContainerName(base.containerId, new_name)
+ base.materialManager.setMaterialName(base.currentMaterialNode, new_name)
materialProperties.name = new_name
}
// update the type of the material
function updateMaterialType (old_type, new_type) {
base.setMetaDataEntry("material", old_type, new_type)
- materialProperties.material_type = new_type
+ materialProperties.material= new_type
}
- // update the supplier of the material
- function updateMaterialSupplier (old_supplier, new_supplier) {
- base.setMetaDataEntry("brand", old_supplier, new_supplier)
- materialProperties.supplier = new_supplier
+ // update the brand of the material
+ function updateMaterialBrand (old_brand, new_brand) {
+ base.setMetaDataEntry("brand", old_brand, new_brand)
+ materialProperties.brand = new_brand
}
}
diff --git a/resources/qml/Preferences/MaterialsPage.qml b/resources/qml/Preferences/MaterialsPage.qml
index fa2c68ef36..7f06ffecde 100644
--- a/resources/qml/Preferences/MaterialsPage.qml
+++ b/resources/qml/Preferences/MaterialsPage.qml
@@ -1,414 +1,567 @@
-//Copyright (c) 2017 Ultimaker B.V.
-//Cura is released under the terms of the LGPLv3 or higher.
+// Copyright (c) 2018 Ultimaker B.V.
+// Uranium is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.1
-import QtQuick.Controls 1.1
+import QtQuick 2.7
+import QtQuick.Controls 1.4
+import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2
import UM 1.2 as UM
import Cura 1.0 as Cura
-UM.ManagementPage
-{
- id: base;
- title: catalog.i18nc("@title:tab", "Materials");
+Item
+{
+ id: base
+
+ property QtObject materialManager: CuraApplication.getMaterialManager()
+ property var resetEnabled: false // Keep PreferencesDialog happy
+
+ UM.I18nCatalog { id: catalog; name: "cura"; }
+
+ Cura.MaterialManagementModel
+ {
+ id: materialsModel
+ }
+
+ Label
+ {
+ id: titleLabel
+
+ anchors
+ {
+ top: parent.top
+ left: parent.left
+ right: parent.right
+ margins: 5 * screenScaleFactor
+ }
+
+ font.pointSize: 18
+ text: catalog.i18nc("@title:tab", "Materials")
+ }
+
+ property var hasCurrentItem: materialListView.currentItem != null
+
+ property var currentItem:
+ { // is soon to be overwritten
+ var current_index = materialListView.currentIndex;
+ return materialsModel.getItem(current_index);
+ }
+
+ property var isCurrentItemActivated:
+ {
+ const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
+ const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
+ return base.currentItem.root_material_id == root_material_id;
+ }
Component.onCompleted:
{
- // Workaround to make sure all of the items are visible
- objectList.positionViewAtBeginning();
- }
-
- model: Cura.MaterialsModel
- {
- filter:
+ // Select the activated material when this page shows up
+ const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
+ const active_root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
+ var itemIndex = -1;
+ for (var i = 0; i < materialsModel.rowCount(); ++i)
{
- var result = { "type": "material", "approximate_diameter": Math.round(materialDiameterProvider.properties.value).toString() }
- if(Cura.MachineManager.filterMaterialsByMachine)
+ var item = materialsModel.getItem(i);
+ if (item.root_material_id == active_root_material_id)
{
- result.definition = Cura.MachineManager.activeQualityDefinitionId;
- if(Cura.MachineManager.hasVariants)
- {
- result.variant = Cura.MachineManager.activeQualityVariantId;
- }
+ itemIndex = i;
+ break;
}
- else
- {
- result.definition = "fdmprinter";
- result.compatible = true; //NB: Only checks for compatibility in global version of material, but we don't have machine-specific materials anyway.
- }
- return result
}
-
- sectionProperty: "brand"
+ materialListView.currentIndex = itemIndex;
}
- delegate: Rectangle
+ Row // Button Row
{
- width: objectList.width;
- height: childrenRect.height;
- color: isCurrentItem ? palette.highlight : index % 2 ? palette.base : palette.alternateBase
- property bool isCurrentItem: ListView.isCurrentItem
-
- Row
+ id: buttonRow
+ anchors
{
- spacing: (UM.Theme.getSize("default_margin").width / 2) | 0
- anchors.left: parent.left
- anchors.leftMargin: UM.Theme.getSize("default_margin").width
- anchors.right: parent.right
- Rectangle
+ left: parent.left
+ right: parent.right
+ top: titleLabel.bottom
+ }
+ height: childrenRect.height
+
+ // Activate button
+ Button
+ {
+ text: catalog.i18nc("@action:button", "Activate")
+ iconName: "list-activate"
+ enabled: !isCurrentItemActivated
+ onClicked:
{
- width: (parent.height * 0.8) | 0
- height: (parent.height * 0.8) | 0
- color: model.metadata.color_code
- border.color: isCurrentItem ? palette.highlightedText : palette.text;
- anchors.verticalCenter: parent.verticalCenter
- }
- Label
- {
- width: Math.floor((parent.width * 0.3))
- text: model.metadata.material
- elide: Text.ElideRight
- font.italic: model.id == activeId
- color: isCurrentItem ? palette.highlightedText : palette.text;
- }
- Label
- {
- text: (model.name != model.metadata.material) ? model.name : ""
- elide: Text.ElideRight
- font.italic: model.id == activeId
- color: isCurrentItem ? palette.highlightedText : palette.text;
+ forceActiveFocus()
+
+ const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
+ Cura.MachineManager.setMaterial(extruder_position, base.currentItem.container_node);
}
}
- MouseArea
+ // Create button
+ Button
{
- anchors.fill: parent;
+ text: catalog.i18nc("@action:button", "Create")
+ iconName: "list-add"
onClicked:
{
forceActiveFocus();
- if(!parent.ListView.isCurrentItem)
- {
- parent.ListView.view.currentIndex = index;
- base.itemActivated();
- }
+ base.newRootMaterialIdToSwitchTo = base.materialManager.createMaterial();
+ base.toActivateNewMaterial = true;
}
}
- }
-
- activeId: Cura.MachineManager.activeMaterialId
- activeIndex: getIndexById(activeId)
- function getIndexById(material_id)
- {
- for(var i = 0; i < model.rowCount(); i++) {
- if (model.getItem(i).id == material_id) {
- return i;
- }
- }
- return -1;
- }
-
- scrollviewCaption:
- {
- if (Cura.MachineManager.hasVariants)
- {
- catalog.i18nc("@action:label %1 is printer name, %2 is how this printer names variants, %3 is variant name", "Printer: %1, %2: %3").arg(Cura.MachineManager.activeMachineName).arg(Cura.MachineManager.activeDefinitionVariantsName).arg(Cura.MachineManager.activeVariantName)
- }
- else
- {
- catalog.i18nc("@action:label %1 is printer name","Printer: %1").arg(Cura.MachineManager.activeMachineName)
- }
- }
- detailsVisible: true
-
- section.property: "section"
- section.delegate: Label
- {
- text: section
- font.bold: true
- anchors.left: parent.left;
- anchors.leftMargin: UM.Theme.getSize("default_lining").width;
- }
-
- buttons: [
-
- // Activate button
- Button {
- text: catalog.i18nc("@action:button", "Activate")
- iconName: "list-activate";
- enabled: base.currentItem != null && base.currentItem.id != Cura.MachineManager.activeMaterialId && Cura.MachineManager.hasMaterials
- onClicked: {
- forceActiveFocus()
- Cura.MachineManager.setActiveMaterial(base.currentItem.id)
- currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
- }
- },
-
- // Create button
- Button {
- text: catalog.i18nc("@action:button", "Create")
- iconName: "list-add"
- onClicked: {
- forceActiveFocus()
- Cura.ContainerManager.createMaterial()
- }
- },
// Duplicate button
- Button {
+ Button
+ {
text: catalog.i18nc("@action:button", "Duplicate");
- iconName: "list-add";
- enabled: base.currentItem != null
- onClicked: {
- forceActiveFocus()
- Cura.ContainerManager.duplicateOriginalMaterial(base.currentItem.id)
+ iconName: "list-add"
+ enabled: base.hasCurrentItem
+ onClicked:
+ {
+ forceActiveFocus();
+ base.newRootMaterialIdToSwitchTo = base.materialManager.duplicateMaterial(base.currentItem.container_node);
+ base.toActivateNewMaterial = true;
}
- },
+ }
// Remove button
- Button {
+ Button
+ {
text: catalog.i18nc("@action:button", "Remove")
iconName: "list-remove"
- enabled: base.currentItem != null && !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id)
- onClicked: {
- forceActiveFocus()
- confirmDialog.open()
+ enabled: base.hasCurrentItem && !base.currentItem.is_read_only && !base.isCurrentItemActivated
+ onClicked:
+ {
+ forceActiveFocus();
+ confirmRemoveMaterialDialog.open();
}
- },
+ }
// Import button
- Button {
+ Button
+ {
text: catalog.i18nc("@action:button", "Import")
iconName: "document-import"
- onClicked: {
- forceActiveFocus()
- importDialog.open()
+ onClicked:
+ {
+ forceActiveFocus();
+ importMaterialDialog.open();
}
visible: true
- },
+ }
// Export button
- Button {
+ Button
+ {
text: catalog.i18nc("@action:button", "Export")
iconName: "document-export"
- onClicked: {
- forceActiveFocus()
- exportDialog.open()
+ onClicked:
+ {
+ forceActiveFocus();
+ exportMaterialDialog.open();
}
enabled: currentItem != null
}
-
- ]
-
- Item {
- visible: base.currentItem != null
- anchors.fill: parent
-
- Item
- {
- id: profileName
-
- width: parent.width;
- height: childrenRect.height
-
- Label { text: materialProperties.name; font: UM.Theme.getFont("large"); }
- }
-
- MaterialView
- {
- anchors
- {
- left: parent.left
- right: parent.right
- top: profileName.bottom
- topMargin: UM.Theme.getSize("default_margin").height
- bottom: parent.bottom
- }
-
- editingEnabled: base.currentItem != null && !base.currentItem.readOnly
-
- properties: materialProperties
- containerId: base.currentItem != null ? base.currentItem.id : ""
-
- property alias pane: base
- }
-
- QtObject
- {
- id: materialProperties
-
- property string guid: "00000000-0000-0000-0000-000000000000"
- property string name: "Unknown";
- property string profile_type: "Unknown";
- property string supplier: "Unknown";
- property string material_type: "Unknown";
-
- property string color_name: "Yellow";
- property color color_code: "yellow";
-
- property real density: 0.0;
- property real diameter: 0.0;
- property string approximate_diameter: "0";
-
- property real spool_cost: 0.0;
- property real spool_weight: 0.0;
- property real spool_length: 0.0;
- property real cost_per_meter: 0.0;
-
- property string description: "";
- property string adhesion_info: "";
- }
-
- UM.ConfirmRemoveDialog
- {
- id: confirmDialog
- object: base.currentItem != null ? base.currentItem.name : ""
- onYes:
- {
- // A material container can actually be multiple items, so we need to find (and remove) all of them.
- var base_file = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "base_file")
- if(base_file == "")
- {
- base_file = base.currentItem.id
- }
- var guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID")
- // remove base container first, it otherwise triggers loading the base file while removing other containers
- var base_containers = Cura.ContainerManager.findInstanceContainers({"GUID": guid, "id": base_file, "base_file": base_file, "type": "material"})
- for(var i in base_containers)
- {
- Cura.ContainerManager.removeContainer(base_containers[i]);
- }
- var containers = Cura.ContainerManager.findInstanceContainers({"GUID": guid, "base_file": base_file, "type": "material"})
- for(var i in containers)
- {
- Cura.ContainerManager.removeContainer(containers[i]);
- }
- if(base.objectList.currentIndex > 0)
- {
- base.objectList.currentIndex--;
- }
- currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
- }
- }
-
- FileDialog
- {
- id: importDialog;
- title: catalog.i18nc("@title:window", "Import Material");
- selectExisting: true;
- nameFilters: Cura.ContainerManager.getContainerNameFilters("material")
- folder: CuraApplication.getDefaultPath("dialog_material_path")
- onAccepted:
- {
- var result = Cura.ContainerManager.importMaterialContainer(fileUrl)
-
- messageDialog.title = catalog.i18nc("@title:window", "Import Material")
- messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags or !", "Could not import material %1: %2").arg(fileUrl).arg(result.message)
- if(result.status == "success")
- {
- messageDialog.icon = StandardIcon.Information
- messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag !", "Successfully imported material %1").arg(fileUrl)
- }
- else if(result.status == "duplicate")
- {
- messageDialog.icon = StandardIcon.Warning
- }
- else
- {
- messageDialog.icon = StandardIcon.Critical
- }
- messageDialog.open()
- CuraApplication.setDefaultPath("dialog_material_path", folder)
- }
- }
-
- FileDialog
- {
- id: exportDialog;
- title: catalog.i18nc("@title:window", "Export Material");
- selectExisting: false;
- nameFilters: Cura.ContainerManager.getContainerNameFilters("material")
- folder: CuraApplication.getDefaultPath("dialog_material_path")
- onAccepted:
- {
- if(base.currentItem.metadata.base_file)
- {
- var result = Cura.ContainerManager.exportContainer(base.currentItem.metadata.base_file, selectedNameFilter, fileUrl)
- }
- else
- {
- var result = Cura.ContainerManager.exportContainer(base.currentItem.id, selectedNameFilter, fileUrl)
- }
-
- messageDialog.title = catalog.i18nc("@title:window", "Export Material")
- if(result.status == "error")
- {
- messageDialog.icon = StandardIcon.Critical
- messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags and !", "Failed to export material to %1: %2").arg(fileUrl).arg(result.message)
- messageDialog.open()
- }
- else if(result.status == "success")
- {
- messageDialog.icon = StandardIcon.Information
- messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag !", "Successfully exported material to %1").arg(result.path)
- messageDialog.open()
- }
- CuraApplication.setDefaultPath("dialog_material_path", folder)
- }
- }
-
- MessageDialog
- {
- id: messageDialog
- }
-
- UM.SettingPropertyProvider
- {
- id: materialDiameterProvider
-
- containerStackId: Cura.ExtruderManager.activeExtruderStackId
- key: "material_diameter"
- watchedProperties: [ "value" ]
- storeIndex: 5
- }
-
- UM.I18nCatalog { id: catalog; name: "cura"; }
- SystemPalette { id: palette }
}
- onCurrentItemChanged:
+ property string newRootMaterialIdToSwitchTo: ""
+ property bool toActivateNewMaterial: false
+
+ // This connection makes sure that we will switch to the new
+ Connections
{
- if(currentItem == null)
+ target: materialsModel
+ onItemsChanged:
{
- return
- }
- materialProperties.name = currentItem.name;
- materialProperties.guid = Cura.ContainerManager.getContainerMetaDataEntry(base.currentItem.id, "GUID");
+ var currentItemId = base.currentItem == null ? "" : base.currentItem.root_material_id;
+ var position = Cura.ExtruderManager.activeExtruderIndex;
- if(currentItem.metadata != undefined && currentItem.metadata != null)
- {
- materialProperties.supplier = currentItem.metadata.brand ? currentItem.metadata.brand : "Unknown";
- materialProperties.material_type = currentItem.metadata.material ? currentItem.metadata.material : "Unknown";
- materialProperties.color_name = currentItem.metadata.color_name ? currentItem.metadata.color_name : "Yellow";
- materialProperties.color_code = currentItem.metadata.color_code ? currentItem.metadata.color_code : "yellow";
-
- materialProperties.description = currentItem.metadata.description ? currentItem.metadata.description : "";
- materialProperties.adhesion_info = currentItem.metadata.adhesion_info ? currentItem.metadata.adhesion_info : "";
-
- if(currentItem.metadata.properties != undefined && currentItem.metadata.properties != null)
+ // try to pick the currently selected item; it may have been moved
+ if (base.newRootMaterialIdToSwitchTo == "")
{
- materialProperties.density = currentItem.metadata.properties.density ? currentItem.metadata.properties.density : 0.0;
- materialProperties.diameter = currentItem.metadata.properties.diameter ? currentItem.metadata.properties.diameter : 0.0;
- materialProperties.approximate_diameter = currentItem.metadata.approximate_diameter ? currentItem.metadata.approximate_diameter : "0";
+ base.newRootMaterialIdToSwitchTo = currentItemId;
+ }
+
+ for (var idx = 0; idx < materialsModel.rowCount(); ++idx)
+ {
+ var item = materialsModel.getItem(idx);
+ if (item.root_material_id == base.newRootMaterialIdToSwitchTo)
+ {
+ // Switch to the newly created profile if needed
+ materialListView.currentIndex = idx;
+ materialListView.activateDetailsWithIndex(materialListView.currentIndex);
+ if (base.toActivateNewMaterial)
+ {
+ Cura.MachineManager.setMaterial(position, item.container_node);
+ }
+ base.newRootMaterialIdToSwitchTo = "";
+ base.toActivateNewMaterial = false;
+ return
+ }
+ }
+
+ materialListView.currentIndex = 0;
+ materialListView.activateDetailsWithIndex(materialListView.currentIndex);
+ if (base.toActivateNewMaterial)
+ {
+ Cura.MachineManager.setMaterial(position, materialsModel.getItem(0).container_node);
+ }
+ base.newRootMaterialIdToSwitchTo = "";
+ base.toActivateNewMaterial = false;
+ }
+ }
+
+ MessageDialog
+ {
+ id: confirmRemoveMaterialDialog
+
+ icon: StandardIcon.Question;
+ title: catalog.i18nc("@title:window", "Confirm Remove")
+ text: catalog.i18nc("@label (%1 is object name)", "Are you sure you wish to remove %1? This cannot be undone!").arg(base.currentItem.name)
+ standardButtons: StandardButton.Yes | StandardButton.No
+ modality: Qt.ApplicationModal
+
+ onYes:
+ {
+ base.materialManager.removeMaterial(base.currentItem.container_node);
+ }
+ }
+
+ FileDialog
+ {
+ id: importMaterialDialog
+ title: catalog.i18nc("@title:window", "Import Material")
+ selectExisting: true
+ nameFilters: Cura.ContainerManager.getContainerNameFilters("material")
+ folder: CuraApplication.getDefaultPath("dialog_material_path")
+ onAccepted:
+ {
+ var result = Cura.ContainerManager.importMaterialContainer(fileUrl);
+
+ messageDialog.title = catalog.i18nc("@title:window", "Import Material");
+ messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags or !", "Could not import material %1: %2").arg(fileUrl).arg(result.message);
+ if (result.status == "success")
+ {
+ messageDialog.icon = StandardIcon.Information;
+ messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag !", "Successfully imported material %1").arg(fileUrl);
+ }
+ else if (result.status == "duplicate")
+ {
+ messageDialog.icon = StandardIcon.Warning;
}
else
{
- materialProperties.density = 0.0;
- materialProperties.diameter = 0.0;
- materialProperties.approximate_diameter = "0";
+ messageDialog.icon = StandardIcon.Critical;
+ }
+ messageDialog.open();
+ CuraApplication.setDefaultPath("dialog_material_path", folder);
+ }
+ }
+
+ FileDialog
+ {
+ id: exportMaterialDialog
+ title: catalog.i18nc("@title:window", "Export Material")
+ selectExisting: false
+ nameFilters: Cura.ContainerManager.getContainerNameFilters("material")
+ folder: CuraApplication.getDefaultPath("dialog_material_path")
+ onAccepted:
+ {
+ var result = Cura.ContainerManager.exportContainer(base.currentItem.root_material_id, selectedNameFilter, fileUrl);
+
+ messageDialog.title = catalog.i18nc("@title:window", "Export Material");
+ if (result.status == "error")
+ {
+ messageDialog.icon = StandardIcon.Critical;
+ messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tags and !", "Failed to export material to %1: %2").arg(fileUrl).arg(result.message);
+ messageDialog.open();
+ }
+ else if (result.status == "success")
+ {
+ messageDialog.icon = StandardIcon.Information;
+ messageDialog.text = catalog.i18nc("@info:status Don't translate the XML tag !", "Successfully exported material to %1").arg(result.path);
+ messageDialog.open();
+ }
+ CuraApplication.setDefaultPath("dialog_material_path", folder);
+ }
+ }
+
+ MessageDialog
+ {
+ id: messageDialog
+ }
+
+
+ Item {
+ id: contentsItem
+
+ anchors
+ {
+ top: titleLabel.bottom
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ margins: 5 * screenScaleFactor
+ bottomMargin: 0
+ }
+
+ clip: true
+ }
+
+ Item
+ {
+ anchors
+ {
+ top: buttonRow.bottom
+ topMargin: UM.Theme.getSize("default_margin").height
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ }
+
+ SystemPalette { id: palette }
+
+ Label
+ {
+ id: captionLabel
+ anchors
+ {
+ top: parent.top
+ left: parent.left
+ }
+ visible: text != ""
+ text:
+ {
+ var caption = catalog.i18nc("@action:label", "Printer") + ": " + Cura.MachineManager.activeMachineName;
+ if (Cura.MachineManager.hasVariants)
+ {
+ caption += ", " + Cura.MachineManager.activeDefinitionVariantsName + ": " + Cura.MachineManager.activeVariantName;
+ }
+ return caption;
+ }
+ width: materialScrollView.width
+ elide: Text.ElideRight
+ }
+
+ ScrollView
+ {
+ id: materialScrollView
+ anchors
+ {
+ top: captionLabel.visible ? captionLabel.bottom : parent.top
+ topMargin: captionLabel.visible ? UM.Theme.getSize("default_margin").height : 0
+ bottom: parent.bottom
+ left: parent.left
}
+ Rectangle
+ {
+ parent: viewport
+ anchors.fill: parent
+ color: palette.light
+ }
+
+ width: true ? (parent.width * 0.4) | 0 : parent.width
+
+ ListView
+ {
+ id: materialListView
+
+ model: materialsModel
+
+ section.property: "brand"
+ section.criteria: ViewSection.FullString
+ section.delegate: Rectangle
+ {
+ width: materialScrollView.width
+ height: childrenRect.height
+ color: palette.light
+
+ Label
+ {
+ anchors.left: parent.left
+ anchors.leftMargin: UM.Theme.getSize("default_lining").width
+ text: section
+ font.bold: true
+ color: palette.text
+ }
+ }
+
+ delegate: Rectangle
+ {
+ width: materialScrollView.width
+ height: childrenRect.height
+ color: ListView.isCurrentItem ? palette.highlight : (model.index % 2) ? palette.base : palette.alternateBase
+
+ Row
+ {
+ id: materialRow
+ spacing: (UM.Theme.getSize("default_margin").width / 2) | 0
+ anchors.left: parent.left
+ anchors.leftMargin: UM.Theme.getSize("default_margin").width
+ anchors.right: parent.right
+
+ property bool isItemActivated:
+ {
+ const extruder_position = Cura.ExtruderManager.activeExtruderIndex;
+ const root_material_id = Cura.MachineManager.currentRootMaterialId[extruder_position];
+ return model.root_material_id == root_material_id;
+ }
+
+ Rectangle
+ {
+ width: Math.floor(parent.height * 0.8)
+ height: Math.floor(parent.height * 0.8)
+ color: model.color_code
+ border.color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ Label
+ {
+ width: Math.floor((parent.width * 0.3))
+ text: model.material
+ elide: Text.ElideRight
+ font.italic: materialRow.isItemActivated
+ color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
+ }
+ Label
+ {
+ text: (model.name != model.material) ? model.name : ""
+ elide: Text.ElideRight
+ font.italic: materialRow.isItemActivated
+ color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text;
+ }
+ }
+
+ MouseArea
+ {
+ anchors.fill: parent
+ onClicked:
+ {
+ parent.ListView.view.currentIndex = model.index;
+ }
+ }
+ }
+
+ function activateDetailsWithIndex(index)
+ {
+ var model = materialsModel.getItem(index);
+ base.currentItem = model;
+ materialDetailsView.containerId = model.container_id;
+ materialDetailsView.currentMaterialNode = model.container_node;
+
+ detailsPanel.updateMaterialPropertiesObject();
+ }
+
+ onCurrentIndexChanged:
+ {
+ forceActiveFocus(); // causes the changed fields to be saved
+ activateDetailsWithIndex(currentIndex);
+ }
+ }
+ }
+
+
+ Item
+ {
+ id: detailsPanel
+
+ anchors
+ {
+ left: materialScrollView.right
+ leftMargin: UM.Theme.getSize("default_margin").width
+ top: parent.top
+ bottom: parent.bottom
+ right: parent.right
+ }
+
+ function updateMaterialPropertiesObject()
+ {
+ var currentItem = materialsModel.getItem(materialListView.currentIndex);
+
+ materialProperties.name = currentItem.name;
+ materialProperties.guid = currentItem.guid;
+
+ materialProperties.brand = currentItem.brand ? currentItem.brand : "Unknown";
+ materialProperties.material = currentItem.material ? currentItem.material : "Unknown";
+ materialProperties.color_name = currentItem.color_name ? currentItem.color_name : "Yellow";
+ materialProperties.color_code = currentItem.color_code ? currentItem.color_code : "yellow";
+
+ materialProperties.description = currentItem.description ? currentItem.description : "";
+ materialProperties.adhesion_info = currentItem.adhesion_info ? currentItem.adhesion_info : "";
+
+ materialProperties.density = currentItem.density ? currentItem.density : 0.0;
+ materialProperties.diameter = currentItem.diameter ? currentItem.diameter : 0.0;
+ materialProperties.approximate_diameter = currentItem.approximate_diameter ? currentItem.approximate_diameter : "0";
+ }
+
+ Item
+ {
+ anchors.fill: parent
+
+ Item // Material title Label
+ {
+ id: profileName
+
+ width: parent.width
+ height: childrenRect.height
+
+ Label {
+ text: materialProperties.name
+ font: UM.Theme.getFont("large")
+ }
+ }
+
+ MaterialView // Material detailed information view below the title Label
+ {
+ id: materialDetailsView
+ anchors
+ {
+ left: parent.left
+ right: parent.right
+ top: profileName.bottom
+ topMargin: UM.Theme.getSize("default_margin").height
+ bottom: parent.bottom
+ }
+
+ editingEnabled: base.currentItem != null && !base.currentItem.is_read_only
+
+ properties: materialProperties
+ containerId: base.currentItem != null ? base.currentItem.container_id : ""
+ currentMaterialNode: base.currentItem.container_node
+
+ property alias pane: base
+ }
+
+ QtObject
+ {
+ id: materialProperties
+
+ property string guid: "00000000-0000-0000-0000-000000000000"
+ property string name: "Unknown";
+ property string profile_type: "Unknown";
+ property string brand: "Unknown";
+ property string material: "Unknown"; // This needs to be named as "material" to be consistent with
+ // the material container's metadata entry
+
+ property string color_name: "Yellow";
+ property color color_code: "yellow";
+
+ property real density: 0.0;
+ property real diameter: 0.0;
+ property string approximate_diameter: "0";
+
+ property real spool_cost: 0.0;
+ property real spool_weight: 0.0;
+ property real spool_length: 0.0;
+ property real cost_per_meter: 0.0;
+
+ property string description: "";
+ property string adhesion_info: "";
+ }
+ }
}
}
}
diff --git a/resources/qml/Preferences/ProfileTab.qml b/resources/qml/Preferences/ProfileTab.qml
index acebea3500..0ae0899051 100644
--- a/resources/qml/Preferences/ProfileTab.qml
+++ b/resources/qml/Preferences/ProfileTab.qml
@@ -1,8 +1,8 @@
-// Copyright (c) 2016 Ultimaker B.V.
+// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.1
-import QtQuick.Controls 1.1
+import QtQuick 2.7
+import QtQuick.Controls 1.4
import UM 1.2 as UM
import Cura 1.0 as Cura
@@ -11,10 +11,17 @@ Tab
{
id: base
- property string extruderId: "";
- property string extruderDefinition: "";
- property string quality: "";
- property string material: "";
+ property int extruderPosition: -1 //Denotes the global stack.
+ property var qualityItem: null
+
+ property bool isQualityItemCurrentlyActivated:
+ {
+ if (qualityItem == null)
+ {
+ return false;
+ }
+ return qualityItem.name == Cura.MachineManager.activeQualityOrQualityChangesName;
+ }
TableView
{
@@ -38,8 +45,8 @@ Tab
anchors.leftMargin: UM.Theme.getSize("default_margin").width
anchors.right: parent.right
text: (styleData.value.substr(0,1) == "=") ? catalog.i18nc("@info:status", "Calculated") : styleData.value
- font.strikeout: styleData.column == 1 && quality == Cura.MachineManager.globalQualityId && setting.user_value != ""
- font.italic: setting.profile_value_source == "quality_changes" || (quality == Cura.MachineManager.globalQualityId && setting.user_value != "")
+ font.strikeout: styleData.column == 1 && setting.user_value != "" && base.isQualityItemCurrentlyActivated
+ font.italic: setting.profile_value_source == "quality_changes" || (setting.user_value != "" && base.isQualityItemCurrentlyActivated)
opacity: font.strikeout ? 0.5 : 1
color: styleData.textColor
elide: Text.ElideRight
@@ -65,7 +72,7 @@ Tab
{
role: "user_value"
title: catalog.i18nc("@title:column", "Current");
- visible: quality == Cura.MachineManager.globalQualityId
+ visible: base.isQualityItemCurrentlyActivated
width: (parent.width * 0.18) | 0
delegate: itemDelegate
}
@@ -87,10 +94,8 @@ Tab
model: Cura.QualitySettingsModel
{
id: qualitySettings
- extruderId: base.extruderId
- extruderDefinition: base.extruderDefinition
- quality: base.quality != null ? base.quality : ""
- material: base.material != null ? base.material : ""
+ selectedPosition: base.extruderPosition
+ selectedQualityItem: base.qualityItem == null ? {} : base.qualityItem
}
SystemPalette { id: palette }
diff --git a/resources/qml/Preferences/ProfilesPage.qml b/resources/qml/Preferences/ProfilesPage.qml
index e3ba9b23a4..ff35e27eeb 100644
--- a/resources/qml/Preferences/ProfilesPage.qml
+++ b/resources/qml/Preferences/ProfilesPage.qml
@@ -1,355 +1,535 @@
-// Copyright (c) 2016 Ultimaker B.V.
-// Cura is released under the terms of the LGPLv3 or higher.
+// Copyright (c) 2018 Ultimaker B.V.
+// Uranium is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.1
-import QtQuick.Controls 1.1
+import QtQuick 2.7
+import QtQuick.Controls 1.4
+import QtQuick.Layouts 1.3
import QtQuick.Dialogs 1.2
import UM 1.2 as UM
import Cura 1.0 as Cura
-UM.ManagementPage
+
+Item
{
- id: base;
+ id: base
- title: catalog.i18nc("@title:tab", "Profiles");
- property var extrudersModel: Cura.ExtrudersModel{}
+ property QtObject qualityManager: CuraApplication.getQualityManager()
+ property var resetEnabled: false // Keep PreferencesDialog happy
+ property var extrudersModel: Cura.ExtrudersModel {}
- model: Cura.QualityAndUserProfilesModel { }
+ UM.I18nCatalog { id: catalog; name: "cura"; }
- section.property: "readOnly"
- section.delegate: Rectangle
+ Cura.QualityManagementModel {
+ id: qualitiesModel
+ }
+
+ Label {
+ id: titleLabel
+ anchors {
+ top: parent.top
+ left: parent.left
+ right: parent.right
+ margins: 5 * screenScaleFactor
+ }
+ font.pointSize: 18
+ text: catalog.i18nc("@title:tab", "Profiles")
+ }
+
+ property var hasCurrentItem: base.currentItem != null
+
+ property var currentItem: {
+ var current_index = qualityListView.currentIndex;
+ return (current_index == -1) ? null : qualitiesModel.getItem(current_index);
+ }
+
+ property var currentItemName: hasCurrentItem ? base.currentItem.name : ""
+
+ property var isCurrentItemActivated: {
+ if (!base.currentItem) {
+ return false;
+ }
+ return base.currentItem.name == Cura.MachineManager.activeQualityOrQualityChangesName;
+ }
+
+ property var canCreateProfile: {
+ return isCurrentItemActivated && Cura.MachineManager.hasUserSettings;
+ }
+
+ Row // Button Row
{
- height: childrenRect.height;
-
- Label
- {
- anchors.left: parent.left;
- anchors.leftMargin: UM.Theme.getSize("default_lining").width;
- text: section == "true" ? catalog.i18nc("@label", "Protected profiles") : catalog.i18nc("@label", "Custom profiles")
- font.bold: true
+ id: buttonRow
+ anchors {
+ left: parent.left
+ right: parent.right
+ top: titleLabel.bottom
}
- }
+ height: childrenRect.height
- activeId: Cura.MachineManager.activeQualityId
- activeIndex: {
- for(var i = 0; i < model.rowCount(); i++) {
- if (model.getItem(i).id == Cura.MachineManager.activeQualityId) {
- return i;
- }
- }
- return -1;
- }
-
- function canCreateProfile() {
- return base.currentItem && (base.currentItem.id == Cura.MachineManager.activeQualityId) && Cura.MachineManager.hasUserSettings;
- }
-
- buttons: [
+ // Activate button
Button
{
- text: catalog.i18nc("@action:button", "Activate");
- iconName: "list-activate";
- enabled: base.currentItem != null ? base.currentItem.id != Cura.MachineManager.activeQualityId : false;
- onClicked:
- {
- Cura.MachineManager.setActiveQuality(base.currentItem.id)
- currentItem = base.model.getItem(base.objectList.currentIndex) // Refresh the current item.
+ text: catalog.i18nc("@action:button", "Activate")
+ iconName: "list-activate"
+ enabled: !isCurrentItemActivated
+ onClicked: {
+ if (base.currentItem.is_read_only) {
+ Cura.MachineManager.setQualityGroup(base.currentItem.quality_group);
+ } else {
+ Cura.MachineManager.setQualityChangesGroup(base.currentItem.quality_changes_group);
+ }
}
- },
+ }
// Create button
Button
{
text: catalog.i18nc("@label", "Create")
- enabled: base.canCreateProfile() && !Cura.MachineManager.stacksHaveErrors
- visible: base.canCreateProfile()
- iconName: "list-add";
+ iconName: "list-add"
+ enabled: base.canCreateProfile && !Cura.MachineManager.stacksHaveErrors
+ visible: base.canCreateProfile
- onClicked:
- {
- newNameDialog.object = base.currentItem != null ? Cura.ContainerManager.makeUniqueName(base.currentItem.name) : "";
- newNameDialog.open();
- newNameDialog.selectText();
+ onClicked: {
+ createQualityDialog.object = Cura.ContainerManager.makeUniqueName(base.currentItem.name);
+ createQualityDialog.open();
+ createQualityDialog.selectText();
}
- },
+ }
// Duplicate button
Button
{
text: catalog.i18nc("@label", "Duplicate")
- enabled: ! base.canCreateProfile()
- visible: ! base.canCreateProfile()
- iconName: "list-add";
+ iconName: "list-add"
+ enabled: !base.canCreateProfile
+ visible: !base.canCreateProfile
- onClicked:
- {
- newDuplicateNameDialog.object = Cura.ContainerManager.makeUniqueName(base.currentItem.name);
- newDuplicateNameDialog.open();
- newDuplicateNameDialog.selectText();
+ onClicked: {
+ duplicateQualityDialog.object = Cura.ContainerManager.makeUniqueName(base.currentItem.name);
+ duplicateQualityDialog.open();
+ duplicateQualityDialog.selectText();
}
- },
+ }
+ // Remove button
Button
{
- text: catalog.i18nc("@action:button", "Remove");
- iconName: "list-remove";
- enabled: base.currentItem != null ? !base.currentItem.readOnly && !Cura.ContainerManager.isContainerUsed(base.currentItem.id) : false;
- onClicked: confirmDialog.open();
- },
- Button
- {
- text: catalog.i18nc("@action:button", "Rename");
- iconName: "edit-rename";
- enabled: base.currentItem != null ? !base.currentItem.readOnly : false;
- onClicked:
- {
- renameDialog.open();
- renameDialog.selectText();
+ text: catalog.i18nc("@action:button", "Remove")
+ iconName: "list-remove"
+ enabled: base.hasCurrentItem && !base.currentItem.is_read_only && !base.isCurrentItemActivated
+ onClicked: {
+ forceActiveFocus();
+ confirmRemoveQualityDialog.open();
}
- },
+ }
+
+ // Rename button
Button
{
- text: catalog.i18nc("@action:button", "Import");
- iconName: "document-import";
- onClicked: importDialog.open();
- },
+ text: catalog.i18nc("@action:button", "Rename")
+ iconName: "edit-rename"
+ enabled: base.hasCurrentItem && !base.currentItem.is_read_only
+ onClicked: {
+ renameQualityDialog.object = base.currentItem.name;
+ renameQualityDialog.open();
+ renameQualityDialog.selectText();
+ }
+ }
+
+ // Import button
+ Button
+ {
+ text: catalog.i18nc("@action:button", "Import")
+ iconName: "document-import"
+ onClicked: {
+ importDialog.open();
+ }
+ }
+
+ // Export button
Button
{
text: catalog.i18nc("@action:button", "Export")
iconName: "document-export"
- onClicked: exportDialog.open()
- enabled: currentItem != null && !base.currentItem.readOnly
+ enabled: base.hasCurrentItem && !base.currentItem.is_read_only
+ onClicked: {
+ exportDialog.open();
+ }
}
- ]
-
- scrollviewCaption: catalog.i18nc("@label %1 is printer name","Printer: %1").arg(Cura.MachineManager.activeMachineName)
+ }
+ // Click create profile from ... in Profile context menu
signal createProfile()
onCreateProfile:
{
- newNameDialog.object = base.currentItem != null ? Cura.ContainerManager.makeUniqueName(base.currentItem.name) : "";
- newNameDialog.open();
- newNameDialog.selectText();
+ createQualityDialog.object = Cura.ContainerManager.makeUniqueName(Cura.MachineManager.activeQualityOrQualityChangesName);
+ createQualityDialog.open();
+ createQualityDialog.selectText();
}
- signal selectContainer(string name)
- onSelectContainer:
+ // Dialog to request a name when creating a new profile
+ UM.RenameDialog
{
- objectList.currentIndex = objectList.model.find("name", name);
+ id: createQualityDialog
+ title: catalog.i18nc("@title:window", "Create Profile")
+ object: ""
+ onAccepted:
+ {
+ base.newQualityNameToSelect = newName; // We want to switch to the new profile once it's created
+ base.toActivateNewQuality = true;
+ base.qualityManager.createQualityChanges(newName);
+ }
+ }
+
+ property string newQualityNameToSelect: ""
+ property bool toActivateNewQuality: false
+
+ // This connection makes sure that we will switch to the correct quality after the model gets updated
+ Connections
+ {
+ target: qualitiesModel
+ onItemsChanged: {
+ var toSelectItemName = base.currentItem == null ? "" : base.currentItem.name;
+ if (newQualityNameToSelect != "") {
+ toSelectItemName = newQualityNameToSelect;
+ }
+
+ var newIdx = -1; // Default to nothing if nothing can be found
+ if (toSelectItemName != "") {
+ // Select the required quality name if given
+ for (var idx = 0; idx < qualitiesModel.rowCount(); ++idx) {
+ var item = qualitiesModel.getItem(idx);
+ if (item.name == toSelectItemName) {
+ // Switch to the newly created profile if needed
+ newIdx = idx;
+ if (base.toActivateNewQuality) {
+ // Activate this custom quality if required
+ Cura.MachineManager.setQualityChangesGroup(item.quality_changes_group);
+ }
+ break;
+ }
+ }
+ }
+ qualityListView.currentIndex = newIdx;
+
+ // Reset states
+ base.newQualityNameToSelect = "";
+ base.toActivateNewQuality = false;
+ }
+ }
+
+ // Dialog to request a name when duplicating a new profile
+ UM.RenameDialog
+ {
+ id: duplicateQualityDialog
+ title: catalog.i18nc("@title:window", "Duplicate Profile")
+ object: ""
+ onAccepted:
+ {
+ base.qualityManager.duplicateQualityChanges(newName, base.currentItem);
+ }
+ }
+
+ // Confirmation dialog for removing a profile
+ MessageDialog
+ {
+ id: confirmRemoveQualityDialog
+
+ icon: StandardIcon.Question;
+ title: catalog.i18nc("@title:window", "Confirm Remove")
+ text: catalog.i18nc("@label (%1 is object name)", "Are you sure you wish to remove %1? This cannot be undone!").arg(base.currentItemName)
+ standardButtons: StandardButton.Yes | StandardButton.No
+ modality: Qt.ApplicationModal
+
+ onYes:
+ {
+ base.qualityManager.removeQualityChangesGroup(base.currentItem.quality_changes_group);
+ // reset current item to the first if available
+ qualityListView.currentIndex = -1; // Reset selection.
+ }
+ }
+
+ // Dialog to rename a quality profile
+ UM.RenameDialog
+ {
+ id: renameQualityDialog
+ title: catalog.i18nc("@title:window", "Rename Profile")
+ object: ""
+ onAccepted:
+ {
+ var actualNewName = base.qualityManager.renameQualityChangesGroup(base.currentItem.quality_changes_group, newName);
+ base.newQualityNameToSelect = actualNewName; // Select the new name after the model gets updated
+ }
+ }
+
+ // Dialog for importing a quality profile
+ FileDialog
+ {
+ id: importDialog
+ title: catalog.i18nc("@title:window", "Import Profile")
+ selectExisting: true
+ nameFilters: qualitiesModel.getFileNameFilters("profile_reader")
+ folder: CuraApplication.getDefaultPath("dialog_profile_path")
+ onAccepted:
+ {
+ var result = Cura.ContainerManager.importProfile(fileUrl);
+ messageDialog.text = result.message;
+ if (result.status == "ok") {
+ messageDialog.icon = StandardIcon.Information;
+ }
+ else if (result.status == "duplicate") {
+ messageDialog.icon = StandardIcon.Warning;
+ }
+ else {
+ messageDialog.icon = StandardIcon.Critical;
+ }
+ messageDialog.open();
+ CuraApplication.setDefaultPath("dialog_profile_path", folder);
+ }
+ }
+
+ // Dialog for exporting a quality profile
+ FileDialog
+ {
+ id: exportDialog
+ title: catalog.i18nc("@title:window", "Export Profile")
+ selectExisting: false
+ nameFilters: qualitiesModel.getFileNameFilters("profile_writer")
+ folder: CuraApplication.getDefaultPath("dialog_profile_path")
+ onAccepted:
+ {
+ var result = Cura.ContainerManager.exportQualityChangesGroup(base.currentItem.quality_changes_group,
+ fileUrl, selectedNameFilter);
+
+ if (result && result.status == "error") {
+ messageDialog.icon = StandardIcon.Critical;
+ messageDialog.text = result.message;
+ messageDialog.open();
+ }
+
+ // else pop-up Message thing from python code
+ CuraApplication.setDefaultPath("dialog_profile_path", folder);
+ }
}
Item {
- visible: base.currentItem != null
- anchors.fill: parent
+ id: contentsItem
- Label {
- id: profileName
- text: base.currentItem ? base.currentItem.name: ""
- font: UM.Theme.getFont("large")
- width: parent.width
- elide: Text.ElideRight
+ anchors {
+ top: titleLabel.bottom
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ margins: 5 * screenScaleFactor
+ bottomMargin: 0
}
- Flow {
- id: currentSettingsActions
- visible: currentItem && currentItem.id == Cura.MachineManager.activeQualityId
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.top: profileName.bottom
- anchors.topMargin: UM.Theme.getSize("default_margin").height
-
- Button
- {
- text: {
- return catalog.i18nc("@action:button", "Update profile with current settings/overrides");
- }
- enabled: Cura.MachineManager.hasUserSettings && !Cura.MachineManager.isReadOnly(Cura.MachineManager.activeQualityId)
- onClicked: Cura.ContainerManager.updateQualityChanges()
- }
-
- Button
- {
- text: catalog.i18nc("@action:button", "Discard current changes");
- enabled: Cura.MachineManager.hasUserSettings
- onClicked: Cura.ContainerManager.clearUserContainers();
- }
- }
-
- Column {
- id: profileNotices
- anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : currentSettingsActions.anchors.top
- anchors.topMargin: UM.Theme.getSize("default_margin").height
- anchors.left: parent.left
- anchors.right: parent.right
- spacing: UM.Theme.getSize("default_margin").height
-
- Label {
- id: defaultsMessage
- visible: false
- text: catalog.i18nc("@action:label", "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below.")
- wrapMode: Text.WordWrap
- width: parent.width
- }
- Label {
- id: noCurrentSettingsMessage
- visible: currentItem && currentItem.id == Cura.MachineManager.activeQualityId && !Cura.MachineManager.hasUserSettings
- text: catalog.i18nc("@action:label", "Your current settings match the selected profile.")
- wrapMode: Text.WordWrap
- width: parent.width
- }
- }
-
- TabView
- {
- anchors.left: parent.left
- anchors.top: profileNotices.visible ? profileNotices.bottom : profileNotices.anchors.top
- anchors.topMargin: UM.Theme.getSize("default_margin").height
- anchors.right: parent.right
- anchors.bottom: parent.bottom
-
- currentIndex: Cura.ExtruderManager.extruderCount > 0 ? Cura.ExtruderManager.activeExtruderIndex + 1 : 0
-
- ProfileTab
- {
- title: catalog.i18nc("@title:tab", "Global Settings");
- quality: base.currentItem != null ? base.currentItem.id : "";
- material: Cura.MachineManager.allActiveMaterialIds[Cura.MachineManager.activeMachineId]
- }
-
- Repeater
- {
- model: base.extrudersModel
-
- ProfileTab
- {
- title: model.name;
- extruderId: model.id;
- extruderDefinition: model.definition;
- quality: base.currentItem != null ? base.currentItem.id : "";
- material: Cura.MachineManager.allActiveMaterialIds[model.id]
- }
- }
- }
+ clip: true
}
Item
{
- UM.I18nCatalog { id: catalog; name: "cura"; }
+ anchors {
+ top: buttonRow.bottom
+ topMargin: UM.Theme.getSize("default_margin").height
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ }
- UM.ConfirmRemoveDialog
+ SystemPalette { id: palette }
+
+ Label
{
- id: confirmDialog
- object: base.currentItem != null ? base.currentItem.name : ""
- onYes:
+ id: captionLabel
+ anchors {
+ top: parent.top
+ left: parent.left
+ }
+ visible: text != ""
+ text: catalog.i18nc("@label %1 is printer name", "Printer: %1").arg(Cura.MachineManager.activeMachineName)
+ width: profileScrollView.width
+ elide: Text.ElideRight
+ }
+
+ ScrollView
+ {
+ id: profileScrollView
+ anchors {
+ top: captionLabel.visible ? captionLabel.bottom : parent.top
+ topMargin: captionLabel.visible ? UM.Theme.getSize("default_margin").height : 0
+ bottom: parent.bottom
+ left: parent.left
+ }
+
+ Rectangle {
+ parent: viewport
+ anchors.fill: parent
+ color: palette.light
+ }
+
+ width: true ? (parent.width * 0.4) | 0 : parent.width
+
+ ListView
{
- var name = base.currentItem.name;
- Cura.ContainerManager.removeQualityChanges(name)
- if(Cura.MachineManager.activeQualityName == name)
+ id: qualityListView
+
+ model: qualitiesModel
+
+ section.property: "is_read_only"
+ section.delegate: Rectangle
{
- Cura.MachineManager.setActiveQuality(base.model.getItem(0).name)
+ height: childrenRect.height
+
+ Label
+ {
+ anchors.left: parent.left
+ anchors.leftMargin: UM.Theme.getSize("default_lining").width
+ text: section == "true" ? catalog.i18nc("@label", "Protected profiles") : catalog.i18nc("@label", "Custom profiles")
+ font.bold: true
+ }
+ }
+
+ delegate: Rectangle
+ {
+ width: profileScrollView.width
+ height: childrenRect.height
+ color: ListView.isCurrentItem ? palette.highlight : (model.index % 2) ? palette.base : palette.alternateBase
+
+ Row
+ {
+ spacing: (UM.Theme.getSize("default_margin").width / 2) | 0
+ anchors.left: parent.left
+ anchors.leftMargin: UM.Theme.getSize("default_margin").width
+ anchors.right: parent.right
+ Label
+ {
+ width: Math.floor((parent.width * 0.8))
+ text: model.name
+ elide: Text.ElideRight
+ font.italic: model.name == Cura.MachineManager.activeQualityOrQualityChangesName
+ color: parent.ListView.isCurrentItem ? palette.highlightedText : palette.text
+ }
+ }
+
+ MouseArea
+ {
+ anchors.fill: parent
+ onClicked: {
+ parent.ListView.view.currentIndex = model.index;
+ }
+ }
}
- objectList.currentIndex = -1 //Reset selection.
}
}
- UM.RenameDialog
+ // details panel on the right
+ Item
{
- title: catalog.i18nc("@title:window", "Rename Profile")
- id: renameDialog;
- object: base.currentItem != null ? base.currentItem.name : ""
- onAccepted:
- {
- Cura.ContainerManager.renameQualityChanges(base.currentItem.name, newName)
- objectList.currentIndex = -1 //Reset selection.
+ id: detailsPanel
+
+ anchors {
+ left: profileScrollView.right
+ leftMargin: UM.Theme.getSize("default_margin").width
+ top: parent.top
+ bottom: parent.bottom
+ right: parent.right
}
- }
- // Dialog to request a name when creating a new profile
- UM.RenameDialog
- {
- title: catalog.i18nc("@title:window", "Create Profile")
- id: newNameDialog;
- object: "";
- onAccepted:
+ Item
{
- var selectedContainer = Cura.ContainerManager.createQualityChanges(newName);
- base.selectContainer(selectedContainer);
- objectList.currentIndex = -1 //Reset selection.
- }
- }
+ anchors.fill: parent
+ visible: base.currentItem != null
- // Dialog to request a name when duplicating a new profile
- UM.RenameDialog
- {
- title: catalog.i18nc("@title:window", "Duplicate Profile")
- id: newDuplicateNameDialog;
- object: "";
- onAccepted:
- {
- var selectedContainer = Cura.ContainerManager.duplicateQualityOrQualityChanges(base.currentItem.name, newName);
- base.selectContainer(selectedContainer);
- objectList.currentIndex = -1 //Reset selection.
- }
- }
-
- MessageDialog
- {
- id: messageDialog
- title: catalog.i18nc("@window:title", "Import Profile");
- standardButtons: StandardButton.Ok
- modality: Qt.ApplicationModal
- }
-
- FileDialog
- {
- id: importDialog;
- title: catalog.i18nc("@title:window", "Import Profile");
- selectExisting: true;
- nameFilters: base.model.getFileNameFilters("profile_reader")
- folder: CuraApplication.getDefaultPath("dialog_profile_path")
- onAccepted:
- {
- var result = Cura.ContainerManager.importProfile(fileUrl);
- messageDialog.text = result.message
- if(result.status == "ok")
+ Item // Profile title Label
{
- messageDialog.icon = StandardIcon.Information
- }
- else if(result.status == "duplicate")
- {
- messageDialog.icon = StandardIcon.Warning
- }
- else
- {
- messageDialog.icon = StandardIcon.Critical
- }
- messageDialog.open()
- CuraApplication.setDefaultPath("dialog_profile_path", folder)
- }
- }
+ id: profileName
- FileDialog
- {
- id: exportDialog;
- title: catalog.i18nc("@title:window", "Export Profile");
- selectExisting: false;
- nameFilters: base.model.getFileNameFilters("profile_writer")
- folder: CuraApplication.getDefaultPath("dialog_profile_path")
- onAccepted:
- {
- var containers = Cura.ContainerManager.findInstanceContainers({"type": "quality_changes", "name": base.currentItem.name})
- var result = Cura.ContainerManager.exportProfile(containers, fileUrl, selectedNameFilter)
+ width: parent.width
+ height: childrenRect.height
- if(result && result.status == "error")
- {
- messageDialog.icon = StandardIcon.Critical
- messageDialog.text = result.message
- messageDialog.open()
+ Label {
+ text: base.currentItemName
+ font: UM.Theme.getFont("large")
+ }
}
- // else pop-up Message thing from python code
- CuraApplication.setDefaultPath("dialog_profile_path", folder)
+ Flow {
+ id: currentSettingsActions
+ visible: base.hasCurrentItem && base.currentItem.name == Cura.MachineManager.activeQualityOrQualityChangesName
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.top: profileName.bottom
+ anchors.topMargin: UM.Theme.getSize("default_margin").height
+
+ Button
+ {
+ text: catalog.i18nc("@action:button", "Update profile with current settings/overrides")
+ enabled: Cura.MachineManager.hasUserSettings && !base.currentItem.is_read_only
+ onClicked: Cura.ContainerManager.updateQualityChanges()
+ }
+
+ Button
+ {
+ text: catalog.i18nc("@action:button", "Discard current changes");
+ enabled: Cura.MachineManager.hasUserSettings
+ onClicked: Cura.ContainerManager.clearUserContainers();
+ }
+ }
+
+ Column {
+ id: profileNotices
+ anchors.top: currentSettingsActions.visible ? currentSettingsActions.bottom : currentSettingsActions.anchors.top
+ anchors.topMargin: UM.Theme.getSize("default_margin").height
+ anchors.left: parent.left
+ anchors.right: parent.right
+ spacing: UM.Theme.getSize("default_margin").height
+
+ Label {
+ id: defaultsMessage
+ visible: false
+ text: catalog.i18nc("@action:label", "This profile uses the defaults specified by the printer, so it has no settings/overrides in the list below.")
+ wrapMode: Text.WordWrap
+ width: parent.width
+ }
+ Label {
+ id: noCurrentSettingsMessage
+ visible: base.isCurrentItemActivated && !Cura.MachineManager.hasUserSettings
+ text: catalog.i18nc("@action:label", "Your current settings match the selected profile.")
+ wrapMode: Text.WordWrap
+ width: parent.width
+ }
+ }
+
+
+ TabView
+ {
+ anchors.left: parent.left
+ anchors.top: profileNotices.visible ? profileNotices.bottom : profileNotices.anchors.top
+ anchors.topMargin: UM.Theme.getSize("default_margin").height
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+
+ currentIndex: 0
+
+ ProfileTab
+ {
+ title: catalog.i18nc("@title:tab", "Global Settings")
+ qualityItem: base.currentItem
+ }
+
+ Repeater
+ {
+ model: base.extrudersModel
+
+ ProfileTab
+ {
+ title: model.name
+ extruderPosition: model.index
+ qualityItem: base.currentItem
+ }
+ }
+ }
}
}
}
diff --git a/resources/qml/Preferences/SettingVisibilityPage.qml b/resources/qml/Preferences/SettingVisibilityPage.qml
index c0a6d42b65..0e3069d194 100644
--- a/resources/qml/Preferences/SettingVisibilityPage.qml
+++ b/resources/qml/Preferences/SettingVisibilityPage.qml
@@ -179,8 +179,10 @@ UM.PreferencesPage
onActivated:
{
// TODO What to do if user is selected "Custom from Combobox" ?
- if (model.get(index).text == "Custom")
+ if (model.get(index).text == "Custom"){
+ UM.Preferences.setValue("general/preset_setting_visibility_choice", model.get(index).text)
return
+ }
var newVisibleSettings = CuraApplication.getVisibilitySettingPreset(model.get(index).text)
UM.Preferences.setValue("general/visible_settings", newVisibleSettings)
@@ -267,7 +269,6 @@ UM.PreferencesPage
{
visibilityPreset.currentIndex = visibilityPreset.model.count - 1
UM.Preferences.setValue("general/preset_setting_visibility_choice", visibilityPreset.model.get(visibilityPreset.currentIndex).text)
-
}
}
}
diff --git a/resources/qml/PrintMonitor.qml b/resources/qml/PrintMonitor.qml
index 471729192e..ae74170004 100644
--- a/resources/qml/PrintMonitor.qml
+++ b/resources/qml/PrintMonitor.qml
@@ -1,7 +1,7 @@
-// Copyright (c) 2017 Ultimaker B.V.
+// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.2
+import QtQuick 2.7
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
@@ -50,7 +50,7 @@ Column
ExtruderBox
{
color: UM.Theme.getColor("sidebar")
- width: index == machineExtruderCount.properties.value - 1 && index % 2 == 0 ? extrudersGrid.width : Math.floor(extrudersGrid.width / 2 - UM.Theme.getSize("sidebar_lining_thin").width / 2)
+ width: index == machineExtruderCount.properties.value - 1 && index % 2 == 0 ? extrudersGrid.width : Math.round(extrudersGrid.width / 2 - UM.Theme.getSize("sidebar_lining_thin").width / 2)
extruderModel: modelData
}
}
@@ -122,7 +122,7 @@ Column
{
label: catalog.i18nc("@label", "Printing Time")
value: activePrintJob != null ? getPrettyTime(activePrintJob.timeTotal) : ""
- width:base.width
+ width: base.width
visible: activePrinter != null
}
diff --git a/resources/qml/SaveButton.qml b/resources/qml/SaveButton.qml
index bf44a29cf5..0369f492b4 100644
--- a/resources/qml/SaveButton.qml
+++ b/resources/qml/SaveButton.qml
@@ -1,7 +1,7 @@
-// Copyright (c) 2017 Ultimaker B.V.
+// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.2
+import QtQuick 2.7
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
@@ -76,7 +76,7 @@ Item {
width: parent.width - 2 * UM.Theme.getSize("sidebar_margin").width
height: UM.Theme.getSize("progressbar").height
anchors.top: statusLabel.bottom
- anchors.topMargin: UM.Theme.getSize("sidebar_margin").height/4
+ anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 4)
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
radius: UM.Theme.getSize("progressbar_radius").width
@@ -131,7 +131,7 @@ Item {
Row {
id: additionalComponentsRow
anchors.top: parent.top
- anchors.right: saveToButton.visible ? saveToButton.left : parent.right
+ anchors.right: saveToButton.visible ? saveToButton.left : (prepareButton.visible ? prepareButton.left : parent.right)
anchors.rightMargin: UM.Theme.getSize("default_margin").width
spacing: UM.Theme.getSize("default_margin").width
@@ -354,7 +354,7 @@ Item {
}
Behavior on color { ColorAnimation { duration: 50; } }
anchors.left: parent.left
- anchors.leftMargin: UM.Theme.getSize("save_button_text_margin").width / 2;
+ anchors.leftMargin: Math.round(UM.Theme.getSize("save_button_text_margin").width / 2);
width: parent.height
height: parent.height
diff --git a/resources/qml/Settings/SettingCategory.qml b/resources/qml/Settings/SettingCategory.qml
index 13576eb483..3612c4cf29 100644
--- a/resources/qml/Settings/SettingCategory.qml
+++ b/resources/qml/Settings/SettingCategory.qml
@@ -78,6 +78,7 @@ Button
verticalCenter: parent.verticalCenter;
}
text: definition.label
+ renderType: Text.NativeRendering
font: UM.Theme.getFont("setting_category")
color:
{
@@ -187,13 +188,13 @@ Button
id: settingsButton
visible: base.hovered || settingsButton.hovered
- height: base.height * 0.6
- width: base.height * 0.6
+ height: Math.round(base.height * 0.6)
+ width: Math.round(base.height * 0.6)
anchors {
right: inheritButton.visible ? inheritButton.left : parent.right
// use 1.9 as the factor because there is a 0.1 difference between the settings and inheritance warning icons
- rightMargin: inheritButton.visible ? UM.Theme.getSize("default_margin").width / 2 : category_arrow.width + UM.Theme.getSize("default_margin").width * 1.9
+ rightMargin: inheritButton.visible ? Math.round(UM.Theme.getSize("default_margin").width / 2) : category_arrow.width + Math.round(UM.Theme.getSize("default_margin").width * 1.9)
verticalCenter: parent.verticalCenter
}
@@ -231,7 +232,7 @@ Button
return false
}
- height: parent.height / 2
+ height: Math.round(parent.height / 2)
width: height
onClicked:
diff --git a/resources/qml/Settings/SettingCheckBox.qml b/resources/qml/Settings/SettingCheckBox.qml
index c4d6a5c764..d37754d27c 100644
--- a/resources/qml/Settings/SettingCheckBox.qml
+++ b/resources/qml/Settings/SettingCheckBox.qml
@@ -1,8 +1,8 @@
-// Copyright (c) 2015 Ultimaker B.V.
+// Copyright (c) 2018 Ultimaker B.V.
// Uranium is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
-import QtQuick.Layouts 1.1
+import QtQuick.Layouts 1.2
import QtQuick.Controls 2.0
import UM 1.2 as UM
@@ -118,8 +118,8 @@ SettingItem
UM.RecolorImage {
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
- width: parent.width / 2.5
- height: parent.height / 2.5
+ width: Math.round(parent.width / 2.5)
+ height: Math.round(parent.height / 2.5)
sourceSize.width: width
sourceSize.height: width
color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text");
diff --git a/resources/qml/Settings/SettingComboBox.qml b/resources/qml/Settings/SettingComboBox.qml
index 64b704c51f..ed4a7b41c2 100644
--- a/resources/qml/Settings/SettingComboBox.qml
+++ b/resources/qml/Settings/SettingComboBox.qml
@@ -61,7 +61,7 @@ SettingItem
{
id: downArrow
x: control.width - width - control.rightPadding
- y: control.topPadding + (control.availableHeight - height) / 2
+ y: control.topPadding + Math.round((control.availableHeight - height) / 2)
source: UM.Theme.getIcon("arrow_bottom")
width: UM.Theme.getSize("standard_arrow").width
@@ -80,6 +80,7 @@ SettingItem
anchors.right: downArrow.left
text: control.currentText
+ renderType: Text.NativeRendering
font: UM.Theme.getFont("default")
color: !enabled ? UM.Theme.getColor("setting_control_disabled_text") : UM.Theme.getColor("setting_control_text")
elide: Text.ElideRight
@@ -116,6 +117,7 @@ SettingItem
contentItem: Label
{
text: modelData.value
+ renderType: Text.NativeRendering
color: control.contentItem.color
font: UM.Theme.getFont("default")
elide: Text.ElideRight
diff --git a/resources/qml/Settings/SettingExtruder.qml b/resources/qml/Settings/SettingExtruder.qml
index 50c46ae321..2ddbb135c7 100644
--- a/resources/qml/Settings/SettingExtruder.qml
+++ b/resources/qml/Settings/SettingExtruder.qml
@@ -17,14 +17,39 @@ SettingItem
id: control
anchors.fill: parent
- model: Cura.ExtrudersModel { onModelChanged: control.color = getItem(control.currentIndex).color }
+ model: Cura.ExtrudersModel
+ {
+ onModelChanged: {
+ control.color = getItem(control.currentIndex).color;
+ }
+ }
textRole: "name"
+ // knowing the extruder position, try to find the item index in the model
+ function getIndexByPosition(position)
+ {
+ for (var item_index in model.items)
+ {
+ var item = model.getItem(item_index)
+ if (item.index == position)
+ {
+ return item_index
+ }
+ }
+ return -1
+ }
+
onActivated:
{
- forceActiveFocus();
- propertyProvider.setPropertyValue("value", model.getItem(index).index);
+ if (model.getItem(index).enabled)
+ {
+ forceActiveFocus();
+ propertyProvider.setPropertyValue("value", model.getItem(index).index);
+ } else
+ {
+ currentIndex = propertyProvider.properties.value; // keep the old value
+ }
}
onActiveFocusChanged:
@@ -64,11 +89,28 @@ SettingItem
value: control.currentText != "" ? control.model.getItem(control.currentIndex).color : ""
}
+ Binding
+ {
+ target: control
+ property: "currentIndex"
+ value:
+ {
+ if(propertyProvider.properties.value == -1)
+ {
+ return control.getIndexByPosition(Cura.MachineManager.defaultExtruderPosition);
+ }
+ return propertyProvider.properties.value
+ }
+ // Sometimes when the value is already changed, the model is still being built.
+ // The when clause ensures that the current index is not updated when this happens.
+ when: control.model.items.length > 0
+ }
+
indicator: UM.RecolorImage
{
id: downArrow
x: control.width - width - control.rightPadding
- y: control.topPadding + (control.availableHeight - height) / 2
+ y: control.topPadding + Math.round((control.availableHeight - height) / 2)
source: UM.Theme.getIcon("arrow_bottom")
width: UM.Theme.getSize("standard_arrow").width
@@ -117,6 +159,7 @@ SettingItem
rightPadding: swatch.width + UM.Theme.getSize("setting_unit_margin").width
text: control.currentText
+ renderType: Text.NativeRendering
font: UM.Theme.getFont("default")
color: enabled ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text")
@@ -126,16 +169,16 @@ SettingItem
background: Rectangle
{
id: swatch
- height: UM.Theme.getSize("setting_control").height / 2
+ height: Math.round(UM.Theme.getSize("setting_control").height / 2)
width: height
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
- anchors.margins: UM.Theme.getSize("default_margin").width / 4
+ anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4)
border.width: UM.Theme.getSize("default_lining").width
border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border")
- radius: width / 2
+ radius: Math.round(width / 2)
color: control.color
}
@@ -171,7 +214,14 @@ SettingItem
contentItem: Label
{
text: model.name
- color: UM.Theme.getColor("setting_control_text")
+ renderType: Text.NativeRendering
+ color: {
+ if (model.enabled) {
+ UM.Theme.getColor("setting_control_text")
+ } else {
+ UM.Theme.getColor("action_button_disabled_text");
+ }
+ }
font: UM.Theme.getFont("default")
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
@@ -180,16 +230,16 @@ SettingItem
background: Rectangle
{
id: swatch
- height: UM.Theme.getSize("setting_control").height / 2
+ height: Math.round(UM.Theme.getSize("setting_control").height / 2)
width: height
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
- anchors.margins: UM.Theme.getSize("default_margin").width / 4
+ anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4)
border.width: UM.Theme.getSize("default_lining").width
border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border")
- radius: width / 2
+ radius: Math.round(width / 2)
color: control.model.getItem(index).color
}
diff --git a/resources/qml/Settings/SettingItem.qml b/resources/qml/Settings/SettingItem.qml
index 414f05d80e..013371e528 100644
--- a/resources/qml/Settings/SettingItem.qml
+++ b/resources/qml/Settings/SettingItem.qml
@@ -1,8 +1,8 @@
-// Copyright (c) 2017 Ultimaker B.V.
+// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
-import QtQuick.Layouts 1.1
+import QtQuick.Layouts 1.2
import QtQuick.Controls 2.0
import UM 1.1 as UM
@@ -108,15 +108,13 @@ Item {
id: label;
anchors.left: parent.left;
- anchors.leftMargin: doDepthIndentation ? (UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width) : 0
+ anchors.leftMargin: doDepthIndentation ? Math.round((UM.Theme.getSize("section_icon_column").width + 5) + ((definition.depth - 1) * UM.Theme.getSize("setting_control_depth_margin").width)) : 0
anchors.right: settingControls.left;
anchors.verticalCenter: parent.verticalCenter
- height: UM.Theme.getSize("section").height;
- verticalAlignment: Text.AlignVCenter;
-
text: definition.label
elide: Text.ElideMiddle;
+ renderType: Text.NativeRendering
color: UM.Theme.getColor("setting_control_text");
opacity: (definition.visible) ? 1 : 0.5
@@ -128,12 +126,12 @@ Item {
{
id: settingControls
- height: parent.height / 2
- spacing: UM.Theme.getSize("sidebar_margin").height / 2
+ height: Math.round(parent.height / 2)
+ spacing: Math.round(UM.Theme.getSize("sidebar_margin").height / 2)
anchors {
right: controlContainer.left
- rightMargin: UM.Theme.getSize("sidebar_margin").width / 2
+ rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width / 2)
verticalCenter: parent.verticalCenter
}
diff --git a/resources/qml/Settings/SettingOptionalExtruder.qml b/resources/qml/Settings/SettingOptionalExtruder.qml
index 409587b487..f49b7035d7 100644
--- a/resources/qml/Settings/SettingOptionalExtruder.qml
+++ b/resources/qml/Settings/SettingOptionalExtruder.qml
@@ -87,7 +87,7 @@ SettingItem
{
id: downArrow
x: control.width - width - control.rightPadding
- y: control.topPadding + (control.availableHeight - height) / 2
+ y: control.topPadding + Math.round((control.availableHeight - height) / 2)
source: UM.Theme.getIcon("arrow_bottom")
width: UM.Theme.getSize("standard_arrow").width
@@ -136,6 +136,7 @@ SettingItem
rightPadding: swatch.width + UM.Theme.getSize("setting_unit_margin").width
text: control.currentText
+ renderType: Text.NativeRendering
font: UM.Theme.getFont("default")
color: enabled ? UM.Theme.getColor("setting_control_text") : UM.Theme.getColor("setting_control_disabled_text")
@@ -145,16 +146,16 @@ SettingItem
background: Rectangle
{
id: swatch
- height: UM.Theme.getSize("setting_control").height / 2
+ height: Math.round(UM.Theme.getSize("setting_control").height / 2)
width: height
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
- anchors.margins: UM.Theme.getSize("default_margin").width / 4
+ anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4)
border.width: UM.Theme.getSize("default_lining").width
border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border")
- radius: width / 2
+ radius: Math.round(width / 2)
color: control.color
}
@@ -190,6 +191,7 @@ SettingItem
contentItem: Label
{
text: model.name
+ renderType: Text.NativeRendering
color: UM.Theme.getColor("setting_control_text")
font: UM.Theme.getFont("default")
elide: Text.ElideRight
@@ -199,16 +201,16 @@ SettingItem
background: Rectangle
{
id: swatch
- height: UM.Theme.getSize("setting_control").height / 2
+ height: Math.round(UM.Theme.getSize("setting_control").height / 2)
width: height
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
- anchors.margins: UM.Theme.getSize("default_margin").width / 4
+ anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4)
border.width: UM.Theme.getSize("default_lining").width
border.color: enabled ? UM.Theme.getColor("setting_control_border") : UM.Theme.getColor("setting_control_disabled_border")
- radius: width / 2
+ radius: Math.round(width / 2)
color: control.model.getItem(index).color
}
diff --git a/resources/qml/Settings/SettingTextField.qml b/resources/qml/Settings/SettingTextField.qml
index 489f23c6d1..4693bec50d 100644
--- a/resources/qml/Settings/SettingTextField.qml
+++ b/resources/qml/Settings/SettingTextField.qml
@@ -26,7 +26,7 @@ SettingItem
anchors.fill: parent
- border.width: UM.Theme.getSize("default_lining").width
+ border.width: Math.round(UM.Theme.getSize("default_lining").width)
border.color:
{
if(!enabled)
@@ -76,18 +76,19 @@ SettingItem
Rectangle
{
anchors.fill: parent;
- anchors.margins: UM.Theme.getSize("default_lining").width;
+ anchors.margins: Math.round(UM.Theme.getSize("default_lining").width);
color: UM.Theme.getColor("setting_control_highlight")
opacity: !control.hovered ? 0 : propertyProvider.properties.validationState == "ValidatorState.Valid" ? 1.0 : 0.35;
}
Label
{
- anchors.right: parent.right;
- anchors.rightMargin: UM.Theme.getSize("setting_unit_margin").width
- anchors.verticalCenter: parent.verticalCenter;
+ anchors.right: parent.right
+ anchors.rightMargin: Math.round(UM.Theme.getSize("setting_unit_margin").width)
+ anchors.verticalCenter: parent.verticalCenter
- text: definition.unit;
+ text: definition.unit
+ renderType: Text.NativeRendering
color: UM.Theme.getColor("setting_unit")
font: UM.Theme.getFont("default")
}
@@ -107,9 +108,9 @@ SettingItem
anchors
{
left: parent.left
- leftMargin: UM.Theme.getSize("setting_unit_margin").width
+ leftMargin: Math.round(UM.Theme.getSize("setting_unit_margin").width)
right: parent.right
- rightMargin: UM.Theme.getSize("setting_unit_margin").width
+ rightMargin: Math.round(UM.Theme.getSize("setting_unit_margin").width)
verticalCenter: parent.verticalCenter
}
renderType: Text.NativeRendering
diff --git a/resources/qml/Settings/SettingView.qml b/resources/qml/Settings/SettingView.qml
index 21e79ee967..615e66277b 100644
--- a/resources/qml/Settings/SettingView.qml
+++ b/resources/qml/Settings/SettingView.qml
@@ -4,7 +4,7 @@
import QtQuick 2.7
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
-import QtQuick.Layouts 1.1
+import QtQuick.Layouts 1.2
import UM 1.2 as UM
import Cura 1.0 as Cura
@@ -30,16 +30,16 @@ Item
{
top: parent.top
left: parent.left
- leftMargin: UM.Theme.getSize("sidebar_margin").width
+ leftMargin: Math.round(UM.Theme.getSize("sidebar_margin").width)
right: parent.right
- rightMargin: UM.Theme.getSize("sidebar_margin").width
+ rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width)
}
Label
{
id: globalProfileLabel
text: catalog.i18nc("@label","Profile:");
- width: Math.floor(parent.width * 0.45 - UM.Theme.getSize("sidebar_margin").width - 2)
+ width: Math.round(parent.width * 0.45 - UM.Theme.getSize("sidebar_margin").width - 2)
font: UM.Theme.getFont("default");
color: UM.Theme.getColor("text");
verticalAlignment: Text.AlignVCenter
@@ -53,17 +53,17 @@ Item
text: generateActiveQualityText()
enabled: !header.currentExtruderVisible || header.currentExtruderIndex > -1
- width: Math.floor(parent.width * 0.55)
+ width: Math.round(parent.width * 0.55)
height: UM.Theme.getSize("setting_control").height
anchors.left: globalProfileLabel.right
anchors.right: parent.right
- tooltip: Cura.MachineManager.activeQualityName
+ tooltip: Cura.MachineManager.activeQualityOrQualityChangesName
style: UM.Theme.styles.sidebar_header_button
activeFocusOnPress: true
menu: ProfileMenu { }
function generateActiveQualityText () {
- var result = Cura.MachineManager.activeQualityName;
+ var result = Cura.MachineManager.activeQualityOrQualityChangesName;
if (Cura.MachineManager.isActiveQualitySupported) {
if (Cura.MachineManager.activeQualityLayerHeight > 0) {
@@ -82,12 +82,12 @@ Item
id: customisedSettings
visible: Cura.MachineManager.hasUserSettings
- height: Math.floor(parent.height * 0.6)
- width: Math.floor(parent.height * 0.6)
+ height: Math.round(parent.height * 0.6)
+ width: Math.round(parent.height * 0.6)
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
- anchors.rightMargin: UM.Theme.getSize("setting_preferences_button_margin").width - UM.Theme.getSize("sidebar_margin").width
+ anchors.rightMargin: Math.round(UM.Theme.getSize("setting_preferences_button_margin").width - UM.Theme.getSize("sidebar_margin").width)
color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button");
iconSource: UM.Theme.getIcon("star");
@@ -112,7 +112,7 @@ Item
id: filterContainer
visible: true
- border.width: UM.Theme.getSize("default_lining").width
+ border.width: Math.round(UM.Theme.getSize("default_lining").width)
border.color:
{
if(hoverMouseArea.containsMouse || clearFilterButton.containsMouse)
@@ -132,9 +132,9 @@ Item
top: globalProfileRow.bottom
topMargin: UM.Theme.getSize("sidebar_margin").height
left: parent.left
- leftMargin: UM.Theme.getSize("sidebar_margin").width
+ leftMargin: Math.round(UM.Theme.getSize("sidebar_margin").width)
right: parent.right
- rightMargin: UM.Theme.getSize("sidebar_margin").width
+ rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width)
}
height: visible ? UM.Theme.getSize("setting_control").height : 0
Behavior on height { NumberAnimation { duration: 100 } }
@@ -142,10 +142,10 @@ Item
TextField
{
id: filter;
-
+ height: parent.height
anchors.left: parent.left
anchors.right: clearFilterButton.left
- anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
+ anchors.rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width)
placeholderText: catalog.i18nc("@label:textbox", "Search...")
@@ -204,12 +204,12 @@ Item
iconSource: UM.Theme.getIcon("cross1")
visible: findingSettings
- height: parent.height * 0.4
+ height: Math.round(parent.height * 0.4)
width: visible ? height : 0
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
- anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
+ anchors.rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width)
color: UM.Theme.getColor("setting_control_button")
hoverColor: UM.Theme.getColor("setting_control_button_hover")
@@ -238,7 +238,7 @@ Item
ListView
{
id: contents
- spacing: UM.Theme.getSize("default_lining").height;
+ spacing: Math.round(UM.Theme.getSize("default_lining").height);
cacheBuffer: 1000000; // Set a large cache to effectively just cache every list item.
model: UM.SettingDefinitionsModel
@@ -266,7 +266,7 @@ Item
{
id: delegate
- width: UM.Theme.getSize("sidebar").width;
+ width: Math.round(UM.Theme.getSize("sidebar").width);
height: provider.properties.enabled == "True" ? UM.Theme.getSize("section").height : - contents.spacing
Behavior on height { NumberAnimation { duration: 100 } }
opacity: provider.properties.enabled == "True" ? 1 : 0
@@ -388,7 +388,7 @@ Item
contextMenu.provider = provider
contextMenu.popup();
}
- onShowTooltip: base.showTooltip(delegate, { x: -UM.Theme.getSize("default_arrow").width, y: delegate.height / 2 }, text)
+ onShowTooltip: base.showTooltip(delegate, { x: -UM.Theme.getSize("default_arrow").width, y: Math.round(delegate.height / 2) }, text)
onHideTooltip: base.hideTooltip()
onShowAllHiddenInheritedSettings:
{
@@ -544,4 +544,4 @@ Item
}
}
}
-}
\ No newline at end of file
+}
diff --git a/resources/qml/Sidebar.qml b/resources/qml/Sidebar.qml
index 8903478bde..e3107ea7f8 100644
--- a/resources/qml/Sidebar.qml
+++ b/resources/qml/Sidebar.qml
@@ -126,11 +126,12 @@ Rectangle
{
id: settingsModeLabel
text: !hideSettings ? catalog.i18nc("@label:listbox", "Print Setup") : catalog.i18nc("@label:listbox", "Print Setup disabled\nG-code files cannot be modified")
+ renderType: Text.NativeRendering
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
anchors.top: hideSettings ? machineSelection.bottom : headerSeparator.bottom
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
- width: Math.floor(parent.width * 0.45)
+ width: Math.round(parent.width * 0.45)
font: UM.Theme.getFont("large")
color: UM.Theme.getColor("text")
visible: !monitoringPrint && !hideView
@@ -142,7 +143,7 @@ Rectangle
id: settingsModeSelection
color: "transparent"
- width: Math.floor(parent.width * 0.55)
+ width: Math.round(parent.width * 0.55)
height: UM.Theme.getSize("sidebar_header_mode_toggle").height
anchors.right: parent.right
@@ -171,10 +172,10 @@ Rectangle
id: control
height: settingsModeSelection.height
- width: Math.floor(0.5 * parent.width)
+ width: Math.round(parent.width / 2)
anchors.left: parent.left
- anchors.leftMargin: model.index * Math.floor(settingsModeSelection.width / 2)
+ anchors.leftMargin: model.index * Math.round(settingsModeSelection.width / 2)
anchors.verticalCenter: parent.verticalCenter
ButtonGroup.group: modeMenuGroup
@@ -207,12 +208,13 @@ Rectangle
color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active") : control.hovered ? UM.Theme.getColor("action_button_hovered") : UM.Theme.getColor("action_button")
}
- contentItem: Text
+ contentItem: Label
{
text: model.text
font: UM.Theme.getFont("default")
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
+ renderType: Text.NativeRendering
elide: Text.ElideRight
color:
{
@@ -329,7 +331,7 @@ Rectangle
height: UM.Theme.getSize("sidebar_lining").height
color: UM.Theme.getColor("sidebar_lining")
anchors.bottom: printSpecs.top
- anchors.bottomMargin: Math.floor(UM.Theme.getSize("sidebar_margin").height * 2 + UM.Theme.getSize("progressbar").height + UM.Theme.getFont("default_bold").pixelSize)
+ anchors.bottomMargin: Math.round(UM.Theme.getSize("sidebar_margin").height * 2 + UM.Theme.getSize("progressbar").height + UM.Theme.getFont("default_bold").pixelSize)
}
Item
@@ -352,6 +354,7 @@ Rectangle
font: UM.Theme.getFont("large")
color: UM.Theme.getColor("text_subtext")
text: (!base.printDuration || !base.printDuration.valid) ? catalog.i18nc("@label Hours and minutes", "00h 00min") : base.printDuration.getDisplayString(UM.DurationFormat.Short)
+ renderType: Text.NativeRendering
MouseArea
{
@@ -429,7 +432,7 @@ Rectangle
{
names.push(base.printMaterialNames[index]);
lengths.push(base.printMaterialLengths[index].toFixed(2));
- weights.push(String(Math.floor(base.printMaterialWeights[index])));
+ weights.push(String(Math.round(base.printMaterialWeights[index])));
var cost = base.printMaterialCosts[index] == undefined ? 0 : base.printMaterialCosts[index].toFixed(2);
costs.push(cost);
if(cost > 0)
@@ -479,6 +482,7 @@ Rectangle
anchors.left: parent.left
anchors.bottom: parent.bottom
font: UM.Theme.getFont("very_small")
+ renderType: Text.NativeRendering
color: UM.Theme.getColor("text_subtext")
elide: Text.ElideMiddle
width: parent.width
@@ -495,7 +499,7 @@ Rectangle
if(base.printMaterialLengths[index] > 0)
{
lengths.push(base.printMaterialLengths[index].toFixed(2));
- weights.push(String(Math.floor(base.printMaterialWeights[index])));
+ weights.push(String(Math.round(base.printMaterialWeights[index])));
var cost = base.printMaterialCosts[index] == undefined ? 0 : base.printMaterialCosts[index].toFixed(2);
costs.push(cost);
if(cost > 0)
@@ -511,15 +515,12 @@ Rectangle
weights = ["0"];
costs = ["0.00"];
}
+ var result = lengths.join(" + ") + "m / ~ " + weights.join(" + ") + "g";
if(someCostsKnown)
{
- return catalog.i18nc("@label Print estimates: m for meters, g for grams, %4 is currency and %3 is print cost", "%1m / ~ %2g / ~ %4 %3").arg(lengths.join(" + "))
- .arg(weights.join(" + ")).arg(costs.join(" + ")).arg(UM.Preferences.getValue("cura/currency"));
- }
- else
- {
- return catalog.i18nc("@label Print estimates: m for meters, g for grams", "%1m / ~ %2g").arg(lengths.join(" + ")).arg(weights.join(" + "));
+ result += " / ~ " + costs.join(" + ") + " " + UM.Preferences.getValue("cura/currency");
}
+ return result;
}
MouseArea
{
@@ -610,7 +611,7 @@ Rectangle
})
sidebarContents.replace(modesListModel.get(base.currentModeIndex).item, { "immediate": true })
- var index = Math.floor(UM.Preferences.getValue("cura/active_mode"))
+ var index = Math.round(UM.Preferences.getValue("cura/active_mode"))
if(index)
{
currentModeIndex = index;
diff --git a/resources/qml/SidebarContents.qml b/resources/qml/SidebarContents.qml
index eae718023b..0b19bfe3c1 100644
--- a/resources/qml/SidebarContents.qml
+++ b/resources/qml/SidebarContents.qml
@@ -1,7 +1,7 @@
// Copyright (c) 2016 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.2
+import QtQuick 2.7
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
diff --git a/resources/qml/SidebarHeader.qml b/resources/qml/SidebarHeader.qml
index 7fe087c767..473f4c5cc8 100644
--- a/resources/qml/SidebarHeader.qml
+++ b/resources/qml/SidebarHeader.qml
@@ -1,7 +1,7 @@
// Copyright (c) 2017 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.2
+import QtQuick 2.7
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
@@ -17,7 +17,7 @@ Column
property int currentExtruderIndex: Cura.ExtruderManager.activeExtruderIndex;
property bool currentExtruderVisible: extrudersList.visible;
- spacing: Math.floor(UM.Theme.getSize("sidebar_margin").width * 0.9)
+ spacing: Math.round(UM.Theme.getSize("sidebar_margin").width * 0.9)
signal showTooltip(Item item, point location, string text)
signal hideTooltip()
@@ -39,15 +39,15 @@ Column
{
id: extruderSelectionRow
width: parent.width
- height: Math.floor(UM.Theme.getSize("sidebar_tabs").height * 2 / 3)
+ height: Math.round(UM.Theme.getSize("sidebar_tabs").height * 2 / 3)
visible: machineExtruderCount.properties.value > 1 && !sidebar.monitoringPrint
anchors
{
left: parent.left
- leftMargin: Math.floor(UM.Theme.getSize("sidebar_margin").width * 0.7)
+ leftMargin: Math.round(UM.Theme.getSize("sidebar_margin").width * 0.7)
right: parent.right
- rightMargin: Math.floor(UM.Theme.getSize("sidebar_margin").width * 0.7)
+ rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width * 0.7)
topMargin: UM.Theme.getSize("sidebar_margin").height
}
@@ -57,15 +57,15 @@ Column
property var index: 0
height: UM.Theme.getSize("sidebar_header_mode_tabs").height
- width: Math.floor(parent.width)
+ width: Math.round(parent.width)
boundsBehavior: Flickable.StopAtBounds
anchors
{
left: parent.left
- leftMargin: Math.floor(UM.Theme.getSize("default_margin").width / 2)
+ leftMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
right: parent.right
- rightMargin: Math.floor(UM.Theme.getSize("default_margin").width / 2)
+ rightMargin: Math.round(UM.Theme.getSize("default_margin").width / 2)
verticalCenter: parent.verticalCenter
}
@@ -84,17 +84,46 @@ Column
delegate: Button
{
height: ListView.view.height
- width: ListView.view.width / extrudersModel.rowCount()
+ width: Math.round(ListView.view.width / extrudersModel.rowCount())
text: model.name
tooltip: model.name
exclusiveGroup: extruderMenuGroup
checked: base.currentExtruderIndex == index
- onClicked:
+ MouseArea
{
- forceActiveFocus() // Changing focus applies the currently-being-typed values so it can change the displayed setting values.
- Cura.ExtruderManager.setActiveExtruderIndex(index);
+ anchors.fill: parent
+ acceptedButtons: Qt.LeftButton | Qt.RightButton
+ onClicked: {
+ switch (mouse.button) {
+ case Qt.LeftButton:
+ forceActiveFocus(); // Changing focus applies the currently-being-typed values so it can change the displayed setting values.
+ Cura.ExtruderManager.setActiveExtruderIndex(index);
+ break;
+ case Qt.RightButton:
+ extruderMenu.popup();
+ break;
+ }
+
+ }
+ }
+
+ Menu
+ {
+ id: extruderMenu
+
+ MenuItem {
+ text: catalog.i18nc("@action:inmenu", "Enable Extruder")
+ onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, true)
+ visible: !Cura.MachineManager.getExtruder(model.index).isEnabled
+ }
+
+ MenuItem {
+ text: catalog.i18nc("@action:inmenu", "Disable Extruder")
+ onTriggered: Cura.MachineManager.setExtruderEnabled(model.index, false)
+ visible: Cura.MachineManager.getExtruder(model.index).isEnabled
+ }
}
style: ButtonStyle
@@ -114,6 +143,18 @@ Column
Behavior on color { ColorAnimation { duration: 50; } }
}
+ function buttonColor(index) {
+ var extruder = Cura.MachineManager.getExtruder(index);
+ if (extruder.isEnabled) {
+ return (
+ control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_text") :
+ control.hovered ? UM.Theme.getColor("action_button_hovered_text") :
+ UM.Theme.getColor("action_button_text");
+ } else {
+ return UM.Theme.getColor("action_button_disabled_text");
+ }
+ }
+
Item
{
id: extruderButtonFace
@@ -121,7 +162,7 @@ Column
width: {
var extruderTextWidth = extruderStaticText.visible ? extruderStaticText.width : 0;
var iconWidth = extruderIconItem.width;
- return Math.floor(extruderTextWidth + iconWidth + UM.Theme.getSize("default_margin").width / 2);
+ return Math.round(extruderTextWidth + iconWidth + UM.Theme.getSize("default_margin").width / 2);
}
// Static text "Extruder"
@@ -131,9 +172,7 @@ Column
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
- color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_text") :
- control.hovered ? UM.Theme.getColor("action_button_hovered_text") :
- UM.Theme.getColor("action_button_text")
+ color: buttonColor(index)
font: UM.Theme.getFont("large_nonbold")
text: catalog.i18nc("@label", "Extruder")
@@ -153,7 +192,7 @@ Column
var minimumWidth = control.width < UM.Theme.getSize("button").width ? control.width : UM.Theme.getSize("button").width;
var minimumHeight = control.height < UM.Theme.getSize("button").height ? control.height : UM.Theme.getSize("button").height;
var minimumSize = minimumWidth < minimumHeight ? minimumWidth : minimumHeight;
- minimumSize -= Math.floor(UM.Theme.getSize("default_margin").width / 2);
+ minimumSize -= Math.round(UM.Theme.getSize("default_margin").width / 2);
return minimumSize;
}
@@ -176,9 +215,7 @@ Column
id: extruderNumberText
anchors.centerIn: parent
text: index + 1;
- color: (control.checked || control.pressed) ? UM.Theme.getColor("action_button_active_text") :
- control.hovered ? UM.Theme.getColor("action_button_hovered_text") :
- UM.Theme.getColor("action_button_text")
+ color: buttonColor(index)
font: UM.Theme.getFont("default_bold")
}
@@ -192,15 +229,15 @@ Column
{
right: parent.right
top: parent.top
- rightMargin: parent.sizeToUse * 0.01
- topMargin: parent.sizeToUse * 0.05
+ rightMargin: Math.round(parent.sizeToUse * 0.01)
+ topMargin: Math.round(parent.sizeToUse * 0.05)
}
color: model.color
- width: parent.width * 0.35
- height: parent.height * 0.35
- radius: width / 2
+ width: Math.round(parent.width * 0.35)
+ height: Math.round(parent.height * 0.35)
+ radius: Math.round(width / 2)
border.width: 1
border.color: UM.Theme.getColor("extruder_button_material_border")
@@ -219,7 +256,7 @@ Column
Item
{
id: variantRowSpacer
- height: UM.Theme.getSize("sidebar_margin").height / 4
+ height: Math.round(UM.Theme.getSize("sidebar_margin").height / 4)
width: height
visible: !extruderSelectionRow.visible
}
@@ -243,7 +280,7 @@ Column
{
id: materialLabel
text: catalog.i18nc("@label", "Material");
- width: Math.floor(parent.width * 0.45 - UM.Theme.getSize("default_margin").width)
+ width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width)
font: UM.Theme.getFont("default");
color: UM.Theme.getColor("text");
}
@@ -252,12 +289,22 @@ Column
{
id: materialSelection
- text: Cura.MachineManager.activeMaterialName
- tooltip: Cura.MachineManager.activeMaterialName
+ property var currentRootMaterialName:
+ {
+ var materials = Cura.MachineManager.currentRootMaterialName;
+ var materialName = "";
+ if (base.currentExtruderIndex in materials) {
+ materialName = materials[base.currentExtruderIndex];
+ }
+ return materialName;
+ }
+
+ text: currentRootMaterialName
+ tooltip: currentRootMaterialName
visible: Cura.MachineManager.hasMaterials
- enabled: !extrudersList.visible || base.currentExtruderIndex > -1
+ enabled: !extrudersList.visible || base.currentExtruderIndex > -1
height: UM.Theme.getSize("setting_control").height
- width: parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width
+ width: Math.round(parent.width * 0.7) + UM.Theme.getSize("sidebar_margin").width
anchors.right: parent.right
style: UM.Theme.styles.sidebar_header_button
activeFocusOnPress: true;
@@ -293,7 +340,7 @@ Column
{
id: variantLabel
text: Cura.MachineManager.activeDefinitionVariantsName;
- width: Math.floor(parent.width * 0.45 - UM.Theme.getSize("default_margin").width)
+ width: Math.round(parent.width * 0.45 - UM.Theme.getSize("default_margin").width)
font: UM.Theme.getFont("default");
color: UM.Theme.getColor("text");
}
@@ -305,7 +352,7 @@ Column
visible: Cura.MachineManager.hasVariants
height: UM.Theme.getSize("setting_control").height
- width: Math.floor(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width)
+ width: Math.round(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width)
anchors.right: parent.right
style: UM.Theme.styles.sidebar_header_button
activeFocusOnPress: true;
@@ -323,7 +370,7 @@ Column
anchors.horizontalCenter: parent.horizontalCenter
visible: buildplateRow.visible
width: parent.width - UM.Theme.getSize("sidebar_margin").width * 2
- height: visible ? UM.Theme.getSize("sidebar_lining_thin").height / 2 : 0
+ height: visible ? Math.floor(UM.Theme.getSize("sidebar_lining_thin").height / 2) : 0
color: UM.Theme.getColor("sidebar_lining_thin")
}
@@ -374,7 +421,7 @@ Column
Item
{
id: materialInfoRow
- height: Math.floor(UM.Theme.getSize("sidebar_setup").height / 2)
+ height: Math.round(UM.Theme.getSize("sidebar_setup").height / 2)
visible: (Cura.MachineManager.hasVariants || Cura.MachineManager.hasMaterials) && !sidebar.monitoringPrint && !sidebar.hideSettings
anchors
@@ -388,7 +435,7 @@ Column
Item {
height: UM.Theme.getSize("sidebar_setup").height
anchors.right: parent.right
- width: Math.floor(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width)
+ width: Math.round(parent.width * 0.7 + UM.Theme.getSize("sidebar_margin").width)
UM.RecolorImage {
id: warningImage
@@ -421,7 +468,7 @@ Column
// open the material URL with web browser
var version = UM.Application.version;
var machineName = Cura.MachineManager.activeMachine.definition.id;
- var url = "https://ultimaker.com/materialcompatibility/" + version + "/" + machineName;
+ var url = "https://ultimaker.com/materialcompatibility/" + version + "/" + machineName + "?utm_source=cura&utm_medium=software&utm_campaign=resources";
Qt.openUrlExternally(url);
}
onEntered: {
diff --git a/resources/qml/SidebarSimple.qml b/resources/qml/SidebarSimple.qml
index b96c40d9ea..7cc67be03a 100644
--- a/resources/qml/SidebarSimple.qml
+++ b/resources/qml/SidebarSimple.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2017 Ultimaker B.V.
+// Copyright (c) 2018 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.7
@@ -7,7 +7,7 @@ import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.3
import UM 1.2 as UM
-import Cura 1.2 as Cura
+import Cura 1.0 as Cura
Item
{
@@ -19,7 +19,7 @@ Item
property Action configureSettings;
property variant minimumPrintTime: PrintInformation.minimumPrintTime;
property variant maximumPrintTime: PrintInformation.maximumPrintTime;
- property bool settingsEnabled: Cura.ExtruderManager.activeExtruderStackId || machineExtruderCount.properties.value == 1
+ property bool settingsEnabled: Cura.ExtruderManager.activeExtruderStackId || extrudersEnabledCount.properties.value == 1
Component.onCompleted: PrintInformation.enabled = true
Component.onDestruction: PrintInformation.enabled = false
@@ -57,17 +57,18 @@ Item
interval: 50
running: false
repeat: false
- onTriggered: Cura.MachineManager.setActiveQuality(Cura.ProfilesModel.getItem(qualitySlider.value).id)
+ onTriggered: {
+ var item = Cura.QualityProfilesDropDownMenuModel.getItem(qualitySlider.value);
+ Cura.MachineManager.activeQualityGroup = item.quality_group;
+ }
}
Component.onCompleted: qualityModel.update()
Connections
{
- target: Cura.MachineManager
- onActiveQualityChanged: qualityModel.update()
- onActiveMaterialChanged: qualityModel.update()
- onActiveVariantChanged: qualityModel.update()
+ target: Cura.QualityProfilesDropDownMenuModel
+ onItemsChanged: qualityModel.update()
}
Connections {
@@ -102,14 +103,14 @@ Item
var availableMin = -1
var availableMax = -1
- for (var i = 0; i < Cura.ProfilesModel.rowCount(); i++) {
- var qualityItem = Cura.ProfilesModel.getItem(i)
+ for (var i = 0; i < Cura.QualityProfilesDropDownMenuModel.rowCount(); i++) {
+ var qualityItem = Cura.QualityProfilesDropDownMenuModel.getItem(i)
// Add each quality item to the UI quality model
qualityModel.append(qualityItem)
// Set selected value
- if (Cura.MachineManager.activeQualityType == qualityItem.metadata.quality_type) {
+ if (Cura.MachineManager.activeQualityType == qualityItem.quality_type) {
// set to -1 when switching to user created profile so all ticks are clickable
if (Cura.SimpleModeSettingsManager.isProfileUserCreated) {
@@ -134,7 +135,7 @@ Item
// Set total available ticks for active slider part
if (availableMin != -1) {
- qualityModel.availableTotalTicks = availableMax - availableMin
+ qualityModel.availableTotalTicks = availableMax - availableMin + 1
}
// Calculate slider values
@@ -146,26 +147,26 @@ Item
}
function calculateSliderStepWidth (totalTicks) {
- qualityModel.qualitySliderStepWidth = totalTicks != 0 ? (base.width * 0.55) / (totalTicks) : 0
+ qualityModel.qualitySliderStepWidth = totalTicks != 0 ? Math.round((base.width * 0.55) / (totalTicks)) : 0
}
function calculateSliderMargins (availableMin, availableMax, totalTicks) {
if (availableMin == -1 || (availableMin == 0 && availableMax == 0)) {
- qualityModel.qualitySliderMarginRight = base.width * 0.55
+ qualityModel.qualitySliderMarginRight = Math.round(base.width * 0.55)
} else if (availableMin == availableMax) {
- qualityModel.qualitySliderMarginRight = (totalTicks - availableMin) * qualitySliderStepWidth
+ qualityModel.qualitySliderMarginRight = Math.round((totalTicks - availableMin) * qualitySliderStepWidth)
} else {
- qualityModel.qualitySliderMarginRight = (totalTicks - availableMax) * qualitySliderStepWidth
+ qualityModel.qualitySliderMarginRight = Math.round((totalTicks - availableMax) * qualitySliderStepWidth)
}
}
function reset () {
qualityModel.clear()
- qualityModel.availableTotalTicks = -1
+ qualityModel.availableTotalTicks = 0
qualityModel.existingQualityProfile = 0
// check, the ticks count cannot be less than zero
- qualityModel.totalTicks = Math.max(0, Cura.ProfilesModel.rowCount() - 1)
+ qualityModel.totalTicks = Math.max(0, Cura.QualityProfilesDropDownMenuModel.rowCount() - 1)
}
}
@@ -190,14 +191,14 @@ Item
{
anchors.verticalCenter: parent.verticalCenter
anchors.top: parent.top
- anchors.topMargin: parseInt(UM.Theme.getSize("sidebar_margin").height / 2)
- color: (Cura.MachineManager.activeMachine != null && Cura.ProfilesModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
+ anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 2)
+ color: (Cura.MachineManager.activeMachine != null && Cura.QualityProfilesDropDownMenuModel.getItem(index).available) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
text:
{
var result = ""
if(Cura.MachineManager.activeMachine != null)
{
- result = Cura.ProfilesModel.getItem(index).layer_height_without_unit
+ result = Cura.QualityProfilesDropDownMenuModel.getItem(index).layer_height
if(result == undefined)
{
@@ -219,13 +220,13 @@ Item
// Make sure the text aligns correctly with each tick
if (qualityModel.totalTicks == 0) {
// If there is only one tick, align it centrally
- return parseInt(((base.width * 0.55) - width) / 2)
+ return Math.round(((base.width * 0.55) - width) / 2)
} else if (index == 0) {
- return (base.width * 0.55 / qualityModel.totalTicks) * index
+ return Math.round(base.width * 0.55 / qualityModel.totalTicks) * index
} else if (index == qualityModel.totalTicks) {
- return (base.width * 0.55 / qualityModel.totalTicks) * index - width
+ return Math.round(base.width * 0.55 / qualityModel.totalTicks) * index - width
} else {
- return parseInt((base.width * 0.55 / qualityModel.totalTicks) * index - (width / 2))
+ return Math.round((base.width * 0.55 / qualityModel.totalTicks) * index - (width / 2))
}
}
}
@@ -236,7 +237,7 @@ Item
Item
{
id: speedSlider
- width: base.width * 0.55
+ width: Math.round(base.width * 0.55)
height: UM.Theme.getSize("sidebar_margin").height
anchors.right: parent.right
anchors.top: parent.top
@@ -246,7 +247,7 @@ Item
Rectangle
{
id: groovechildrect
- width: base.width * 0.55
+ width: Math.round(base.width * 0.55)
height: 2 * screenScaleFactor
color: UM.Theme.getColor("quality_slider_unavailable")
anchors.verticalCenter: qualitySlider.verticalCenter
@@ -262,40 +263,32 @@ Item
Rectangle
{
anchors.verticalCenter: parent.verticalCenter
- color: Cura.ProfilesModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
+ color: Cura.QualityProfilesDropDownMenuModel.getItem(index).available ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
width: 1 * screenScaleFactor
height: 6 * screenScaleFactor
y: 0
- x: qualityModel.qualitySliderStepWidth * index
+ x: Math.round(qualityModel.qualitySliderStepWidth * index)
}
}
- Rectangle {
- id: disabledHandleButton
- visible: !qualitySlider.visible
- anchors.centerIn: parent
- color: UM.Theme.getColor("quality_slider_unavailable")
- implicitWidth: 10 * screenScaleFactor
- implicitHeight: implicitWidth
- radius: width / 2
- }
-
Slider
{
id: qualitySlider
height: UM.Theme.getSize("sidebar_margin").height
anchors.bottom: speedSlider.bottom
- enabled: qualityModel.availableTotalTicks > 0 && !Cura.SimpleModeSettingsManager.isProfileCustomized
- visible: qualityModel.totalTicks > 0
+ enabled: qualityModel.totalTicks > 0 && !Cura.SimpleModeSettingsManager.isProfileCustomized
+ visible: qualityModel.availableTotalTicks > 0
updateValueWhileDragging : false
minimumValue: qualityModel.qualitySliderAvailableMin >= 0 ? qualityModel.qualitySliderAvailableMin : 0
- maximumValue: qualityModel.qualitySliderAvailableMax >= 0 ? qualityModel.qualitySliderAvailableMax : 0
+ // maximumValue must be greater than minimumValue to be able to see the handle. While the value is strictly
+ // speaking not always correct, it seems to have the correct behavior (switching from 0 available to 1 available)
+ maximumValue: qualityModel.qualitySliderAvailableMax >= 1 ? qualityModel.qualitySliderAvailableMax : 1
stepSize: 1
value: qualityModel.qualitySliderActiveIndex
- width: qualityModel.qualitySliderStepWidth * qualityModel.availableTotalTicks
+ width: qualityModel.qualitySliderStepWidth * (qualityModel.availableTotalTicks - 1)
anchors.right: parent.right
anchors.rightMargin: qualityModel.qualitySliderMarginRight
@@ -306,7 +299,7 @@ Item
groove: Rectangle {
implicitHeight: 2 * screenScaleFactor
color: UM.Theme.getColor("quality_slider_available")
- radius: height / 2
+ radius: Math.round(height / 2)
}
handle: Item {
Rectangle {
@@ -315,7 +308,7 @@ Item
color: UM.Theme.getColor("quality_slider_available")
implicitWidth: 10 * screenScaleFactor
implicitHeight: implicitWidth
- radius: implicitWidth / 2
+ radius: Math.round(implicitWidth / 2)
visible: !Cura.SimpleModeSettingsManager.isProfileCustomized && !Cura.SimpleModeSettingsManager.isProfileUserCreated && qualityModel.existingQualityProfile
}
}
@@ -362,7 +355,7 @@ Item
text: catalog.i18nc("@label", "Print Speed")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
- width: parseInt(UM.Theme.getSize("sidebar").width * 0.35)
+ width: Math.round(UM.Theme.getSize("sidebar").width * 0.35)
elide: Text.ElideRight
}
@@ -373,7 +366,7 @@ Item
text: catalog.i18nc("@label", "Slower")
font: UM.Theme.getFont("default")
- color: (qualityModel.availableTotalTicks > 0) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
+ color: (qualityModel.availableTotalTicks > 1) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
horizontalAlignment: Text.AlignLeft
}
@@ -384,7 +377,7 @@ Item
text: catalog.i18nc("@label", "Faster")
font: UM.Theme.getFont("default")
- color: (qualityModel.availableTotalTicks > 0) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
+ color: (qualityModel.availableTotalTicks > 1) ? UM.Theme.getColor("quality_slider_available") : UM.Theme.getColor("quality_slider_unavailable")
horizontalAlignment: Text.AlignRight
}
@@ -393,12 +386,12 @@ Item
id: customisedSettings
visible: Cura.SimpleModeSettingsManager.isProfileCustomized || Cura.SimpleModeSettingsManager.isProfileUserCreated
- height: speedSlider.height * 0.8
- width: speedSlider.height * 0.8
+ height: Math.round(speedSlider.height * 0.8)
+ width: Math.round(speedSlider.height * 0.8)
anchors.verticalCenter: speedSlider.verticalCenter
anchors.right: speedSlider.left
- anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width / 2
+ anchors.rightMargin: Math.round(UM.Theme.getSize("sidebar_margin").width / 2)
color: hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button");
iconSource: UM.Theme.getIcon("reset");
@@ -408,9 +401,10 @@ Item
// if the current profile is user-created, switch to a built-in quality
if (Cura.SimpleModeSettingsManager.isProfileUserCreated)
{
- if (Cura.ProfilesModel.rowCount() > 0)
+ if (Cura.QualityProfilesDropDownMenuModel.rowCount() > 0)
{
- Cura.MachineManager.setActiveQuality(Cura.ProfilesModel.getItem(0).id)
+ var item = Cura.QualityProfilesDropDownMenuModel.getItem(0);
+ Cura.MachineManager.activeQualityGroup = item.quality_group;
}
}
if (Cura.SimpleModeSettingsManager.isProfileCustomized)
@@ -438,7 +432,7 @@ Item
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height * 2
anchors.left: parent.left
- width: parseInt(UM.Theme.getSize("sidebar").width * .45 - UM.Theme.getSize("sidebar_margin").width)
+ width: Math.round(UM.Theme.getSize("sidebar").width * .45) - UM.Theme.getSize("sidebar_margin").width
Label
{
@@ -448,7 +442,7 @@ Item
color: UM.Theme.getColor("text")
anchors.top: parent.top
- anchors.topMargin: parseInt(UM.Theme.getSize("sidebar_margin").height * 1.7)
+ anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height * 1.7)
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
}
@@ -459,7 +453,7 @@ Item
id: infillCellRight
height: infillSlider.height + UM.Theme.getSize("sidebar_margin").height + enableGradualInfillCheckBox.visible * (enableGradualInfillCheckBox.height + UM.Theme.getSize("sidebar_margin").height)
- width: parseInt(UM.Theme.getSize("sidebar").width * .55)
+ width: Math.round(UM.Theme.getSize("sidebar").width * .55)
anchors.left: infillCellLeft.right
anchors.top: infillCellLeft.top
@@ -470,7 +464,7 @@ Item
//anchors.top: parent.top
anchors.left: infillSlider.left
- anchors.leftMargin: parseInt((infillSlider.value / infillSlider.stepSize) * (infillSlider.width / (infillSlider.maximumValue / infillSlider.stepSize)) - 10 * screenScaleFactor)
+ anchors.leftMargin: Math.round((infillSlider.value / infillSlider.stepSize) * (infillSlider.width / (infillSlider.maximumValue / infillSlider.stepSize)) - 10 * screenScaleFactor)
anchors.right: parent.right
text: parseInt(infillDensity.properties.value) + "%"
@@ -522,8 +516,7 @@ Item
// Update the slider value to represent the rounded value
infillSlider.value = roundedSliderValue
- // Explicitly cast to string to make sure the value passed to Python is an integer.
- infillDensity.setPropertyValue("value", String(roundedSliderValue))
+ Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", roundedSliderValue)
}
style: SliderStyle
@@ -565,7 +558,7 @@ Item
width: 1 * screenScaleFactor
height: 6 * screenScaleFactor
y: 0
- x: styleData.handleWidth / 2 + index * ((repeater.width - styleData.handleWidth) / (repeater.count-1))
+ x: Math.round(styleData.handleWidth / 2 + index * ((repeater.width - styleData.handleWidth) / (repeater.count-1)))
visible: shouldShowTick(index)
}
}
@@ -576,12 +569,12 @@ Item
{
id: infillIcon
- width: (parent.width / 5) - (UM.Theme.getSize("sidebar_margin").width)
+ width: Math.round((parent.width / 5) - (UM.Theme.getSize("sidebar_margin").width))
height: width
anchors.right: parent.right
anchors.top: parent.top
- anchors.topMargin: parseInt(UM.Theme.getSize("sidebar_margin").height / 2)
+ anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 2)
// we loop over all density icons and only show the one that has the current density and steps
Repeater
@@ -592,8 +585,8 @@ Item
function activeIndex () {
for (var i = 0; i < infillModel.count; i++) {
- var density = parseInt(infillDensity.properties.value)
- var steps = parseInt(infillSteps.properties.value)
+ var density = Math.round(infillDensity.properties.value)
+ var steps = Math.round(infillSteps.properties.value)
var infillModelItem = infillModel.get(i)
if (infillModelItem != "undefined"
@@ -634,7 +627,7 @@ Item
property alias _hovered: enableGradualInfillMouseArea.containsMouse
anchors.top: infillSlider.bottom
- anchors.topMargin: parseInt(UM.Theme.getSize("sidebar_margin").height / 2) // closer to slider since it belongs to the same category
+ anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height / 2) // closer to slider since it belongs to the same category
anchors.left: infillCellRight.left
style: UM.Theme.styles.checkbox
@@ -653,14 +646,20 @@ Item
onClicked: {
// Set to 90% only when enabling gradual infill
+ var newInfillDensity;
if (parseInt(infillSteps.properties.value) == 0) {
previousInfillDensity = parseInt(infillDensity.properties.value)
- infillDensity.setPropertyValue("value", String(90))
+ newInfillDensity = 90;
} else {
- infillDensity.setPropertyValue("value", String(previousInfillDensity))
+ newInfillDensity = previousInfillDensity;
}
+ Cura.MachineManager.setSettingForAllExtruders("infill_sparse_density", "value", String(newInfillDensity))
- infillSteps.setPropertyValue("value", (parseInt(infillSteps.properties.value) == 0) ? 5 : 0)
+ var infill_steps_value = 0;
+ if (parseInt(infillSteps.properties.value) == 0)
+ infill_steps_value = 5;
+
+ Cura.MachineManager.setSettingForAllExtruders("gradual_infill_steps", "value", infill_steps_value)
}
onEntered: {
@@ -676,7 +675,7 @@ Item
Label {
id: gradualInfillLabel
anchors.left: enableGradualInfillCheckBox.right
- anchors.leftMargin: parseInt(UM.Theme.getSize("sidebar_margin").width / 2)
+ anchors.leftMargin: Math.round(UM.Theme.getSize("sidebar_margin").width / 2)
text: catalog.i18nc("@label", "Enable gradual")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
@@ -737,7 +736,7 @@ Item
visible: enableSupportCheckBox.visible
anchors.top: infillCellRight.bottom
- anchors.topMargin: parseInt(UM.Theme.getSize("sidebar_margin").height * 1.5)
+ anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height * 1.5)
anchors.left: parent.left
anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
anchors.right: infillCellLeft.right
@@ -787,25 +786,10 @@ Item
}
}
- Label
- {
- id: supportExtruderLabel
- visible: supportExtruderCombobox.visible
- anchors.left: parent.left
- anchors.leftMargin: UM.Theme.getSize("sidebar_margin").width
- anchors.right: infillCellLeft.right
- anchors.rightMargin: UM.Theme.getSize("sidebar_margin").width
- anchors.verticalCenter: supportExtruderCombobox.verticalCenter
- text: catalog.i18nc("@label", "Support Extruder");
- font: UM.Theme.getFont("default");
- color: UM.Theme.getColor("text");
- elide: Text.ElideRight
- }
-
ComboBox
{
id: supportExtruderCombobox
- visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)
+ visible: enableSupportCheckBox.visible && (supportEnabled.properties.value == "True") && (extrudersEnabledCount.properties.value > 1)
model: extruderModel
property string color_override: "" // for manually setting values
@@ -819,11 +803,12 @@ Item
textRole: "text" // this solves that the combobox isn't populated in the first time Cura is started
- anchors.top: enableSupportCheckBox.bottom
- anchors.topMargin: ((supportEnabled.properties.value === "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("sidebar_margin").height : 0
- anchors.left: infillCellRight.left
+ anchors.top: enableSupportCheckBox.top
+ //anchors.topMargin: ((supportEnabled.properties.value === "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("sidebar_margin").height : 0
+ anchors.left: enableSupportCheckBox.right
+ anchors.leftMargin: Math.round(UM.Theme.getSize("sidebar_margin").width / 2)
- width: UM.Theme.getSize("sidebar").width * .55
+ width: Math.round(UM.Theme.getSize("sidebar").width * .55) - Math.round(UM.Theme.getSize("sidebar_margin").width / 2) - enableSupportCheckBox.width
height: ((supportEnabled.properties.value == "True") && (machineExtruderCount.properties.value > 1)) ? UM.Theme.getSize("setting_control").height : 0
Behavior on height { NumberAnimation { duration: 100 } }
@@ -890,7 +875,7 @@ Item
id: adhesionCheckBox
property alias _hovered: adhesionMouseArea.containsMouse
- anchors.top: enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom
+ anchors.top: enableSupportCheckBox.bottom
anchors.topMargin: UM.Theme.getSize("sidebar_margin").height
anchors.left: infillCellRight.left
@@ -952,7 +937,7 @@ Item
{
id: tipsCell
anchors.top: adhesionCheckBox.visible ? adhesionCheckBox.bottom : (enableSupportCheckBox.visible ? supportExtruderCombobox.bottom : infillCellRight.bottom)
- anchors.topMargin: parseInt(UM.Theme.getSize("sidebar_margin").height * 2)
+ anchors.topMargin: Math.round(UM.Theme.getSize("sidebar_margin").height * 2)
anchors.left: parent.left
width: parent.width
height: tipsText.contentHeight * tipsText.lineCount
@@ -1021,9 +1006,9 @@ Item
UM.SettingPropertyProvider
{
- id: machineExtruderCount
+ id: extrudersEnabledCount
containerStackId: Cura.MachineManager.activeMachineId
- key: "machine_extruder_count"
+ key: "extruders_enabled_count"
watchedProperties: [ "value" ]
storeIndex: 0
}
diff --git a/resources/qml/SidebarTooltip.qml b/resources/qml/SidebarTooltip.qml
index 07b95777b5..29199481f6 100644
--- a/resources/qml/SidebarTooltip.qml
+++ b/resources/qml/SidebarTooltip.qml
@@ -1,7 +1,7 @@
// Copyright (c) 2015 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
-import QtQuick 2.2
+import QtQuick 2.7
import QtQuick.Controls 1.1
import QtQuick.Controls.Styles 1.1
import QtQuick.Layouts 1.1
@@ -36,7 +36,7 @@ UM.PointingRectangle {
}
}
base.opacity = 1;
- target = Qt.point(40 , position.y + UM.Theme.getSize("tooltip_arrow_margins").height / 2)
+ target = Qt.point(40 , position.y + Math.round(UM.Theme.getSize("tooltip_arrow_margins").height / 2))
}
function hide() {
diff --git a/resources/qml/Toolbar.qml b/resources/qml/Toolbar.qml
index 77ffc7f2a9..613a462db9 100644
--- a/resources/qml/Toolbar.qml
+++ b/resources/qml/Toolbar.qml
@@ -91,7 +91,7 @@ Item
anchors.topMargin: base.activeY
z: buttons.z -1
- target: Qt.point(parent.right, base.activeY + UM.Theme.getSize("button").height/2)
+ target: Qt.point(parent.right, base.activeY + Math.round(UM.Theme.getSize("button").height/2))
arrowSize: UM.Theme.getSize("default_arrow").width
width:
diff --git a/resources/qml/Topbar.qml b/resources/qml/Topbar.qml
index dc041ab5b7..950b9ec12d 100644
--- a/resources/qml/Topbar.qml
+++ b/resources/qml/Topbar.qml
@@ -220,7 +220,7 @@ Rectangle
anchors.topMargin: UM.Theme.getSize("default_margin").height
anchors.right: viewModeButton.right
- property var buttonTarget: Qt.point(viewModeButton.x + viewModeButton.width / 2, viewModeButton.y + viewModeButton.height / 2)
+ property var buttonTarget: Qt.point(viewModeButton.x + Math.round(viewModeButton.width / 2), viewModeButton.y + Math.round(viewModeButton.height / 2))
height: childrenRect.height
width: childrenRect.width
diff --git a/resources/qml/WorkspaceSummaryDialog.qml b/resources/qml/WorkspaceSummaryDialog.qml
index d5cc416f39..1cfe36d14b 100644
--- a/resources/qml/WorkspaceSummaryDialog.qml
+++ b/resources/qml/WorkspaceSummaryDialog.qml
@@ -101,7 +101,7 @@ UM.Dialog
}
Label
{
- text: Cura.MachineManager.activeDefinitionName
+ text: Cura.MachineManager.activeMachine.definition.name
width: (parent.width / 3) | 0
}
}
@@ -120,10 +120,35 @@ UM.Dialog
width: (parent.width / 3) | 0
}
}
+ Column
+ {
+ width: parent.width
+ visible: Cura.MachineManager.hasVariantBuildplates
+ Item // Spacer
+ {
+ height: spacerHeight
+ width: height
+ }
+ Row
+ {
+ width: parent.width
+ height: childrenRect.height
+ Label
+ {
+ text: catalog.i18nc("@action:label", "Build plate")
+ width: (parent.width / 3) | 0
+ }
+ Label
+ {
+ text: Cura.MachineManager.activeVariantBuildplateName
+ width: (parent.width / 3) | 0
+ }
+ }
+ }
Repeater
{
- model: Cura.MachineManager.activeMaterialNames
+ model: Cura.MachineManager.currentExtruderPositions
delegate: Column
{
Item // Spacer
@@ -133,7 +158,7 @@ UM.Dialog
}
Label
{
- text: catalog.i18nc("@action:label", "Extruder %1").arg(index+1)
+ text: catalog.i18nc("@action:label", "Extruder %1").arg(modelData)
}
height: childrenRect.height
width: parent.width
@@ -148,7 +173,7 @@ UM.Dialog
}
Label
{
- text: Cura.MachineManager.activeVariantNames[index] + ", " + modelData
+ text: Cura.MachineManager.activeVariantNames[modelData] + ", " + Cura.MachineManager.currentRootMaterialName[modelData]
width: (parent.width / 3) | 0
}
}
@@ -192,7 +217,7 @@ UM.Dialog
}
Label
{
- text: Cura.MachineManager.activeQualityName
+ text: Cura.MachineManager.activeQualityOrQualityChangesName
width: (parent.width / 3) | 0
}
@@ -269,4 +294,4 @@ UM.Dialog
}
}
}
-}
\ 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 32550d86a5..50ff90670f 100644
--- a/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg
+++ b/resources/quality/abax_pri3/apri3_pla_fast.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fine
definition = abax_pri3
[metadata]
-type = quality
-material = generic_pla
-weight = -1
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = -1
+material = generic_pla
[values]
layer_height = 0.2
@@ -19,4 +19,4 @@ speed_print = 80
speed_layer_0 = =round(speed_print * 30 / 50)
speed_topbottom = 20
cool_min_layer_time = 5
-cool_min_speed = 10
\ No newline at end of file
+cool_min_speed = 10
diff --git a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg
index 2007785719..0bcd5ef77d 100644
--- a/resources/quality/abax_pri3/apri3_pla_high.inst.cfg
+++ b/resources/quality/abax_pri3/apri3_pla_high.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = abax_pri3
[metadata]
-type = quality
-material = generic_pla
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+material = generic_pla
[values]
layer_height = 0.1
@@ -19,4 +19,4 @@ speed_print = 50
speed_layer_0 = =round(speed_print * 30 / 50)
speed_topbottom = 20
cool_min_layer_time = 5
-cool_min_speed = 10
\ No newline at end of file
+cool_min_speed = 10
diff --git a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg
index dba0a0460f..5ef275652d 100644
--- a/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg
+++ b/resources/quality/abax_pri3/apri3_pla_normal.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fine
definition = abax_pri3
[metadata]
-type = quality
-material = generic_pla
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_pla
[values]
layer_height = 0.2
@@ -19,4 +19,4 @@ speed_print = 50
speed_layer_0 = =round(speed_print * 30 / 50)
speed_topbottom = 20
cool_min_layer_time = 5
-cool_min_speed = 10
\ No newline at end of file
+cool_min_speed = 10
diff --git a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg
index 11892a6223..922da8e88e 100644
--- a/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg
+++ b/resources/quality/abax_pri5/apri5_pla_fast.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fine
definition = abax_pri5
[metadata]
-type = quality
-material = generic_pla
-weight = -1
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = -1
+material = generic_pla
[values]
layer_height = 0.2
@@ -19,4 +19,4 @@ speed_print = 80
speed_layer_0 = =round(speed_print * 30 / 50)
speed_topbottom = 20
cool_min_layer_time = 5
-cool_min_speed = 10
\ No newline at end of file
+cool_min_speed = 10
diff --git a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg
index 852efe699e..2b1c6b017b 100644
--- a/resources/quality/abax_pri5/apri5_pla_high.inst.cfg
+++ b/resources/quality/abax_pri5/apri5_pla_high.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = abax_pri5
[metadata]
-type = quality
-material = generic_pla
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+material = generic_pla
[values]
layer_height = 0.1
@@ -19,4 +19,4 @@ speed_print = 50
speed_layer_0 = =round(speed_print * 30 / 50)
speed_topbottom = 20
cool_min_layer_time = 5
-cool_min_speed = 10
\ No newline at end of file
+cool_min_speed = 10
diff --git a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg
index 244d544c80..23b21f597b 100644
--- a/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg
+++ b/resources/quality/abax_pri5/apri5_pla_normal.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fine
definition = abax_pri5
[metadata]
-type = quality
-material = generic_pla
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_pla
[values]
layer_height = 0.2
@@ -19,4 +19,4 @@ speed_print = 50
speed_layer_0 = =round(speed_print * 30 / 50)
speed_topbottom = 20
cool_min_layer_time = 5
-cool_min_speed = 10
\ No newline at end of file
+cool_min_speed = 10
diff --git a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg
index a2d802a3ba..5d935a915a 100644
--- a/resources/quality/abax_titan/atitan_pla_fast.inst.cfg
+++ b/resources/quality/abax_titan/atitan_pla_fast.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fine
definition = abax_titan
[metadata]
-type = quality
-material = generic_pla
-weight = -1
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = -1
+material = generic_pla
[values]
layer_height = 0.2
@@ -19,4 +19,4 @@ speed_print = 80
speed_layer_0 = =round(speed_print * 30 / 50)
speed_topbottom = 20
cool_min_layer_time = 5
-cool_min_speed = 10
\ No newline at end of file
+cool_min_speed = 10
diff --git a/resources/quality/abax_titan/atitan_pla_high.inst.cfg b/resources/quality/abax_titan/atitan_pla_high.inst.cfg
index 7ee8c35133..8bd45034e3 100644
--- a/resources/quality/abax_titan/atitan_pla_high.inst.cfg
+++ b/resources/quality/abax_titan/atitan_pla_high.inst.cfg
@@ -1,13 +1,14 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = abax_titan
+
[metadata]
-type = quality
-material = generic_pla
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+material = generic_pla
[values]
layer_height = 0.1
@@ -18,4 +19,4 @@ speed_print = 50
speed_layer_0 = =round(speed_print * 30 / 50)
speed_topbottom = 20
cool_min_layer_time = 5
-cool_min_speed = 10
\ No newline at end of file
+cool_min_speed = 10
diff --git a/resources/quality/abax_titan/atitan_pla_normal.inst.cfg b/resources/quality/abax_titan/atitan_pla_normal.inst.cfg
index 6c40914566..081e5ad977 100644
--- a/resources/quality/abax_titan/atitan_pla_normal.inst.cfg
+++ b/resources/quality/abax_titan/atitan_pla_normal.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fine
definition = abax_titan
[metadata]
-type = quality
-material = generic_pla
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_pla
[values]
layer_height = 0.2
@@ -19,4 +19,4 @@ speed_print = 50
speed_layer_0 = =round(speed_print * 30 / 50)
speed_topbottom = 20
cool_min_layer_time = 5
-cool_min_speed = 10
\ No newline at end of file
+cool_min_speed = 10
diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg
index c6281767f9..821205ca69 100644
--- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg
+++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_draft.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = Draft
definition = anycubic_i3_mega
[metadata]
+setting_version = 4
type = quality
quality_type = draft
weight = 0
-setting_version = 4
[values]
acceleration_enabled = True
@@ -57,4 +57,4 @@ support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
-wall_thickness = 1.2
\ No newline at end of file
+wall_thickness = 1.2
diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg
index 839054a4df..e686ce50ac 100644
--- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg
+++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_high.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = High
definition = anycubic_i3_mega
[metadata]
+setting_version = 4
type = quality
quality_type = high
weight = 2
-setting_version = 4
[values]
acceleration_enabled = True
@@ -57,4 +57,4 @@ support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
-wall_thickness = 1.2
\ No newline at end of file
+wall_thickness = 1.2
diff --git a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg
index 241a8b2e2c..3e855c1bbc 100644
--- a/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg
+++ b/resources/quality/anycubic_i3_mega/anycubic_i3_mega_normal.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = Normal
definition = anycubic_i3_mega
[metadata]
+setting_version = 4
type = quality
quality_type = normal
weight = 1
-setting_version = 4
[values]
acceleration_enabled = True
@@ -57,4 +57,4 @@ support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
-wall_thickness = 1.2
\ No newline at end of file
+wall_thickness = 1.2
diff --git a/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg
index 92f899bdeb..c5a92e3c93 100644
--- a/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_BVOH_Coarse_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = coarse
-material = verbatim_bvoh_175
-setting_version = 4
weight = -1
+material = verbatim_bvoh_175
[values]
material_print_temperature = =default_material_print_temperature + 5
@@ -21,4 +21,3 @@ layer_height = 0.3
top_thickness = =layer_height * 5
bottom_thickness = =layer_height * 3
speed_print = 40
-
diff --git a/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg
index cd8947aa80..72ce4f3555 100644
--- a/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_BVOH_High_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = High Quality
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = verbatim_bvoh_175
-setting_version = 4
weight = 1
+material = verbatim_bvoh_175
[values]
acceleration_print = 2000
@@ -22,4 +22,4 @@ layer_height = 0.1
top_thickness = =layer_height * 7
bottom_thickness = =layer_height * 5
speed_print = 40
-layer_height_0 = 0.2
\ No newline at end of file
+layer_height_0 = 0.2
diff --git a/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg
index d59f768470..daa1d8bc78 100644
--- a/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_BVOH_Normal_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = verbatim_bvoh_175
-setting_version = 4
weight = 0
+material = verbatim_bvoh_175
[values]
material_print_temperature = =default_material_print_temperature + 5
@@ -20,4 +20,4 @@ material_bed_temperature_layer_0= =material_bed_temperature
layer_height = 0.2
top_thickness = =layer_height * 5
bottom_thickness = =layer_height * 3
-speed_print = 40
\ No newline at end of file
+speed_print = 40
diff --git a/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg
index 41d882ee1d..827c726071 100644
--- a/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_Innoflex60_Coarse_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = coarse
-material = innofill_innoflex60_175
-setting_version = 4
weight = -1
+material = innofill_innoflex60_175
[values]
material_print_temperature = =default_material_print_temperature
@@ -21,4 +21,3 @@ layer_height = 0.3
top_thickness = =layer_height * 5
bottom_thickness = =layer_height * 3
speed_print = 30
-
diff --git a/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg
index 147e1f4db8..4c84d0ddfe 100644
--- a/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_Innoflex60_High_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = High Quality
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = innofill_innoflex60_175
-setting_version = 4
weight = 1
+material = innofill_innoflex60_175
[values]
acceleration_print = 2000
@@ -22,4 +22,4 @@ layer_height = 0.1
top_thickness = =layer_height * 7
bottom_thickness = =layer_height * 5
speed_print = 30
-layer_height_0 = 0.2
\ No newline at end of file
+layer_height_0 = 0.2
diff --git a/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg
index fb43c8de19..23813f85b9 100644
--- a/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_Innoflex60_Normal_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = innofill_innoflex60_175
-setting_version = 4
weight = 0
+material = innofill_innoflex60_175
[values]
material_print_temperature = =default_material_print_temperature
@@ -20,4 +20,4 @@ material_bed_temperature_layer_0= =material_bed_temperature
layer_height = 0.2
top_thickness = =layer_height * 5
bottom_thickness = =layer_height * 3
-speed_print = 30
\ No newline at end of file
+speed_print = 30
diff --git a/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg
index f887600585..da0d40393c 100644
--- a/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_PET_Coarse_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = coarse
-material = generic_petg_175
-setting_version = 4
weight = -1
+material = generic_petg
[values]
material_print_temperature = =default_material_print_temperature - 5
@@ -21,4 +21,3 @@ layer_height = 0.3
top_thickness = =layer_height * 5
bottom_thickness = =layer_height * 3
speed_print = 60
-
diff --git a/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg
index 4258f2f708..b78a5a29d7 100644
--- a/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_PET_High_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = High Quality
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_petg_175
-setting_version = 4
weight = 1
+material = generic_petg
[values]
acceleration_print = 2000
@@ -22,4 +22,4 @@ layer_height = 0.1
top_thickness = =layer_height * 7
bottom_thickness = =layer_height * 5
speed_print = 40
-layer_height_0 = 0.2
\ No newline at end of file
+layer_height_0 = 0.2
diff --git a/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg
index b732073795..600fbed476 100644
--- a/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_PET_Normal_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_petg_175
-setting_version = 4
weight = 0
+material = generic_petg
[values]
material_print_temperature = =default_material_print_temperature - 5
@@ -20,4 +20,4 @@ material_bed_temperature_layer_0= =material_bed_temperature
layer_height = 0.2
top_thickness = =layer_height * 5
bottom_thickness = =layer_height * 3
-speed_print = 50
\ No newline at end of file
+speed_print = 50
diff --git a/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg
index 4f0c26dd7d..d1c1d4d563 100644
--- a/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_PLA_Coarse_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = coarse
-material = generic_pla_175
-setting_version = 4
weight = -1
+material = generic_pla
[values]
material_print_temperature = =default_material_print_temperature + 15
@@ -21,4 +21,3 @@ layer_height = 0.3
top_thickness = =layer_height * 5
bottom_thickness = =layer_height * 3
speed_print = 60
-
diff --git a/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg
index 4a9bcb90bf..1063342b89 100644
--- a/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_PLA_High_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = High Quality
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pla_175
-setting_version = 4
weight = 1
+material = generic_pla
[values]
acceleration_print = 2000
@@ -22,4 +22,4 @@ layer_height = 0.1
top_thickness = =layer_height * 7
bottom_thickness = =layer_height * 5
speed_print = 40
-layer_height_0 = 0.2
\ No newline at end of file
+layer_height_0 = 0.2
diff --git a/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg
index 6af5601fd6..6612c704f3 100644
--- a/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_PLA_Normal_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pla_175
-setting_version = 4
weight = 0
+material = generic_pla
[values]
material_print_temperature = =default_material_print_temperature + 15
@@ -20,4 +20,4 @@ material_bed_temperature_layer_0= =material_bed_temperature
layer_height = 0.2
top_thickness = =layer_height * 5
bottom_thickness = =layer_height * 3
-speed_print = 50
\ No newline at end of file
+speed_print = 50
diff --git a/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg
index 12a4c9d883..2717ffe998 100644
--- a/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_PVA_Coarse_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = coarse
-material = generic_pva_175
-setting_version = 4
weight = -1
+material = generic_pva
[values]
material_print_temperature = =default_material_print_temperature + 10
@@ -21,4 +21,3 @@ layer_height = 0.3
top_thickness = =layer_height * 5
bottom_thickness = =layer_height * 3
speed_print = 40
-
diff --git a/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg
index d32017c5f2..3ab782af5c 100644
--- a/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_PVA_High_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = High Quality
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pva_175
-setting_version = 4
weight = 1
+material = generic_pva
[values]
acceleration_print = 2000
@@ -22,4 +22,4 @@ layer_height = 0.1
top_thickness = =layer_height * 7
bottom_thickness = =layer_height * 5
speed_print = 40
-layer_height_0 = 0.2
\ No newline at end of file
+layer_height_0 = 0.2
diff --git a/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg
index 2acc354822..fe24e976c7 100644
--- a/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_PVA_Normal_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pva_175
-setting_version = 4
weight = 0
+material = generic_pva
[values]
material_print_temperature = =default_material_print_temperature + 10
@@ -20,4 +20,4 @@ material_bed_temperature_layer_0= =material_bed_temperature
layer_height = 0.2
top_thickness = =layer_height * 5
bottom_thickness = =layer_height * 3
-speed_print = 40
\ No newline at end of file
+speed_print = 40
diff --git a/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg
index 4b66293d04..708a135847 100644
--- a/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_global_Coarse_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = coarse
-setting_version = 4
weight = -1
global_quality = True
[values]
-layer_height = 0.3
\ No newline at end of file
+layer_height = 0.3
diff --git a/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg
index 4a97dda084..0c96206a7d 100644
--- a/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_global_High_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = High Quality
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = high
-setting_version = 4
weight = 1
global_quality = True
[values]
-layer_height = 0.1
\ No newline at end of file
+layer_height = 0.1
diff --git a/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg b/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg
index 15ea66879f..833e7e8905 100644
--- a/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg
+++ b/resources/quality/builder_premium/bp_global_Normal_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = builder_premium_small
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-setting_version = 4
weight = 0
global_quality = True
[values]
-layer_height = 0.2
\ No newline at end of file
+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 418855a9ba..5e713275c6 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_abs_175_cartesio_0.25_mm
weight = 1
-setting_version = 4
+material = generic_abs
+variant = 0.25 mm
[values]
infill_line_width = 0.3
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 e95ef08e22..d35dcf1c18 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_abs_175_cartesio_0.25_mm
weight = 2
-setting_version = 4
+material = generic_abs
+variant = 0.25 mm
[values]
infill_line_width = 0.3
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 524f5ba12a..06ef74108b 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_abs_175_cartesio_0.4_mm
weight = 1
-setting_version = 4
+material = generic_abs
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 24ffb19d6f..8e5b6aadc0 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_abs_175_cartesio_0.4_mm
weight = 2
-setting_version = 4
+material = generic_abs
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 1281a3afdd..5da823a2d8 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = coarse
-material = generic_abs_175_cartesio_0.8_mm
weight = 3
-setting_version = 4
+material = generic_abs
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 a8d19deef7..267857cff1 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = extra coarse
-material = generic_abs_175_cartesio_0.8_mm
weight = 4
-setting_version = 4
+material = generic_abs
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 87cc855f44..e3219d145c 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_abs_175_cartesio_0.8_mm
weight = 1
-setting_version = 4
+material = generic_abs
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 4ca2598051..111bef11dc 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_abs_175_cartesio_0.8_mm
weight = 2
-setting_version = 4
+material = generic_abs
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 42eb705f11..35dddeca91 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = dsm_arnitel2045_175_cartesio_0.4_mm
weight = 1
-setting_version = 4
+material = dsm_arnitel2045_175
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 2
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 538fe91b76..3234881c72 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = dsm_arnitel2045_175_cartesio_0.4_mm
weight = 2
-setting_version = 4
+material = dsm_arnitel2045_175
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 2
diff --git a/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg b/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg
index 11760b139f..017483f79a 100644
--- a/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg
+++ b/resources/quality/cartesio/cartesio_global_Coarse_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = coarse
-global_quality = True
weight = -3
-setting_version = 4
+global_quality = True
[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 c654dba598..aadb582309 100644
--- a/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg
+++ b/resources/quality/cartesio/cartesio_global_Extra_Coarse_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Extra Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = extra coarse
-global_quality = True
weight = -4
-setting_version = 4
+global_quality = True
[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 393a5f3b39..e4131dc3a2 100644
--- a/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg
+++ b/resources/quality/cartesio/cartesio_global_High_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-global_quality = True
weight = 1
-setting_version = 4
+global_quality = True
[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 c09493ba10..e29a98c980 100644
--- a/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg
+++ b/resources/quality/cartesio/cartesio_global_Normal_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-global_quality = True
weight = 0
-setting_version = 4
+global_quality = True
[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 eae4e82cd3..b2dc76479f 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_hips_175_cartesio_0.25_mm
weight = 1
-setting_version = 4
+material = generic_hips
+variant = 0.25 mm
[values]
infill_line_width = 0.3
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 0c47b18196..c18167b97a 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_hips_175_cartesio_0.25_mm
weight = 2
-setting_version = 4
+material = generic_hips
+variant = 0.25 mm
[values]
infill_line_width = 0.3
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 14f1ea4662..506ff1807b 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_hips_175_cartesio_0.4_mm
weight = 1
-setting_version = 4
+material = generic_hips
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 bd13b358ff..1f2ee24064 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_hips_175_cartesio_0.4_mm
weight = 2
-setting_version = 4
+material = generic_hips
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 ca864692c3..d117df88a6 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = coarse
-material = generic_hips_175_cartesio_0.8_mm
weight = 3
-setting_version = 4
+material = generic_hips
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 3cadef4fdd..e833abcdad 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = extra coarse
-material = generic_hips_175_cartesio_0.8_mm
weight = 4
-setting_version = 4
+material = generic_hips
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 07839c8a9a..eee5862fea 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_hips_175_cartesio_0.8_mm
weight = 1
-setting_version = 4
+material = generic_hips
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 acc9db0891..b0057d5b03 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_hips_175_cartesio_0.8_mm
weight = 2
-setting_version = 4
+material = generic_hips
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 b1f2f17d41..6dce2b7ea2 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_nylon_175_cartesio_0.25_mm
weight = 1
-setting_version = 4
+material = generic_nylon
+variant = 0.25 mm
[values]
infill_line_width = 0.3
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 bcfa1c2e30..169a7cab65 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_nylon_175_cartesio_0.25_mm
weight = 2
-setting_version = 4
+material = generic_nylon
+variant = 0.25 mm
[values]
infill_line_width = 0.3
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 2cd50efeb2..101fb595d5 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_nylon_175_cartesio_0.4_mm
weight = 1
-setting_version = 4
+material = generic_nylon
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 7a7d767ea3..dc5522bda3 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_nylon_175_cartesio_0.4_mm
weight = 2
-setting_version = 4
+material = generic_nylon
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 5684c89e23..0b4ef88282 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = coarse
-material = generic_nylon_175_cartesio_0.8_mm
weight = 3
-setting_version = 4
+material = generic_nylon
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 8d97e9ac5f..2fd9aa3220 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = extra coarse
-material = generic_nylon_175_cartesio_0.8_mm
weight = 4
-setting_version = 4
+material = generic_nylon
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 946f8de34d..26f749e357 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_nylon_175_cartesio_0.8_mm
weight = 1
-setting_version = 4
+material = generic_nylon
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 80f390c254..4843c9cbf4 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_nylon_175_cartesio_0.8_mm
weight = 2
-setting_version = 4
+material = generic_nylon
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 ff6547dd91..d29c8c6801 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pc_175_cartesio_0.25_mm
weight = 1
-setting_version = 4
+material = generic_pc
+variant = 0.25 mm
[values]
infill_line_width = 0.3
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 f3faa9c129..35168f8ed7 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pc_175_cartesio_0.25_mm
weight = 2
-setting_version = 4
+material = generic_pc
+variant = 0.25 mm
[values]
infill_line_width = 0.3
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 3aa808fab5..05bb623a90 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pc_175_cartesio_0.4_mm
weight = 1
-setting_version = 4
+material = generic_pc
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 f9be12da3a..569ecb069a 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pc_175_cartesio_0.4_mm
weight = 2
-setting_version = 4
+material = generic_pc
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 597187437b..b35681187d 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = coarse
-material = generic_pc_175_cartesio_0.8_mm
weight = 3
-setting_version = 4
+material = generic_pc
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 6d1fa196ec..75fe030443 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = extra coarse
-material = generic_pc_175_cartesio_0.8_mm
weight = 4
-setting_version = 4
+material = generic_pc
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 c570b65350..05232ac1b3 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pc_175_cartesio_0.8_mm
weight = 1
-setting_version = 4
+material = generic_pc
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 0d73b24197..106afcf992 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pc_175_cartesio_0.8_mm
weight = 2
-setting_version = 4
+material = generic_pc
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 c5c4be6f4a..edeb791847 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_petg_175_cartesio_0.25_mm
weight = 1
-setting_version = 4
+material = generic_petg
+variant = 0.25 mm
[values]
infill_line_width = 0.3
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
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 6d12bdc402..ca95ba4d55 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_petg_175_cartesio_0.25_mm
weight = 2
-setting_version = 4
+material = generic_petg
+variant = 0.25 mm
[values]
infill_line_width = 0.3
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
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 43dda5007c..47e4e74fba 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_petg_175_cartesio_0.4_mm
weight = 1
-setting_version = 4
+material = generic_petg
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
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 094dc33263..737289f778 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_petg_175_cartesio_0.4_mm
weight = 2
-setting_version = 4
+material = generic_petg
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
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 da9e4ad3dd..54abbbeb46 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = coarse
-material = generic_petg_175_cartesio_0.8_mm
weight = 3
-setting_version = 4
+material = generic_petg
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
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 607ba778a1..75ef0ed89b 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = extra coarse
-material = generic_petg_175_cartesio_0.8_mm
weight = 4
-setting_version = 4
+material = generic_petg
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
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 3010d95dab..2a9542ce56 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_petg_175_cartesio_0.8_mm
weight = 1
-setting_version = 4
+material = generic_petg
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 50
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
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 fbf8fac67f..9f27c3c8d1 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_petg_175_cartesio_0.8_mm
weight = 2
-setting_version = 4
+material = generic_petg
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
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 9d8130602e..62cf3194c0 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pla_175_cartesio_0.25_mm
weight = 1
-setting_version = 4
+material = generic_pla
+variant = 0.25 mm
[values]
infill_line_width = 0.3
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 98401dbf42..5dd27477e1 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pla_175_cartesio_0.25_mm
weight = 0
-setting_version = 4
+material = generic_pla
+variant = 0.25 mm
[values]
infill_line_width = 0.3
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 2eda5103d7..b6bf3808be 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pla_175_cartesio_0.4_mm
weight = 1
-setting_version = 4
+material = generic_pla
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 f3d3820ff7..a03b316e6f 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pla_175_cartesio_0.4_mm
weight = 0
-setting_version = 4
+material = generic_pla
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 d2cf708336..6284ab3325 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = coarse
-material = generic_pla_175_cartesio_0.8_mm
weight = -3
-setting_version = 4
+material = generic_pla
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 888d8f91a7..58b4c347f3 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = extra coarse
-material = generic_pla_175_cartesio_0.8_mm
weight = -4
-setting_version = 4
+material = generic_pla
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 558514db98..f0d22251bb 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pla_175_cartesio_0.8_mm
weight = 1
-setting_version = 4
+material = generic_pla
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 9c508e4a1f..44ed46ddd3 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pla_175_cartesio_0.8_mm
weight = 0
-setting_version = 4
+material = generic_pla
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 10
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 fcbf4913de..aa9ac8393d 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pva_175_cartesio_0.25_mm
weight = 1
-setting_version = 4
+material = generic_pva
+variant = 0.25 mm
[values]
infill_line_width = 0.3
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
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 3893421df0..b4de6b5730 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pva_175_cartesio_0.25_mm
weight = 2
-setting_version = 4
+material = generic_pva
+variant = 0.25 mm
[values]
infill_line_width = 0.3
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
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 5876db1e2e..5a60dfbe17 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pva_175_cartesio_0.4_mm
weight = 1
-setting_version = 4
+material = generic_pva
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
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 c977e79a5c..9cc57ac16a 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pva_175_cartesio_0.4_mm
weight = 2
-setting_version = 4
+material = generic_pva
+variant = 0.4 mm
[values]
infill_line_width = 0.5
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
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 8c36d8e7ed..df1bffeb41 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = coarse
-material = generic_pva_175_cartesio_0.8_mm
weight = 3
-setting_version = 4
+material = generic_pva
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
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 c2b19868f6..30ade55494 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Coarse
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = extra coarse
-material = generic_pva_175_cartesio_0.8_mm
weight = 4
-setting_version = 4
+material = generic_pva
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
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 5bd285285a..c8ab571baf 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = High
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pva_175_cartesio_0.8_mm
weight = 1
-setting_version = 4
+material = generic_pva
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
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 a11bff95e1..815694e410 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = cartesio
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pva_175_cartesio_0.8_mm
weight = 2
-setting_version = 4
+material = generic_pva
+variant = 0.8 mm
[values]
infill_line_width = 0.9
@@ -23,7 +24,7 @@ infill_sparse_density = 40
infill_pattern = grid
material_print_temperature_layer_0 = =material_print_temperature + 5
-material_initial_print_temperature = =material_print_temperature
+material_initial_print_temperature = =material_print_temperature_layer_0 + 5
material_final_print_temperature = =material_print_temperature
retraction_min_travel = =round(line_width * 10)
retraction_prime_speed = 8
diff --git a/resources/quality/coarse.inst.cfg b/resources/quality/coarse.inst.cfg
index 133ffc8951..9dff2a02b3 100644
--- a/resources/quality/coarse.inst.cfg
+++ b/resources/quality/coarse.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Coarse Quality
definition = fdmprinter
[metadata]
+setting_version = 4
type = quality
quality_type = coarse
-global_quality = True
weight = -3
-setting_version = 4
+global_quality = True
[values]
layer_height = 0.4
diff --git a/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg
index 43643b6b92..3863cb6940 100644
--- a/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg
+++ b/resources/quality/deltacomb/deltacomb_abs_fast.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
definition = deltacomb
name = Fast Quality (beta)
[metadata]
-type = quality
setting_version = 4
-material = generic_abs_175
+type = quality
quality_type = fast
weight = -1
+material = generic_abs
[values]
adhesion_type = raft
@@ -22,4 +22,3 @@ cool_fan_speed_min = 50
cool_min_layer_time = 3
cool_min_speed = 20
material_bed_temperature = 80
-
diff --git a/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg
index 99e47bc9cb..715d8a6841 100644
--- a/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg
+++ b/resources/quality/deltacomb/deltacomb_abs_high.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
definition = deltacomb
name = High Quality (beta)
[metadata]
-type = quality
setting_version = 4
-material = generic_abs_175
+type = quality
quality_type = high
weight = 1
+material = generic_abs
[values]
adhesion_type = raft
@@ -22,4 +22,3 @@ cool_fan_speed_min = 50
cool_min_layer_time = 3
cool_min_speed = 20
material_bed_temperature = 80
-
diff --git a/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg b/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg
index a2aa2be769..7cddbb154a 100644
--- a/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg
+++ b/resources/quality/deltacomb/deltacomb_abs_normal.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
definition = deltacomb
name = Normal Quality (beta)
[metadata]
-type = quality
setting_version = 4
-material = generic_abs_175
+type = quality
quality_type = normal
weight = 0
+material = generic_abs
[values]
adhesion_type = raft
diff --git a/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg b/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg
index fac23939cf..72d2b30199 100644
--- a/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg
+++ b/resources/quality/deltacomb/deltacomb_nylon_fast.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fast Quality (beta)
definition = deltacomb
[metadata]
+setting_version = 4
type = quality
-material = generic_nylon_175
quality_type = fast
weight = -1
-setting_version = 4
+material = generic_nylon
[values]
adhesion_type = raft
diff --git a/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg b/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg
index d594126474..2cd71a96b1 100644
--- a/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg
+++ b/resources/quality/deltacomb/deltacomb_nylon_high.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = High Quality (beta)
definition = deltacomb
[metadata]
+setting_version = 4
type = quality
-material = generic_nylon_175
quality_type = high
weight = 1
-setting_version = 4
+material = generic_nylon
[values]
adhesion_type = raft
diff --git a/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg b/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg
index 76716fc16d..d42fdee730 100644
--- a/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg
+++ b/resources/quality/deltacomb/deltacomb_nylon_normal.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal Quality (beta)
definition = deltacomb
[metadata]
+setting_version = 4
type = quality
-material = generic_nylon_175
quality_type = normal
weight = 0
-setting_version = 4
+material = generic_nylon
[values]
adhesion_type = raft
@@ -55,4 +55,3 @@ support_z_distance = 0.15
top_bottom_thickness = 0.8
wall_thickness = 0.8
z_seam_type = random
-
diff --git a/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg
index 9783cb11cc..11fefbaed1 100644
--- a/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg
+++ b/resources/quality/deltacomb/deltacomb_pla_fast.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
definition = deltacomb
name = Fast Quality
[metadata]
-type = quality
setting_version = 4
-material = generic_pla_175
+type = quality
quality_type = fast
weight = -1
+material = generic_pla
[values]
adhesion_type = skirt
@@ -21,4 +21,3 @@ cool_fan_speed_max = 100
cool_fan_speed_min = 100
cool_min_layer_time = 5
cool_min_speed = 20
-
diff --git a/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg
index 9513e98b6a..4b7125dbb9 100644
--- a/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg
+++ b/resources/quality/deltacomb/deltacomb_pla_high.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
definition = deltacomb
name = High Quality
[metadata]
-type = quality
setting_version = 4
-material = generic_pla_175
+type = quality
quality_type = high
weight = 1
+material = generic_pla
[values]
adhesion_type = skirt
@@ -22,4 +22,3 @@ cool_fan_speed_min = 100
cool_min_layer_time = 5
cool_min_speed = 20
material_print_temperature_layer_0 = =default_material_print_temperature + 5
-
diff --git a/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg b/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg
index d88f5909f0..e935c45567 100644
--- a/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg
+++ b/resources/quality/deltacomb/deltacomb_pla_normal.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
definition = deltacomb
name = Normal Quality
[metadata]
-type = quality
setting_version = 4
-material = generic_pla_175
+type = quality
quality_type = normal
weight = 0
+material = generic_pla
[values]
adhesion_type = skirt
diff --git a/resources/quality/draft.inst.cfg b/resources/quality/draft.inst.cfg
index a155c8f2e1..211525e7d6 100644
--- a/resources/quality/draft.inst.cfg
+++ b/resources/quality/draft.inst.cfg
@@ -1,15 +1,14 @@
-
[general]
-version = 2
+version = 3
name = Draft Quality
definition = fdmprinter
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-global_quality = True
weight = -2
-setting_version = 4
+global_quality = True
[values]
layer_height = 0.2
diff --git a/resources/quality/extra_coarse.inst.cfg b/resources/quality/extra_coarse.inst.cfg
index ce28e54721..e25b813f2f 100644
--- a/resources/quality/extra_coarse.inst.cfg
+++ b/resources/quality/extra_coarse.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Extra Coarse Quality
definition = fdmprinter
[metadata]
-type = quality
-quality_type = Extra coarse
-global_quality = True
-weight = -4
setting_version = 4
+type = quality
+quality_type = extra coarse
+weight = -4
+global_quality = True
[values]
layer_height = 0.6
diff --git a/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg
index 245997a27e..78a4eb6f9f 100644
--- a/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg
+++ b/resources/quality/fabtotum/fabtotum_abs_fast.inst.cfg
@@ -1,24 +1,24 @@
[general]
-version = 2
+version = 3
definition = fabtotum
name = Fast Quality
[metadata]
-type = quality
setting_version = 4
-material = fabtotum_abs
+type = quality
quality_type = fast
weight = -1
+material = fabtotum_abs
[values]
adhesion_type = raft
+speed_print = 80
layer_height = 0.2
layer_height_0 = 0.2
-cool_fan_enabled = True
+cool_fan_enabled = False
cool_fan_full_at_height = 0.4
cool_fan_speed = 50
cool_fan_speed_max = 50
cool_fan_speed_min = 50
cool_min_layer_time = 3
cool_min_speed = 20
-
diff --git a/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg
index 26300eec7d..786ae18fa5 100644
--- a/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg
+++ b/resources/quality/fabtotum/fabtotum_abs_high.inst.cfg
@@ -1,24 +1,24 @@
[general]
-version = 2
+version = 3
definition = fabtotum
name = High Quality
[metadata]
-type = quality
setting_version = 4
-material = fabtotum_abs
+type = quality
quality_type = high
weight = 1
+material = fabtotum_abs
[values]
adhesion_type = raft
+speed_print = 45
layer_height = 0.1
layer_height_0 = 0.1
-cool_fan_enabled = True
+cool_fan_enabled = False
cool_fan_full_at_height = 0.2
cool_fan_speed = 50
cool_fan_speed_max = 50
cool_fan_speed_min = 50
cool_min_layer_time = 3
cool_min_speed = 20
-
diff --git a/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg
index 53d20c8cbc..da75417c87 100644
--- a/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg
+++ b/resources/quality/fabtotum/fabtotum_abs_normal.inst.cfg
@@ -1,24 +1,24 @@
[general]
-version = 2
+version = 3
definition = fabtotum
name = Normal Quality
[metadata]
-type = quality
setting_version = 4
-material = fabtotum_abs
+type = quality
quality_type = normal
weight = 0
+material = fabtotum_abs
[values]
adhesion_type = raft
+speed_print = 60
layer_height = 0.15
layer_height_0 = 0.15
-cool_fan_enabled = True
+cool_fan_enabled = False
cool_fan_full_at_height = 0.3
cool_fan_speed = 50
cool_fan_speed_max = 50
cool_fan_speed_min = 50
cool_min_layer_time = 3
cool_min_speed = 20
-
diff --git a/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg
index 22bbcbeaeb..db86543322 100644
--- a/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg
+++ b/resources/quality/fabtotum/fabtotum_nylon_fast.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fast Quality
definition = fabtotum
[metadata]
+setting_version = 4
type = quality
-material = fabtotum_nylon
quality_type = fast
weight = -1
-setting_version = 4
+material = fabtotum_nylon
[values]
adhesion_type = raft
@@ -44,7 +44,7 @@ skirt_gap = 1.5
skirt_line_count = 5
speed_infill = =speed_print
speed_layer_0 = 25
-speed_print = 50
+speed_print = 30
speed_topbottom = 40
speed_travel = 200
speed_wall_0 = 40
@@ -54,4 +54,4 @@ support_type = buildplate
support_z_distance = 0.15
top_bottom_thickness = 0.8
wall_thickness = 0.8
-z_seam_type = random
\ No newline at end of file
+z_seam_type = random
diff --git a/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg
index a625bd715f..010298c472 100644
--- a/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg
+++ b/resources/quality/fabtotum/fabtotum_nylon_high.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = High Quality
definition = fabtotum
[metadata]
+setting_version = 4
type = quality
-material = fabtotum_nylon
quality_type = high
weight = 1
-setting_version = 4
+material = fabtotum_nylon
[values]
adhesion_type = raft
@@ -44,7 +44,7 @@ skirt_gap = 1.5
skirt_line_count = 5
speed_infill = =speed_print
speed_layer_0 = 25
-speed_print = 50
+speed_print = 30
speed_topbottom = 40
speed_travel = 200
speed_wall_0 = 40
@@ -54,4 +54,4 @@ support_type = buildplate
support_z_distance = 0.15
top_bottom_thickness = 0.8
wall_thickness = 0.8
-z_seam_type = random
\ No newline at end of file
+z_seam_type = random
diff --git a/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg
index b05d30c5c6..b9a80d82b3 100644
--- a/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg
+++ b/resources/quality/fabtotum/fabtotum_nylon_normal.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal Quality
definition = fabtotum
[metadata]
+setting_version = 4
type = quality
-material = fabtotum_nylon
quality_type = normal
weight = 0
-setting_version = 4
+material = fabtotum_nylon
[values]
adhesion_type = raft
@@ -44,7 +44,7 @@ skirt_gap = 1.5
skirt_line_count = 5
speed_infill = =speed_print
speed_layer_0 = 25
-speed_print = 50
+speed_print = 30
speed_topbottom = 40
speed_travel = 200
speed_wall_0 = 40
@@ -55,4 +55,3 @@ support_z_distance = 0.15
top_bottom_thickness = 0.8
wall_thickness = 0.8
z_seam_type = random
-
diff --git a/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg
index 1f1c93961b..bea0ea4aff 100644
--- a/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg
+++ b/resources/quality/fabtotum/fabtotum_pla_fast.inst.cfg
@@ -1,17 +1,18 @@
[general]
-version = 2
+version = 3
definition = fabtotum
name = Fast Quality
[metadata]
-type = quality
setting_version = 4
-material = fabtotum_pla
+type = quality
quality_type = fast
weight = -1
+material = fabtotum_pla
[values]
adhesion_type = skirt
+speed_print = 80
layer_height = 0.2
layer_height_0 = 0.2
cool_fan_enabled = True
@@ -21,4 +22,3 @@ cool_fan_speed_max = 100
cool_fan_speed_min = 100
cool_min_layer_time = 5
cool_min_speed = 20
-
diff --git a/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg
index 9cd067703c..b77a0d8300 100644
--- a/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg
+++ b/resources/quality/fabtotum/fabtotum_pla_high.inst.cfg
@@ -1,17 +1,18 @@
[general]
-version = 2
+version = 3
definition = fabtotum
name = High Quality
[metadata]
-type = quality
setting_version = 4
-material = fabtotum_pla
+type = quality
quality_type = high
weight = 1
+material = fabtotum_pla
[values]
adhesion_type = skirt
+speed_print = 45
layer_height = 0.1
layer_height_0 = 0.1
cool_fan_enabled = True
@@ -21,4 +22,3 @@ cool_fan_speed_max = 100
cool_fan_speed_min = 100
cool_min_layer_time = 5
cool_min_speed = 20
-
diff --git a/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg
index 5b5125c4e5..11e5890cc5 100644
--- a/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg
+++ b/resources/quality/fabtotum/fabtotum_pla_normal.inst.cfg
@@ -1,17 +1,18 @@
[general]
-version = 2
+version = 3
definition = fabtotum
name = Normal Quality
[metadata]
-type = quality
setting_version = 4
-material = fabtotum_pla
+type = quality
quality_type = normal
weight = 0
+material = fabtotum_pla
[values]
adhesion_type = skirt
+speed_print = 60
layer_height = 0.15
layer_height_0 = 0.15
cool_fan_enabled = True
@@ -21,4 +22,3 @@ cool_fan_speed_max = 100
cool_fan_speed_min = 100
cool_min_layer_time = 5
cool_min_speed = 20
-
diff --git a/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg b/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg
new file mode 100644
index 0000000000..d689f704aa
--- /dev/null
+++ b/resources/quality/fabtotum/fabtotum_tpu_fast.inst.cfg
@@ -0,0 +1,25 @@
+[general]
+version = 3
+definition = fabtotum
+name = Fast Quality
+
+[metadata]
+type = quality
+setting_version = 4
+material = fabtotum_tpu
+quality_type = fast
+weight = -1
+
+[values]
+adhesion_type = skirt
+speed_print = 80
+layer_height = 0.2
+layer_height_0 = 0.2
+cool_fan_enabled = True
+cool_fan_full_at_height = 0.4
+cool_fan_speed = 100
+cool_fan_speed_max = 100
+cool_fan_speed_min = 100
+cool_min_layer_time = 5
+cool_min_speed = 20
+
diff --git a/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg b/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg
new file mode 100644
index 0000000000..6193b3b573
--- /dev/null
+++ b/resources/quality/fabtotum/fabtotum_tpu_high.inst.cfg
@@ -0,0 +1,24 @@
+[general]
+version = 3
+definition = fabtotum
+name = High Quality
+
+[metadata]
+type = quality
+setting_version = 4
+material = fabtotum_tpu
+quality_type = high
+weight = 1
+
+[values]
+adhesion_type = skirt
+layer_height = 0.1
+layer_height_0 = 0.1
+cool_fan_enabled = True
+cool_fan_full_at_height = 0.2
+cool_fan_speed = 100
+cool_fan_speed_max = 100
+cool_fan_speed_min = 100
+cool_min_layer_time = 5
+cool_min_speed = 20
+
diff --git a/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg b/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg
new file mode 100644
index 0000000000..7ccbe296e3
--- /dev/null
+++ b/resources/quality/fabtotum/fabtotum_tpu_normal.inst.cfg
@@ -0,0 +1,25 @@
+[general]
+version = 3
+definition = fabtotum
+name = Normal Quality
+
+[metadata]
+type = quality
+setting_version = 4
+material = fabtotum_TPU
+quality_type = normal
+weight = 0
+
+[values]
+adhesion_type = skirt
+speed_print = 80
+layer_height = 0.15
+layer_height_0 = 0.15
+cool_fan_enabled = True
+cool_fan_full_at_height = 0.3
+cool_fan_speed = 100
+cool_fan_speed_max = 100
+cool_fan_speed_min = 100
+cool_min_layer_time = 5
+cool_min_speed = 20
+
diff --git a/resources/quality/low.inst.cfg b/resources/quality/fast.inst.cfg
similarity index 90%
rename from resources/quality/low.inst.cfg
rename to resources/quality/fast.inst.cfg
index e92490722d..56bc6be48d 100644
--- a/resources/quality/low.inst.cfg
+++ b/resources/quality/fast.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Low Quality
definition = fdmprinter
[metadata]
-type = quality
-quality_type = low
-global_quality = True
-weight = -1
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+global_quality = True
[values]
infill_sparse_density = 10
diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg
index 74d3d1c134..ae31f92447 100644
--- a/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg
+++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_normal.inst.cfg
@@ -1,14 +1,13 @@
[general]
-version = 2
+version = 3
name = gMax 1.5+ Dual Normal Layers
definition = gmax15plus_dual
[metadata]
+setting_version = 4
type = quality
quality_type = normal
weight = -1
-setting_version = 4
-global_quality = True
[values]
layer_height = 0.2
diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg
index 32191f36d8..4e262d8ecf 100644
--- a/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg
+++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_thick.inst.cfg
@@ -1,14 +1,13 @@
[general]
-version = 2
+version = 3
name = gMax 1.5+ Dual Thick Layers
definition = gmax15plus_dual
[metadata]
+setting_version = 4
type = quality
quality_type = course
weight = -2
-setting_version = 4
-global_quality = True
[values]
layer_height = 0.28
diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg
index 5906875a3a..a1b43d5d08 100644
--- a/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg
+++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_thin.inst.cfg
@@ -1,14 +1,13 @@
[general]
-version = 2
+version = 3
name = gMax 1.5+ Dual Thin Layers
definition = gmax15plus_dual
[metadata]
+setting_version = 4
type = quality
quality_type = high
weight = 0
-setting_version = 4
-global_quality = True
[values]
layer_height = 0.16
diff --git a/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg
index a94a621a88..1d5c7eca91 100644
--- a/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg
+++ b/resources/quality/gmax15plus/gmax15plus_pla_dual_very_thick.inst.cfg
@@ -1,14 +1,13 @@
[general]
-version = 2
+version = 3
name = gMax 1.5+ Dual Very Thick Layers
definition = gmax15plus_dual
[metadata]
+setting_version = 4
type = quality
quality_type = extra_course
weight = -3
-setting_version = 4
-global_quality = True
[values]
layer_height = 0.32
diff --git a/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg
index a6513cba80..1d01b82d3c 100644
--- a/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg
+++ b/resources/quality/gmax15plus/gmax15plus_pla_normal.inst.cfg
@@ -1,14 +1,13 @@
[general]
-version = 2
+version = 3
name = gMax 1.5+ Normal Layers
definition = gmax15plus
[metadata]
+setting_version = 4
type = quality
quality_type = normal
weight = -1
-setting_version = 4
-global_quality = True
[values]
layer_height = 0.2
@@ -58,5 +57,3 @@ top_thickness = 1
bottom_layers = 2
wall_line_count = 2
z_seam_corner = z_seam_corner_none
-
-
diff --git a/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg
index be0d99a413..dd6b3e702b 100644
--- a/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg
+++ b/resources/quality/gmax15plus/gmax15plus_pla_thick.inst.cfg
@@ -1,14 +1,13 @@
[general]
-version = 2
+version = 3
name = gMax 1.5+ Thick Layers
definition = gmax15plus
[metadata]
+setting_version = 4
type = quality
quality_type = course
weight = -2
-setting_version = 4
-global_quality = True
[values]
layer_height = 0.28
@@ -57,4 +56,4 @@ top_layers = 3
top_thickness = 1
bottom_layers = 2
wall_line_count = 2
-z_seam_corner = z_seam_corner_none
\ No newline at end of file
+z_seam_corner = z_seam_corner_none
diff --git a/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg
index 7069db6dd6..f90cb27647 100644
--- a/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg
+++ b/resources/quality/gmax15plus/gmax15plus_pla_thin.inst.cfg
@@ -1,14 +1,13 @@
[general]
-version = 2
+version = 3
name = gMax 1.5+ Thin Layers
definition = gmax15plus
[metadata]
+setting_version = 4
type = quality
quality_type = high
weight = 0
-setting_version = 4
-global_quality = True
[values]
layer_height = 0.16
@@ -57,4 +56,4 @@ top_layers = 5
top_thickness = 1
bottom_layers = 3
wall_line_count = 2
-z_seam_corner = z_seam_corner_none
\ No newline at end of file
+z_seam_corner = z_seam_corner_none
diff --git a/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg b/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg
index 88d03ee77f..171cf2f28d 100644
--- a/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg
+++ b/resources/quality/gmax15plus/gmax15plus_pla_very_thick.inst.cfg
@@ -1,14 +1,13 @@
[general]
-version = 2
+version = 3
name = gMax 1.5+ Very Thick Layers
definition = gmax15plus
[metadata]
+setting_version = 4
type = quality
quality_type = extra_course
weight = -3
-setting_version = 4
-global_quality = True
[values]
layer_height = 0.32
@@ -56,4 +55,4 @@ top_layers = 3
top_thickness = 1
bottom_layers = 2
wall_line_count = 2
-z_seam_corner = z_seam_corner_none
\ No newline at end of file
+z_seam_corner = z_seam_corner_none
diff --git a/resources/quality/high.inst.cfg b/resources/quality/high.inst.cfg
index d4333c90da..bb9e77ad38 100644
--- a/resources/quality/high.inst.cfg
+++ b/resources/quality/high.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = fdmprinter
[metadata]
+setting_version = 4
type = quality
quality_type = high
-global_quality = True
weight = 1
-setting_version = 4
+global_quality = True
[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 e36286c6ae..020e9d9b0f 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = imade3d_jellybox
[metadata]
-type = quality
-material = generic_petg_imade3d_jellybox_0.4_mm
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_petg
+variant = 0.4 mm
[values]
adhesion_type = skirt
@@ -26,8 +27,6 @@ infill_line_width = 0.6
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 20
-layer_height = 0.3
-layer_height_0 = 0.3
line_width = 0.4
material_bed_temperature = 50
material_bed_temperature_layer_0 = 55
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 3240bad98b..3aba34126e 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = imade3d_jellybox
[metadata]
-type = quality
-material = generic_petg_imade3d_jellybox_0.4_mm_2-fans
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_petg
+variant = 0.4 mm 2-fans
[values]
adhesion_type = skirt
@@ -26,8 +27,6 @@ infill_line_width = 0.6
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 20
-layer_height = 0.3
-layer_height_0 = 0.3
line_width = 0.4
material_bed_temperature = 50
material_bed_temperature_layer_0 = 55
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 2790a5a742..b235662e9f 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Medium
definition = imade3d_jellybox
[metadata]
-type = quality
-material = generic_petg_imade3d_jellybox_0.4_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_petg
+variant = 0.4 mm
[values]
adhesion_type = skirt
@@ -26,8 +27,6 @@ infill_line_width = 0.6
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 20
-layer_height = 0.2
-layer_height_0 = 0.3
line_width = 0.4
material_bed_temperature = 50
material_bed_temperature_layer_0 = 55
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 14f141f0bf..d5a9b09ed7 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Medium
definition = imade3d_jellybox
[metadata]
-type = quality
-material = generic_petg_imade3d_jellybox_0.4_mm_2-fans
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_petg
+variant = 0.4 mm 2-fans
[values]
adhesion_type = skirt
@@ -26,8 +27,6 @@ infill_line_width = 0.6
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 20
-layer_height = 0.2
-layer_height_0 = 0.3
line_width = 0.4
material_bed_temperature = 50
material_bed_temperature_layer_0 = 55
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 842ec618e0..797f77fa72 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = imade3d_jellybox
[metadata]
-type = quality
-material = generic_pla_imade3d_jellybox_0.4_mm
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_pla
+variant = 0.4 mm
[values]
adhesion_type = skirt
@@ -26,8 +27,6 @@ infill_line_width = 0.6
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 20
-layer_height = 0.3
-layer_height_0 = 0.3
line_width = 0.4
material_flow = 90
meshfix_union_all = False
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 17e085d84d..61bb573a25 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Coarse
definition = imade3d_jellybox
[metadata]
-type = quality
-material = generic_pla_imade3d_jellybox_0.4_mm_2-fans
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_pla
+variant = 0.4 mm 2-fans
[values]
adhesion_type = skirt
@@ -26,8 +27,6 @@ infill_line_width = 0.6
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 20
-layer_height = 0.3
-layer_height_0 = 0.3
line_width = 0.4
material_flow = 90
meshfix_union_all = False
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 a4b44f47f6..3c37910112 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = imade3d_jellybox
[metadata]
-type = quality
-material = generic_pla_imade3d_jellybox_0.4_mm
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+material = generic_pla
+variant = 0.4 mm
[values]
adhesion_type = skirt
@@ -26,8 +27,6 @@ infill_line_width = 0.6
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 20
-layer_height = 0.1
-layer_height_0 = 0.3
line_width = 0.4
material_flow = 90
material_print_temperature = 205
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 962b3c9ad4..eb31b07794 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = imade3d_jellybox
[metadata]
-type = quality
-material = generic_pla_imade3d_jellybox_0.4_mm_2-fans
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+material = generic_pla
+variant = 0.4 mm 2-fans
[values]
adhesion_type = skirt
@@ -26,8 +27,6 @@ infill_line_width = 0.6
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 20
-layer_height = 0.1
-layer_height_0 = 0.3
line_width = 0.4
material_flow = 90
material_print_temperature = 205
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 952b16ecf8..b8bbd674e0 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Medium
definition = imade3d_jellybox
[metadata]
-type = quality
-material = generic_pla_imade3d_jellybox_0.4_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_pla
+variant = 0.4 mm
[values]
adhesion_type = skirt
@@ -26,8 +27,6 @@ infill_line_width = 0.6
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 20
-layer_height = 0.2
-layer_height_0 = 0.3
line_width = 0.4
material_flow = 90
meshfix_union_all = False
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 bd70d105a4..56ae48379f 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Medium
definition = imade3d_jellybox
[metadata]
-type = quality
-material = generic_pla_imade3d_jellybox_0.4_mm_2-fans
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_pla
+variant = 0.4 mm 2-fans
[values]
adhesion_type = skirt
@@ -26,8 +27,6 @@ infill_line_width = 0.6
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 20
-layer_height = 0.2
-layer_height_0 = 0.3
line_width = 0.4
material_flow = 90
meshfix_union_all = False
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 a9d0679612..16fb70252b 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = UltraFine
definition = imade3d_jellybox
[metadata]
-type = quality
-material = generic_pla_imade3d_jellybox_0.4_mm
-weight = 2
-quality_type = ultrahigh
setting_version = 4
+type = quality
+quality_type = ultrahigh
+weight = 2
+material = generic_pla
+variant = 0.4 mm
[values]
adhesion_type = skirt
@@ -26,8 +27,6 @@ infill_line_width = 0.6
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 20
-layer_height = 0.05
-layer_height_0 = 0.3
line_width = 0.4
material_flow = 90
material_print_temperature = 202
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 097e1fc76a..2cab1fad46 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = UltraFine
definition = imade3d_jellybox
[metadata]
-type = quality
-material = generic_pla_imade3d_jellybox_0.4_mm_2-fans
-weight = 2
-quality_type = ultrahigh
setting_version = 4
+type = quality
+quality_type = ultrahigh
+weight = 2
+material = generic_pla
+variant = 0.4 mm 2-fans
[values]
adhesion_type = skirt
@@ -26,8 +27,6 @@ infill_line_width = 0.6
infill_overlap = 15
infill_pattern = zigzag
infill_sparse_density = 20
-layer_height = 0.05
-layer_height_0 = 0.3
line_width = 0.4
material_flow = 90
material_print_temperature = 202
diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg
new file mode 100644
index 0000000000..7a778a788f
--- /dev/null
+++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_coarse.inst.cfg
@@ -0,0 +1,16 @@
+[general]
+version = 3
+name = Coarse
+definition = imade3d_jellybox
+
+[metadata]
+setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+global_quality = True
+
+[values]
+adhesion_type = skirt
+layer_height = 0.3
+layer_height_0 = 0.3
diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg
new file mode 100644
index 0000000000..51767e0c93
--- /dev/null
+++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_fine.inst.cfg
@@ -0,0 +1,16 @@
+[general]
+version = 3
+name = Fine
+definition = imade3d_jellybox
+
+[metadata]
+setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+global_quality = True
+
+[values]
+adhesion_type = skirt
+layer_height = 0.1
+layer_height_0 = 0.3
diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg
new file mode 100644
index 0000000000..407ae608a4
--- /dev/null
+++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_normal.inst.cfg
@@ -0,0 +1,16 @@
+[general]
+version = 3
+name = Medium
+definition = imade3d_jellybox
+
+[metadata]
+setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+global_quality = True
+
+[values]
+adhesion_type = skirt
+layer_height = 0.2
+layer_height_0 = 0.3
diff --git a/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg b/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg
new file mode 100644
index 0000000000..f531d84234
--- /dev/null
+++ b/resources/quality/imade3d_jellybox/imade3d_jellybox_ultrafine.inst.cfg
@@ -0,0 +1,16 @@
+[general]
+version = 3
+name = UltraFine
+definition = imade3d_jellybox
+
+[metadata]
+setting_version = 4
+type = quality
+quality_type = ultrahigh
+weight = 2
+global_quality = True
+
+[values]
+adhesion_type = skirt
+layer_height = 0.05
+layer_height_0 = 0.3
diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg
index 5401ec7bd6..69c2b328cf 100644
--- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg
+++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_draft.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Draft
definition = kemiq_q2_beta
[metadata]
+setting_version = 4
type = quality
+quality_type = coarse
weight = -3
material = generic_abs
-quality_type = coarse
-setting_version = 4
[values]
layer_height = 0.35
diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg
index aea8fc9535..0bb72ce073 100644
--- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg
+++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_extra_fine.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = kemiq_q2_beta
[metadata]
+setting_version = 4
type = quality
+quality_type = high
weight = 1
material = generic_abs
-quality_type = high
-setting_version = 4
[values]
layer_height = 0.06
diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg
index 24adbd9f6c..1fd5874b70 100644
--- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg
+++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_fine.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fine
definition = kemiq_q2_beta
[metadata]
+setting_version = 4
type = quality
+quality_type = normal
weight = 0
material = generic_abs
-quality_type = normal
-setting_version = 4
[values]
layer_height = 0.1
diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg
index 98d2475633..78f80c576d 100644
--- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg
+++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_low.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Low
definition = kemiq_q2_beta
[metadata]
+setting_version = 4
type = quality
+quality_type = draft
weight = -2
material = generic_abs
-quality_type = draft
-setting_version = 4
[values]
layer_height = 0.2
diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg
index ab2e9dabbc..626de7bde6 100644
--- a/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg
+++ b/resources/quality/kemiq_q2/kemiq_q2_beta_abs_normal.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = kemiq_q2_beta
[metadata]
+setting_version = 4
type = quality
+quality_type = fast
weight = -1
material = generic_abs
-quality_type = low
-setting_version = 4
[values]
layer_height = 0.15
diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg
index f868ab40fc..63a49e6bc1 100644
--- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg
+++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_draft.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Draft
definition = kemiq_q2_beta
[metadata]
+setting_version = 4
type = quality
+quality_type = coarse
weight = -3
material = generic_pla
-quality_type = coarse
-setting_version = 4
[values]
layer_height = 0.35
diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg
index e907f7ccaf..2d49b01b92 100644
--- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg
+++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_extra_fine.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = kemiq_q2_beta
[metadata]
-type = quality
-material = generic_pla
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+material = generic_pla
[values]
layer_height = 0.06
diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg
index 841023d532..e79a3188d7 100644
--- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg
+++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_fine.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fine
definition = kemiq_q2_beta
[metadata]
+setting_version = 4
type = quality
+quality_type = normal
weight = 0
material = generic_pla
-quality_type = normal
-setting_version = 4
[values]
layer_height = 0.1
diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg
index ca874c6bce..db391b95ca 100644
--- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg
+++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_low.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Low
definition = kemiq_q2_beta
[metadata]
+setting_version = 4
type = quality
+quality_type = draft
weight = -2
material = generic_pla
-quality_type = draft
-setting_version = 4
[values]
layer_height = 0.2
diff --git a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg
index fcfbe72b24..336b1f47b9 100644
--- a/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg
+++ b/resources/quality/kemiq_q2/kemiq_q2_beta_pla_normal.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = kemiq_q2_beta
[metadata]
+setting_version = 4
type = quality
+quality_type = fast
weight = -1
material = generic_pla
-quality_type = low
-setting_version = 4
[values]
layer_height = 0.15
diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg
index 009af9b87b..6044fa25a4 100644
--- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg
+++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_draft.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Draft
definition = kemiq_q2_gama
[metadata]
+setting_version = 4
type = quality
+quality_type = coarse
weight = -3
material = generic_pla
-quality_type = coarse
-setting_version = 4
[values]
layer_height = 0.35
diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg
index 447e3b012d..9962c554ca 100644
--- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg
+++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_extra_fine.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = kemiq_q2_gama
[metadata]
-type = quality
-material = generic_pla
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+material = generic_pla
[values]
layer_height = 0.06
diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg
index 80b2375108..4b5b3b62ed 100644
--- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg
+++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_fine.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fine
definition = kemiq_q2_gama
[metadata]
+setting_version = 4
type = quality
+quality_type = normal
weight = 0
material = generic_pla
-quality_type = normal
-setting_version = 4
[values]
layer_height = 0.1
diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg
index e30c52f4e6..a187507632 100644
--- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg
+++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_low.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Low
definition = kemiq_q2_gama
[metadata]
+setting_version = 4
type = quality
+quality_type = draft
weight = -2
material = generic_pla
-quality_type = draft
-setting_version = 4
[values]
layer_height = 0.2
diff --git a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg
index 31bdaa51bc..281f73393a 100644
--- a/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg
+++ b/resources/quality/kemiq_q2/kemiq_q2_gama_pla_normal.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = kemiq_q2_gama
[metadata]
+setting_version = 4
type = quality
+quality_type = fast
weight = -1
material = generic_pla
-quality_type = low
-setting_version = 4
[values]
layer_height = 0.15
diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg
index 19cc9fd00d..104b747aea 100644
--- a/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg
+++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_draft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_abs_175
weight = -2
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg
index 5677a0d58d..3f2eec9867 100644
--- a/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg
+++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_fast.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_abs_175
weight = -1
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg
index 7798b3f545..55a6c0d4ba 100644
--- a/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg
+++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_high.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Finer
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_abs_175
weight = 1
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg
index c87c66c813..98587bdf7d 100644
--- a/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg
+++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_normal.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_abs_175
weight = 0
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg
index e6e3cfcd6c..49fcd1e935 100644
--- a/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg
+++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_superdraft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Lowest Quality Draft
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_abs_175
weight = -5
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg
index fb08013809..f9a9fe3d98 100644
--- a/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg
+++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_thickerdraft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Draft
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = thickerdraft
-material = generic_abs_175
weight = -3
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg
index 385d852688..dcc2813031 100644
--- a/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg
+++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_ultra.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Ultra Fine
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = ultra
-material = generic_abs_175
weight = 2
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg
index 7026391fb6..251d024a85 100644
--- a/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg
+++ b/resources/quality/malyan_m200/abs/malyan_m200_abs_verydraft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Low Detail Draft
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-material = generic_abs_175
weight = -4
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/malyan_m200/malyan_m200_0.04375.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.04375.inst.cfg
index 54be6ecbcc..c9dd72f5f5 100644
--- a/resources/quality/malyan_m200/malyan_m200_0.04375.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_0.04375.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = M1 Quality
definition = malyan_m200
[metadata]
-type = quality
-weight = 2
-quality_type = fine
setting_version = 4
+type = quality
+quality_type = fine
+weight = 2
[values]
layer_height = 0.04375
diff --git a/resources/quality/malyan_m200/malyan_m200_0.0875.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.0875.inst.cfg
index 568dd796f3..65d7d0d0b8 100644
--- a/resources/quality/malyan_m200/malyan_m200_0.0875.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_0.0875.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = M2 Quality
definition = malyan_m200
[metadata]
-type = quality
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
[values]
layer_height = 0.0875
diff --git a/resources/quality/malyan_m200/malyan_m200_0.13125.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.13125.inst.cfg
index 1dc436502b..89aea54fdc 100644
--- a/resources/quality/malyan_m200/malyan_m200_0.13125.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_0.13125.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = M3 Quality
definition = malyan_m200
[metadata]
-type = quality
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
[values]
layer_height = 0.13125
diff --git a/resources/quality/malyan_m200/malyan_m200_0.175.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.175.inst.cfg
index 314a8acd83..613988a437 100644
--- a/resources/quality/malyan_m200/malyan_m200_0.175.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_0.175.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = M4 Quality
definition = malyan_m200
[metadata]
-type = quality
-weight = -1
-quality_type = fast
-global_quality = true
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+global_quality = true
[values]
layer_height = 0.175
diff --git a/resources/quality/malyan_m200/malyan_m200_0.21875.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.21875.inst.cfg
index a7fedb7e04..75d7601af3 100644
--- a/resources/quality/malyan_m200/malyan_m200_0.21875.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_0.21875.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = M5 Quality
definition = malyan_m200
[metadata]
-type = quality
-weight = -2
-quality_type = faster
setting_version = 4
+type = quality
+quality_type = faster
+weight = -2
[values]
layer_height = 0.21875
diff --git a/resources/quality/malyan_m200/malyan_m200_0.2625.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.2625.inst.cfg
index 441abc3070..470af78595 100644
--- a/resources/quality/malyan_m200/malyan_m200_0.2625.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_0.2625.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = M6 Quality
definition = malyan_m200
[metadata]
-type = quality
-weight = -3
-quality_type = draft
setting_version = 4
+type = quality
+quality_type = draft
+weight = -3
[values]
layer_height = 0.2625
diff --git a/resources/quality/malyan_m200/malyan_m200_0.30625.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.30625.inst.cfg
index 2588838174..32fa8c5641 100644
--- a/resources/quality/malyan_m200/malyan_m200_0.30625.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_0.30625.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = M7 Quality
definition = malyan_m200
[metadata]
-type = quality
-weight = -4
-quality_type = turbo
setting_version = 4
+type = quality
+quality_type = turbo
+weight = -4
[values]
layer_height = 0.30625
diff --git a/resources/quality/malyan_m200/malyan_m200_0.35.inst.cfg b/resources/quality/malyan_m200/malyan_m200_0.35.inst.cfg
index 800b6104d9..1e168e7690 100644
--- a/resources/quality/malyan_m200/malyan_m200_0.35.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_0.35.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = M8 Quality
definition = malyan_m200
[metadata]
-type = quality
-weight = -5
-quality_type = hyper
-global_quality = true
setting_version = 4
+type = quality
+quality_type = hyper
+weight = -5
+global_quality = true
[values]
layer_height = 0.35
diff --git a/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg
index d3104caa87..12796a140f 100644
--- a/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_global_Draft_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fast
definition = malyan_m200
[metadata]
-type = quality
-weight = -2
-quality_type = draft
-global_quality = True
setting_version = 4
+type = quality
+quality_type = draft
+weight = -2
+global_quality = True
[values]
layer_height = 0.21875
diff --git a/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg
index aec535bd71..78f014bd9e 100644
--- a/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_global_Fast_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = malyan_m200
[metadata]
-type = quality
-weight = -1
-quality_type = fast
-global_quality = True
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+global_quality = True
[values]
layer_height = 0.175
diff --git a/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg
index ca202862a2..bf2f25b418 100644
--- a/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_global_High_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Finer
definition = malyan_m200
[metadata]
-type = quality
-weight = 1
-quality_type = high
-global_quality = True
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+global_quality = True
[values]
layer_height = 0.0875
diff --git a/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg
index 7076718903..cd9609cc2d 100644
--- a/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_global_Normal_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fine
definition = malyan_m200
[metadata]
-type = quality
-weight = 0
-quality_type = normal
-global_quality = True
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+global_quality = True
[values]
layer_height = 0.13125
diff --git a/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg
index 7dfbdb5886..880eb5068d 100644
--- a/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_global_SuperDraft_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Lowest Quality Draft
definition = malyan_m200
[metadata]
-type = quality
-weight = -5
-quality_type = superdraft
-global_quality = True
setting_version = 4
+type = quality
+quality_type = superdraft
+weight = -5
+global_quality = True
[values]
layer_height = 0.35
diff --git a/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg
index 2fbf82b128..9ebc812738 100644
--- a/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_global_ThickerDraft_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Draft
definition = malyan_m200
[metadata]
-type = quality
-weight = -3
-quality_type = thickerdraft
-global_quality = True
setting_version = 4
+type = quality
+quality_type = thickerdraft
+weight = -3
+global_quality = True
[values]
layer_height = 0.2625
diff --git a/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg
index 90e589cca5..f1841970af 100644
--- a/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_global_Ultra_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Ultra Fine
definition = malyan_m200
[metadata]
-type = quality
-weight = 2
-quality_type = ultra
-global_quality = True
setting_version = 4
+type = quality
+quality_type = ultra
+weight = 2
+global_quality = True
[values]
layer_height = 0.04375
diff --git a/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg b/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg
index 1210ee214b..7da342c437 100644
--- a/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg
+++ b/resources/quality/malyan_m200/malyan_m200_global_VeryDraft_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Low Detail Draft
definition = malyan_m200
[metadata]
-type = quality
-weight = -4
-quality_type = verydraft
-global_quality = True
setting_version = 4
+type = quality
+quality_type = verydraft
+weight = -4
+global_quality = True
[values]
layer_height = 0.30625
diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg
index aef83471ba..0434decedc 100644
--- a/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg
+++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_draft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Fast
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_petg_175
weight = -2
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg
index 3c7fc2c239..2049403af4 100644
--- a/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg
+++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_fast.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Normal
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_petg_175
weight = -1
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg
index eb1654eae3..00882f2418 100644
--- a/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg
+++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_high.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Finer
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_petg_175
weight = 1
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg
index 53e60d2d62..58ad4a1085 100644
--- a/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg
+++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_normal.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Fine
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_petg_175
weight = 0
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg
index d2a96386ae..09a72e261a 100644
--- a/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg
+++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_superdraft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Lowest Quality Draft
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_petg_175
weight = -5
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg
index e2f37ae43b..e57b1d24f2 100644
--- a/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg
+++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_thickerdraft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Draft
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = thickerdraft
-material = generic_petg_175
weight = -3
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg
index 0fa89f2569..0c3de72835 100644
--- a/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg
+++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_ultra.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Ultra Fine
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = ultra
-material = generic_petg_175
weight = 2
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg
index 84bedf5c14..0139e972f6 100644
--- a/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg
+++ b/resources/quality/malyan_m200/petg/malyan_m200_petg_verydraft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Low Detail Draft
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-material = generic_petg_175
weight = -4
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg
index 4f221eceb7..c30df8a9b3 100644
--- a/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg
+++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_draft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_pla_175
weight = -2
-setting_version = 4
+material = generic_pla
[values]
material_bed_temperature = 60
-material_bed_temperature_layer_0 = 60
\ No newline at end of file
+material_bed_temperature_layer_0 = 60
diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg
index 3097fe055a..8e1b0478ad 100644
--- a/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg
+++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_fast.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_pla_175
weight = -1
-setting_version = 4
+material = generic_pla
[values]
material_bed_temperature = 60
-material_bed_temperature_layer_0 = 60
\ No newline at end of file
+material_bed_temperature_layer_0 = 60
diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg
index 062c120ad0..44713b2386 100644
--- a/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg
+++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_high.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Finer
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pla_175
weight = 1
-setting_version = 4
+material = generic_pla
[values]
material_bed_temperature = 60
-material_bed_temperature_layer_0 = 60
\ No newline at end of file
+material_bed_temperature_layer_0 = 60
diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg
index e01141ed9e..cd6497d9bf 100644
--- a/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg
+++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_normal.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pla_175
weight = 0
-setting_version = 4
+material = generic_pla
[values]
material_bed_temperature = 60
-material_bed_temperature_layer_0 = 60
\ No newline at end of file
+material_bed_temperature_layer_0 = 60
diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg
index 53eb4380eb..447de8a48b 100644
--- a/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg
+++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_superdraft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Lowest Quality Draft
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_pla_175
weight = -5
-setting_version = 4
+material = generic_pla
[values]
material_bed_temperature = 60
-material_bed_temperature_layer_0 = 60
\ No newline at end of file
+material_bed_temperature_layer_0 = 60
diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg
index 32d2b419bc..f2c5e3c9cc 100644
--- a/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg
+++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_thickerdraft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Draft
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = thickerdraft
-material = generic_pla_175
weight = -3
-setting_version = 4
+material = generic_pla
[values]
material_bed_temperature = 60
-material_bed_temperature_layer_0 = 60
\ No newline at end of file
+material_bed_temperature_layer_0 = 60
diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg
index 3865059254..63f19bef41 100644
--- a/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg
+++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_ultra.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Ultra Fine
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = ultra
-material = generic_pla_175
weight = 2
-setting_version = 4
+material = generic_pla
[values]
material_bed_temperature = 60
-material_bed_temperature_layer_0 = 60
\ No newline at end of file
+material_bed_temperature_layer_0 = 60
diff --git a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg
index a624c056be..6a96b3d678 100644
--- a/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg
+++ b/resources/quality/malyan_m200/pla/malyan_m200_pla_verydraft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Low Detail Draft
definition = malyan_m200
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-material = generic_pla_175
weight = -4
-setting_version = 4
+material = generic_pla
[values]
material_bed_temperature = 60
-material_bed_temperature_layer_0 = 60
\ No newline at end of file
+material_bed_temperature_layer_0 = 60
diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg
index a63256573a..6fec85b563 100644
--- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_draft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_abs_175
weight = -2
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg
index 49f4486596..0d79f2cc72 100644
--- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_fast.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_abs_175
weight = -1
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg
index eab16a8e2b..f02e3b5838 100644
--- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_high.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Finer
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_abs_175
weight = 1
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg
index 03aeb4067b..a046cfa561 100644
--- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_normal.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_abs_175
weight = 0
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg
index 148f53ba73..f5861ce734 100644
--- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_superdraft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Lowest Quality Draft
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_abs_175
weight = -5
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg
index e2ad71a360..b63fd3cfad 100644
--- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_thickerdraft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Draft
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = thickerdraft
-material = generic_abs_175
weight = -3
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg
index 7ebdf80baf..6aed450961 100644
--- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_ultra.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Ultra Fine
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = thickerdraft
-material = generic_abs_175
weight = 2
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg
index 9965ae8bcf..1c462fd435 100644
--- a/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/abs/monoprice_select_mini_v2_abs_verydraft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Low Detail Draft
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-material = generic_abs_175
weight = -4
-setting_version = 4
+material = generic_abs
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg
index b7d0faa2c7..c70ccc9946 100644
--- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Draft_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fast
definition = monoprice_select_mini_v2
[metadata]
-type = quality
-weight = -2
-quality_type = draft
-global_quality = True
setting_version = 4
+type = quality
+quality_type = draft
+weight = -2
+global_quality = True
[values]
layer_height = 0.21875
diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg
index f7f338e4c9..1bc10e2186 100644
--- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Fast_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = monoprice_select_mini_v2
[metadata]
-type = quality
-weight = -1
-quality_type = fast
-global_quality = True
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+global_quality = True
[values]
layer_height = 0.175
diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg
index 4a37a1afd8..24d5d5819f 100644
--- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_High_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Finer
definition = monoprice_select_mini_v2
[metadata]
-type = quality
-weight = 1
-quality_type = high
-global_quality = True
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+global_quality = True
[values]
layer_height = 0.0875
diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg
index b8e545adcf..0a884c80ca 100644
--- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Normal_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fine
definition = monoprice_select_mini_v2
[metadata]
-type = quality
-weight = 0
-quality_type = normal
-global_quality = True
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+global_quality = True
[values]
layer_height = 0.13125
diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg
index 0ef9db5875..9a0928186c 100644
--- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_SuperDraft_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Lowest Quality Draft
definition = monoprice_select_mini_v2
[metadata]
-type = quality
-weight = -5
-quality_type = superdraft
-global_quality = True
setting_version = 4
+type = quality
+quality_type = superdraft
+weight = -5
+global_quality = True
[values]
layer_height = 0.35
diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg
index 4dd3a7aafe..994ec14a3e 100644
--- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_ThickerDraft_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Draft
definition = monoprice_select_mini_v2
[metadata]
-type = quality
-weight = -3
-quality_type = thickerdraft
-global_quality = True
setting_version = 4
+type = quality
+quality_type = thickerdraft
+weight = -3
+global_quality = True
[values]
layer_height = 0.2625
diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg
index 337f0d06bc..813d156588 100644
--- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_Ultra_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Ultra Fine
definition = monoprice_select_mini_v2
[metadata]
-type = quality
-weight = 2
-quality_type = ultra
-global_quality = True
setting_version = 4
+type = quality
+quality_type = ultra
+weight = 2
+global_quality = True
[values]
layer_height = 0.04375
diff --git a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg
index e884077069..0a461945f5 100644
--- a/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/monoprice_select_mini_v2_global_VeryDraft_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Low Detail Draft
definition = monoprice_select_mini_v2
[metadata]
-type = quality
-weight = -4
-quality_type = verydraft
-global_quality = True
setting_version = 4
+type = quality
+quality_type = verydraft
+weight = -4
+global_quality = True
[values]
layer_height = 0.30625
diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg
index 4a03c17a63..d5ccd3070b 100644
--- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_draft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Fast
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_nylon_175
weight = -2
-setting_version = 4
\ No newline at end of file
+material = generic_nylon
diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg
index 1c04f77b8b..aca8884024 100644
--- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_fast.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Normal
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_nylon_175
weight = -1
-setting_version = 4
\ No newline at end of file
+material = generic_nylon
diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg
index d57516598a..080a06d84f 100644
--- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_high.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Finer
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_nylon_175
weight = 1
-setting_version = 4
\ No newline at end of file
+material = generic_nylon
diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg
index 308ea86311..7f3222d229 100644
--- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_normal.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Fine
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_nylon_175
weight = 0
-setting_version = 4
\ No newline at end of file
+material = generic_nylon
diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg
index db4f3ca907..88777be100 100644
--- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_superdraft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Lowest Quality Draft
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_nylon_175
weight = -5
-setting_version = 4
\ No newline at end of file
+material = generic_nylon
diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg
index 9a1afc0e48..8880d6defa 100644
--- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_thickerdraft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Draft
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = thickerdraft
-material = generic_nylon_175
weight = -3
-setting_version = 4
\ No newline at end of file
+material = generic_nylon
diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg
index 3453671a72..945964cfac 100644
--- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_ultra.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Ultra Fine
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = ultra
-material = generic_nylon_175
weight = 2
-setting_version = 4
\ No newline at end of file
+material = generic_nylon
diff --git a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg
index ee2531fc4e..fbebffde3a 100644
--- a/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/nylon/monoprice_select_mini_v2_nylon_verydraft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Low Detail Draft
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-material = generic_nylon_175
weight = -4
-setting_version = 4
\ No newline at end of file
+material = generic_nylon
diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg
index aa5fc7844d..be4f438df5 100644
--- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_draft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_pc_175
weight = -2
-setting_version = 4
+material = generic_pc
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg
index 232c4ab6f3..c81f19a03e 100644
--- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_fast.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_pc_175
weight = -1
-setting_version = 4
+material = generic_pc
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg
index aa9da322fb..714cd66c1f 100644
--- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_high.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Finer
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pc_175
weight = 1
-setting_version = 4
+material = generic_pc
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg
index 145b21221b..a314288364 100644
--- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_normal.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pc_175
weight = 0
-setting_version = 4
+material = generic_pc
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg
index b6e53bda62..4889d3fc7d 100644
--- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_superdraft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Lowest Quality Draft
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_pc_175
weight = -5
-setting_version = 4
+material = generic_pc
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg
index 055228ab13..12a5c2ac6f 100644
--- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_thickerdraft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Draft
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = thickerdraft
-material = generic_pc_175
weight = -3
-setting_version = 4
+material = generic_pc
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg
index a3e99b998e..3b70904476 100644
--- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_ultra.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Ultra Fine
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = ultra
-material = generic_pc_175
weight = 2
-setting_version = 4
+material = generic_pc
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg
index 73f5a2f2c9..2ea13105ef 100644
--- a/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pc/monoprice_select_mini_v2_pc_verydraft.inst.cfg
@@ -1,15 +1,15 @@
[general]
-version = 2
+version = 3
name = Low Detail Draft
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-material = generic_pc_175
weight = -4
-setting_version = 4
+material = generic_pc
[values]
material_bed_temperature = 70
-material_bed_temperature_layer_0 = 70
\ No newline at end of file
+material_bed_temperature_layer_0 = 70
diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg
index 8a33e03310..da8f6a7c9a 100644
--- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_draft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Fast
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_petg_175
weight = -2
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg
index fb084fa08e..bc151b9635 100644
--- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_fast.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Normal
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_petg_175
weight = -1
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg
index 16891f6f43..bc1101603e 100644
--- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_high.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Finer
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_petg_175
weight = 1
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg
index bb2f0b47a8..932bfdf97a 100644
--- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_normal.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Fine
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_petg_175
weight = 0
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg
index 78ca1b6b7a..77fb261821 100644
--- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_superdraft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Lowest Quality Draft
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_petg_175
weight = -5
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg
index 69606ff913..096ff5c2f6 100644
--- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_thickerdraft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Draft
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = thickerdraft
-material = generic_petg_175
weight = -3
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg
index 7c5ac599c8..9a3cc19a0c 100644
--- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_ultra.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Ultra Fine
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = ultra
-material = generic_petg_175
weight = 2
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg
index ed0c2510f5..c9e0aae2c4 100644
--- a/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/petg/monoprice_select_mini_v2_petg_verydraft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Low Detail Draft
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-material = generic_petg_175
weight = -4
-setting_version = 4
\ No newline at end of file
+material = generic_petg
diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg
index 04a955cf6c..8f85c598bd 100644
--- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_draft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Fast
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_pla_175
weight = -2
-setting_version = 4
\ No newline at end of file
+material = generic_pla
diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg
index 6efc0935e2..09e741ad07 100644
--- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_fast.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Normal
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_pla_175
weight = 0
-setting_version = 4
\ No newline at end of file
+material = generic_pla
diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg
index 8fe2371e5d..cf00fb02b0 100644
--- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_high.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Finer
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pla_175
weight = 0
-setting_version = 4
\ No newline at end of file
+material = generic_pla
diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg
index 01351154c4..eaa85450d8 100644
--- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_normal.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Fine
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pla_175
weight = 0
-setting_version = 4
\ No newline at end of file
+material = generic_pla
diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg
index adfced9787..66f888cd6e 100644
--- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_superdraft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Lowest Quality Draft
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_pla_175
weight = -5
-setting_version = 4
\ No newline at end of file
+material = generic_pla
diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg
index f4522c9778..c4c2a0c2d1 100644
--- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_thickerdraft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Draft
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = thickerdraft
-material = generic_pla_175
weight = -3
-setting_version = 4
\ No newline at end of file
+material = generic_pla
diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg
index 2fa8eb7f81..b9b0fea26e 100644
--- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_ultra.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Ultra Fine
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
quality_type = ultra
-material = generic_pla_175
weight = 2
-setting_version = 4
\ No newline at end of file
+material = generic_pla
diff --git a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg
index e59cf4a490..bd6febd83c 100644
--- a/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg
+++ b/resources/quality/monoprice_select_mini_v2/pla/monoprice_select_mini_v2_pla_verydraft.inst.cfg
@@ -1,11 +1,11 @@
[general]
-version = 2
+version = 3
name = Low Detail Draft
definition = monoprice_select_mini_v2
[metadata]
+setting_version = 4
type = quality
-quality_type = verydraft
-material = generic_pla_175
+material = generic_pla
weight = 0
-setting_version = 4
\ No newline at end of file
+quality_type = verydraft
diff --git a/resources/quality/normal.inst.cfg b/resources/quality/normal.inst.cfg
index 9fb7b238cd..0f1a4d6905 100644
--- a/resources/quality/normal.inst.cfg
+++ b/resources/quality/normal.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = Fine
definition = fdmprinter
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-global_quality = True
weight = 0
-setting_version = 4
+global_quality = True
[values]
diff --git a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg
index ae8a377116..57c955f4b7 100644
--- a/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg
+++ b/resources/quality/peopoly_moai/peopoly_moai_high.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = peopoly_moai
[metadata]
-type = quality
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 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 07ab7e364b..4cce7e2d85 100644
--- a/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg
+++ b/resources/quality/peopoly_moai/peopoly_moai_max.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = Maximum Quality
definition = peopoly_moai
[metadata]
-type = quality
-weight = 2
-quality_type = extra_high
setting_version = 4
+type = quality
+quality_type = extra_high
+weight = 2
[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 e0d2f7d818..a1465a86c9 100644
--- a/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg
+++ b/resources/quality/peopoly_moai/peopoly_moai_normal.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = Fine
definition = peopoly_moai
[metadata]
-type = quality
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
[values]
infill_sparse_density = 70
diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg
index 082b7dded7..184205b1cd 100644
--- a/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg
+++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_draft.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = Draft
definition = tevo_blackwidow
[metadata]
+setting_version = 4
type = quality
quality_type = draft
weight = -2
-setting_version = 4
[values]
brim_width = 4.0
@@ -30,4 +30,4 @@ support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
-wall_thickness = 1.2
\ No newline at end of file
+wall_thickness = 1.2
diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg
index 79d020463f..d158af4123 100644
--- a/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg
+++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_high.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = High
definition = tevo_blackwidow
[metadata]
+setting_version = 4
type = quality
quality_type = high
weight = 1
-setting_version = 4
[values]
brim_width = 4.0
@@ -30,4 +30,4 @@ support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
-wall_thickness = 1.2
\ No newline at end of file
+wall_thickness = 1.2
diff --git a/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg b/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg
index 2982c44d3d..a44ff8bcdb 100644
--- a/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg
+++ b/resources/quality/tevo_blackwidow/tevo_blackwidow_normal.inst.cfg
@@ -1,13 +1,13 @@
[general]
-version = 2
+version = 3
name = Normal
definition = tevo_blackwidow
[metadata]
+setting_version = 4
type = quality
quality_type = normal
weight = 0
-setting_version = 4
[values]
brim_width = 4.0
@@ -30,4 +30,4 @@ support_type = everywhere
support_use_towers = False
support_xy_distance = 0.7
top_bottom_thickness = 1.2
-wall_thickness = 1.2
\ No newline at end of file
+wall_thickness = 1.2
diff --git a/resources/quality/ultimaker2/um2_draft.inst.cfg b/resources/quality/ultimaker2/um2_draft.inst.cfg
index 4fe3f51e20..dc761afc0b 100644
--- a/resources/quality/ultimaker2/um2_draft.inst.cfg
+++ b/resources/quality/ultimaker2/um2_draft.inst.cfg
@@ -1,13 +1,14 @@
[general]
-version = 2
+version = 3
name = Draft Quality
definition = ultimaker2
[metadata]
+setting_version = 4
type = quality
quality_type = draft
weight = -2
-setting_version = 4
+global_quality = True
[values]
layer_height = 0.2
diff --git a/resources/quality/ultimaker2/um2_low.inst.cfg b/resources/quality/ultimaker2/um2_fast.inst.cfg
similarity index 84%
rename from resources/quality/ultimaker2/um2_low.inst.cfg
rename to resources/quality/ultimaker2/um2_fast.inst.cfg
index 832962984c..04c24dc4c2 100644
--- a/resources/quality/ultimaker2/um2_low.inst.cfg
+++ b/resources/quality/ultimaker2/um2_fast.inst.cfg
@@ -1,13 +1,14 @@
[general]
-version = 2
+version = 3
name = Low Quality
definition = ultimaker2
[metadata]
-type = quality
-quality_type = low
-weight = -1
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+global_quality = True
[values]
infill_sparse_density = 10
diff --git a/resources/quality/ultimaker2/um2_high.inst.cfg b/resources/quality/ultimaker2/um2_high.inst.cfg
index 96941beed2..1c83ea350b 100644
--- a/resources/quality/ultimaker2/um2_high.inst.cfg
+++ b/resources/quality/ultimaker2/um2_high.inst.cfg
@@ -1,13 +1,14 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker2
[metadata]
+setting_version = 4
type = quality
quality_type = high
weight = 1
-setting_version = 4
+global_quality = True
[values]
layer_height = 0.06
diff --git a/resources/quality/ultimaker2/um2_normal.inst.cfg b/resources/quality/ultimaker2/um2_normal.inst.cfg
index ea804feb80..bddbe6e243 100644
--- a/resources/quality/ultimaker2/um2_normal.inst.cfg
+++ b/resources/quality/ultimaker2/um2_normal.inst.cfg
@@ -1,12 +1,13 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2
[metadata]
+setting_version = 4
type = quality
quality_type = normal
weight = 0
-setting_version = 4
+global_quality = True
[values]
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 638a1a9384..eecaa2fa0f 100644
--- a/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/pla_0.25_normal.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pla_ultimaker2_plus_0.25_mm
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+material = generic_pla
+variant = 0.25 mm
[values]
cool_min_layer_time = 5
@@ -19,4 +20,3 @@ speed_layer_0 = =round(speed_print * 30 / 30)
speed_print = 30
top_bottom_thickness = 0.72
wall_thickness = 0.88
-
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 9f4dfc0b5d..207d237fa3 100644
--- a/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg
+++ b/resources/quality/ultimaker2_plus/pla_0.4_fast.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pla_ultimaker2_plus_0.4_mm
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_pla
+variant = 0.4 mm
[values]
cool_min_layer_time = 5
@@ -22,4 +23,3 @@ speed_travel = 150
speed_wall = 50
top_bottom_thickness = 0.75
wall_thickness = 0.7
-
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 7bf51b0211..83ffa99d07 100644
--- a/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg
+++ b/resources/quality/ultimaker2_plus/pla_0.4_high.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pla_ultimaker2_plus_0.4_mm
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+material = generic_pla
+variant = 0.4 mm
[values]
cool_min_layer_time = 5
@@ -20,4 +21,3 @@ speed_print = 50
speed_topbottom = 20
top_bottom_thickness = 0.72
wall_thickness = 1.05
-
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 3c6f40e0bc..683eab7166 100644
--- a/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/pla_0.4_normal.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pla_ultimaker2_plus_0.4_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_pla
+variant = 0.4 mm
[values]
cool_min_layer_time = 5
@@ -20,4 +21,3 @@ speed_print = 50
speed_topbottom = 20
top_bottom_thickness = 0.8
wall_thickness = 1.05
-
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 ef79e30b74..80dea5f5fd 100644
--- a/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/pla_0.6_normal.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-material = generic_pla_ultimaker2_plus_0.6_mm
-type = quality
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_pla
+variant = 0.6 mm
[values]
cool_min_layer_time = 5
@@ -22,4 +23,3 @@ speed_wall = 40
speed_wall_0 = 25
top_bottom_thickness = 1.2
wall_thickness = 1.59
-
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 42418ea392..5c898c74ec 100644
--- a/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/pla_0.8_normal.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker2_plus
[metadata]
-material = generic_pla_ultimaker2_plus_0.8_mm
-type = quality
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_pla
+variant = 0.8 mm
[values]
cool_min_layer_time = 5
@@ -20,4 +21,3 @@ speed_print = 40
speed_wall_0 = 25
top_bottom_thickness = 1.2
wall_thickness = 2.1
-
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 50a4076de2..275a4595a0 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_abs_ultimaker2_plus_0.25_mm
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+material = generic_abs
+variant = 0.25 mm
[values]
cool_fan_speed_min = =cool_fan_speed * 0.2
@@ -21,4 +22,3 @@ speed_layer_0 = =round(speed_print * 30 / 30)
speed_print = 30
top_bottom_thickness = 0.72
wall_thickness = 0.88
-
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 9d1bcf6ff5..a95417c711 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_abs_ultimaker2_plus_0.4_mm
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_abs
+variant = 0.4 mm
[values]
cool_fan_speed_min = =cool_fan_speed * 0.2
@@ -24,4 +25,3 @@ speed_travel = 150
speed_wall = 40
top_bottom_thickness = 0.75
wall_thickness = 0.7
-
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 84a5557434..97d35fe6bf 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_abs_ultimaker2_plus_0.4_mm
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+material = generic_abs
+variant = 0.4 mm
[values]
cool_fan_speed_min = =cool_fan_speed * 0.2
@@ -22,4 +23,3 @@ speed_print = 45
speed_wall = 30
top_bottom_thickness = 0.72
wall_thickness = 1.05
-
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 efc749ad8c..162805f5c2 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_abs_ultimaker2_plus_0.4_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_abs
+variant = 0.4 mm
[values]
cool_fan_speed_min = =cool_fan_speed * 0.2
@@ -22,4 +23,3 @@ speed_print = 45
speed_wall = 30
top_bottom_thickness = 0.8
wall_thickness = 1.05
-
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 eb706c5762..5291356b4e 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_abs_ultimaker2_plus_0.6_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_abs
+variant = 0.6 mm
[values]
cool_fan_speed_min = =cool_fan_speed * 0.5
@@ -22,4 +23,3 @@ speed_layer_0 = =round(speed_print * 30 / 40)
speed_print = 40
top_bottom_thickness = 1.2
wall_thickness = 1.59
-
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 2dba5a9304..01c0b5467b 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_abs_ultimaker2_plus_0.8_mm
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_abs
+variant = 0.8 mm
[values]
cool_fan_speed_min = =cool_fan_speed * 0.5
@@ -21,4 +22,3 @@ speed_layer_0 = =round(speed_print * 30 / 40)
speed_print = 40
top_bottom_thickness = 1.2
wall_thickness = 2.1
-
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 8e87e0e7b6..1b656eb4f1 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_cpe_ultimaker2_plus_0.25_mm
-weight = -1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = -1
+material = generic_cpe
+variant = 0.25 mm
[values]
cool_fan_speed_min = =cool_fan_speed * 0.2
@@ -21,4 +22,3 @@ speed_layer_0 = =round(speed_print * 30 / 30)
speed_print = 30
top_bottom_thickness = 0.72
wall_thickness = 0.88
-
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 e311df00a8..8385800e15 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_cpe_ultimaker2_plus_0.4_mm
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_cpe
+variant = 0.4 mm
[values]
cool_fan_speed_min = =cool_fan_speed * 0.8
@@ -23,4 +24,3 @@ speed_travel = 150
speed_wall = 40
top_bottom_thickness = 0.75
wall_thickness = 0.7
-
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 685b7798fc..6d810ee231 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_cpe_ultimaker2_plus_0.4_mm
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+material = generic_cpe
+variant = 0.4 mm
[values]
cool_fan_speed_min = =cool_fan_speed * 0.8
@@ -22,4 +23,3 @@ speed_print = 45
speed_wall = 30
top_bottom_thickness = 0.72
wall_thickness = 1.05
-
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 aadb4195f3..1b6ab4edc5 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_cpe_ultimaker2_plus_0.4_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_cpe
+variant = 0.4 mm
[values]
cool_fan_speed_min = =cool_fan_speed * 0.8
@@ -22,4 +23,3 @@ speed_print = 45
speed_wall = 30
top_bottom_thickness = 0.8
wall_thickness = 1.05
-
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 332033368f..7f79c013b3 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_cpe_ultimaker2_plus_0.6_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_cpe
+variant = 0.6 mm
[values]
cool_fan_speed_min = =cool_fan_speed * 0.8
@@ -21,4 +22,3 @@ speed_layer_0 = =round(speed_print * 30 / 40)
speed_print = 40
top_bottom_thickness = 1.2
wall_thickness = 1.59
-
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 e4fcae8aa1..df92d3e2dd 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_cpe_ultimaker2_plus_0.8_mm
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_cpe
+variant = 0.8 mm
[values]
cool_fan_speed_min = =cool_fan_speed * 0.8
@@ -21,4 +22,3 @@ speed_layer_0 = =round(speed_print * 30 / 40)
speed_print = 40
top_bottom_thickness = 1.2
wall_thickness = 2.1
-
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 55af936a89..e83ae78d36 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_cpe_plus_ultimaker2_plus_0.4_mm
-weight = -2
-quality_type = draft
setting_version = 4
+type = quality
+quality_type = draft
+weight = -2
+material = generic_cpe_plus
+variant = 0.4 mm
[values]
adhesion_type = raft
@@ -40,4 +41,3 @@ support_pattern = lines
support_z_distance = 0.26
top_bottom_thickness = 1.5
wall_thickness = 1.14
-
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 eb0ca5e81f..ee0b659b91 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_cpe_plus_ultimaker2_plus_0.4_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_cpe_plus
+variant = 0.4 mm
[values]
adhesion_type = raft
@@ -40,4 +41,3 @@ support_pattern = lines
support_z_distance = 0.26
top_bottom_thickness = 1.5
wall_thickness = 1.14
-
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 b324d867bc..0773a81834 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_cpe_plus_ultimaker2_plus_0.6_mm
-weight = -2
-quality_type = draft
setting_version = 4
+type = quality
+quality_type = draft
+weight = -2
+material = generic_cpe_plus
+variant = 0.6 mm
[values]
adhesion_type = raft
@@ -44,4 +45,3 @@ support_xy_distance = 0.6
support_z_distance = 0.22
top_bottom_thickness = 0.75
wall_thickness = 1.14
-
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 c8c7576d30..4cea2db94e 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_cpe_plus_ultimaker2_plus_0.6_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_cpe_plus
+variant = 0.6 mm
[values]
adhesion_type = raft
@@ -44,4 +45,3 @@ support_xy_distance = 0.6
support_z_distance = 0.22
top_bottom_thickness = 0.75
wall_thickness = 1.14
-
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 28353f729d..27c3052885 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_cpe_plus_ultimaker2_plus_0.8_mm
-weight = -2
-quality_type = draft
setting_version = 4
+type = quality
+quality_type = draft
+weight = -2
+material = generic_cpe_plus
+variant = 0.8 mm
[values]
adhesion_type = raft
@@ -39,4 +40,3 @@ support_pattern = lines
support_z_distance = 0.26
top_bottom_thickness = 1.2
wall_thickness = 2.1
-
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 f74db21b91..26d44f332b 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_cpe_plus_ultimaker2_plus_0.8_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_cpe_plus
+variant = 0.8 mm
[values]
adhesion_type = raft
@@ -39,4 +40,3 @@ support_pattern = lines
support_z_distance = 0.26
top_bottom_thickness = 1.2
wall_thickness = 2.1
-
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 b8924423e2..d2c9c9d8d3 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_nylon_ultimaker2_plus_0.25_mm
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+material = generic_nylon
+variant = 0.25 mm
[values]
adhesion_type = raft
@@ -41,4 +42,3 @@ support_xy_distance = 0.6
support_z_distance = =layer_height * 2
top_bottom_thickness = 1.2
wall_thickness = 1
-
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 323fa51a8d..115e4dd0d3 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_nylon_ultimaker2_plus_0.25_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_nylon
+variant = 0.25 mm
[values]
adhesion_type = raft
@@ -41,4 +42,3 @@ support_xy_distance = 0.6
support_z_distance = =layer_height * 2
top_bottom_thickness = 1.2
wall_thickness = 1
-
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 7628cd0be1..917715ef33 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_nylon_ultimaker2_plus_0.4_mm
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_nylon
+variant = 0.4 mm
[values]
adhesion_type = raft
@@ -40,4 +41,3 @@ support_xy_distance = 0.6
support_z_distance = =layer_height * 2
top_bottom_thickness = 0.75
wall_thickness = 1.06
-
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 a97a4c4e8f..125930991a 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_nylon_ultimaker2_plus_0.4_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_nylon
+variant = 0.4 mm
[values]
adhesion_type = raft
@@ -39,4 +40,3 @@ support_xy_distance = 0.6
support_z_distance = =layer_height * 2
top_bottom_thickness = 0.75
wall_thickness = 1.06
-
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 0cd7bbdbfd..3602182288 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_nylon_ultimaker2_plus_0.6_mm
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_nylon
+variant = 0.6 mm
[values]
adhesion_type = raft
@@ -45,4 +46,3 @@ support_xy_distance = 0.7
support_z_distance = =layer_height * 2
top_bottom_thickness = 1.2
wall_thickness = 1.2
-
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 d5e0025913..c41a8b3612 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_nylon_ultimaker2_plus_0.6_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_nylon
+variant = 0.6 mm
[values]
adhesion_type = raft
@@ -43,4 +44,3 @@ support_xy_distance = 0.7
support_z_distance = =layer_height * 2
top_bottom_thickness = 1.2
wall_thickness = 1.2
-
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 f653a90f95..6e68d79f34 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_nylon_ultimaker2_plus_0.8_mm
-weight = -2
-quality_type = draft
setting_version = 4
+type = quality
+quality_type = draft
+weight = -2
+material = generic_nylon
+variant = 0.8 mm
[values]
adhesion_type = raft
@@ -44,4 +45,3 @@ support_xy_distance = 0.75
support_z_distance = =layer_height * 2
top_bottom_thickness = 1.2
wall_thickness = 2.4
-
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 144c8e74ac..e01006cf58 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_nylon_ultimaker2_plus_0.8_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_nylon
+variant = 0.8 mm
[values]
adhesion_type = raft
@@ -44,4 +45,3 @@ support_xy_distance = 0.75
support_z_distance = =layer_height * 2
top_bottom_thickness = 1.2
wall_thickness = 2.4
-
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 d38f2af4d3..91bc5e523a 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pc_ultimaker2_plus_0.25_mm
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+material = generic_pc
+variant = 0.25 mm
[values]
adhesion_type = raft
@@ -35,4 +36,3 @@ support_infill_rate = 20
support_pattern = lines
support_z_distance = 0.19
wall_thickness = 0.88
-
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 aa176f67a2..5407edf56d 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pc_ultimaker2_plus_0.25_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_pc
+variant = 0.25 mm
[values]
adhesion_type = raft
@@ -35,4 +36,3 @@ support_infill_rate = 20
support_pattern = lines
support_z_distance = 0.19
wall_thickness = 0.88
-
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 0408ead05e..5e0cef44cc 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pc_ultimaker2_plus_0.4_mm
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_pc
+variant = 0.4 mm
[values]
adhesion_type = raft
@@ -36,4 +37,3 @@ support_infill_rate = 20
support_pattern = lines
support_z_distance = 0.19
wall_thickness = 1.2
-
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 ed430f10c0..9e400a46e7 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pc_ultimaker2_plus_0.4_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_pc
+variant = 0.4 mm
[values]
adhesion_type = raft
@@ -36,4 +37,3 @@ support_infill_rate = 20
support_pattern = lines
support_z_distance = 0.19
wall_thickness = 1.2
-
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 b6c3a66c0b..1741eb47e9 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pc_ultimaker2_plus_0.6_mm
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_pc
+variant = 0.6 mm
[values]
adhesion_type = raft
@@ -42,4 +43,3 @@ support_pattern = lines
support_z_distance = 0.21
top_bottom_thickness = 0.75
wall_thickness = 1.06
-
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 0dfb533f56..17df729157 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pc_ultimaker2_plus_0.6_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_pc
+variant = 0.6 mm
[values]
adhesion_type = raft
@@ -42,4 +43,3 @@ support_pattern = lines
support_z_distance = 0.21
top_bottom_thickness = 0.75
wall_thickness = 1.06
-
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 3eee23006f..87bad0bd64 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pc_ultimaker2_plus_0.8_mm
-weight = -2
-quality_type = draft
setting_version = 4
+type = quality
+quality_type = draft
+weight = -2
+material = generic_pc
+variant = 0.8 mm
[values]
adhesion_type = raft
@@ -36,4 +37,3 @@ support_pattern = lines
support_z_distance = 0.26
top_bottom_thickness = 2.0
wall_thickness = 2.1
-
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 40da82e6bf..e1f208b2f1 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pc_ultimaker2_plus_0.8_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_pc
+variant = 0.8 mm
[values]
adhesion_type = raft
@@ -36,4 +37,3 @@ support_pattern = lines
support_z_distance = 0.26
top_bottom_thickness = 1.2
wall_thickness = 2.1
-
diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg
index 6f4e366209..cbb4f2f881 100644
--- a/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_pp_0.4_fast.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pp_ultimaker2_plus_0.4_mm
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_pp
+variant = 0.4 mm
[values]
acceleration_enabled = True
@@ -68,4 +69,3 @@ travel_avoid_distance = 3
wall_0_inset = 0
wall_line_width_x = =round(line_width * 0.38 / 0.38, 2)
wall_thickness = 0.76
-
diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg
index c7224f475f..ee38faa33a 100644
--- a/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_pp_0.4_normal.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pp_ultimaker2_plus_0.4_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_pp
+variant = 0.4 mm
[values]
acceleration_enabled = True
@@ -67,4 +68,3 @@ travel_avoid_distance = 3
wall_0_inset = 0
wall_line_width_x = =round(line_width * 0.38 / 0.38, 2)
wall_thickness = 0.76
-
diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg
index 203db9883e..9fe8c72397 100644
--- a/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_pp_0.6_draft.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pp_ultimaker2_plus_0.6_mm
-weight = -2
-quality_type = draft
setting_version = 4
+type = quality
+quality_type = draft
+weight = -2
+material = generic_pp
+variant = 0.6 mm
[values]
acceleration_enabled = True
@@ -46,7 +47,6 @@ retraction_extrusion_window = 1
retraction_hop = 0.15
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
-retraction_min_travel = 0.5
retraction_prime_speed = 15
skin_overlap = 10
skirt_brim_line_width = 0.6
@@ -70,4 +70,3 @@ travel_avoid_distance = 3
wall_0_inset = 0
wall_line_width_x = =round(line_width * 0.57 / 0.57, 2)
wall_thickness = 1.14
-
diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg
index 64dfbc9281..ba9052818c 100644
--- a/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_pp_0.6_fast.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pp_ultimaker2_plus_0.6_mm
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_pp
+variant = 0.6 mm
[values]
acceleration_enabled = True
@@ -46,7 +47,6 @@ retraction_extrusion_window = 1
retraction_hop = 0.15
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
-retraction_min_travel = 0.5
retraction_prime_speed = 15
skin_overlap = 10
skirt_brim_line_width = 0.6
@@ -70,4 +70,3 @@ travel_avoid_distance = 3
wall_0_inset = 0
wall_line_width_x = =round(line_width * 0.57 / 0.57, 2)
wall_thickness = 1.14
-
diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg
index f6d56242dd..2a6b4d1de8 100644
--- a/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_pp_0.8_draft.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pp_ultimaker2_plus_0.8_mm
-weight = -2
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -2
+material = generic_pp
+variant = 0.8 mm
[values]
acceleration_enabled = True
@@ -46,7 +47,6 @@ retraction_extrusion_window = 1
retraction_hop = 0.15
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
-retraction_min_travel = 0.5
retraction_prime_speed = 15
skin_overlap = 10
skirt_brim_line_width = 0.8
@@ -70,4 +70,3 @@ travel_avoid_distance = 3
wall_0_inset = 0
wall_line_width_x = =round(line_width * 0.76 / 0.76, 2)
wall_thickness = 1.52
-
diff --git a/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg b/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg
index ecb3e3da4a..92f605f557 100644
--- a/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg
+++ b/resources/quality/ultimaker2_plus/um2p_pp_0.8_verydraft.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fast
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_pp_ultimaker2_plus_0.8_mm
-weight = -3
-quality_type = draft
setting_version = 4
+type = quality
+quality_type = draft
+weight = -3
+material = generic_pp
+variant = 0.8 mm
[values]
acceleration_enabled = True
@@ -46,7 +47,6 @@ retraction_extrusion_window = 1
retraction_hop = 0.15
retraction_hop_enabled = True
retraction_hop_only_when_collides = True
-retraction_min_travel = 0.5
retraction_prime_speed = 15
skin_overlap = 10
skirt_brim_line_width = 0.8
@@ -70,4 +70,3 @@ travel_avoid_distance = 3
wall_0_inset = 0
wall_line_width_x = =round(line_width * 0.76 / 0.76, 2)
wall_thickness = 1.52
-
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 b1cb56a543..b6fe1515c0 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_tpu_ultimaker2_plus_0.25_mm
-weight = 1
-quality_type = high
setting_version = 4
+type = quality
+quality_type = high
+weight = 1
+material = generic_tpu
+variant = 0.25 mm
[values]
adhesion_type = brim
@@ -40,4 +41,3 @@ support_xy_distance = 0.6
support_z_distance = =layer_height * 2
top_bottom_thickness = 1.2
wall_thickness = 0.88
-
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 80cc92fe64..27e09bdf10 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_tpu_ultimaker2_plus_0.4_mm
-weight = 0
-quality_type = normal
setting_version = 4
+type = quality
+quality_type = normal
+weight = 0
+material = generic_tpu
+variant = 0.4 mm
[values]
adhesion_type = brim
@@ -37,4 +38,3 @@ support_xy_distance = 0.65
support_z_distance = =layer_height * 2
top_bottom_thickness = 1.2
wall_thickness = 1.05
-
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 9796adada9..6d0b1ef8de 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker2_plus
[metadata]
-type = quality
-material = generic_tpu_ultimaker2_plus_0.6_mm
-weight = -1
-quality_type = fast
setting_version = 4
+type = quality
+quality_type = fast
+weight = -1
+material = generic_tpu
+variant = 0.6 mm
[values]
adhesion_type = brim
@@ -42,4 +43,3 @@ support_xy_distance = 0.7
support_z_distance = =layer_height * 2
top_bottom_thickness = 1.2
wall_thickness = 1.14
-
diff --git a/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg
index fc7d4d12d2..c79c831984 100644
--- a/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.25_ABS_Normal_Quality.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_abs_ultimaker3_AA_0.25
weight = 0
-setting_version = 4
+material = generic_abs
+variant = AA 0.25
[values]
cool_fan_speed = 40
@@ -20,4 +21,3 @@ prime_tower_wall_thickness = 0.9
retraction_prime_speed = 25
speed_topbottom = =math.ceil(speed_print * 30 / 55)
wall_thickness = 0.92
-
diff --git a/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg
index 83e0c549c4..83e77eb117 100644
--- a/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.25_CPE_Normal_Quality.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_cpe_ultimaker3_AA_0.25
weight = 0
-setting_version = 4
+material = generic_cpe
+variant = AA 0.25
[values]
prime_tower_size = 12
@@ -18,4 +19,3 @@ speed_infill = 40
speed_topbottom = =math.ceil(speed_print * 30 / 55)
top_bottom_thickness = 0.8
wall_thickness = 0.92
-
diff --git a/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg
index 58ddc32101..c3ead92b51 100644
--- a/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.25_Nylon_Normal_Quality.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_nylon_ultimaker3_AA_0.25
weight = 0
-setting_version = 4
+material = generic_nylon
+variant = AA 0.25
[values]
cool_min_layer_time_fan_speed_max = 20
@@ -32,4 +33,3 @@ switch_extruder_prime_speed = 30
switch_extruder_retraction_amount = 30
switch_extruder_retraction_speeds = 40
wall_line_width_x = =wall_line_width
-
diff --git a/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg
index 925af3f73c..bd95837fee 100644
--- a/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.25_PC_Normal_Quality.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine - Experimental
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pc_ultimaker3_AA_0.25
weight = 0
-setting_version = 4
+material = generic_pc
+variant = AA 0.25
[values]
acceleration_enabled = True
@@ -52,4 +53,3 @@ switch_extruder_retraction_speeds = 35
wall_0_inset = 0
wall_line_width_x = =line_width
wall_thickness = 1.2
-
diff --git a/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg
index 1bee4b8f18..7f6fb9fa4d 100644
--- a/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.25_PLA_Normal_Quality.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pla_ultimaker3_AA_0.25
weight = 0
-setting_version = 4
+material = generic_pla
+variant = AA 0.25
[values]
brim_width = 8
@@ -33,4 +34,3 @@ travel_avoid_distance = 0.4
wall_0_inset = 0.015
wall_0_wipe_dist = 0.25
wall_thickness = 0.7
-
diff --git a/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg
index e12729878d..6bdd94f58f 100644
--- a/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.25_PP_Normal_Quality.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine - Experimental
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pp_ultimaker3_AA_0.25
weight = 0
-setting_version = 4
+material = generic_pp
+variant = AA 0.25
[values]
acceleration_enabled = True
@@ -33,7 +34,7 @@ multiple_mesh_overlap = 0
prime_tower_enable = False
prime_tower_size = 16
prime_tower_wipe_enabled = True
-retraction_count_max = 6
+retraction_count_max = 45
retraction_extra_prime_amount = 0.2
retraction_extrusion_window = 6.5
retraction_hop = 2
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 13dca72c27..4b05943b64 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_abs_ultimaker3_AA_0.4
weight = -2
-setting_version = 4
+material = generic_abs
+variant = AA 0.4
[values]
machine_nozzle_cool_down_speed = 0.85
@@ -24,4 +25,3 @@ speed_topbottom = =math.ceil(speed_print * 35 / 60)
speed_wall = =math.ceil(speed_print * 45 / 60)
speed_wall_0 = =math.ceil(speed_wall * 35 / 45)
wall_thickness = 1
-
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 10fa10c726..3b441942ac 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_abs_ultimaker3_AA_0.4
weight = -1
-setting_version = 4
+material = generic_abs
+variant = AA 0.4
[values]
cool_min_speed = 7
@@ -24,4 +25,3 @@ speed_layer_0 = 20
speed_topbottom = =math.ceil(speed_print * 30 / 60)
speed_wall = =math.ceil(speed_print * 40 / 60)
speed_wall_0 = =math.ceil(speed_wall * 30 / 40)
-
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 02f2327468..79cdb4069d 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_abs_ultimaker3_AA_0.4
weight = 1
-setting_version = 4
+material = generic_abs
+variant = AA 0.4
[values]
cool_min_speed = 12
@@ -23,4 +24,3 @@ speed_print = 50
speed_layer_0 = 20
speed_topbottom = =math.ceil(speed_print * 30 / 50)
speed_wall = =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 fccb6a35f5..412bc4c5a8 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_abs_ultimaker3_AA_0.4
weight = 0
-setting_version = 4
+material = generic_abs
+variant = AA 0.4
[values]
machine_nozzle_cool_down_speed = 0.85
@@ -21,4 +22,3 @@ speed_print = 55
speed_layer_0 = 20
speed_topbottom = =math.ceil(speed_print * 30 / 55)
speed_wall = =math.ceil(speed_print * 30 / 55)
-
diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg
index f3c6ae8387..e4ef572efb 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Draft_Print.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_bam_ultimaker3_AA_0.4
weight = -2
-setting_version = 4
+material = generic_bam
+variant = AA 0.4
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg
index e027477595..c896c74233 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Fast_Print.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_bam_ultimaker3_AA_0.4
weight = -1
-setting_version = 4
+material = generic_bam
+variant = AA 0.4
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
diff --git a/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg
index 3ced3a0417..9fdcfb4cf3 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_BAM_Normal_Quality.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_bam_ultimaker3_AA_0.4
weight = 0
-setting_version = 4
+material = generic_bam
+variant = AA 0.4
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
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 dfdb1ca8a7..14263ee800 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_cpe_plus_ultimaker3_AA_0.4
weight = -2
-setting_version = 4
+material = generic_cpe_plus
+variant = AA 0.4
[values]
acceleration_enabled = True
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 93b371a627..05d8988c36 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_cpe_plus_ultimaker3_AA_0.4
weight = -1
-setting_version = 4
+material = generic_cpe_plus
+variant = AA 0.4
[values]
acceleration_enabled = True
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 93647f9f44..6a6fa94730 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_cpe_plus_ultimaker3_AA_0.4
weight = 1
-setting_version = 4
+material = generic_cpe_plus
+variant = AA 0.4
[values]
acceleration_enabled = True
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 2886ef2229..402e23436a 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_cpe_plus_ultimaker3_AA_0.4
weight = 0
-setting_version = 4
+material = generic_cpe_plus
+variant = AA 0.4
[values]
acceleration_enabled = True
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 5e3daf5a9e..9a85ab9b3e 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_cpe_ultimaker3_AA_0.4
weight = -2
-setting_version = 4
+material = generic_cpe
+variant = AA 0.4
[values]
material_print_temperature = =default_material_print_temperature + 10
@@ -22,4 +23,3 @@ speed_topbottom = =math.ceil(speed_print * 35 / 60)
speed_wall = =math.ceil(speed_print * 45 / 60)
speed_wall_0 = =math.ceil(speed_wall * 35 / 45)
wall_thickness = 1
-
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 e48f83994d..7099062daf 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_cpe_ultimaker3_AA_0.4
weight = -1
-setting_version = 4
+material = generic_cpe
+variant = AA 0.4
[values]
cool_min_speed = 7
@@ -21,4 +22,3 @@ speed_layer_0 = 20
speed_topbottom = =math.ceil(speed_print * 30 / 60)
speed_wall = =math.ceil(speed_print * 40 / 60)
speed_wall_0 = =math.ceil(speed_wall * 30 / 40)
-
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 fd0a8cd18d..00adfcc2d7 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_cpe_ultimaker3_AA_0.4
weight = 1
-setting_version = 4
+material = generic_cpe
+variant = AA 0.4
[values]
cool_min_speed = 12
@@ -22,4 +23,3 @@ speed_print = 50
speed_layer_0 = 20
speed_topbottom = =math.ceil(speed_print * 30 / 50)
speed_wall = =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 56c997eb15..590eddf43b 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_cpe_ultimaker3_AA_0.4
weight = 0
-setting_version = 4
+material = generic_cpe
+variant = AA 0.4
[values]
machine_nozzle_cool_down_speed = 0.85
@@ -20,4 +21,3 @@ speed_print = 55
speed_layer_0 = 20
speed_topbottom = =math.ceil(speed_print * 30 / 55)
speed_wall = =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 15283a3242..8ade8d4fe4 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_nylon_ultimaker3_AA_0.4
weight = -2
-setting_version = 4
+material = generic_nylon
+variant = AA 0.4
[values]
adhesion_type = brim
@@ -33,4 +34,3 @@ switch_extruder_prime_speed = 30
switch_extruder_retraction_amount = 30
switch_extruder_retraction_speeds = 40
wall_line_width_x = =wall_line_width
-
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 c063725e82..2fef1fb2a2 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_nylon_ultimaker3_AA_0.4
weight = -1
-setting_version = 4
+material = generic_nylon
+variant = AA 0.4
[values]
adhesion_type = brim
@@ -33,4 +34,3 @@ switch_extruder_prime_speed = 30
switch_extruder_retraction_amount = 30
switch_extruder_retraction_speeds = 40
wall_line_width_x = =wall_line_width
-
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 218e1e50e1..9a320ecde3 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_nylon_ultimaker3_AA_0.4
weight = 1
-setting_version = 4
+material = generic_nylon
+variant = AA 0.4
[values]
adhesion_type = brim
@@ -32,4 +33,3 @@ switch_extruder_prime_speed = 30
switch_extruder_retraction_amount = 30
switch_extruder_retraction_speeds = 40
wall_line_width_x = =wall_line_width
-
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 3b96939ac9..34efb4df95 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_nylon_ultimaker3_AA_0.4
weight = 0
-setting_version = 4
+material = generic_nylon
+variant = AA 0.4
[values]
adhesion_type = brim
@@ -32,4 +33,3 @@ switch_extruder_prime_speed = 30
switch_extruder_retraction_amount = 30
switch_extruder_retraction_speeds = 40
wall_line_width_x = =wall_line_width
-
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 fb185d95b8..79ae457587 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_pc_ultimaker3_AA_0.4
weight = -2
-setting_version = 4
+material = generic_pc
+variant = AA 0.4
[values]
acceleration_enabled = True
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 ab53edfa73..2e07e65bbe 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_pc_ultimaker3_AA_0.4
weight = -1
-setting_version = 4
+material = generic_pc
+variant = AA 0.4
[values]
acceleration_enabled = True
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 9900aed7d2..2b1b1f850b 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pc_ultimaker3_AA_0.4
weight = 1
-setting_version = 4
+material = generic_pc
+variant = AA 0.4
[values]
acceleration_enabled = True
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 63be70e4e2..437ef43878 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pc_ultimaker3_AA_0.4
weight = 0
-setting_version = 4
+material = generic_pc
+variant = AA 0.4
[values]
acceleration_enabled = True
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 a32d9268d3..3805d7a396 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_pla_ultimaker3_AA_0.4
weight = -2
-setting_version = 4
+material = generic_pla
+variant = AA 0.4
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
@@ -26,4 +27,3 @@ speed_wall = =math.ceil(speed_print * 55 / 70)
speed_wall_0 = =math.ceil(speed_wall * 45 / 50)
top_bottom_thickness = 1
wall_thickness = 1
-
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 30b7d44d4e..3a8c6df621 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_pla_ultimaker3_AA_0.4
weight = -1
-setting_version = 4
+material = generic_pla
+variant = AA 0.4
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
@@ -25,4 +26,3 @@ speed_wall = =math.ceil(speed_print * 40 / 80)
speed_wall_0 = =math.ceil(speed_wall * 30 / 40)
top_bottom_thickness = 1
wall_thickness = 1
-
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 da62ce2e3f..543391fd6b 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = generic_pla_ultimaker3_AA_0.4
weight = 1
-setting_version = 4
+material = generic_pla
+variant = AA 0.4
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
@@ -27,4 +28,3 @@ speed_topbottom = =math.ceil(speed_print * 30 / 60)
speed_wall = =math.ceil(speed_print * 30 / 60)
top_bottom_thickness = 1
wall_thickness = 1
-
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 04707735f5..c3c2a8d624 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pla_ultimaker3_AA_0.4
weight = 0
-setting_version = 4
+material = generic_pla
+variant = AA 0.4
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
@@ -23,4 +24,3 @@ skin_overlap = 10
speed_layer_0 = 20
top_bottom_thickness = 1
wall_thickness = 1
-
diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg
index f543c3ae78..1db33d9073 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Draft_Print.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_pp_ultimaker3_AA_0.4
weight = -2
-setting_version = 4
+material = generic_pp
+variant = AA 0.4
[values]
acceleration_enabled = True
@@ -61,4 +62,4 @@ switch_extruder_retraction_amount = 20
switch_extruder_retraction_speeds = 35
wall_0_inset = 0
wall_line_width_x = =line_width
-wall_thickness = =line_width * 3
\ No newline at end of file
+wall_thickness = =line_width * 3
diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg
index 0d1fb6af58..fe7da92bbe 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Fast_Print.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_pp_ultimaker3_AA_0.4
weight = -1
-setting_version = 4
+material = generic_pp
+variant = AA 0.4
[values]
acceleration_enabled = True
@@ -61,4 +62,4 @@ switch_extruder_retraction_speeds = 35
top_bottom_thickness = 1.1
wall_0_inset = 0
wall_line_width_x = =line_width
-wall_thickness = =line_width * 3
\ No newline at end of file
+wall_thickness = =line_width * 3
diff --git a/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg b/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg
index 141015348f..8bbb0118b5 100644
--- a/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.4_PP_Normal_Quality.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pp_ultimaker3_AA_0.4
weight = 0
-setting_version = 4
+material = generic_pp
+variant = AA 0.4
[values]
acceleration_enabled = True
@@ -60,4 +61,4 @@ switch_extruder_retraction_speeds = 35
top_bottom_thickness = 1
wall_0_inset = 0
wall_line_width_x = =line_width
-wall_thickness = =line_width * 3
\ No newline at end of file
+wall_thickness = =line_width * 3
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 8c8b9691df..25e7c2c0ab 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_tpu_ultimaker3_AA_0.4
weight = -2
-setting_version = 4
+material = generic_tpu
+variant = AA 0.4
[values]
acceleration_enabled = True
@@ -61,4 +62,4 @@ top_bottom_thickness = 0.7
travel_avoid_distance = 1.5
wall_0_inset = 0
wall_line_width_x = =line_width
-wall_thickness = 0.76
\ No newline at end of file
+wall_thickness = 0.76
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 0e3ad215d6..0b7fa6501e 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-material = generic_tpu_ultimaker3_AA_0.4
weight = -1
-setting_version = 4
+material = generic_tpu
+variant = AA 0.4
[values]
acceleration_enabled = True
@@ -62,4 +63,4 @@ top_bottom_thickness = 0.7
travel_avoid_distance = 1.5
wall_0_inset = 0
wall_line_width_x = =line_width
-wall_thickness = 0.76
\ No newline at end of file
+wall_thickness = 0.76
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 7e338e6a47..9afecb8987 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = generic_tpu_ultimaker3_AA_0.4
weight = 0
-setting_version = 4
+material = generic_tpu
+variant = AA 0.4
[values]
acceleration_enabled = True
@@ -59,4 +60,4 @@ top_bottom_thickness = 0.7
travel_avoid_distance = 1.5
wall_0_inset = 0
wall_line_width_x = =line_width
-wall_thickness = 0.76
\ No newline at end of file
+wall_thickness = 0.76
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 7c16e6e8ee..85e1415147 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_abs_ultimaker3_AA_0.8
weight = -2
-setting_version = 4
+material = generic_abs
+variant = AA 0.8
[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 728b4c868f..3167473cc6 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Sprint
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_abs_ultimaker3_AA_0.8
weight = -4
-setting_version = 4
+material = generic_abs
+variant = AA 0.8
[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 98ae70c568..0414bf724c 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-material = generic_abs_ultimaker3_AA_0.8
weight = -3
-setting_version = 4
+material = generic_abs
+variant = AA 0.8
[values]
layer_height = 0.3
diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg
index 3d9b4bb798..87728c2297 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Fast_Print.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast - Experimental
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_cpe_plus_ultimaker3_AA_0.8
weight = -2
-setting_version = 4
+material = generic_cpe_plus
+variant = AA 0.8
[values]
brim_width = 14
@@ -34,4 +35,4 @@ speed_wall_0 = =math.ceil(speed_wall * 35 / 40)
support_bottom_distance = =support_z_distance
support_line_width = =round(line_width * 0.6 / 0.7, 2)
support_z_distance = =layer_height
-top_bottom_thickness = 1.2
\ No newline at end of file
+top_bottom_thickness = 1.2
diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg
index ccd87313e7..603f32a688 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Superdraft_Print.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Sprint - Experimental
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_cpe_plus_ultimaker3_AA_0.8
weight = -4
-setting_version = 4
+material = generic_cpe_plus
+variant = AA 0.8
[values]
brim_width = 14
@@ -35,4 +36,4 @@ speed_wall_0 = =math.ceil(speed_wall * 35 / 40)
support_bottom_distance = =support_z_distance
support_line_width = =round(line_width * 0.6 / 0.7, 2)
support_z_distance = =layer_height
-top_bottom_thickness = 1.2
\ No newline at end of file
+top_bottom_thickness = 1.2
diff --git a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg
index 9ba6195df4..432d502245 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_CPEP_Verydraft_Print.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fast - Experimental
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-material = generic_cpe_plus_ultimaker3_AA_0.8
weight = -3
-setting_version = 4
+material = generic_cpe_plus
+variant = AA 0.8
[values]
brim_width = 14
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 b4d7035b8d..fd138ae2f2 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_cpe_ultimaker3_AA_0.8
weight = -2
-setting_version = 4
+material = generic_cpe
+variant = AA 0.8
[values]
brim_width = 15
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 b5ccc38534..feba0b3160 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Sprint
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_cpe_ultimaker3_AA_0.8
weight = -4
-setting_version = 4
+material = generic_cpe
+variant = AA 0.8
[values]
brim_width = 15
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 33ae223526..1d9537097e 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-material = generic_cpe_ultimaker3_AA_0.8
weight = -3
-setting_version = 4
+material = generic_cpe
+variant = AA 0.8
[values]
brim_width = 15
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 43ec77453c..e205720539 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_nylon_ultimaker3_AA_0.8
weight = -2
-setting_version = 4
+material = generic_nylon
+variant = AA 0.8
[values]
brim_width = 5.6
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 5b8626e8c2..f2853a8781 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Sprint
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_nylon_ultimaker3_AA_0.8
weight = -4
-setting_version = 4
+material = generic_nylon
+variant = AA 0.8
[values]
brim_width = 5.6
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 0b115ada4b..442323877c 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-material = generic_nylon_ultimaker3_AA_0.8
weight = -3
-setting_version = 4
+material = generic_nylon
+variant = AA 0.8
[values]
brim_width = 5.6
diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg
index 1d0c094496..d8460c6971 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Fast_Print.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast - Experimental
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_pc_ultimaker3_AA_0.8
weight = 0
-setting_version = 4
+material = generic_pc
+variant = AA 0.8
[values]
brim_width = 14
diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg
index 23f654a586..53f613ec70 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Superdraft_Print.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Sprint - Experimental
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_pc_ultimaker3_AA_0.8
weight = -2
-setting_version = 4
+material = generic_pc
+variant = AA 0.8
[values]
brim_width = 14
diff --git a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg
index 82986f68cf..a4fdaaa791 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_PC_Verydraft_Print.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fast - Experimental
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-material = generic_pc_ultimaker3_AA_0.8
weight = -1
-setting_version = 4
+material = generic_pc
+variant = AA 0.8
[values]
brim_width = 14
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 8b3c3e56c6..3293fa8382 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_pla_ultimaker3_AA_0.8
weight = -2
-setting_version = 4
+material = generic_pla
+variant = AA 0.8
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
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 2fe8f7c6f9..b989d7e11a 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Sprint
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_pla_ultimaker3_AA_0.8
weight = -4
-setting_version = 4
+material = generic_pla
+variant = AA 0.8
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
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 9072e0c60f..684eb11c5b 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-material = generic_pla_ultimaker3_AA_0.8
weight = -3
-setting_version = 4
+material = generic_pla
+variant = AA 0.8
[values]
cool_fan_full_at_height = =layer_height_0 + 2 * layer_height
diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg
index f46c3cfb8f..8ed11c1946 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Draft_Print.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_pp_ultimaker3_AA_0.8
weight = -2
-setting_version = 4
+material = generic_pp
+variant = AA 0.8
[values]
brim_width = 25
@@ -48,4 +49,4 @@ top_bottom_thickness = 1.6
travel_compensate_overlapping_walls_0_enabled = False
wall_0_wipe_dist = =line_width * 2
wall_line_width_x = =round(line_width * 0.8 / 0.8, 2)
-wall_thickness = 1.6
\ No newline at end of file
+wall_thickness = 1.6
diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg
index ac8087d0c4..01b947995d 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Superdraft_Print.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Sprint
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_pp_ultimaker3_AA_0.8
weight = -4
-setting_version = 4
+material = generic_pp
+variant = AA 0.8
[values]
brim_width = 25
@@ -48,4 +49,4 @@ top_bottom_thickness = 1.6
travel_compensate_overlapping_walls_0_enabled = False
wall_0_wipe_dist = =line_width * 2
wall_line_width_x = =round(line_width * 0.8 / 0.8, 2)
-wall_thickness = 1.6
\ No newline at end of file
+wall_thickness = 1.6
diff --git a/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg
index daf60f24e6..ba1aa89c91 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_PP_Verydraft_Print.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-material = generic_pp_ultimaker3_AA_0.8
weight = -3
-setting_version = 4
+material = generic_pp
+variant = AA 0.8
[values]
brim_width = 25
@@ -48,4 +49,4 @@ top_bottom_thickness = 1.6
travel_compensate_overlapping_walls_0_enabled = False
wall_0_wipe_dist = =line_width * 2
wall_line_width_x = =round(line_width * 0.8 / 0.8, 2)
-wall_thickness = 1.6
\ No newline at end of file
+wall_thickness = 1.6
diff --git a/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg b/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg
index 8c11e1247a..e133d335f8 100644
--- a/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg
+++ b/resources/quality/ultimaker3/um3_aa0.8_TPU_Draft_Print.inst.cfg
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-material = generic_tpu_ultimaker3_AA_0.8
weight = -2
-setting_version = 4
+material = generic_tpu
+variant = AA 0.8
[values]
brim_width = 8.75
@@ -60,4 +61,4 @@ travel_avoid_distance = 1.5
travel_compensate_overlapping_walls_0_enabled = False
wall_0_wipe_dist = =line_width * 2
wall_line_width_x = =round(line_width * 0.6 / 0.8, 2)
-wall_thickness = 1.3
\ No newline at end of file
+wall_thickness = 1.3
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 6bd777f4b0..c835de26f4 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Sprint
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-material = generic_tpu_ultimaker3_AA_0.8
weight = -4
-setting_version = 4
+material = generic_tpu
+variant = AA 0.8
[values]
brim_width = 8.75
@@ -61,4 +62,4 @@ travel_avoid_distance = 1.5
travel_compensate_overlapping_walls_0_enabled = False
wall_0_wipe_dist = =line_width * 2
wall_line_width_x = =round(line_width * 0.6 / 0.8, 2)
-wall_thickness = 1.3
\ No newline at end of file
+wall_thickness = 1.3
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 f43818d7d4..2e3ad5cf44 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
@@ -1,14 +1,15 @@
[general]
-version = 2
+version = 3
name = Extra Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-material = generic_tpu_ultimaker3_AA_0.8
weight = -3
-setting_version = 4
+material = generic_tpu
+variant = AA 0.8
[values]
brim_width = 8.75
@@ -60,4 +61,4 @@ travel_avoid_distance = 1.5
travel_compensate_overlapping_walls_0_enabled = False
wall_0_wipe_dist = =line_width * 2
wall_line_width_x = =round(line_width * 0.6 / 0.8, 2)
-wall_thickness = 1.3
\ No newline at end of file
+wall_thickness = 1.3
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 c87f744932..4fff8be5ee 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
@@ -1,17 +1,18 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
weight = -2
-material = generic_pva_ultimaker3_BB_0.4
-setting_version = 4
+material = generic_pva
+variant = BB 0.4
[values]
material_print_temperature = =default_material_print_temperature + 10
material_standby_temperature = 100
prime_tower_enable = False
-skin_overlap = 20
\ No newline at end of file
+skin_overlap = 20
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 23fa6d61d8..8abce151bf 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
@@ -1,18 +1,19 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker3
[metadata]
-weight = -1
+setting_version = 4
type = quality
quality_type = fast
-material = generic_pva_ultimaker3_BB_0.4
-setting_version = 4
+weight = -1
+material = generic_pva
+variant = BB 0.4
[values]
material_print_temperature = =default_material_print_temperature + 5
material_standby_temperature = 100
prime_tower_enable = False
skin_overlap = 15
-support_infill_sparse_thickness = 0.3
\ No newline at end of file
+support_infill_sparse_thickness = 0.3
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 3ba82d65c6..0caf36e51b 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
@@ -1,16 +1,17 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker3
[metadata]
-weight = 1
+setting_version = 4
type = quality
quality_type = high
-material = generic_pva_ultimaker3_BB_0.4
-setting_version = 4
+weight = 1
+material = generic_pva
+variant = BB 0.4
[values]
material_standby_temperature = 100
prime_tower_enable = False
-support_infill_sparse_thickness = 0.18
\ No newline at end of file
+support_infill_sparse_thickness = 0.18
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 a709d5613b..0a8304a743 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
@@ -1,15 +1,16 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker3
[metadata]
-weight = 0
+setting_version = 4
type = quality
quality_type = normal
-material = generic_pva_ultimaker3_BB_0.4
-setting_version = 4
+weight = 0
+material = generic_pva
+variant = BB 0.4
[values]
material_standby_temperature = 100
-prime_tower_enable = False
\ No newline at end of file
+prime_tower_enable = False
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 4cb296b4c7..d59f283eb6 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
@@ -1,15 +1,16 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
weight = -2
-material = generic_pva_ultimaker3_BB_0.8
-setting_version = 4
+material = generic_pva
+variant = BB 0.8
[values]
material_print_temperature = =default_material_print_temperature + 5
-material_standby_temperature = 100
\ No newline at end of file
+material_standby_temperature = 100
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 5249517844..4039d39d6a 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
@@ -1,16 +1,17 @@
[general]
-version = 2
+version = 3
name = Sprint
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
weight = -4
-material = generic_pva_ultimaker3_BB_0.8
-setting_version = 4
+material = generic_pva
+variant = BB 0.8
[values]
layer_height = 0.4
material_standby_temperature = 100
-support_interface_height = 0.9
\ No newline at end of file
+support_interface_height = 0.9
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 c34e19b134..247ee3d4da 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
@@ -1,17 +1,18 @@
[general]
-version = 2
+version = 3
name = Extra Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
weight = -3
-material = generic_pva_ultimaker3_BB_0.8
-setting_version = 4
+material = generic_pva
+variant = BB 0.8
[values]
layer_height = 0.3
material_standby_temperature = 100
support_infill_sparse_thickness = 0.3
-support_interface_height = 1.2
\ No newline at end of file
+support_interface_height = 1.2
diff --git a/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg
index b56775a987..49a514bff3 100644
--- a/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_global_Draft_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = draft
-global_quality = True
weight = -2
-setting_version = 4
+global_quality = True
[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 12f1183364..69a94be93a 100644
--- a/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_global_Fast_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = fast
-global_quality = True
weight = -1
-setting_version = 4
+global_quality = True
[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 cf6e6c45e0..2aebb18ab5 100644
--- a/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_global_High_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Extra Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = high
-global_quality = True
weight = 0
-setting_version = 4
+global_quality = True
[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 fef2328923..5effc44fc5 100644
--- a/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_global_Normal_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Fine
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-global_quality = True
weight = 0
-setting_version = 4
+global_quality = True
[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 be9acd4394..55f5796240 100644
--- a/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_global_Superdraft_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Sprint
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = superdraft
-global_quality = True
weight = -4
-setting_version = 4
+global_quality = True
[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 e2c828fc2d..5d72a76c7c 100644
--- a/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg
+++ b/resources/quality/ultimaker3/um3_global_Verydraft_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Extra Fast
definition = ultimaker3
[metadata]
+setting_version = 4
type = quality
quality_type = verydraft
-global_quality = True
weight = -3
-setting_version = 4
+global_quality = True
[values]
layer_height = 0.3
diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg
index 2c42bd82b6..30c2749ac6 100644
--- a/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg
+++ b/resources/quality/vertex_delta_k8800/k8800_ABS_Extreme_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Extreme
definition = vertex_delta_k8800
[metadata]
+setting_version = 4
type = quality
quality_type = extreme
-material = Vertex_Delta_ABS
weight = 2
-setting_version = 4
+material = Vertex_Delta_ABS
[values]
layer_height = 0.05
@@ -19,4 +19,4 @@ material_initial_print_temperature = 250
material_print_temperature = 250
retraction_amount = 3
material_standby_temperature = 225
-cool_fan_speed = 0
\ No newline at end of file
+cool_fan_speed = 0
diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg
index a770131adb..102901ab3d 100644
--- a/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg
+++ b/resources/quality/vertex_delta_k8800/k8800_ABS_High_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = High
definition = vertex_delta_k8800
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = Vertex_Delta_ABS
weight = 1
-setting_version = 4
+material = Vertex_Delta_ABS
[values]
layer_height = 0.1
@@ -19,4 +19,4 @@ material_initial_print_temperature = 250
material_print_temperature = 250
retraction_amount = 3
material_standby_temperature = 225
-cool_fan_speed = 0
\ No newline at end of file
+cool_fan_speed = 0
diff --git a/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg
index 7c7e635149..f2e699f571 100644
--- a/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg
+++ b/resources/quality/vertex_delta_k8800/k8800_ABS_Normal_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = vertex_delta_k8800
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = Vertex_Delta_ABS
weight = 0
-setting_version = 4
+material = Vertex_Delta_ABS
[values]
layer_height = 0.2
@@ -19,4 +19,4 @@ material_initial_print_temperature = 250
material_print_temperature = 250
retraction_amount = 3
material_standby_temperature = 225
-cool_fan_speed = 00
\ No newline at end of file
+cool_fan_speed = 00
diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg
index 836d900247..1f98ded1db 100644
--- a/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg
+++ b/resources/quality/vertex_delta_k8800/k8800_PET_Extreme_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Extreme
definition = vertex_delta_k8800
[metadata]
+setting_version = 4
type = quality
quality_type = extreme
-material = Vertex_Delta_PET
weight = 2
-setting_version = 4
+material = Vertex_Delta_PET
[values]
layer_height = 0.05
@@ -19,4 +19,4 @@ material_initial_print_temperature = 240
material_print_temperature = 240
retraction_amount = 3
material_standby_temperature = 215
-cool_fan_speed = 10
\ No newline at end of file
+cool_fan_speed = 10
diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg
index b0cae312b2..f050c741c2 100644
--- a/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg
+++ b/resources/quality/vertex_delta_k8800/k8800_PET_High_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = High
definition = vertex_delta_k8800
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = Vertex_Delta_PET
weight = 1
-setting_version = 4
+material = Vertex_Delta_PET
[values]
layer_height = 0.1
@@ -19,4 +19,4 @@ material_initial_print_temperature = 240
material_print_temperature = 240
retraction_amount = 3
material_standby_temperature = 215
-cool_fan_speed = 10
\ No newline at end of file
+cool_fan_speed = 10
diff --git a/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg
index ebec26d04a..faeb8343fb 100644
--- a/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg
+++ b/resources/quality/vertex_delta_k8800/k8800_PET_Normal_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = vertex_delta_k8800
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = Vertex_Delta_PET
weight = 0
-setting_version = 4
+material = Vertex_Delta_PET
[values]
layer_height = 0.2
@@ -19,4 +19,4 @@ material_initial_print_temperature = 240
material_print_temperature = 240
retraction_amount = 3
material_standby_temperature = 215
-cool_fan_speed = 10
\ No newline at end of file
+cool_fan_speed = 10
diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg
index 13ad6455c9..f5ac232d06 100644
--- a/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg
+++ b/resources/quality/vertex_delta_k8800/k8800_PLA_Extreme_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Extreme
definition = vertex_delta_k8800
[metadata]
+setting_version = 4
type = quality
quality_type = extreme
-material = Vertex_Delta_PLA
weight = 2
-setting_version = 4
+material = Vertex_Delta_PLA
[values]
layer_height = 0.05
@@ -19,4 +19,4 @@ material_initial_print_temperature = 200
material_print_temperature = 200
retraction_amount = 3
material_standby_temperature = 175
-cool_fan_speed = 40
\ No newline at end of file
+cool_fan_speed = 40
diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg
index e8c7e893cb..63ed8389db 100644
--- a/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg
+++ b/resources/quality/vertex_delta_k8800/k8800_PLA_High_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = High
definition = vertex_delta_k8800
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = Vertex_Delta_PLA
weight = 1
-setting_version = 4
+material = Vertex_Delta_PLA
[values]
layer_height = 0.1
@@ -19,4 +19,4 @@ material_initial_print_temperature = 200
material_print_temperature = 200
retraction_amount = 3
material_standby_temperature = 175
-cool_fan_speed = 40
\ No newline at end of file
+cool_fan_speed = 40
diff --git a/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg
index 27002caea2..e84cbabade 100644
--- a/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg
+++ b/resources/quality/vertex_delta_k8800/k8800_PLA_Normal_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = vertex_delta_k8800
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = Vertex_Delta_PLA
weight = 0
-setting_version = 4
+material = Vertex_Delta_PLA
[values]
layer_height = 0.2
@@ -19,4 +19,4 @@ material_initial_print_temperature = 200
material_print_temperature = 200
retraction_amount = 3
material_standby_temperature = 175
-cool_fan_speed = 40
\ No newline at end of file
+cool_fan_speed = 40
diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg
index 8a0a01fb0b..a2e8a334f7 100644
--- a/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg
+++ b/resources/quality/vertex_delta_k8800/k8800_TPU_Extreme_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Extreme
definition = vertex_delta_k8800
[metadata]
+setting_version = 4
type = quality
quality_type = extreme
-material = Vertex_Delta_TPU
weight = 2
-setting_version = 4
+material = Vertex_Delta_TPU
[values]
layer_height = 0.05
@@ -19,4 +19,4 @@ material_initial_print_temperature = 220
material_print_temperature = 220
retraction_amount = 3
material_standby_temperature = 195
-cool_fan_speed = 20
\ No newline at end of file
+cool_fan_speed = 20
diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg
index 7e23947f39..4598332ba6 100644
--- a/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg
+++ b/resources/quality/vertex_delta_k8800/k8800_TPU_High_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = High
definition = vertex_delta_k8800
[metadata]
+setting_version = 4
type = quality
quality_type = high
-material = Vertex_Delta_TPU
weight = 1
-setting_version = 4
+material = Vertex_Delta_TPU
[values]
layer_height = 0.1
@@ -19,4 +19,4 @@ material_initial_print_temperature = 220
material_print_temperature = 220
retraction_amount = 3
material_standby_temperature = 195
-cool_fan_speed = 20
\ No newline at end of file
+cool_fan_speed = 20
diff --git a/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg b/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg
index 5fb46e1ea6..7a8a964b1c 100644
--- a/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg
+++ b/resources/quality/vertex_delta_k8800/k8800_TPU_Normal_Quality.inst.cfg
@@ -1,14 +1,14 @@
[general]
-version = 2
+version = 3
name = Normal
definition = vertex_delta_k8800
[metadata]
+setting_version = 4
type = quality
quality_type = normal
-material = Vertex_Delta_TPU
weight = 0
-setting_version = 4
+material = Vertex_Delta_TPU
[values]
layer_height = 0.2
diff --git a/resources/themes/cura-light/fonts/LICENSE.txt b/resources/themes/cura-light/fonts/LICENSE.txt
deleted file mode 100644
index d645695673..0000000000
--- a/resources/themes/cura-light/fonts/LICENSE.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/resources/themes/cura-light/fonts/OpenSans-Bold.ttf b/resources/themes/cura-light/fonts/OpenSans-Bold.ttf
deleted file mode 100644
index fd79d43bea..0000000000
Binary files a/resources/themes/cura-light/fonts/OpenSans-Bold.ttf and /dev/null differ
diff --git a/resources/themes/cura-light/fonts/OpenSans-BoldItalic.ttf b/resources/themes/cura-light/fonts/OpenSans-BoldItalic.ttf
deleted file mode 100644
index 9bc800958a..0000000000
Binary files a/resources/themes/cura-light/fonts/OpenSans-BoldItalic.ttf and /dev/null differ
diff --git a/resources/themes/cura-light/fonts/OpenSans-Italic.ttf b/resources/themes/cura-light/fonts/OpenSans-Italic.ttf
deleted file mode 100644
index c90da48ff3..0000000000
Binary files a/resources/themes/cura-light/fonts/OpenSans-Italic.ttf and /dev/null differ
diff --git a/resources/themes/cura-light/fonts/OpenSans-Light.ttf b/resources/themes/cura-light/fonts/OpenSans-Light.ttf
deleted file mode 100644
index 0d381897da..0000000000
Binary files a/resources/themes/cura-light/fonts/OpenSans-Light.ttf and /dev/null differ
diff --git a/resources/themes/cura-light/fonts/OpenSans-LightItalic.ttf b/resources/themes/cura-light/fonts/OpenSans-LightItalic.ttf
deleted file mode 100644
index 68299c4bc6..0000000000
Binary files a/resources/themes/cura-light/fonts/OpenSans-LightItalic.ttf and /dev/null differ
diff --git a/resources/themes/cura-light/fonts/OpenSans-Regular.ttf b/resources/themes/cura-light/fonts/OpenSans-Regular.ttf
deleted file mode 100644
index db433349b7..0000000000
Binary files a/resources/themes/cura-light/fonts/OpenSans-Regular.ttf and /dev/null differ
diff --git a/resources/themes/cura-light/fonts/OpenSans-Semibold.ttf b/resources/themes/cura-light/fonts/OpenSans-Semibold.ttf
deleted file mode 100644
index 1a7679e394..0000000000
Binary files a/resources/themes/cura-light/fonts/OpenSans-Semibold.ttf and /dev/null differ
diff --git a/resources/themes/cura-light/fonts/OpenSans-SemiboldItalic.ttf b/resources/themes/cura-light/fonts/OpenSans-SemiboldItalic.ttf
deleted file mode 100644
index 59b6d16b06..0000000000
Binary files a/resources/themes/cura-light/fonts/OpenSans-SemiboldItalic.ttf and /dev/null differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/LICENSE_OFL.txt b/resources/themes/cura-light/fonts/noto-sans-display/LICENSE_OFL.txt
new file mode 100644
index 0000000000..d952d62c06
--- /dev/null
+++ b/resources/themes/cura-light/fonts/noto-sans-display/LICENSE_OFL.txt
@@ -0,0 +1,92 @@
+This Font Software is licensed under the SIL Open Font License,
+Version 1.1.
+
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font
+creation efforts of academic and linguistic communities, and to
+provide a free and open framework in which fonts may be shared and
+improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply to
+any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software
+components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to,
+deleting, or substituting -- in part or in whole -- any of the
+components of the Original Version, by changing formats or by porting
+the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed,
+modify, redistribute, and sell modified and unmodified copies of the
+Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in
+Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the
+corresponding Copyright Holder. This restriction only applies to the
+primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created using
+the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-100-thin-italic.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-100-thin-italic.ttf
new file mode 100644
index 0000000000..498240f65f
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-100-thin-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-100-thin.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-100-thin.ttf
new file mode 100644
index 0000000000..4607b9ae49
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-100-thin.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-200-extra-light-italic.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-200-extra-light-italic.ttf
new file mode 100644
index 0000000000..f5adf19193
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-200-extra-light-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-200-extra-light.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-200-extra-light.ttf
new file mode 100644
index 0000000000..3417180964
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-200-extra-light.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-300-light-italic.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-300-light-italic.ttf
new file mode 100644
index 0000000000..1e93062cec
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-300-light-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-300-light.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-300-light.ttf
new file mode 100644
index 0000000000..368b0498f7
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-300-light.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-400-regular-italic.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-400-regular-italic.ttf
new file mode 100644
index 0000000000..9cbdab9187
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-400-regular-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-400-regular.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-400-regular.ttf
new file mode 100644
index 0000000000..b695c97b10
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-400-regular.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-500-medium-italic.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-500-medium-italic.ttf
new file mode 100644
index 0000000000..76fa05fc08
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-500-medium-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-500-medium.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-500-medium.ttf
new file mode 100644
index 0000000000..9e62d58b83
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-500-medium.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-600-semi-bold-italic.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-600-semi-bold-italic.ttf
new file mode 100644
index 0000000000..458dfa9e76
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-600-semi-bold-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-600-semi-bold.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-600-semi-bold.ttf
new file mode 100644
index 0000000000..39c27e2ab0
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-600-semi-bold.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-700-bold-italic.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-700-bold-italic.ttf
new file mode 100644
index 0000000000..7089e08be1
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-700-bold-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-700-bold.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-700-bold.ttf
new file mode 100644
index 0000000000..47f0728946
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-700-bold.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-800-extra-bold-italic.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-800-extra-bold-italic.ttf
new file mode 100644
index 0000000000..148c2f80ad
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-800-extra-bold-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-800-extra-bold.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-800-extra-bold.ttf
new file mode 100644
index 0000000000..973938bfe8
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-800-extra-bold.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-900-black-italic.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-900-black-italic.ttf
new file mode 100644
index 0000000000..409757d744
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-900-black-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-900-black.ttf b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-900-black.ttf
new file mode 100644
index 0000000000..333efd9a55
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans-display/noto-sans-display-900-black.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/LICENSE_OFL.txt b/resources/themes/cura-light/fonts/noto-sans/LICENSE_OFL.txt
new file mode 100644
index 0000000000..d952d62c06
--- /dev/null
+++ b/resources/themes/cura-light/fonts/noto-sans/LICENSE_OFL.txt
@@ -0,0 +1,92 @@
+This Font Software is licensed under the SIL Open Font License,
+Version 1.1.
+
+This license is copied below, and is also available with a FAQ at:
+http://scripts.sil.org/OFL
+
+-----------------------------------------------------------
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font
+creation efforts of academic and linguistic communities, and to
+provide a free and open framework in which fonts may be shared and
+improved in partnership with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply to
+any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software
+components as distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to,
+deleting, or substituting -- in part or in whole -- any of the
+components of the Original Version, by changing formats or by porting
+the Font Software to a new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed,
+modify, redistribute, and sell modified and unmodified copies of the
+Font Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components, in
+Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the
+corresponding Copyright Holder. This restriction only applies to the
+primary font name as presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created using
+the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-100-thin-italic.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-100-thin-italic.ttf
new file mode 100644
index 0000000000..f0bf0da52f
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-100-thin-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-100-thin.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-100-thin.ttf
new file mode 100644
index 0000000000..6f8b4eb58e
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-100-thin.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-200-extra-light-italic.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-200-extra-light-italic.ttf
new file mode 100644
index 0000000000..3751b82180
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-200-extra-light-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-200-extra-light.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-200-extra-light.ttf
new file mode 100644
index 0000000000..bfa4d4a9c9
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-200-extra-light.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-300-light-italic.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-300-light-italic.ttf
new file mode 100644
index 0000000000..4c338dba3c
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-300-light-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-300-light.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-300-light.ttf
new file mode 100644
index 0000000000..404ed0787c
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-300-light.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-400-regular-italic.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-400-regular-italic.ttf
new file mode 100644
index 0000000000..6d2c71c864
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-400-regular-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-400-regular.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-400-regular.ttf
new file mode 100644
index 0000000000..0a01a062f0
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-400-regular.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-500-medium-italic.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-500-medium-italic.ttf
new file mode 100644
index 0000000000..3641525eac
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-500-medium-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-500-medium.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-500-medium.ttf
new file mode 100644
index 0000000000..5dbefd3727
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-500-medium.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-600-semi-bold-italic.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-600-semi-bold-italic.ttf
new file mode 100644
index 0000000000..a7e904c38e
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-600-semi-bold-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-600-semi-bold.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-600-semi-bold.ttf
new file mode 100644
index 0000000000..8b7fd13026
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-600-semi-bold.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-700-bold-italic.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-700-bold-italic.ttf
new file mode 100644
index 0000000000..385e6acb77
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-700-bold-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-700-bold.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-700-bold.ttf
new file mode 100644
index 0000000000..1db7886e94
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-700-bold.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-800-extra-bold-italic.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-800-extra-bold-italic.ttf
new file mode 100644
index 0000000000..cb17fee1ae
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-800-extra-bold-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-800-extra-bold.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-800-extra-bold.ttf
new file mode 100644
index 0000000000..d181ffa9e1
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-800-extra-bold.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-900-black-italic.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-900-black-italic.ttf
new file mode 100644
index 0000000000..1cf0fca658
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-900-black-italic.ttf differ
diff --git a/resources/themes/cura-light/fonts/noto-sans/noto-sans-900-black.ttf b/resources/themes/cura-light/fonts/noto-sans/noto-sans-900-black.ttf
new file mode 100644
index 0000000000..aa9e05fc9d
Binary files /dev/null and b/resources/themes/cura-light/fonts/noto-sans/noto-sans-900-black.ttf differ
diff --git a/resources/themes/cura-light/styles.qml b/resources/themes/cura-light/styles.qml
index 20f858c238..6b454b7cf1 100755
--- a/resources/themes/cura-light/styles.qml
+++ b/resources/themes/cura-light/styles.qml
@@ -121,13 +121,13 @@ QtObject {
Item
{
anchors.centerIn: parent
- width: textLabel.width + icon.width + Theme.getSize("default_margin").width / 2
+ width: Math.round(textLabel.width + icon.width + Theme.getSize("default_margin").width / 2)
Label
{
id: textLabel
text: control.text
anchors.right: icon.visible ? icon.left : parent.right
- anchors.rightMargin: icon.visible ? Theme.getSize("default_margin").width / 2 : 0
+ anchors.rightMargin: icon.visible ? Math.round(Theme.getSize("default_margin").width / 2) : 0
anchors.verticalCenter: parent.verticalCenter;
font: control.checked ? UM.Theme.getFont("large") : UM.Theme.getFont("large_nonbold")
color:
@@ -268,7 +268,7 @@ QtObject {
anchors.leftMargin: Theme.getSize("button_tooltip_arrow").width * 2
anchors.verticalCenter: parent.verticalCenter
- target: Qt.point(parent.x, y + height/2)
+ target: Qt.point(parent.x, y + Math.round(height/2))
arrowSize: Theme.getSize("button_tooltip_arrow").width
color: Theme.getColor("button_tooltip")
opacity: control.hovered ? 1.0 : 0.0;
@@ -329,9 +329,9 @@ QtObject {
UM.RecolorImage {
id: tool_button_arrow
anchors.right: parent.right;
- anchors.rightMargin: (Theme.getSize("button").width - Theme.getSize("button_icon").width) / 4
+ anchors.rightMargin: Theme.getSize("button").width - Math.round(Theme.getSize("button_icon").width / 4)
anchors.bottom: parent.bottom;
- anchors.bottomMargin: (Theme.getSize("button").height - Theme.getSize("button_icon").height) / 4
+ anchors.bottomMargin: Theme.getSize("button").height - Math.round(Theme.getSize("button_icon").height / 4)
width: Theme.getSize("standard_arrow").width
height: Theme.getSize("standard_arrow").height
sourceSize.width: width
@@ -669,7 +669,7 @@ QtObject {
id: category_arrow
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
- anchors.rightMargin: Theme.getSize("default_margin").width * 3 - width / 2
+ anchors.rightMargin: Theme.getSize("default_margin").width * 3 - Math.round(width / 2)
width: Theme.getSize("standard_arrow").width
height: Theme.getSize("standard_arrow").height
sourceSize.width: width
@@ -712,14 +712,14 @@ QtObject {
scrollBarBackground: Rectangle {
implicitWidth: Theme.getSize("scrollbar").width
- radius: implicitWidth / 2
+ radius: Math.round(implicitWidth / 2)
color: Theme.getColor("scrollbar_background");
}
handle: Rectangle {
id: scrollViewHandle
implicitWidth: Theme.getSize("scrollbar").width;
- radius: implicitWidth / 2
+ radius: Math.round(implicitWidth / 2)
color: styleData.pressed ? Theme.getColor("scrollbar_handle_down") : styleData.hovered ? Theme.getColor("scrollbar_handle_hover") : Theme.getColor("scrollbar_handle");
Behavior on color { ColorAnimation { duration: 50; } }
@@ -806,12 +806,12 @@ QtObject {
Rectangle {
id: swatch
- height: UM.Theme.getSize("setting_control").height / 2
+ height: Math.round(UM.Theme.getSize("setting_control").height / 2)
width: height
anchors.right: downArrow.left
anchors.verticalCenter: parent.verticalCenter
- anchors.margins: UM.Theme.getSize("default_margin").width / 4
- radius: width / 2
+ anchors.margins: Math.round(UM.Theme.getSize("default_margin").width / 4)
+ radius: Math.round(width / 2)
border.width: UM.Theme.getSize("default_lining").width
border.color: UM.Theme.getColor("lining")
color: (control.color_override !== "") ? control.color_override : control.color
@@ -845,7 +845,7 @@ QtObject {
color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : Theme.getColor("checkbox");
Behavior on color { ColorAnimation { duration: 50; } }
- radius: control.exclusiveGroup ? Theme.getSize("checkbox").width / 2 : 0
+ radius: control.exclusiveGroup ? Math.round(Theme.getSize("checkbox").width / 2) : 0
border.width: Theme.getSize("default_lining").width;
border.color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_border_hover") : Theme.getColor("checkbox_border");
@@ -853,8 +853,8 @@ QtObject {
UM.RecolorImage {
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
- width: parent.width / 2.5
- height: parent.height / 2.5
+ width: Math.round(parent.width / 2.5)
+ height: Math.round(parent.height / 2.5)
sourceSize.width: width
sourceSize.height: width
color: Theme.getColor("checkbox_mark")
@@ -882,7 +882,7 @@ QtObject {
color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_hover") : Theme.getColor("checkbox");
Behavior on color { ColorAnimation { duration: 50; } }
- radius: control.exclusiveGroup ? Theme.getSize("checkbox").width / 2 : 0
+ radius: control.exclusiveGroup ? Math.round(Theme.getSize("checkbox").width / 2) : 0
border.width: Theme.getSize("default_lining").width;
border.color: (control.hovered || control._hovered) ? Theme.getColor("checkbox_border_hover") : Theme.getColor("checkbox_border");
@@ -890,8 +890,8 @@ QtObject {
UM.RecolorImage {
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
- width: parent.width / 2.5
- height: parent.height / 2.5
+ width: Math.round(parent.width / 2.5)
+ height: Math.round(parent.height / 2.5)
sourceSize.width: width
sourceSize.height: width
color: Theme.getColor("checkbox_mark")
@@ -925,7 +925,7 @@ QtObject {
border.width: Theme.getSize("default_lining").width;
border.color: Theme.getColor("slider_groove_border");
- radius: width / 2;
+ radius: Math.round(width / 2);
Rectangle {
anchors {
@@ -934,8 +934,8 @@ QtObject {
bottom: parent.bottom;
}
color: Theme.getColor("slider_groove_fill");
- width: (control.value / (control.maximumValue - control.minimumValue)) * parent.width;
- radius: width / 2;
+ width: Math.round((control.value / (control.maximumValue - control.minimumValue)) * parent.width);
+ radius: Math.round(width / 2);
}
}
handle: Rectangle {
@@ -944,7 +944,7 @@ QtObject {
color: control.hovered ? Theme.getColor("slider_handle_hover") : Theme.getColor("slider_handle");
border.width: Theme.getSize("default_lining").width
border.color: control.hovered ? Theme.getColor("slider_handle_hover_border") : Theme.getColor("slider_handle_border")
- radius: Theme.getSize("slider_handle").width / 2; //Round.
+ radius: Math.round(Theme.getSize("slider_handle").width / 2); //Round.
Behavior on color { ColorAnimation { duration: 50; } }
}
}
diff --git a/resources/themes/cura-light/theme.json b/resources/themes/cura-light/theme.json
index 51c96a5f82..8c8e6d1c47 100644
--- a/resources/themes/cura-light/theme.json
+++ b/resources/themes/cura-light/theme.json
@@ -5,50 +5,55 @@
"fonts": {
"large": {
- "size": 1.25,
- "bold": true,
- "family": "Open Sans"
+ "size": 1.35,
+ "weight": 63,
+ "family": "Noto Sans"
},
"large_nonbold": {
- "size": 1.25,
- "family": "Open Sans"
+ "size": 1.35,
+ "weight": 50,
+ "family": "Noto Sans"
},
"default": {
- "size": 1.15,
- "family": "Open Sans"
+ "size": 1.0,
+ "weight": 50,
+ "family": "Noto Sans"
},
"default_bold": {
- "size": 1.15,
- "bold": true,
- "family": "Open Sans"
+ "size": 1.0,
+ "weight": 63,
+ "family": "Noto Sans"
},
"default_italic": {
"size": 1.15,
+ "weight": 50,
"italic": true,
- "family": "Open Sans"
+ "family": "Noto Sans"
},
"small": {
"size": 1.0,
- "bold": true,
- "family": "Open Sans"
+ "weight": 63,
+ "family": "Noto Sans"
},
"very_small": {
"size": 1.0,
- "family": "Open Sans"
+ "weight": 50,
+ "family": "Noto Sans"
},
"button_tooltip": {
"size": 1.0,
- "family": "Open Sans"
+ "weight": 50,
+ "family": "Noto Sans"
},
"setting_category": {
"size": 1.15,
- "bold": true,
- "family": "Open Sans"
+ "weight": 63,
+ "family": "Noto Sans"
},
"action_button": {
"size": 1.15,
- "bold": true,
- "family": "Open Sans"
+ "weight": 50,
+ "family": "Noto Sans"
}
},
diff --git a/resources/variants/cartesio_0.25.inst.cfg b/resources/variants/cartesio_0.25.inst.cfg
index 0cc01093f2..a3fbe67606 100644
--- a/resources/variants/cartesio_0.25.inst.cfg
+++ b/resources/variants/cartesio_0.25.inst.cfg
@@ -1,12 +1,12 @@
[general]
name = 0.25 mm
-version = 2
+version = 3
definition = cartesio
[metadata]
author = Cartesio
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/cartesio_0.4.inst.cfg b/resources/variants/cartesio_0.4.inst.cfg
index 9920e699f5..d5fbc4dc26 100644
--- a/resources/variants/cartesio_0.4.inst.cfg
+++ b/resources/variants/cartesio_0.4.inst.cfg
@@ -1,12 +1,12 @@
[general]
name = 0.4 mm
-version = 2
+version = 3
definition = cartesio
[metadata]
author = Cartesio
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/cartesio_0.8.inst.cfg b/resources/variants/cartesio_0.8.inst.cfg
index 8031a9fa31..a309c47424 100644
--- a/resources/variants/cartesio_0.8.inst.cfg
+++ b/resources/variants/cartesio_0.8.inst.cfg
@@ -1,12 +1,12 @@
[general]
name = 0.8 mm
-version = 2
+version = 3
definition = cartesio
[metadata]
author = Cartesio
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/fabtotum_hyb35.inst.cfg b/resources/variants/fabtotum_hyb35.inst.cfg
index e8fa13cc0d..d96189e88e 100644
--- a/resources/variants/fabtotum_hyb35.inst.cfg
+++ b/resources/variants/fabtotum_hyb35.inst.cfg
@@ -1,12 +1,12 @@
[general]
name = Hybrid 0.35 mm
-version = 2
+version = 3
definition = fabtotum
[metadata]
author = FABtotum
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/fabtotum_lite04.inst.cfg b/resources/variants/fabtotum_lite04.inst.cfg
index 7264abbdda..0309b81733 100644
--- a/resources/variants/fabtotum_lite04.inst.cfg
+++ b/resources/variants/fabtotum_lite04.inst.cfg
@@ -1,12 +1,12 @@
[general]
name = Lite 0.4 mm
-version = 2
+version = 3
definition = fabtotum
[metadata]
author = FABtotum
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/fabtotum_lite06.inst.cfg b/resources/variants/fabtotum_lite06.inst.cfg
index 0ad33ca332..c92e621bd2 100644
--- a/resources/variants/fabtotum_lite06.inst.cfg
+++ b/resources/variants/fabtotum_lite06.inst.cfg
@@ -1,12 +1,12 @@
[general]
name = Lite 0.6 mm
-version = 2
+version = 3
definition = fabtotum
[metadata]
author = FABtotum
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/fabtotum_pro02.inst.cfg b/resources/variants/fabtotum_pro02.inst.cfg
index d83618b712..29d245a24a 100644
--- a/resources/variants/fabtotum_pro02.inst.cfg
+++ b/resources/variants/fabtotum_pro02.inst.cfg
@@ -1,12 +1,12 @@
[general]
name = Pro 0.2 mm
-version = 2
+version = 3
definition = fabtotum
[metadata]
author = FABtotum
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/fabtotum_pro04.inst.cfg b/resources/variants/fabtotum_pro04.inst.cfg
index 4f2a622887..42be71b89d 100644
--- a/resources/variants/fabtotum_pro04.inst.cfg
+++ b/resources/variants/fabtotum_pro04.inst.cfg
@@ -1,12 +1,12 @@
[general]
name = Pro 0.4 mm
-version = 2
+version = 3
definition = fabtotum
[metadata]
author = FABtotum
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/fabtotum_pro06.inst.cfg b/resources/variants/fabtotum_pro06.inst.cfg
index aa44e762ba..9c17d83f47 100644
--- a/resources/variants/fabtotum_pro06.inst.cfg
+++ b/resources/variants/fabtotum_pro06.inst.cfg
@@ -1,12 +1,12 @@
[general]
name = Pro 0.6 mm
-version = 2
+version = 3
definition = fabtotum
[metadata]
author = FABtotum
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/fabtotum_pro08.inst.cfg b/resources/variants/fabtotum_pro08.inst.cfg
index 597d23275e..2fc5507024 100644
--- a/resources/variants/fabtotum_pro08.inst.cfg
+++ b/resources/variants/fabtotum_pro08.inst.cfg
@@ -1,12 +1,12 @@
[general]
name = Pro 0.8 mm
-version = 2
+version = 3
definition = fabtotum
[metadata]
author = FABtotum
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/gmax15plus_025_e3d.inst.cfg b/resources/variants/gmax15plus_025_e3d.inst.cfg
index 0500a63638..53e6a14b23 100644
--- a/resources/variants/gmax15plus_025_e3d.inst.cfg
+++ b/resources/variants/gmax15plus_025_e3d.inst.cfg
@@ -1,12 +1,13 @@
[general]
name = 0.25mm E3D (Difficult)
-version = 2
+version = 3
definition = gmax15plus
[metadata]
author = gcreate
-type = variant
setting_version = 4
+type = variant
+hardware_type = nozzle
[values]
machine_nozzle_size = 0.25
diff --git a/resources/variants/gmax15plus_04_e3d.inst.cfg b/resources/variants/gmax15plus_04_e3d.inst.cfg
index 514893a8a5..a0b0d58b92 100644
--- a/resources/variants/gmax15plus_04_e3d.inst.cfg
+++ b/resources/variants/gmax15plus_04_e3d.inst.cfg
@@ -1,12 +1,13 @@
[general]
name = 0.4mm E3D
-version = 2
+version = 3
definition = gmax15plus
[metadata]
author = gcreate
-type = variant
setting_version = 4
+type = variant
+hardware_type = nozzle
[values]
machine_nozzle_size = 0.4
diff --git a/resources/variants/gmax15plus_05_e3d.inst.cfg b/resources/variants/gmax15plus_05_e3d.inst.cfg
index 2579409d5a..333ab55f81 100644
--- a/resources/variants/gmax15plus_05_e3d.inst.cfg
+++ b/resources/variants/gmax15plus_05_e3d.inst.cfg
@@ -1,12 +1,13 @@
[general]
name = 0.5mm E3D (Default)
-version = 2
+version = 3
definition = gmax15plus
[metadata]
author = gcreate
-type = variant
setting_version = 4
+type = variant
+hardware_type = nozzle
[values]
machine_nozzle_size = 0.5
diff --git a/resources/variants/gmax15plus_05_jhead.inst.cfg b/resources/variants/gmax15plus_05_jhead.inst.cfg
index ca107c9559..51902ffa0c 100644
--- a/resources/variants/gmax15plus_05_jhead.inst.cfg
+++ b/resources/variants/gmax15plus_05_jhead.inst.cfg
@@ -1,12 +1,13 @@
[general]
name = 0.5mm J-Head
-version = 2
+version = 3
definition = gmax15plus
[metadata]
author = gcreate
-type = variant
setting_version = 4
+type = variant
+hardware_type = nozzle
[values]
machine_nozzle_size = 0.5
diff --git a/resources/variants/gmax15plus_06_e3d.inst.cfg b/resources/variants/gmax15plus_06_e3d.inst.cfg
index eb709f1487..3452e5e81f 100644
--- a/resources/variants/gmax15plus_06_e3d.inst.cfg
+++ b/resources/variants/gmax15plus_06_e3d.inst.cfg
@@ -1,12 +1,13 @@
[general]
name = 0.6mm E3D
-version = 2
+version = 3
definition = gmax15plus
[metadata]
author = gcreate
-type = variant
setting_version = 4
+type = variant
+hardware_type = nozzle
[values]
machine_nozzle_size = 0.6
diff --git a/resources/variants/gmax15plus_08_e3d.inst.cfg b/resources/variants/gmax15plus_08_e3d.inst.cfg
index 093bce99c0..cdee755efc 100644
--- a/resources/variants/gmax15plus_08_e3d.inst.cfg
+++ b/resources/variants/gmax15plus_08_e3d.inst.cfg
@@ -1,12 +1,13 @@
[general]
name = 0.8mm E3D
-version = 2
+version = 3
definition = gmax15plus
[metadata]
author = gcreate
-type = variant
setting_version = 4
+type = variant
+hardware_type = nozzle
[values]
machine_nozzle_size = 0.8
diff --git a/resources/variants/gmax15plus_10_jhead.inst.cfg b/resources/variants/gmax15plus_10_jhead.inst.cfg
index 977469e304..ee60c71cc2 100644
--- a/resources/variants/gmax15plus_10_jhead.inst.cfg
+++ b/resources/variants/gmax15plus_10_jhead.inst.cfg
@@ -1,12 +1,13 @@
[general]
name = 1.0mm J-Head
-version = 2
+version = 3
definition = gmax15plus
[metadata]
author = gcreate
-type = variant
setting_version = 4
+type = variant
+hardware_type = nozzle
[values]
machine_nozzle_size = 0.5
diff --git a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg
index b083174beb..002af1a0c5 100644
--- a/resources/variants/gmax15plus_dual_025_e3d.inst.cfg
+++ b/resources/variants/gmax15plus_dual_025_e3d.inst.cfg
@@ -1,12 +1,13 @@
[general]
name = 0.25mm E3D (Difficult)
-version = 2
+version = 3
definition = gmax15plus_dual
[metadata]
author = gcreate
-type = variant
setting_version = 4
+type = variant
+hardware_type = nozzle
[values]
machine_nozzle_size = 0.25
diff --git a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg
index f1a95f4f2a..a98637e9e1 100644
--- a/resources/variants/gmax15plus_dual_04_e3d.inst.cfg
+++ b/resources/variants/gmax15plus_dual_04_e3d.inst.cfg
@@ -1,12 +1,13 @@
[general]
name = 0.4mm E3D
-version = 2
+version = 3
definition = gmax15plus_dual
[metadata]
author = gcreate
-type = variant
setting_version = 4
+type = variant
+hardware_type = nozzle
[values]
machine_nozzle_size = 0.4
diff --git a/resources/variants/gmax15plus_dual_05_e3d.inst.cfg b/resources/variants/gmax15plus_dual_05_e3d.inst.cfg
index dd148f8082..dc7d711043 100644
--- a/resources/variants/gmax15plus_dual_05_e3d.inst.cfg
+++ b/resources/variants/gmax15plus_dual_05_e3d.inst.cfg
@@ -1,12 +1,13 @@
[general]
name = 0.5mm E3D (Default)
-version = 2
+version = 3
definition = gmax15plus_dual
[metadata]
author = gcreate
-type = variant
setting_version = 4
+type = variant
+hardware_type = nozzle
[values]
machine_nozzle_size = 0.5
diff --git a/resources/variants/gmax15plus_dual_05_jhead.inst.cfg b/resources/variants/gmax15plus_dual_05_jhead.inst.cfg
index 7e038a3980..fc4f17d057 100644
--- a/resources/variants/gmax15plus_dual_05_jhead.inst.cfg
+++ b/resources/variants/gmax15plus_dual_05_jhead.inst.cfg
@@ -1,12 +1,13 @@
[general]
name = 0.5mm J-Head
-version = 2
+version = 3
definition = gmax15plus_dual
[metadata]
author = gcreate
-type = variant
setting_version = 4
+type = variant
+hardware_type = nozzle
[values]
machine_nozzle_size = 0.5
diff --git a/resources/variants/gmax15plus_dual_06_e3d.inst.cfg b/resources/variants/gmax15plus_dual_06_e3d.inst.cfg
index 93cf21780f..506f2df06e 100644
--- a/resources/variants/gmax15plus_dual_06_e3d.inst.cfg
+++ b/resources/variants/gmax15plus_dual_06_e3d.inst.cfg
@@ -1,12 +1,13 @@
[general]
name = 0.6mm E3D
-version = 2
+version = 3
definition = gmax15plus_dual
[metadata]
author = gcreate
-type = variant
setting_version = 4
+type = variant
+hardware_type = nozzle
[values]
machine_nozzle_size = 0.6
diff --git a/resources/variants/gmax15plus_dual_08_e3d.inst.cfg b/resources/variants/gmax15plus_dual_08_e3d.inst.cfg
index 3088113f27..d008df70f6 100644
--- a/resources/variants/gmax15plus_dual_08_e3d.inst.cfg
+++ b/resources/variants/gmax15plus_dual_08_e3d.inst.cfg
@@ -1,12 +1,13 @@
[general]
name = 0.8mm E3D
-version = 2
+version = 3
definition = gmax15plus_dual
[metadata]
author = gcreate
-type = variant
setting_version = 4
+type = variant
+hardware_type = nozzle
[values]
machine_nozzle_size = 0.8
diff --git a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg
index a526cc676e..825810997e 100644
--- a/resources/variants/gmax15plus_dual_10_jhead.inst.cfg
+++ b/resources/variants/gmax15plus_dual_10_jhead.inst.cfg
@@ -1,12 +1,13 @@
[general]
name = 1.0mm J-Head
-version = 2
+version = 3
definition = gmax15plus_dual
[metadata]
author = gcreate
-type = variant
setting_version = 4
+type = variant
+hardware_type = nozzle
[values]
machine_nozzle_size = 0.5
diff --git a/resources/variants/imade3d_jellybox_0.4.inst.cfg b/resources/variants/imade3d_jellybox_0.4.inst.cfg
index c37a2ecabf..99b55866c7 100644
--- a/resources/variants/imade3d_jellybox_0.4.inst.cfg
+++ b/resources/variants/imade3d_jellybox_0.4.inst.cfg
@@ -1,12 +1,12 @@
[general]
name = 0.4 mm
-version = 2
+version = 3
definition = imade3d_jellybox
[metadata]
author = IMADE3D
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
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 c3e63aab34..890c394a36 100644
--- a/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg
+++ b/resources/variants/imade3d_jellybox_0.4_2-fans.inst.cfg
@@ -1,12 +1,12 @@
[general]
name = 0.4 mm 2-fans
-version = 2
+version = 3
definition = imade3d_jellybox
[metadata]
author = IMADE3D
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker2_0.25.inst.cfg b/resources/variants/ultimaker2_0.25.inst.cfg
index aee83e2483..c4d778e5cf 100644
--- a/resources/variants/ultimaker2_0.25.inst.cfg
+++ b/resources/variants/ultimaker2_0.25.inst.cfg
@@ -1,15 +1,14 @@
[general]
name = 0.25 mm
-version = 2
+version = 3
definition = ultimaker2
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
machine_nozzle_size = 0.25
machine_nozzle_tip_outer_diameter = 0.8
-raft_airgap = 0.25
\ No newline at end of file
+raft_airgap = 0.25
diff --git a/resources/variants/ultimaker2_0.4.inst.cfg b/resources/variants/ultimaker2_0.4.inst.cfg
index fe128137d9..2ce766a1ac 100644
--- a/resources/variants/ultimaker2_0.4.inst.cfg
+++ b/resources/variants/ultimaker2_0.4.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = 0.4 mm
-version = 2
+version = 3
definition = ultimaker2
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker2_0.6.inst.cfg b/resources/variants/ultimaker2_0.6.inst.cfg
index 7fea2fbb22..0c5bdca240 100644
--- a/resources/variants/ultimaker2_0.6.inst.cfg
+++ b/resources/variants/ultimaker2_0.6.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = 0.6 mm
-version = 2
+version = 3
definition = ultimaker2
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker2_0.8.inst.cfg b/resources/variants/ultimaker2_0.8.inst.cfg
index 5f1176b7ec..fd11520eca 100644
--- a/resources/variants/ultimaker2_0.8.inst.cfg
+++ b/resources/variants/ultimaker2_0.8.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = 0.8 mm
-version = 2
+version = 3
definition = ultimaker2
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker2_extended_0.25.inst.cfg b/resources/variants/ultimaker2_extended_0.25.inst.cfg
index e705327cf8..b8a31641e3 100644
--- a/resources/variants/ultimaker2_extended_0.25.inst.cfg
+++ b/resources/variants/ultimaker2_extended_0.25.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = 0.25 mm
-version = 2
+version = 3
definition = ultimaker2_extended
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker2_extended_0.4.inst.cfg b/resources/variants/ultimaker2_extended_0.4.inst.cfg
index d486ed4f4e..dbceac2890 100644
--- a/resources/variants/ultimaker2_extended_0.4.inst.cfg
+++ b/resources/variants/ultimaker2_extended_0.4.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = 0.4 mm
-version = 2
+version = 3
definition = ultimaker2_extended
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker2_extended_0.6.inst.cfg b/resources/variants/ultimaker2_extended_0.6.inst.cfg
index f9dd4d4e69..6fbb489160 100644
--- a/resources/variants/ultimaker2_extended_0.6.inst.cfg
+++ b/resources/variants/ultimaker2_extended_0.6.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = 0.6 mm
-version = 2
+version = 3
definition = ultimaker2_extended
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker2_extended_0.8.inst.cfg b/resources/variants/ultimaker2_extended_0.8.inst.cfg
index ee56b6d194..94b38de8f2 100644
--- a/resources/variants/ultimaker2_extended_0.8.inst.cfg
+++ b/resources/variants/ultimaker2_extended_0.8.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = 0.8 mm
-version = 2
+version = 3
definition = ultimaker2_extended
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg
index f23406fec3..89916470bb 100644
--- a/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg
+++ b/resources/variants/ultimaker2_extended_plus_0.25.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = 0.25 mm
-version = 2
+version = 3
definition = ultimaker2_extended_plus
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg
index c0b1c6ab79..0de416da11 100644
--- a/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg
+++ b/resources/variants/ultimaker2_extended_plus_0.4.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = 0.4 mm
-version = 2
+version = 3
definition = ultimaker2_extended_plus
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg
index 6ef64bed5f..4e6ace5a59 100644
--- a/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg
+++ b/resources/variants/ultimaker2_extended_plus_0.6.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = 0.6 mm
-version = 2
+version = 3
definition = ultimaker2_extended_plus
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg
index 2f890d0827..7540d5783a 100644
--- a/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg
+++ b/resources/variants/ultimaker2_extended_plus_0.8.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = 0.8 mm
-version = 2
+version = 3
definition = ultimaker2_extended_plus
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker2_plus_0.25.inst.cfg b/resources/variants/ultimaker2_plus_0.25.inst.cfg
index 1c4688568d..d59476a4f7 100644
--- a/resources/variants/ultimaker2_plus_0.25.inst.cfg
+++ b/resources/variants/ultimaker2_plus_0.25.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = 0.25 mm
-version = 2
+version = 3
definition = ultimaker2_plus
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker2_plus_0.4.inst.cfg b/resources/variants/ultimaker2_plus_0.4.inst.cfg
index 00a4ef47dd..a188d10d4a 100644
--- a/resources/variants/ultimaker2_plus_0.4.inst.cfg
+++ b/resources/variants/ultimaker2_plus_0.4.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = 0.4 mm
-version = 2
+version = 3
definition = ultimaker2_plus
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker2_plus_0.6.inst.cfg b/resources/variants/ultimaker2_plus_0.6.inst.cfg
index 4dceab70d0..b3aad334c3 100644
--- a/resources/variants/ultimaker2_plus_0.6.inst.cfg
+++ b/resources/variants/ultimaker2_plus_0.6.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = 0.6 mm
-version = 2
+version = 3
definition = ultimaker2_plus
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker2_plus_0.8.inst.cfg b/resources/variants/ultimaker2_plus_0.8.inst.cfg
index e1bbddb823..3c5dec79f6 100644
--- a/resources/variants/ultimaker2_plus_0.8.inst.cfg
+++ b/resources/variants/ultimaker2_plus_0.8.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = 0.8 mm
-version = 2
+version = 3
definition = ultimaker2_plus
[metadata]
-author = Ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker3_aa0.25.inst.cfg b/resources/variants/ultimaker3_aa0.25.inst.cfg
index 2d2d893202..447bf0e49c 100644
--- a/resources/variants/ultimaker3_aa0.25.inst.cfg
+++ b/resources/variants/ultimaker3_aa0.25.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = AA 0.25
-version = 2
+version = 3
definition = ultimaker3
[metadata]
-author = ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker3_aa0.8.inst.cfg b/resources/variants/ultimaker3_aa0.8.inst.cfg
index 402190c357..9f011b9164 100644
--- a/resources/variants/ultimaker3_aa0.8.inst.cfg
+++ b/resources/variants/ultimaker3_aa0.8.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = AA 0.8
-version = 2
+version = 3
definition = ultimaker3
[metadata]
-author = ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker3_aa04.inst.cfg b/resources/variants/ultimaker3_aa04.inst.cfg
index b9e15f5296..0e0187e4df 100644
--- a/resources/variants/ultimaker3_aa04.inst.cfg
+++ b/resources/variants/ultimaker3_aa04.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = AA 0.4
-version = 2
+version = 3
definition = ultimaker3
[metadata]
-author = ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
@@ -41,4 +40,3 @@ switch_extruder_prime_speed = =switch_extruder_retraction_speeds
switch_extruder_retraction_amount = =machine_heat_zone_length
top_bottom_thickness = 1.2
wall_thickness = 1.3
-
diff --git a/resources/variants/ultimaker3_bb0.8.inst.cfg b/resources/variants/ultimaker3_bb0.8.inst.cfg
index 017da649a0..41c6419ec1 100644
--- a/resources/variants/ultimaker3_bb0.8.inst.cfg
+++ b/resources/variants/ultimaker3_bb0.8.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = BB 0.8
-version = 2
+version = 3
definition = ultimaker3
[metadata]
-author = ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker3_bb04.inst.cfg b/resources/variants/ultimaker3_bb04.inst.cfg
index f3cb236c2b..91e70f9f98 100644
--- a/resources/variants/ultimaker3_bb04.inst.cfg
+++ b/resources/variants/ultimaker3_bb04.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = BB 0.4
-version = 2
+version = 3
definition = ultimaker3
[metadata]
-author = ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
@@ -48,4 +47,4 @@ support_line_width = =round(line_width * 0.4 / 0.35, 2)
support_offset = 3
support_xy_distance = =round(wall_line_width_0 * 0.75, 2)
support_xy_distance_overhang = =wall_line_width_0 / 2
-switch_extruder_retraction_amount = 12
\ No newline at end of file
+switch_extruder_retraction_amount = 12
diff --git a/resources/variants/ultimaker3_extended_aa0.25.inst.cfg b/resources/variants/ultimaker3_extended_aa0.25.inst.cfg
index 04d7a7990a..b06ec0830b 100644
--- a/resources/variants/ultimaker3_extended_aa0.25.inst.cfg
+++ b/resources/variants/ultimaker3_extended_aa0.25.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = AA 0.25
-version = 2
+version = 3
definition = ultimaker3_extended
[metadata]
-author = ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
@@ -38,4 +37,3 @@ support_z_distance = =layer_height * 2
top_bottom_thickness = 1.2
wall_line_width_x = 0.23
wall_thickness = 1.3
-
diff --git a/resources/variants/ultimaker3_extended_aa0.8.inst.cfg b/resources/variants/ultimaker3_extended_aa0.8.inst.cfg
index 3e1b3ed3de..2dfd64a94b 100644
--- a/resources/variants/ultimaker3_extended_aa0.8.inst.cfg
+++ b/resources/variants/ultimaker3_extended_aa0.8.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = AA 0.8
-version = 2
+version = 3
definition = ultimaker3_extended
[metadata]
-author = ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker3_extended_aa04.inst.cfg b/resources/variants/ultimaker3_extended_aa04.inst.cfg
index 8863088a8d..8a2f061224 100644
--- a/resources/variants/ultimaker3_extended_aa04.inst.cfg
+++ b/resources/variants/ultimaker3_extended_aa04.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = AA 0.4
-version = 2
+version = 3
definition = ultimaker3_extended
[metadata]
-author = ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg
index e1086535ec..42d7d85728 100644
--- a/resources/variants/ultimaker3_extended_bb0.8.inst.cfg
+++ b/resources/variants/ultimaker3_extended_bb0.8.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = BB 0.8
-version = 2
+version = 3
definition = ultimaker3_extended
[metadata]
-author = ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
diff --git a/resources/variants/ultimaker3_extended_bb04.inst.cfg b/resources/variants/ultimaker3_extended_bb04.inst.cfg
index b5b35e85ac..5b35351312 100644
--- a/resources/variants/ultimaker3_extended_bb04.inst.cfg
+++ b/resources/variants/ultimaker3_extended_bb04.inst.cfg
@@ -1,12 +1,11 @@
[general]
name = BB 0.4
-version = 2
+version = 3
definition = ultimaker3_extended
[metadata]
-author = ultimaker
-type = variant
setting_version = 4
+type = variant
hardware_type = nozzle
[values]
@@ -48,4 +47,4 @@ support_line_width = =round(line_width * 0.4 / 0.35, 2)
support_offset = 3
support_xy_distance = =round(wall_line_width_0 * 0.75, 2)
support_xy_distance_overhang = =wall_line_width_0 / 2
-switch_extruder_retraction_amount = 12
\ No newline at end of file
+switch_extruder_retraction_amount = 12
diff --git a/run_in_docker.sh b/run_in_docker.sh
new file mode 100644
index 0000000000..eb364fd887
--- /dev/null
+++ b/run_in_docker.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+Xvfb :1 -screen 0 1280x800x16 &
+export DISPLAY=:1.0
+python3 cura_app.py --headless
\ No newline at end of file
diff --git a/setup.py b/setup.py
index a91ba535d5..0d78f44ddc 100644
--- a/setup.py
+++ b/setup.py
@@ -51,24 +51,24 @@ setup(name="Cura",
#console=[{"script": "cura_app.py"}],
options={"py2exe": {"skip_archive": False, "includes": includes}})
-print("Coping Cura plugins.")
+print("Copying Cura plugins.")
shutil.copytree(os.path.dirname(UM.__file__) + "/../plugins", "dist/plugins", ignore = shutil.ignore_patterns("ConsoleLogger", "OBJWriter", "MLPWriter", "MLPReader"))
for path in os.listdir("plugins"):
copytree("plugins/" + path, "dist/plugins/" + path)
-print("Coping resources.")
+print("Copying resources.")
copytree(os.path.dirname(UM.__file__) + "/../resources", "dist/resources")
copytree("resources", "dist/resources")
-print("Coping Uranium QML.")
+print("Copying Uranium QML.")
shutil.copytree(os.path.dirname(UM.__file__) + "/Qt/qml/UM", "dist/qml/UM")
for site_package in site.getsitepackages():
qt_origin_path = os.path.join(site_package, "PyQt5")
if os.path.isdir(qt_origin_path):
- print("Coping PyQt5 plugins from: %s" % qt_origin_path)
+ print("Copying PyQt5 plugins from: %s" % qt_origin_path)
shutil.copytree(os.path.join(qt_origin_path, "plugins"), "dist/PyQt5/plugins")
- print("Coping PyQt5 QtQuick from: %s" % qt_origin_path)
+ print("Copying PyQt5 QtQuick from: %s" % qt_origin_path)
shutil.copytree(os.path.join(qt_origin_path, "qml/QtQuick"), "dist/qml/QtQuick")
shutil.copytree(os.path.join(qt_origin_path, "qml/QtQuick.2"), "dist/qml/QtQuick.2")
- print("Coping PyQt5 svg library from: %s" % qt_origin_path)
+ print("Copying PyQt5 svg library from: %s" % qt_origin_path)
shutil.copy(os.path.join(qt_origin_path, "Qt5Svg.dll"), "dist/Qt5Svg.dll")
print("Copying Angle libraries from %s" % qt_origin_path)
shutil.copy(os.path.join(qt_origin_path, "libEGL.dll"), "dist/libEGL.dll")
diff --git a/tests/Settings/TestExtruderStack.py b/tests/Settings/TestExtruderStack.py
index e1538cd3fc..ce829da4b3 100644
--- a/tests/Settings/TestExtruderStack.py
+++ b/tests/Settings/TestExtruderStack.py
@@ -325,30 +325,6 @@ def test_removeContainer(extruder_stack):
with pytest.raises(InvalidOperationError):
extruder_stack.removeContainer(unittest.mock.MagicMock())
-## Tests setting definitions by specifying an ID of a definition that exists.
-def test_setDefinitionByIdExists(extruder_stack, container_registry):
- container_registry.return_value = DefinitionContainer(container_id = "some_definition")
- extruder_stack.setDefinitionById("some_definition")
- assert extruder_stack.definition.getId() == "some_definition"
-
-## Tests setting definitions by specifying an ID of a definition that doesn't
-# exist.
-def test_setDefinitionByIdDoesntExist(extruder_stack):
- with pytest.raises(InvalidContainerError):
- extruder_stack.setDefinitionById("some_definition") #Container registry is empty now.
-
-## Tests setting materials by specifying an ID of a material that exists.
-def test_setMaterialByIdExists(extruder_stack, container_registry):
- container_registry.return_value = getInstanceContainer(container_type = "material")
- extruder_stack.setMaterialById("InstanceContainer")
- assert extruder_stack.material.getId() == "InstanceContainer"
-
-## Tests setting materials by specifying an ID of a material that doesn't
-# exist.
-def test_setMaterialByIdDoesntExist(extruder_stack):
- with pytest.raises(InvalidContainerError):
- extruder_stack.setMaterialById("some_material") #Container registry is empty now.
-
## Tests setting properties directly on the extruder stack.
@pytest.mark.parametrize("key, property, value", [
("layer_height", "value", 0.1337),
@@ -387,38 +363,3 @@ def test_setPropertyOtherContainers(target_container, stack_variable, extruder_s
extruder_stack.setProperty(key, property, value, target_container = target_container) #The actual test.
getattr(extruder_stack, stack_variable).setProperty.assert_called_once_with(key, property, value) #Make sure that the proper container gets a setProperty call.
-
-## Tests setting qualities by specifying an ID of a quality that exists.
-def test_setQualityByIdExists(extruder_stack, container_registry):
- container_registry.return_value = getInstanceContainer(container_type = "quality")
- extruder_stack.setQualityById("InstanceContainer")
- assert extruder_stack.quality.getId() == "InstanceContainer"
-
-## Tests setting qualities by specifying an ID of a quality that doesn't exist.
-def test_setQualityByIdDoesntExist(extruder_stack):
- with pytest.raises(InvalidContainerError):
- extruder_stack.setQualityById("some_quality") #Container registry is empty now.
-
-## Tests setting quality changes by specifying an ID of a quality change that
-# exists.
-def test_setQualityChangesByIdExists(extruder_stack, container_registry):
- container_registry.return_value = getInstanceContainer(container_type = "quality_changes")
- extruder_stack.setQualityChangesById("InstanceContainer")
- assert extruder_stack.qualityChanges.getId() == "InstanceContainer"
-
-## Tests setting quality changes by specifying an ID of a quality change that
-# doesn't exist.
-def test_setQualityChangesByIdDoesntExist(extruder_stack):
- with pytest.raises(InvalidContainerError):
- extruder_stack.setQualityChangesById("some_quality_changes") #Container registry is empty now.
-
-## Tests setting variants by specifying an ID of a variant that exists.
-def test_setVariantByIdExists(extruder_stack, container_registry):
- container_registry.return_value = getInstanceContainer(container_type = "variant")
- extruder_stack.setVariantById("InstanceContainer")
- assert extruder_stack.variant.getId() == "InstanceContainer"
-
-## Tests setting variants by specifying an ID of a variant that doesn't exist.
-def test_setVariantByIdDoesntExist(extruder_stack):
- with pytest.raises(InvalidContainerError):
- extruder_stack.setVariantById("some_variant") #Container registry is empty now.
diff --git a/tests/Settings/TestGlobalStack.py b/tests/Settings/TestGlobalStack.py
index 9b0735c8f2..6bf10dd8c1 100755
--- a/tests/Settings/TestGlobalStack.py
+++ b/tests/Settings/TestGlobalStack.py
@@ -116,31 +116,6 @@ def test_addExtruder(global_stack):
# global_stack.addExtruder(unittest.mock.MagicMock())
assert len(global_stack.extruders) == 2 #Didn't add the faulty extruder.
-## Tests getting the approximate material diameter.
-@pytest.mark.parametrize("diameter, approximate_diameter", [
- #Some real-life cases that are common in printers.
- (2.85, 3),
- (1.75, 2),
- (3.0, 3),
- (2.0, 2),
- #Exceptional cases.
- (0, 0),
- (-10.1, -10),
- (-1, -1),
- (9000.1, 9000)
-])
-def test_approximateMaterialDiameter(diameter, approximate_diameter, global_stack):
- global_stack.definition = DefinitionContainer(container_id = "TestDefinition")
- material_diameter = UM.Settings.SettingDefinition.SettingDefinition(key = "material_diameter", container = global_stack.definition)
- material_diameter.addSupportedProperty("value", UM.Settings.SettingDefinition.DefinitionPropertyType.Any, default = diameter)
- global_stack.definition.definitions.append(material_diameter)
- assert float(global_stack.approximateMaterialDiameter) == approximate_diameter
-
-## Tests getting the material diameter when there is no material diameter.
-def test_approximateMaterialDiameterNoDiameter(global_stack):
- global_stack.definition = DefinitionContainer(container_id = "TestDefinition")
- assert global_stack.approximateMaterialDiameter == "-1"
-
#Tests setting user changes profiles to invalid containers.
@pytest.mark.parametrize("container", [
getInstanceContainer(container_type = "wrong container type"),
@@ -486,43 +461,6 @@ def test_removeContainer(global_stack):
with pytest.raises(InvalidOperationError):
global_stack.removeContainer(unittest.mock.MagicMock())
-## Tests setting definitions by specifying an ID of a definition that exists.
-def test_setDefinitionByIdExists(global_stack, container_registry):
- container_registry.return_value = DefinitionContainer(container_id = "some_definition")
- global_stack.setDefinitionById("some_definition")
- assert global_stack.definition.getId() == "some_definition"
-
-## Tests setting definitions by specifying an ID of a definition that doesn't
-# exist.
-def test_setDefinitionByIdDoesntExist(global_stack):
- with pytest.raises(InvalidContainerError):
- global_stack.setDefinitionById("some_definition") #Container registry is empty now.
-
-## Tests setting definition changes by specifying an ID of a container that
-# exists.
-def test_setDefinitionChangesByIdExists(global_stack, container_registry):
- container_registry.return_value = getInstanceContainer(container_type = "definition_changes")
- global_stack.setDefinitionChangesById("InstanceContainer")
- assert global_stack.definitionChanges.getId() == "InstanceContainer"
-
-## Tests setting definition changes by specifying an ID of a container that
-# doesn't exist.
-def test_setDefinitionChangesByIdDoesntExist(global_stack):
- with pytest.raises(InvalidContainerError):
- global_stack.setDefinitionChangesById("some_definition_changes") #Container registry is empty now.
-
-## Tests setting materials by specifying an ID of a material that exists.
-def test_setMaterialByIdExists(global_stack, container_registry):
- container_registry.return_value = getInstanceContainer(container_type = "material")
- global_stack.setMaterialById("InstanceContainer")
- assert global_stack.material.getId() == "InstanceContainer"
-
-## Tests setting materials by specifying an ID of a material that doesn't
-# exist.
-def test_setMaterialByIdDoesntExist(global_stack):
- with pytest.raises(InvalidContainerError):
- global_stack.setMaterialById("some_material") #Container registry is empty now.
-
## Tests whether changing the next stack is properly forbidden.
def test_setNextStack(global_stack):
with pytest.raises(InvalidOperationError):
@@ -567,50 +505,3 @@ def test_setPropertyOtherContainers(target_container, stack_variable, global_sta
global_stack.setProperty(key, property, value, target_container = target_container) #The actual test.
getattr(global_stack, stack_variable).setProperty.assert_called_once_with(key, property, value) #Make sure that the proper container gets a setProperty call.
-
-## Tests setting qualities by specifying an ID of a quality that exists.
-def test_setQualityByIdExists(global_stack, container_registry):
- container_registry.return_value = getInstanceContainer(container_type = "quality")
- global_stack.setQualityById("InstanceContainer")
- assert global_stack.quality.getId() == "InstanceContainer"
-
-## Tests setting qualities by specifying an ID of a quality that doesn't exist.
-def test_setQualityByIdDoesntExist(global_stack):
- with pytest.raises(InvalidContainerError):
- global_stack.setQualityById("some_quality") #Container registry is empty now.
-
-## Tests setting quality changes by specifying an ID of a quality change that
-# exists.
-def test_setQualityChangesByIdExists(global_stack, container_registry):
- container_registry.return_value = getInstanceContainer(container_type = "quality_changes")
- global_stack.setQualityChangesById("InstanceContainer")
- assert global_stack.qualityChanges.getId() == "InstanceContainer"
-
-## Tests setting quality changes by specifying an ID of a quality change that
-# doesn't exist.
-def test_setQualityChangesByIdDoesntExist(global_stack):
- with pytest.raises(InvalidContainerError):
- global_stack.setQualityChangesById("some_quality_changes") #Container registry is empty now.
-
-## Tests setting variants by specifying an ID of a variant that exists.
-def test_setVariantByIdExists(global_stack, container_registry):
- container_registry.return_value = getInstanceContainer(container_type = "variant")
- global_stack.setVariantById("InstanceContainer")
- assert global_stack.variant.getId() == "InstanceContainer"
-
-## Tests setting variants by specifying an ID of a variant that doesn't exist.
-def test_setVariantByIdDoesntExist(global_stack):
- with pytest.raises(InvalidContainerError):
- global_stack.setVariantById("some_variant") #Container registry is empty now.
-
-## Smoke test for findDefaultVariant
-def test_smoke_findDefaultVariant(global_stack):
- global_stack.findDefaultVariant()
-
-## Smoke test for findDefaultMaterial
-def test_smoke_findDefaultMaterial(global_stack):
- global_stack.findDefaultMaterial()
-
-## Smoke test for findDefaultQuality
-def test_smoke_findDefaultQuality(global_stack):
- global_stack.findDefaultQuality()