diff --git a/cura/API/Account.py b/cura/API/Account.py
index 4391f730e5..9864de1aaa 100644
--- a/cura/API/Account.py
+++ b/cura/API/Account.py
@@ -29,10 +29,12 @@ class Account(QObject):
# Signal emitted when user logged in or out.
loginStateChanged = pyqtSignal(bool)
accessTokenChanged = pyqtSignal()
+ cloudPrintersDetectedChanged = pyqtSignal(bool)
def __init__(self, application: "CuraApplication", parent = None) -> None:
super().__init__(parent)
self._application = application
+ self._new_cloud_printers_detected = False
self._error_message = None # type: Optional[Message]
self._logged_in = False
@@ -74,6 +76,10 @@ class Account(QObject):
def isLoggedIn(self) -> bool:
return self._logged_in
+ @pyqtProperty(bool, notify=cloudPrintersDetectedChanged)
+ def newCloudPrintersDetected(self) -> bool:
+ return self._new_cloud_printers_detected
+
def _onLoginStateChanged(self, logged_in: bool = False, error_message: Optional[str] = None) -> None:
if error_message:
if self._error_message:
diff --git a/cura/ApplicationMetadata.py b/cura/ApplicationMetadata.py
index c16051d187..ee4eab597f 100644
--- a/cura/ApplicationMetadata.py
+++ b/cura/ApplicationMetadata.py
@@ -13,7 +13,7 @@ DEFAULT_CURA_DEBUG_MODE = False
# Each release has a fixed SDK version coupled with it. It doesn't make sense to make it configurable because, for
# example Cura 3.2 with SDK version 6.1 will not work. So the SDK version is hard-coded here and left out of the
# CuraVersion.py.in template.
-CuraSDKVersion = "7.1.0"
+CuraSDKVersion = "7.2.0"
try:
from cura.CuraVersion import CuraAppName # type: ignore
diff --git a/cura/Arranging/Arrange.py b/cura/Arranging/Arrange.py
index a70ccb9f0c..35f155f4cf 100644
--- a/cura/Arranging/Arrange.py
+++ b/cura/Arranging/Arrange.py
@@ -196,6 +196,7 @@ class Arrange:
start_idx = 0
else:
start_idx = 0
+ priority = 0
for priority in self._priority_unique_values[start_idx::step]:
tryout_idx = numpy.where(self._priority == priority)
for idx in range(len(tryout_idx[0])):
diff --git a/cura/Machines/MachineNode.py b/cura/Machines/MachineNode.py
index 0974c3dca7..6a415b01c4 100644
--- a/cura/Machines/MachineNode.py
+++ b/cura/Machines/MachineNode.py
@@ -171,6 +171,10 @@ class MachineNode(ContainerNode):
if variant_name not in self.variants:
self.variants[variant_name] = VariantNode(variant["id"], machine = self)
self.variants[variant_name].materialsChanged.connect(self.materialsChanged)
+ else:
+ # Force reloading the materials if the variant already exists or else materals won't be loaded
+ # when the G-Code flavor changes --> CURA-7354
+ self.variants[variant_name]._loadAll()
if not self.variants:
self.variants["empty"] = VariantNode("empty_variant", machine = self)
diff --git a/cura/PreviewPass.py b/cura/PreviewPass.py
index da60db2d99..5e3982e1f3 100644
--- a/cura/PreviewPass.py
+++ b/cura/PreviewPass.py
@@ -61,6 +61,7 @@ class PreviewPass(RenderPass):
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._shader.setUniformValue("u_renderError", 0.0) # We don't want any error markers!.
self._shader.setUniformValue("u_faceId", -1) # Don't render any selected faces in the preview.
if not self._non_printing_shader:
diff --git a/cura/Settings/ContainerManager.py b/cura/Settings/ContainerManager.py
index 9514f80e34..4d972ba87e 100644
--- a/cura/Settings/ContainerManager.py
+++ b/cura/Settings/ContainerManager.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2019 Ultimaker B.V.
+# Copyright (c) 2020 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import os
@@ -206,8 +206,11 @@ class ContainerManager(QObject):
if contents is None:
return {"status": "error", "message": "Serialization returned None. Unable to write to file"}
- with SaveFile(file_url, "w") as f:
- f.write(contents)
+ try:
+ with SaveFile(file_url, "w") as f:
+ f.write(contents)
+ except OSError:
+ return {"status": "error", "message": "Unable to write to this location.", "path": file_url}
return {"status": "success", "message": "Successfully exported container", "path": file_url}
diff --git a/cura/Settings/SettingOverrideDecorator.py b/cura/Settings/SettingOverrideDecorator.py
index 2fa5234ec3..03b4c181dd 100644
--- a/cura/Settings/SettingOverrideDecorator.py
+++ b/cura/Settings/SettingOverrideDecorator.py
@@ -94,6 +94,12 @@ class SettingOverrideDecorator(SceneNodeDecorator):
#
# \return An extruder's position, or None if no position info is available.
def getActiveExtruderPosition(self):
+ # for support_meshes, always use the support_extruder
+ if self.getStack().getProperty("support_mesh", "value"):
+ global_container_stack = Application.getInstance().getGlobalContainerStack()
+ if global_container_stack:
+ return str(global_container_stack.getProperty("support_extruder_nr", "value"))
+
containers = ContainerRegistry.getInstance().findContainers(id = self.getActiveExtruder())
if containers:
container_stack = containers[0]
diff --git a/cura/UI/ObjectsModel.py b/cura/UI/ObjectsModel.py
index 6378ebcd1b..659732e895 100644
--- a/cura/UI/ObjectsModel.py
+++ b/cura/UI/ObjectsModel.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2019 Ultimaker B.V.
+# Copyright (c) 2020 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from UM.Logger import Logger
import re
@@ -38,6 +38,9 @@ class ObjectsModel(ListModel):
OutsideAreaRole = Qt.UserRole + 3
BuilplateNumberRole = Qt.UserRole + 4
NodeRole = Qt.UserRole + 5
+ PerObjectSettingsCountRole = Qt.UserRole + 6
+ MeshTypeRole = Qt.UserRole + 7
+ ExtruderNumberRole = Qt.UserRole + 8
def __init__(self, parent = None) -> None:
super().__init__(parent)
@@ -46,6 +49,9 @@ class ObjectsModel(ListModel):
self.addRoleName(self.SelectedRole, "selected")
self.addRoleName(self.OutsideAreaRole, "outside_build_area")
self.addRoleName(self.BuilplateNumberRole, "buildplate_number")
+ self.addRoleName(self.ExtruderNumberRole, "extruder_number")
+ self.addRoleName(self.PerObjectSettingsCountRole, "per_object_settings_count")
+ self.addRoleName(self.MeshTypeRole, "mesh_type")
self.addRoleName(self.NodeRole, "node")
Application.getInstance().getController().getScene().sceneChanged.connect(self._updateSceneDelayed)
@@ -172,11 +178,47 @@ class ObjectsModel(ListModel):
node_build_plate_number = node.callDecoration("getBuildPlateNumber")
+ node_mesh_type = ""
+ per_object_settings_count = 0
+
+ per_object_stack = node.callDecoration("getStack")
+ if per_object_stack:
+ per_object_settings_count = per_object_stack.getTop().getNumInstances()
+
+ for mesh_type in ["anti_overhang_mesh", "infill_mesh", "cutting_mesh", "support_mesh"]:
+ if per_object_stack.getProperty(mesh_type, "value"):
+ node_mesh_type = mesh_type
+ per_object_settings_count -= 1 # do not count this mesh type setting
+ break
+
+ if per_object_settings_count > 0:
+ if node_mesh_type == "support_mesh":
+ # support meshes only allow support settings
+ per_object_settings_count = 0
+ for key in per_object_stack.getTop().getAllKeys():
+ if per_object_stack.getTop().getInstance(key).definition.isAncestor("support"):
+ per_object_settings_count += 1
+ elif node_mesh_type == "anti_overhang_mesh":
+ # anti overhang meshes ignore per model settings
+ per_object_settings_count = 0
+
+ extruder_position = node.callDecoration("getActiveExtruderPosition")
+ if extruder_position is None:
+ extruder_number = -1
+ else:
+ extruder_number = int(extruder_position)
+ if node_mesh_type == "anti_overhang_mesh" or node.callDecoration("isGroup"):
+ # for anti overhang meshes and groups the extruder nr is irrelevant
+ extruder_number = -1
+
nodes.append({
"name": node.getName(),
"selected": Selection.isSelected(node),
"outside_build_area": is_outside_build_area,
"buildplate_number": node_build_plate_number,
+ "extruder_number": extruder_number,
+ "per_object_settings_count": per_object_settings_count,
+ "mesh_type": node_mesh_type,
"node": node
})
diff --git a/cura/UI/WelcomePagesModel.py b/cura/UI/WelcomePagesModel.py
index c16ec3763e..611e62cfd6 100644
--- a/cura/UI/WelcomePagesModel.py
+++ b/cura/UI/WelcomePagesModel.py
@@ -243,6 +243,10 @@ class WelcomePagesModel(ListModel):
{"id": "data_collections",
"page_url": self._getBuiltinWelcomePagePath("DataCollectionsContent.qml"),
},
+ {"id": "cloud",
+ "page_url": self._getBuiltinWelcomePagePath("CloudContent.qml"),
+ "should_show_function": self.shouldShowCloudPage,
+ },
{"id": "add_network_or_local_printer",
"page_url": self._getBuiltinWelcomePagePath("AddNetworkOrLocalPrinterContent.qml"),
"next_page_id": "machine_actions",
@@ -253,12 +257,8 @@ class WelcomePagesModel(ListModel):
},
{"id": "machine_actions",
"page_url": self._getBuiltinWelcomePagePath("FirstStartMachineActionsContent.qml"),
- "next_page_id": "cloud",
"should_show_function": self.shouldShowMachineActions,
},
- {"id": "cloud",
- "page_url": self._getBuiltinWelcomePagePath("CloudContent.qml"),
- },
]
pages_to_show = all_pages_list
@@ -287,6 +287,17 @@ class WelcomePagesModel(ListModel):
first_start_actions = self._application.getMachineActionManager().getFirstStartActions(definition_id)
return len([action for action in first_start_actions if action.needsUserInteraction()]) > 0
+ def shouldShowCloudPage(self) -> bool:
+ """
+ The cloud page should be shown only if the user is not logged in
+
+ :return: True if the user is not logged in, False if he/she is
+ """
+ # Import CuraApplication locally or else it fails
+ from cura.CuraApplication import CuraApplication
+ api = CuraApplication.getInstance().getCuraAPI()
+ return not api.account.isLoggedIn
+
def addPage(self) -> None:
pass
diff --git a/docs/Cura_Data_Model.odg b/docs/Cura_Data_Model.odg
deleted file mode 100644
index b4a6dd548b..0000000000
Binary files a/docs/Cura_Data_Model.odg and /dev/null differ
diff --git a/docs/Profile Stack.drawio b/docs/Profile Stack.drawio
deleted file mode 100644
index ed942c09db..0000000000
--- a/docs/Profile Stack.drawio
+++ /dev/null
@@ -1 +0,0 @@
-7ZtNb9s4EIZ/jY+70LftY+NkuwskQFrvts2pYCRaIkqLBkXXcn79Di3Ssk3ZTR195EDAB82IpIZ8ZgzxBTXyZ8vyI0er7IElmI48JylH/u3I89zA80by5yTbyjOOxpUj5SRRjWrHnLxg5XSUd00SXBw1FIxRQVbHzpjlOY7FkQ9xzjbHzRaMHj91hVJsOOYxoqb3K0lEVnkn3rj2/41Jmuknu9G0urNEurGaSZGhhG0OXP7dyJ9xxkR1tSxnmMrF0+tS9fvrzN19YBzn4jUdvnDvJQzwv+sXOp0/lfHk+3fxh1+N8hPRtZrwXSn4OsF8LlD8Q0Uutno5ig1ZUpSDdbNguZirOw7YcUZoco+2bC3DKWR3bd1kjJMXaI8o3HLBAbe5ULS9SI5GKJ0xyjg4crZ7QN2piqV6DMcFdHvU03ZPXA+oPGp4jwqhA2SUolVBnnchy45LxFOS3zAh2FI1UuuBucDl2YV29/gg7zFbYsG30ER3mCriKuXdsbI3dQK5gfJlB8nj+YFKXJW06X7smitcKLS/gTkwMP9XYG7QhTmLHRzOfuATGg2AECVpDibFC9lNLhqByvmg3IKt5GArFJM8vd+1uQ1qz2c1celi0HdBd9WRkSTBueTHBBLoeZ9fK0ZysVuY8AZ+sH4z589wFELgM7Dd2oafbM7FjOUwF0R23DBkwgbLbHgd5PP1YpJXpCGTXwc66ohzaHD+tAZKQsY4y1Cewl+phd4u9NAbGHpkQP8nF3JGlnS7pMeTgUmPz5e3Rd0qatcJBmY9MVg/IIE5gVcoC7tl2P5rX9C6gj01YH9BgNr+h7fPOhz6HU3vbA9g3+IFyYkgLLfvad2Rnwz9oua6F8lb3u1uxpyhX9c8k/dHyp61nmG1lbdrK4GWEw8g+06v2opWOK248tZ6Psf+vLrSjLqzejbVUiuvdI69QV/pGbupnlqBpRvWDQpLz6wvKKgWdruwmzSWnmmb0qkVWTrD3aCy9Izb1E+tzNIV7QadpWfapoJqdZZe0DcILT2jN/VUK7R0uDFrUFr6Be6ae3B7juWtWosfvrtzLK65A7day1UlXVXM+z3J4pqbbqu1dI598LMsrrn/tlpLN6wHP83imrtvq7V0BHv48yyuufm2WktnuAc/0eKau2+rtXRFe/gzLZc33PaFrTP0gx9q0Z+3WK2ln43Z4KdafBO4gRnnyQf58RVYMUVFQWKpg4illk1gCfj2m1x2WE9lPikKO+O2PLK22iqJOOgG1pMeEa7rTtLQfargcGJ853Wig8AE2JrH+NLUq3YC8RRfo5cdMAsbkGkfxxQJ8vM43iaO6gmPMm9H58/I6BLVQ1TzVL3qbDAG8oLjgaLpyUDVQhgDAXq0PWim6upswF50ErDvXIzLDy62h4sqgjrH9wzekPbmYa7fT/sr0lcaj/CaDPFjflgUV5RPi6Wgc+qd10LknaTK+MpaiMa/KKqWaiE4DbjfWgCz/iK1al5/1+vf/Q8=
\ No newline at end of file
diff --git a/docs/Profile Stack.png b/docs/Profile Stack.png
deleted file mode 100644
index 0bcc9266b3..0000000000
Binary files a/docs/Profile Stack.png and /dev/null differ
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000000..0165e3d741
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,21 @@
+Cura Documentation
+====
+Welcome to the Cura documentation pages.
+
+Objective
+----
+The goal of this documentation is to give an overview of the architecture of Cura's source code. The purpose of this overview is to make programmers familiar with Cura's source code so that they may contribute more easily, write plug-ins more easily or get started within the Cura team more quickly.
+
+There are some caveats though. These are *not* within the scope of this documentation:
+* There is no documentation on individual functions or classes of the code here. For that, refer to the Doxygen documentation and Python Docstrings in the source code itself, or generate the documentation locally using Doxygen.
+* It's virtually impossible and indeed not worth the effort or money to keep this 100% up to date.
+* There are no example plug-ins here. There are a number of example plug-ins in the Ultimaker organisation on Github.com to draw from.
+* The slicing process is not documented here. Refer to CuraEngine for that.
+
+This documentation will touch on the inner workings of Uranium as well though, due to the nature of the architecture.
+
+Index
+----
+The following chapters are available in this documentation:
+* [Repositories](repositories.md): An overview of the repositories that together make up the Cura application.
+* [Profiles](profiles/profiles.md): About the setting and profile system of Cura.
\ No newline at end of file
diff --git a/docs/profiles/container_stacks.md b/docs/profiles/container_stacks.md
new file mode 100644
index 0000000000..05fa5ba1d2
--- /dev/null
+++ b/docs/profiles/container_stacks.md
@@ -0,0 +1,33 @@
+Container Stacks
+====
+When the user selects the profiles and settings to print with, he can swap out a number of profiles. The profiles that are currently in use are stored in several container stacks. These container stacks always have a definition container at the bottom, which defines all available settings and all available properties for each setting. The profiles on top of that definition can then override the `value` property of some of those settings.
+
+When deriving a setting value, a container stack starts looking at the top-most profile to see if it contains an override for that setting. If it does, it returns that override. Otherwise, it looks into the second profile. If that also doesn't have an override for this setting, it looks into the third profile, and so on. The last profile is always a definition container which always contains an value for all settings. This way, the profiles at the top will always win over the profiles at the bottom. There is a clear precedence order for which profile wins over which other profile.
+
+A Machine Instance
+----
+A machine instance is a printer that the user has added to his configuration. It consists of multiple container stacks: One for global settings and one for each of the available extruders. This way, different extruders can contain different materials and quality profiles, for instance. The global stack contains a different set of profiles than the extruder stacks.
+
+While Uranium defines no specific roles for the entries in a container stack, Cura defines rigid roles for each slot in a container stack. These are the layouts for the container stacks of an example printer with 2 extruders.
+
+
+
+To expand on this a bit further, each extruder stack contains the following profiles:
+* A user profile, where extruder-specific setting changes are stored that are not (yet) saved to a custom profile. If the user changes a setting that can be adjusted per extruder (such as infill density) then it gets stored here. If the user adjusts a setting that is global it will immediately be stored in the user profile of the global stack.
+* A custom profile. If the user saves his setting changes to a custom profile, it gets moved from the user profile to here. Actually a "custom profile" as the user sees it consists of multiple profiles: one for each extruder and one for the global settings.
+* An intent profile. The user can select between several intents for his print, such as precision, strength, visual quality, etc. This may be empty as well, which indicates the "default" intent.
+* A quality profile. The user can select between several quality levels.
+* A material profile, where the user selects which material is loaded in this extruder.
+* A nozzle profile, where the user selects which nozzle is installed in this extruder.
+* Definition changes, which stores the changes that the user made for this extruder in the Printer Settings dialogue.
+* Extruder. The user is not able to swap this out. This is a definition that lists the extruder number for this extruder and optionally things that are fixed in the printer, such as the nozzle offset.
+
+The global container stack contains the following profiles:
+* A user profile, where global setting changes are stored that are not (yet) saved to a custom profile. If the user changes for instance the layer height, the new value for the layer height gets stored here.
+* A custom profile. If the user saves his setting changes to a custom profile, the global settings that were in the global user profile get moved here.
+* An intent profile. Currently this must ALWAYS be empty. There are no global intent profiles. This is there for historical reasons.
+* A quality profile. This contains global settings that match with the quality level that the user selected. This global quality profile cannot be specific to a material or nozzle.
+* A material profile. Currently this must ALWAYS be empty. There are no global material profiles. This is there for historical reasons.
+* A variant profile. Currently this must ALWAYS be empty. There are no global variant profiles. This is there for historical reasons.
+* Definition changes, which stores the changes that the user made to the printer in the Printer Settings dialogue.
+* Printer. This specifies the currently used printer model, such as Ultimaker 3, Ultimaker S5, etc.
\ No newline at end of file
diff --git a/docs/profiles/getting_a_setting_value.md b/docs/profiles/getting_a_setting_value.md
new file mode 100644
index 0000000000..49b8c18ed2
--- /dev/null
+++ b/docs/profiles/getting_a_setting_value.md
@@ -0,0 +1,66 @@
+Getting a Setting Value
+====
+How Cura gets a setting's value is a complex endeavour that requires some explanation. The `value` property gets special treatment for this because there are a few other properties that influence the value. In this page we explain the algorithm to getting a setting value.
+
+This page explains all possible cases for a setting, but not all of them may apply. For instance, a global setting will not evaluate the per-object settings to get its value. Exceptions to the rules for other types of settings will be written down.
+
+Per Object Settings
+----
+Per-object settings, which are added to an object using the per-object settings tool, will always prevail over other setting values. They are not evaluated with the rest of the settings system because Cura's front-end doesn't need to send all setting values for all objects to CuraEngine separately. It only sends over the per-object settings that get overridden. CuraEngine then evaluates settings that can be changed per-object using the list of settings for that object but if the object doesn't have the setting attached falls back on the settings in the object's extruder. Refer to the [CuraEngine](#CuraEngine) chapter to see how this works.
+
+Settings where the `settable_per_mesh` property is false will not be shown in Cura's interface in the list of available settings in the per-object settings panel. They cannot be adjusted per object then. CuraEngine will also not evaluate those settings for each object separately. There is (or should always be) a good reason why each of these settings are not evaluated per object: Simply because CuraEngine is not processing one particular mesh at that moment. For instance, when writing the move to change to the next layer, CuraEngine hasn't processed any of the meshes on that layer yet and so the layer change movement speed, or indeed the layer height, can't change for each object.
+
+The per-object settings are stored in a separate container stack that is particular to the object. The container stack is added to the object via a scene decorator. It has just a single container in it, which contains all of the settings that the user changed.
+
+Resolve
+----
+If the setting is not listed in the per-object settings, it needs to be evaluated from the main settings list. However before evaluating it from a particular extruder, Cura will check if the setting has the `resolve` property. If it does, it returns the output of the `resolve` property and that's everything.
+
+The `resolve` property is intended for settings which are global in nature, but still need to be influenced by extruder-specific settings. A good example is the Build Plate Temperature, which is very dependent on the material(s) used by the printer, but there can only be a single bed temperature at a time.
+
+Cura will simply evaluate the `resolve` setting if present, which is an arbitrary Python expression, and return its result as the setting's value. However typically the `resolve` property is a function that takes the values of this setting for all extruders in use and then computes a result based on those. There is a built-in function for that called `extruderValues()`, which returns a list of setting values, one for each extruder. The function can then for instance take the average of those. In the case of the build plate temperature it will take the highest of those. In the case of the adhesion type it will choose "raft" if any extruder uses a raft, or "brim" as second choice, "skirt" as third choice and "none" only if all extruders use "none". Each setting with a `resolve` property has its own way of resolving the setting. The `extruderValues()` function continues with the algorithm as written below, but repeats it for each extruder.
+
+Limit To Extruder
+----
+If a setting is evaluated from a particular extruder stack, it normally gets evaluated from the extruder that the object is assigned to. However there are some exceptions. Some groups of settings belong to a particular "extruder setting", like the Infill Extruder setting, or the Support Extruder setting. Which extruder a setting belongs to is stored in the `limit_to_extruder` property. Settings which have their `limit_to_extruder` property set to `adhesion_extruder_nr`, for instance, belong to the build plate adhesion settings.
+
+If the `limit_to_extruder` property evaluates to a positive number, instead of getting the setting from the object's extruder it will be obtained from the extruder written in the `limit_to_extruder` property. So even if an object is set to be printed with extruder 0, if the infill extruder is set to extruder 1 any infill setting will be obtained from extruder 1. If `limit_to_extruder` is negative (in particular -1, which is the default), then the setting will be obtained from the object's own extruder.
+
+This property is communicated to CuraEngine separately. CuraEngine makes sure that the setting is evaluated from the correct extruder. Refer to the [CuraEngine](#CuraEngine) chapter to see how this works.
+
+Evaluating a Stack
+----
+After the resolve and limit to extruder properties have been checked, the setting value needs to be evaluated from an extruder stack.
+
+This is explained in more detail in the [Container Stacks](container_stacks.md) documentation. In brief, Cura will check the highest container in the extruder stack first to see whether that container overrides the setting. If it does, it returns that as the setting value. Otherwise, it checks the second container on the stack to see if that one overrides it. If it does it returns that value, and otherwise it checks the third container, and so on. If a setting is not overridden by any container in the extruder stack, it continues downward in the global stack. If it is also not overridden there, it eventually arrives at the definition in the bottom of the global stack.
+
+Evaluating a Definition
+----
+If the evaluation for a setting reaches the last entry of the global stack, its definition, a few more things can happen.
+
+Definition containers have an inheritance structure. For instance, the `ultimaker3` definition container specifies in its metadata that it inherits from `ultimaker`, which in turn inherits from `fdmprinter`. So again here, when evaluating a property from the `ultimaker3` definition it will first look to see if the property is overridden by the `ultimaker3` definition itself, and otherwise refer on to the `ultimaker` definition or otherwise finally to the `fdmprinter` definition. `fdmprinter` is the last line of defence, and it contains *all* properties for *all* settings.
+
+But even in `fdmprinter`, not all settings have a `value` property. It is not a required property. If the setting doesn't have a `value` property, the `default_value` property is returned, which is a required property. The distinction between `value` and `default_value` is made in order to allow CuraEngine to load a definition file as well when running from the command line (a debugging technique for CuraEngine). It then won't have all of the correct setting values but it at least doesn't need to evaluate all of the Python expressions and you'll be able to make some debugging slices.
+
+Evaluating a Value Property
+----
+The `value` property may contain a formula, which is an arbitrary Python expression that will be executed by Cura to arrive at a setting value. All containers may set the `value` property. Instance containers can only set the `value`, while definitions can set all properties.
+
+While the value could be any sort of formula, some functions of Python are restricted for security reasons. Since Cura 4.6, profiles are no longer a "trusted" resource and are therefore subject to heavy restrictions. It can use Python's built in mathematical functions and list functions as well as a few basic other ones, but things like writing to a file are prohibited.
+
+There are also a few extra things that can be used in these expressions:
+* Any setting key can be used as a variable that contains the setting's value.
+* As explained before, `extruderValues(key)` is a function that returns a list of setting values for a particular setting for all used extruders.
+* The function `extruderValue(extruder, key)` will evaluate a particular setting for a particular extruder.
+* The function `resolveOrValue(key)` will perform the full setting evaluation as described in this document for the current context (so if this setting is being evaluated for the second extruder it would perform it as if coming from the second extruder).
+* The function `defaultExtruderPosition()` will get the first extruder that is not disabled. For instance, if a printer has three extruders but the first is disabled, this would return `1` to indicate the second extruder (0-indexed).
+* The function `valueFromContainer(key, index)` will get a setting value from the global stack, but skip the first few containers in that stack. It will skip until it reaches a particular index in the container stack.
+* The function `valueFromExtruderContainer(key, index)` will get a setting value from the current extruder stack, but skip the first few containers in that stack. It will skip until it reaches a particular index in the container stack.
+
+CuraEngine
+----
+When starting a slice, Cura will send the scene to CuraEngine and with each model send over the per-object settings that belong to it. It also sends all setting values over, as evaluated from each extruder and from the global stack, and sends the `limit_to_extruder` property along as well. CuraEngine stores this and then starts its slicing process. CuraEngine also has a hierarchical structure for its settings with fallbacks. This is explained in detail in [the documentation of CuraEngine](https://github.com/Ultimaker/CuraEngine/blob/master/docs/settings.md) and shortly again here.
+
+Each model gets a setting container assigned. The per-object settings are stored in those. The fallback for this container is set to be the extruder with which the object is printed. The extruder uses the current *mesh group* as fallback (which is a concept that Cura's front-end doesn't have). Each mesh group uses the global settings container as fallback.
+
+During the slicing process CuraEngine will evaluate the settings from its current context as it goes. For instance, when processing the walls for a particular mesh, it will request the Outer Wall Line Width setting from the settings container of that mesh. When it's not processing a particular mesh but for instance the travel moves between two meshes, it uses the currently applicable extruder. So this business logic defines actually how a setting can be configured per mesh, per extruder or only globally. The `settable_per_extruder`, and related properties of settings are only used in the front-end to determine how the settings are shown to the user.
\ No newline at end of file
diff --git a/docs/profiles/profiles.md b/docs/profiles/profiles.md
new file mode 100644
index 0000000000..544184d480
--- /dev/null
+++ b/docs/profiles/profiles.md
@@ -0,0 +1,30 @@
+Profiles
+====
+Cura's profile system is very advanced and has gotten pretty complex. This chapter is an attempt to document how it is structured.
+
+Index
+----
+The following pages describe the profile and setting system of Cura:
+* [Container Stacks](container_stacks.md): Which profiles can be swapped out and how they are ordered when evaluating a setting.
+* [Setting Properties](setting_properties.md): What properties can each setting have?
+* [Getting a Setting Value](getting_a_setting_value.md): How Cura arrives at a value for a certain setting.
+
+Glossary
+----
+The terminology for these profiles is not always obvious. Here is a glossary of the terms that we'll use in this chapter.
+* **Profile:** Either an *instance container* or a *definition container*.
+* **Definition container:** Profile that's stored as .def.json file, defining new settings and all of their properties. In Cura these represent printer models and extruder trains.
+* **Instance container:** Profile that's stored as .inst.cfg file or .xml.fdm_material file, which override some setting values. In Cura these represent the other profiles.
+* **[Container] stack:** A list of profiles, with one definition container at the bottom and instance containers for the rest. All settings are defined in the definition container. The rest of the profiles each specify a set of value overrides. The profiles at the top always override the profiles at the bottom.
+* **Machine instance:** An instance of a printer that the user has added. The list of all machine instances is shown in a drop-down in Cura's interface.
+* **Material:** A type of filament that's being sold by a vendor as a product.
+* **Filament spool:** A single spool of material.
+* **Quality profile:** A profile that is one of the options when the user selects which quality level they want to print with.
+* **Intent profile:** A profile that is one of the options when the user selects what his intent is.
+* **Custom profile:** A user-made profile that is stored when the user selects to "create a profile from the current settings/overrides".
+* **Quality-changes profile:** Alternative name for *custom profile*. This name is used in the code more often, but it's a bit misleading so this documentation prefers the term "custom profile".
+* **User profile:** A profile containing the settings that the user has changed, but not yet saved to a profile.
+* **Variant profile:** A profile containing some overrides that allow the user to select variants of the definition. As of this writing this is only used for the nozzles.
+* **Quality level:** A measure of quality where the user can select from, for instance "normal", "fast", "high". When selecting a quality level, Cura will select a matching quality profile for each extruder.
+* **Quality type:** Alternative name for *quality level*. This name is used in the code more often, but this documentation prefers the term "quality level".
+* **Inheritance function:** A function through which the `value` of a setting is calculated. This may depend on other settings.
\ No newline at end of file
diff --git a/docs/profiles/setting_properties.md b/docs/profiles/setting_properties.md
new file mode 100644
index 0000000000..84fb458c63
--- /dev/null
+++ b/docs/profiles/setting_properties.md
@@ -0,0 +1,33 @@
+Setting Properties
+====
+Each setting in Cura has a number of properties. It's not just a key and a value. This page lists the properties that a setting can define.
+
+* `key` (string): The identifier by which the setting is referenced. This is not a human-readable name, but just a reference string, such as `layer_height_0`. Typically these are named with the most significant category first, in order to sort them better, such as `material_print_temperature`. This is not actually a real property but just an identifier; it can't be changed.
+* `value` (optional): The current value of the setting. This can be a function, an arbitrary Python expression that depends on the values of other settings. If it's not present, the `default_value` is used.
+* `default_value`: A default value for the setting if `value` is undefined. This property is required however. It can't be a Python expression, but it can be any JSON type. This is made separate so that CuraEngine can read it out as well for its debugging mode via the command line, without needing a complete Python interpreter.
+* `label` (string): The human-readable name for the setting. This label is translated.
+* `description` (string): A longer description of what the setting does when you change it. This description is translated as well.
+* `type` (string): The type of value that this setting contains. Allowed types are: `bool`, `str`, `float`, `int`, `enum`, `category`, `[int]`, `vec3`, `polygon` and `polygons`.
+* `unit` (optional string): A unit that is displayed at the right-hand side of the text field where the user enters the setting value.
+* `resolve` (optional string): A Python expression that resolves disagreements for global settings if multiple per-extruder profiles define different values for a setting. Typically this takes the values for the setting from all stacks and computes one final value for it that will be used for the global setting. For instance, the `resolve` function for the build plate temperature is `max(extruderValues('material_bed_temperature')`, meaning that it will use the hottest bed temperature of all materials of the extruders in use.
+* `limit_to_extruder` (optional): A Python expression that indicates which extruder a setting will be obtained from. This is used for settings that may be extruder-specific but the extruder is not necessarily the current extruder. For instance, support settings need to be evaluated for the support extruder. Infill settings need to be evaluated for the infill extruder if the infill extruder is changed.
+* `enabled` (optional string or boolean): Whether the setting can currently be made visible for the user. This can be a simple true/false, or a Python expression that depends on other settings. Typically used for settings that don't apply when another setting is disabled, such as to hide the support settings if support is disabled.
+* `minimum_value` (optional): The lowest acceptable value for this setting. If it's any lower, Cura will not allow the user to slice. By convention this is used to prevent setting values that are technically or physically impossible, such as a layer height of 0mm. This property only applies to numerical settings.
+* `maximum_value` (optional): The highest acceptable value for this setting. If it's any higher, Cura will not allow the user to slice. By convention this is used to prevent setting values that are technically or physically impossible, such as a support overhang angle of more than 90 degrees. This property only applies to numerical settings.
+* `minimum_value_warning` (optional): The threshold under which a warning is displayed to the user. By convention this is used to indicate that it will probably not print very nicely with such a low setting value. This property only applies to numerical settings.
+* `maximum_value_warning` (optional): The threshold above which a warning is displayed to the user. By convention this is used to indicate that it will probably not print very nicely with such a high setting value. This property only applies to numerical settings.
+* `settable_globally` (optional boolean): Whether the setting can be changed globally. For some mesh-type settings such as `support_mesh` this doesn't make sense, so those can't be changed globally. They are not displayed in the main settings list then.
+* `settable_per_meshgroup` (optional boolean): Whether a setting can be changed per group of meshes. Currently unused in Cura.
+* `settable_per_extruder` (optional boolean): Whether a setting can be changed per extruder. Some settings, like the build plate temperature, can't be adjusted separately for each extruder. An icon is shown in the interface to indicate this. If the user changes these settings they are stored in the global stack.
+* `settable_per_mesh` (optional boolean): Whether a setting can be changed per mesh. The settings that can be changed per mesh are shown in the list of available settings in the per-object settings tool.
+* `children` (optional list): A list of child settings. These are displayed with an indentation. If all child settings are overridden by the user, the parent setting gets greyed out to indicate that the parent setting has no effect any more. This is not strictly always the case though, because that would depend on the inheritance functions in the `value`.
+* `icon` (optional string): A path to an icon to be displayed. Only applies to setting categories.
+* `allow_empty` (optional bool): Whether the setting is allowed to be empty. If it's not, this will be treated as a setting error and Cura will not allow the user to slice. Only applies to string-type settings.
+* `warning_description` (optional string): A warning message to display when the setting has a warning value. This is currently unused by Cura.
+* `error_description` (optional string): An error message to display when the setting has an error value. This is currently unused by Cura.
+* `options` (dictionary): A list of values that the user can choose from. The keys of this dictionary are keys that CuraEngine identifies the option with. The values are human-readable strings and will be translated. Only applies to (and only required for) enum-type settings.
+* `comments` (optional string): Comments to other programmers about the setting. This is not used by Cura.
+* `is_uuid` (optional boolean): Whether or not this setting indicates a UUID-4. If it is, the setting will indicate an error if it's not in the correct format. Only applies to string-type settings.
+* `regex_blacklist_pattern` (optional string): A regular expression, where if the setting value matches with this regular expression, it gets an error state. Only applies to string-type settings.
+* `error_value` (optional): If the setting value is equal to this value, it will show a setting error. This is used to display errors for non-numerical settings such as checkboxes.
+* `warning_value` (optional): If the setting value is equal to this value, it will show a setting warning. This is used to display warnings for non-numerical settings such as checkboxes.
\ No newline at end of file
diff --git a/docs/repositories.md b/docs/repositories.md
new file mode 100644
index 0000000000..3b4c4bc317
--- /dev/null
+++ b/docs/repositories.md
@@ -0,0 +1,21 @@
+Repositories
+====
+Cura uses a number of repositories where parts of our source code are separated, in order to get a cleaner architecture. Those repositories are:
+* [Cura](https://github.com/Ultimaker/Cura), the main repository for the front-end of Cura. This contains all of the business logic for the front-end, including the specific types of profiles that are available, the concept of 3D printers and materials, specific tools for handling 3D printed models, pretty much all of the GUI, as well as Ultimaker services such as the Marketplace and accounts.
+* The Cura repository is built on [Uranium](https://github.com/Ultimaker/Uranium), a framework for desktop applications that handle 3D models and have a separate back-end. This provides Cura with a basic GUI framework ([Qt](https://www.qt.io/)), a 3D scene, a rendering system, a plug-in system and a system for stacked profiles that change settings.
+* In order to slice, Cura starts [CuraEngine](https://github.com/Ultimaker/CuraEngine) in the background. This does the actual process that converts 3D models into a toolpath for the printer.
+* Communication to CuraEngine goes via [libArcus](https://github.com/Ultimaker/libArcus), a small library that wraps around [Protobuf](https://developers.google.com/protocol-buffers/) in order to make it run over a local socket.
+* Cura's build scripts are in [cura-build](https://github.com/Ultimaker/cura-build) and build scripts for building dependencies are in [cura-build-environment](https://github.com/Ultimaker/cura-build-environment).
+
+There are also a number of repositories under our control that are not integral parts of Cura's architecture, but more like separated side-gigs:
+* Loading and writing 3MF files is done through [libSavitar](https://github.com/Ultimaker/libSavitar).
+* Loading and writing UFP files is done through [libCharon](https://github.com/Ultimaker/libCharon).
+* To make the build system a bit simpler, some parts are pre-compiled in [cura-binary-data](https://github.com/Ultimaker/cura-binary-data). This holds things like the machine-readable translation files and the Marlin builds for firmware updates, which would require considerable tooling to build automatically.
+* There are automated GUI tests in [Cura-squish-tests](https://github.com/Ultimaker/Cura-squish-tests).
+* Material profiles are stored in [fdm_materials](https://github.com/Ultimaker/fdm_materials). This is separated out and combined in our build process, so that the firmware for Ultimaker's printers can use the same set of profiles too.
+
+Interplay
+----
+At a very high level, Cura's repositories interconnect as follows:
+
+
\ No newline at end of file
diff --git a/docs/resources/machine_instance.svg b/docs/resources/machine_instance.svg
new file mode 100644
index 0000000000..a215a7b5a4
--- /dev/null
+++ b/docs/resources/machine_instance.svg
@@ -0,0 +1,55 @@
+
+
\ No newline at end of file
diff --git a/docs/resources/repositories.svg b/docs/resources/repositories.svg
new file mode 100644
index 0000000000..4f4ad740f3
--- /dev/null
+++ b/docs/resources/repositories.svg
@@ -0,0 +1,70 @@
+
+
\ No newline at end of file
diff --git a/plugins/3MFReader/ThreeMFWorkspaceReader.py b/plugins/3MFReader/ThreeMFWorkspaceReader.py
index 82b73c66d9..74589b8335 100755
--- a/plugins/3MFReader/ThreeMFWorkspaceReader.py
+++ b/plugins/3MFReader/ThreeMFWorkspaceReader.py
@@ -738,11 +738,15 @@ class ThreeMFWorkspaceReader(WorkspaceReader):
@staticmethod
def _loadMetadata(file_name: str) -> Dict[str, Dict[str, Any]]:
- archive = zipfile.ZipFile(file_name, "r")
+ result = dict() # type: Dict[str, Dict[str, Any]]
+ try:
+ archive = zipfile.ZipFile(file_name, "r")
+ except zipfile.BadZipFile:
+ Logger.logException("w", "Unable to retrieve metadata from {fname}: 3MF archive is corrupt.".format(fname = file_name))
+ return result
metadata_files = [name for name in archive.namelist() if name.endswith("plugin_metadata.json")]
- result = dict()
for metadata_file in metadata_files:
try:
diff --git a/plugins/3MFReader/plugin.json b/plugins/3MFReader/plugin.json
index 7e868d3bd0..7e434d03b2 100644
--- a/plugins/3MFReader/plugin.json
+++ b/plugins/3MFReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides support for reading 3MF files.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/3MFWriter/plugin.json b/plugins/3MFWriter/plugin.json
index 1d22691dfc..421b6b5b6f 100644
--- a/plugins/3MFWriter/plugin.json
+++ b/plugins/3MFWriter/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides support for writing 3MF files.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/AMFReader/plugin.json b/plugins/AMFReader/plugin.json
index cb108011ec..0f828c9393 100644
--- a/plugins/AMFReader/plugin.json
+++ b/plugins/AMFReader/plugin.json
@@ -3,5 +3,5 @@
"author": "fieldOfView",
"version": "1.0.0",
"description": "Provides support for reading AMF files.",
- "api": "7.1.0"
+ "api": "7.2.0"
}
diff --git a/plugins/CuraDrive/plugin.json b/plugins/CuraDrive/plugin.json
index 58a8d95b83..506d4cf231 100644
--- a/plugins/CuraDrive/plugin.json
+++ b/plugins/CuraDrive/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"description": "Backup and restore your configuration.",
"version": "1.2.0",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py
index 3dd0589865..6a8a4a7347 100755
--- a/plugins/CuraEngineBackend/CuraEngineBackend.py
+++ b/plugins/CuraEngineBackend/CuraEngineBackend.py
@@ -720,9 +720,12 @@ class CuraEngineBackend(QObject, Backend):
## Creates a new socket connection.
def _createSocket(self, protocol_file: str = None) -> None:
if not protocol_file:
+ if not self.getPluginId():
+ Logger.error("Can't create socket before CuraEngineBackend plug-in is registered.")
+ return
plugin_path = PluginRegistry.getInstance().getPluginPath(self.getPluginId())
if not plugin_path:
- Logger.log("e", "Could not get plugin path!", self.getPluginId())
+ Logger.error("Could not get plugin path!", self.getPluginId())
return
protocol_file = os.path.abspath(os.path.join(plugin_path, "Cura.proto"))
super()._createSocket(protocol_file)
diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py
index a99c559bac..62b0bd16e7 100644
--- a/plugins/CuraEngineBackend/StartSliceJob.py
+++ b/plugins/CuraEngineBackend/StartSliceJob.py
@@ -13,6 +13,8 @@ from UM.Job import Job
from UM.Logger import Logger
from UM.Scene.SceneNode import SceneNode
from UM.Settings.ContainerStack import ContainerStack #For typing.
+from UM.Settings.InstanceContainer import InstanceContainer
+from UM.Settings.SettingDefinition import SettingDefinition
from UM.Settings.SettingRelation import SettingRelation #For typing.
from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator
@@ -103,20 +105,33 @@ class StartSliceJob(Job):
## Check if a stack has any errors.
## returns true if it has errors, false otherwise.
def _checkStackForErrors(self, stack: ContainerStack) -> bool:
- if stack is None:
- return False
- # if there are no per-object settings we don't need to check the other settings here
- stack_top = stack.getTop()
- if stack_top is None or not stack_top.getAllKeys():
- return False
+ top_of_stack = cast(InstanceContainer, stack.getTop()) # Cache for efficiency.
+ changed_setting_keys = top_of_stack.getAllKeys()
- for key in stack.getAllKeys():
- validation_state = stack.getProperty(key, "validationState")
- if validation_state in (ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError, ValidatorState.Invalid):
- Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", key, validation_state)
+ # Add all relations to changed settings as well.
+ for key in top_of_stack.getAllKeys():
+ instance = top_of_stack.getInstance(key)
+ if instance is None:
+ continue
+ self._addRelations(changed_setting_keys, instance.definition.relations)
+ Job.yieldThread()
+
+ for changed_setting_key in changed_setting_keys:
+ validation_state = stack.getProperty(changed_setting_key, "validationState")
+
+ if validation_state is None:
+ definition = cast(SettingDefinition, stack.getSettingDefinition(changed_setting_key))
+ validator_type = SettingDefinition.getValidatorForType(definition.type)
+ if validator_type:
+ validator = validator_type(changed_setting_key)
+ validation_state = validator(stack)
+ if validation_state in (
+ ValidatorState.Exception, ValidatorState.MaximumError, ValidatorState.MinimumError, ValidatorState.Invalid):
+ Logger.log("w", "Setting %s is not valid, but %s. Aborting slicing.", changed_setting_key, validation_state)
return True
Job.yieldThread()
+
return False
## Runs the job that initiates the slicing.
@@ -511,4 +526,3 @@ class StartSliceJob(Job):
relations_set.add(relation.target.key)
self._addRelations(relations_set, relation.target.relations)
-
diff --git a/plugins/CuraEngineBackend/plugin.json b/plugins/CuraEngineBackend/plugin.json
index 6817ad27be..2eee5deb61 100644
--- a/plugins/CuraEngineBackend/plugin.json
+++ b/plugins/CuraEngineBackend/plugin.json
@@ -2,7 +2,7 @@
"name": "CuraEngine Backend",
"author": "Ultimaker B.V.",
"description": "Provides the link to the CuraEngine slicing backend.",
- "api": "7.1",
+ "api": "7.2.0",
"version": "1.0.1",
"i18n-catalog": "cura"
}
diff --git a/plugins/CuraProfileReader/plugin.json b/plugins/CuraProfileReader/plugin.json
index 82fcd4d61b..080c9c5244 100644
--- a/plugins/CuraProfileReader/plugin.json
+++ b/plugins/CuraProfileReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides support for importing Cura profiles.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/CuraProfileWriter/plugin.json b/plugins/CuraProfileWriter/plugin.json
index 224290cb31..77d18dc76c 100644
--- a/plugins/CuraProfileWriter/plugin.json
+++ b/plugins/CuraProfileWriter/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides support for exporting Cura profiles.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog":"cura"
}
diff --git a/plugins/FirmwareUpdateChecker/plugin.json b/plugins/FirmwareUpdateChecker/plugin.json
index fc20bc5693..7c1f22c753 100644
--- a/plugins/FirmwareUpdateChecker/plugin.json
+++ b/plugins/FirmwareUpdateChecker/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Checks for firmware updates.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/FirmwareUpdater/plugin.json b/plugins/FirmwareUpdater/plugin.json
index 5c44e2629c..fad955a043 100644
--- a/plugins/FirmwareUpdater/plugin.json
+++ b/plugins/FirmwareUpdater/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides a machine actions for updating firmware.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/GCodeGzReader/plugin.json b/plugins/GCodeGzReader/plugin.json
index 6aa4fa8905..05265bf29b 100644
--- a/plugins/GCodeGzReader/plugin.json
+++ b/plugins/GCodeGzReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Reads g-code from a compressed archive.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/GCodeGzWriter/plugin.json b/plugins/GCodeGzWriter/plugin.json
index f663ba2165..48e39c9429 100644
--- a/plugins/GCodeGzWriter/plugin.json
+++ b/plugins/GCodeGzWriter/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Writes g-code to a compressed archive.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/GCodeProfileReader/plugin.json b/plugins/GCodeProfileReader/plugin.json
index 79bb661ada..9e06ab1b73 100644
--- a/plugins/GCodeProfileReader/plugin.json
+++ b/plugins/GCodeProfileReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides support for importing profiles from g-code files.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/GCodeReader/plugin.json b/plugins/GCodeReader/plugin.json
index 49cd06641c..d64bcb2513 100644
--- a/plugins/GCodeReader/plugin.json
+++ b/plugins/GCodeReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Victor Larchenko, Ultimaker B.V.",
"version": "1.0.1",
"description": "Allows loading and displaying G-code files.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/GCodeWriter/plugin.json b/plugins/GCodeWriter/plugin.json
index 9d34c7980a..31e72e2032 100644
--- a/plugins/GCodeWriter/plugin.json
+++ b/plugins/GCodeWriter/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Writes g-code to a file.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/ImageReader/plugin.json b/plugins/ImageReader/plugin.json
index feaff38efe..890c13c202 100644
--- a/plugins/ImageReader/plugin.json
+++ b/plugins/ImageReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Enables ability to generate printable geometry from 2D image files.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/LegacyProfileReader/plugin.json b/plugins/LegacyProfileReader/plugin.json
index 58573f6446..a3036e25d2 100644
--- a/plugins/LegacyProfileReader/plugin.json
+++ b/plugins/LegacyProfileReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides support for importing profiles from legacy Cura versions.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/MachineSettingsAction/plugin.json b/plugins/MachineSettingsAction/plugin.json
index 0e646e4e87..18e28903e1 100644
--- a/plugins/MachineSettingsAction/plugin.json
+++ b/plugins/MachineSettingsAction/plugin.json
@@ -3,6 +3,6 @@
"author": "fieldOfView, Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides a way to change machine settings (such as build volume, nozzle size, etc.).",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/ModelChecker/ModelChecker.py b/plugins/ModelChecker/ModelChecker.py
index 5472a96809..057ee14945 100644
--- a/plugins/ModelChecker/ModelChecker.py
+++ b/plugins/ModelChecker/ModelChecker.py
@@ -86,7 +86,7 @@ class ModelChecker(QObject, Extension):
if material_shrinkage[node_extruder_position] > shrinkage_threshold:
bbox = node.getBoundingBox()
- if bbox.width >= warning_size_xy or bbox.depth >= warning_size_xy or bbox.height >= warning_size_z:
+ if bbox is not None and (bbox.width >= warning_size_xy or bbox.depth >= warning_size_xy or bbox.height >= warning_size_z):
warning_nodes.append(node)
self._caution_message.setText(catalog.i18nc(
diff --git a/plugins/ModelChecker/plugin.json b/plugins/ModelChecker/plugin.json
index 6efccc39bd..4624f24ea9 100644
--- a/plugins/ModelChecker/plugin.json
+++ b/plugins/ModelChecker/plugin.json
@@ -2,7 +2,7 @@
"name": "Model Checker",
"author": "Ultimaker B.V.",
"version": "1.0.1",
- "api": "7.1",
+ "api": "7.2.0",
"description": "Checks models and print configuration for possible printing issues and give suggestions.",
"i18n-catalog": "cura"
}
diff --git a/plugins/MonitorStage/plugin.json b/plugins/MonitorStage/plugin.json
index a79a056cb8..541518b9e1 100644
--- a/plugins/MonitorStage/plugin.json
+++ b/plugins/MonitorStage/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides a monitor stage in Cura.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
index 358fec4a31..6eaadf3e83 100644
--- a/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
+++ b/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml
@@ -54,7 +54,7 @@ Item
UM.ActiveTool.setProperty("MeshType", type)
}
- UM.I18nCatalog { id: catalog; name: "uranium"}
+ UM.I18nCatalog { id: catalog; name: "cura"}
Column
{
diff --git a/plugins/PerObjectSettingsTool/plugin.json b/plugins/PerObjectSettingsTool/plugin.json
index 9567200a6a..ebc51a5e94 100644
--- a/plugins/PerObjectSettingsTool/plugin.json
+++ b/plugins/PerObjectSettingsTool/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides the Per Model Settings.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/PostProcessingPlugin/plugin.json b/plugins/PostProcessingPlugin/plugin.json
index 814499ca0f..21a7cedb75 100644
--- a/plugins/PostProcessingPlugin/plugin.json
+++ b/plugins/PostProcessingPlugin/plugin.json
@@ -2,7 +2,7 @@
"name": "Post Processing",
"author": "Ultimaker",
"version": "2.2.1",
- "api": "7.1",
+ "api": "7.2.0",
"description": "Extension that allows for user created scripts for post processing",
"catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py b/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py
index cdbb4a79ef..f4041b8650 100644
--- a/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py
+++ b/plugins/PostProcessingPlugin/scripts/ChangeAtZ.py
@@ -4,71 +4,86 @@
# 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 ChangeAtZ 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)
# Modified by Jaime van Kessel (Ultimaker), j.vankessel@ultimaker.com to make it work for 15.10 / 2.x
# Modified by Ruben Dulek (Ultimaker), r.dulek@ultimaker.com, to debug.
+# Modified by Wes Hanney, https://github.com/novamxd, Retract Length + Speed, Clean up
-##history / changelog:
-##V3.0.1: TweakAtZ-state default 1 (i.e. the plugin works without any TweakAtZ comment)
-##V3.1: Recognizes UltiGCode and deactivates value reset, fan speed added, alternatively layer no. to tweak at,
-## extruder three temperature disabled by "#Ex3"
-##V3.1.1: Bugfix reset flow rate
-##V3.1.2: Bugfix disable TweakAtZ on Cool Head Lift
-##V3.2: Flow rate for specific extruder added (only for 2 extruders), bugfix parser,
-## added speed reset at the end of the print
-##V4.0: Progress bar, tweaking over multiple layers, M605&M606 implemented, reset after one layer option,
-## extruder three code removed, tweaking print speed, save call of Publisher class,
-## uses previous value from other plugins also on UltiGCode
-##V4.0.1: Bugfix for doubled G1 commands
-##V4.0.2: uses Cura progress bar instead of its own
-##V4.0.3: Bugfix for cool head lift (contributed by luisonoff)
-##V4.9.91: First version for Cura 15.06.x and PostProcessingPlugin
-##V4.9.92: Modifications for Cura 15.10
-##V4.9.93: Minor bugfixes (input settings) / documentation
-##V4.9.94: Bugfix Combobox-selection; remove logger
-##V5.0: Bugfix for fall back after one layer and doubled G0 commands when using print speed tweak, Initial version for Cura 2.x
-##V5.0.1: Bugfix for calling unknown property 'bedTemp' of previous settings storage and unkown variable 'speed'
-##V5.1: API Changes included for use with Cura 2.2
+# history / changelog:
+# V3.0.1: TweakAtZ-state default 1 (i.e. the plugin works without any TweakAtZ comment)
+# V3.1: Recognizes UltiGCode and deactivates value reset, fan speed added, alternatively layer no. to tweak at,
+# extruder three temperature disabled by "#Ex3"
+# V3.1.1: Bugfix reset flow rate
+# V3.1.2: Bugfix disable TweakAtZ on Cool Head Lift
+# V3.2: Flow rate for specific extruder added (only for 2 extruders), bugfix parser,
+# added speed reset at the end of the print
+# V4.0: Progress bar, tweaking over multiple layers, M605&M606 implemented, reset after one layer option,
+# extruder three code removed, tweaking print speed, save call of Publisher class,
+# uses previous value from other plugins also on UltiGCode
+# V4.0.1: Bugfix for doubled G1 commands
+# V4.0.2: Uses Cura progress bar instead of its own
+# V4.0.3: Bugfix for cool head lift (contributed by luisonoff)
+# V4.9.91: First version for Cura 15.06.x and PostProcessingPlugin
+# V4.9.92: Modifications for Cura 15.10
+# V4.9.93: Minor bugfixes (input settings) / documentation
+# V4.9.94: Bugfix Combobox-selection; remove logger
+# V5.0: Bugfix for fall back after one layer and doubled G0 commands when using print speed tweak, Initial version for Cura 2.x
+# V5.0.1: Bugfix for calling unknown property 'bedTemp' of previous settings storage and unkown variable 'speed'
+# V5.1: API Changes included for use with Cura 2.2
+# V5.2.0: Wes Hanney. Added support for changing Retract Length and Speed. Removed layer spread option. Fixed issue of cumulative ChangeZ
+# mods so they can now properly be stacked on top of each other. Applied code refactoring to clean up various coding styles. Added comments.
+# Broke up functions for clarity. Split up class so it can be debugged outside of Cura.
+# V5.2.1: Wes Hanney. Added support for firmware based retractions. Fixed issue of properly restoring previous values in single layer option.
+# Added support for outputting changes to LCD (untested). Added type hints to most functions and variables. Added more comments. Created GCodeCommand
+# class for better detection of G1 vs G10 or G11 commands, and accessing arguments. Moved most GCode methods to GCodeCommand class. Improved wording
+# of Single Layer vs Keep Layer to better reflect what was happening.
-## Uses -
-## M220 S - set speed factor override percentage
-## M221 S - set flow factor override percentage
-## M221 S T<0-#toolheads> - set flow factor override percentage for single extruder
-## M104 S T<0-#toolheads> - set extruder to target temperature
-## M140 S - set bed target temperature
-## M106 S - set fan speed to target speed
-## M605/606 to save and recall material settings on the UM2
+# Uses -
+# M220 S - set speed factor override percentage
+# M221 S - set flow factor override percentage
+# M221 S T<0-#toolheads> - set flow factor override percentage for single extruder
+# M104 S T<0-#toolheads> - set extruder to target temperature
+# M140 S - set bed target temperature
+# M106 S - set fan speed to target speed
+# M207 S F - set the retract length or feed rate
+# M117 - output the current changes
+from typing import List, Optional, Dict
from ..Script import Script
-#from UM.Logger import Logger
import re
+
+# this was broken up into a separate class so the main ChangeZ script could be debugged outside of Cura
class ChangeAtZ(Script):
- version = "5.1.1"
- def __init__(self):
- super().__init__()
+ version = "5.2.1"
def getSettingDataString(self):
return """{
- "name":"ChangeAtZ """ + self.version + """ (Experimental)",
- "key":"ChangeAtZ",
+ "name": "ChangeAtZ """ + self.version + """(Experimental)",
+ "key": "ChangeAtZ",
"metadata": {},
"version": 2,
- "settings":
- {
- "a_trigger":
- {
+ "settings": {
+ "caz_enabled": {
+ "label": "Enabled",
+ "description": "Allows adding multiple ChangeZ mods and disabling them as needed.",
+ "type": "bool",
+ "default_value": true
+ },
+ "a_trigger": {
"label": "Trigger",
"description": "Trigger at height or at layer no.",
"type": "enum",
- "options": {"height":"Height","layer_no":"Layer No."},
+ "options": {
+ "height": "Height",
+ "layer_no": "Layer No."
+ },
"default_value": "height"
},
- "b_targetZ":
- {
+ "b_targetZ": {
"label": "Change Height",
"description": "Z height to change at",
"unit": "mm",
@@ -79,8 +94,7 @@ class ChangeAtZ(Script):
"maximum_value_warning": "230",
"enabled": "a_trigger == 'height'"
},
- "b_targetL":
- {
+ "b_targetL": {
"label": "Change Layer",
"description": "Layer no. to change at",
"unit": "",
@@ -90,34 +104,29 @@ class ChangeAtZ(Script):
"minimum_value_warning": "-1",
"enabled": "a_trigger == 'layer_no'"
},
- "c_behavior":
- {
- "label": "Behavior",
- "description": "Select behavior: Change value and keep it for the rest, Change value for single layer only",
+ "c_behavior": {
+ "label": "Apply To",
+ "description": "Target Layer + Subsequent Layers is good for testing changes between ranges of layers, ex: Layer 0 to 10 or 0mm to 5mm. Single layer is good for testing changes at a single layer, ex: at Layer 10 or 5mm only.",
"type": "enum",
- "options": {"keep_value":"Keep value","single_layer":"Single Layer"},
+ "options": {
+ "keep_value": "Target Layer + Subsequent Layers",
+ "single_layer": "Target Layer Only"
+ },
"default_value": "keep_value"
},
- "d_twLayers":
- {
- "label": "Layer Spread",
- "description": "The change will be gradual over this many layers. Enter 1 to make the change immediate.",
- "unit": "",
- "type": "int",
- "default_value": 1,
- "minimum_value": "1",
- "maximum_value_warning": "50",
- "enabled": "c_behavior == 'keep_value'"
- },
- "e1_Change_speed":
- {
+ "caz_output_to_display": {
+ "label": "Output to Display",
+ "description": "Displays the current changes to the LCD",
+ "type": "bool",
+ "default_value": false
+ },
+ "e1_Change_speed": {
"label": "Change Speed",
"description": "Select if total speed (print and travel) has to be changed",
"type": "bool",
"default_value": false
},
- "e2_speed":
- {
+ "e2_speed": {
"label": "Speed",
"description": "New total speed (print and travel)",
"unit": "%",
@@ -128,15 +137,13 @@ class ChangeAtZ(Script):
"maximum_value_warning": "200",
"enabled": "e1_Change_speed"
},
- "f1_Change_printspeed":
- {
+ "f1_Change_printspeed": {
"label": "Change Print Speed",
"description": "Select if print speed has to be changed",
"type": "bool",
"default_value": false
},
- "f2_printspeed":
- {
+ "f2_printspeed": {
"label": "Print Speed",
"description": "New print speed",
"unit": "%",
@@ -147,15 +154,13 @@ class ChangeAtZ(Script):
"maximum_value_warning": "200",
"enabled": "f1_Change_printspeed"
},
- "g1_Change_flowrate":
- {
+ "g1_Change_flowrate": {
"label": "Change Flow Rate",
"description": "Select if flow rate has to be changed",
"type": "bool",
"default_value": false
},
- "g2_flowrate":
- {
+ "g2_flowrate": {
"label": "Flow Rate",
"description": "New Flow rate",
"unit": "%",
@@ -166,15 +171,13 @@ class ChangeAtZ(Script):
"maximum_value_warning": "200",
"enabled": "g1_Change_flowrate"
},
- "g3_Change_flowrateOne":
- {
+ "g3_Change_flowrateOne": {
"label": "Change Flow Rate 1",
"description": "Select if first extruder flow rate has to be changed",
"type": "bool",
"default_value": false
},
- "g4_flowrateOne":
- {
+ "g4_flowrateOne": {
"label": "Flow Rate One",
"description": "New Flow rate Extruder 1",
"unit": "%",
@@ -185,15 +188,13 @@ class ChangeAtZ(Script):
"maximum_value_warning": "200",
"enabled": "g3_Change_flowrateOne"
},
- "g5_Change_flowrateTwo":
- {
+ "g5_Change_flowrateTwo": {
"label": "Change Flow Rate 2",
"description": "Select if second extruder flow rate has to be changed",
"type": "bool",
"default_value": false
},
- "g6_flowrateTwo":
- {
+ "g6_flowrateTwo": {
"label": "Flow Rate two",
"description": "New Flow rate Extruder 2",
"unit": "%",
@@ -204,15 +205,13 @@ class ChangeAtZ(Script):
"maximum_value_warning": "200",
"enabled": "g5_Change_flowrateTwo"
},
- "h1_Change_bedTemp":
- {
+ "h1_Change_bedTemp": {
"label": "Change Bed Temp",
"description": "Select if Bed Temperature has to be changed",
"type": "bool",
"default_value": false
},
- "h2_bedTemp":
- {
+ "h2_bedTemp": {
"label": "Bed Temp",
"description": "New Bed Temperature",
"unit": "C",
@@ -223,15 +222,13 @@ class ChangeAtZ(Script):
"maximum_value_warning": "120",
"enabled": "h1_Change_bedTemp"
},
- "i1_Change_extruderOne":
- {
+ "i1_Change_extruderOne": {
"label": "Change Extruder 1 Temp",
"description": "Select if First Extruder Temperature has to be changed",
"type": "bool",
"default_value": false
},
- "i2_extruderOne":
- {
+ "i2_extruderOne": {
"label": "Extruder 1 Temp",
"description": "New First Extruder Temperature",
"unit": "C",
@@ -242,15 +239,13 @@ class ChangeAtZ(Script):
"maximum_value_warning": "250",
"enabled": "i1_Change_extruderOne"
},
- "i3_Change_extruderTwo":
- {
+ "i3_Change_extruderTwo": {
"label": "Change Extruder 2 Temp",
"description": "Select if Second Extruder Temperature has to be changed",
"type": "bool",
"default_value": false
},
- "i4_extruderTwo":
- {
+ "i4_extruderTwo": {
"label": "Extruder 2 Temp",
"description": "New Second Extruder Temperature",
"unit": "C",
@@ -261,239 +256,1176 @@ class ChangeAtZ(Script):
"maximum_value_warning": "250",
"enabled": "i3_Change_extruderTwo"
},
- "j1_Change_fanSpeed":
- {
+ "j1_Change_fanSpeed": {
"label": "Change Fan Speed",
"description": "Select if Fan Speed has to be changed",
"type": "bool",
"default_value": false
},
- "j2_fanSpeed":
- {
+ "j2_fanSpeed": {
"label": "Fan Speed",
- "description": "New Fan Speed (0-255)",
- "unit": "PWM",
+ "description": "New Fan Speed (0-100)",
+ "unit": "%",
"type": "int",
- "default_value": 255,
+ "default_value": 100,
"minimum_value": "0",
- "minimum_value_warning": "15",
- "maximum_value_warning": "255",
+ "minimum_value_warning": "0",
+ "maximum_value_warning": "100",
"enabled": "j1_Change_fanSpeed"
- }
+ },
+ "caz_change_retract": {
+ "label": "Change Retraction",
+ "description": "Indicates you would like to modify retraction properties.",
+ "type": "bool",
+ "default_value": false
+ },
+ "caz_retractstyle": {
+ "label": "Retract Style",
+ "description": "Specify if you're using firmware retraction or linear move based retractions. Check your printer settings to see which you're using.",
+ "type": "enum",
+ "options": {
+ "linear": "Linear Move",
+ "firmware": "Firmware"
+ },
+ "default_value": "linear",
+ "enabled": "caz_change_retract"
+ },
+ "caz_change_retractfeedrate": {
+ "label": "Change Retract Feed Rate",
+ "description": "Changes the retraction feed rate during print",
+ "type": "bool",
+ "default_value": false,
+ "enabled": "caz_change_retract"
+ },
+ "caz_retractfeedrate": {
+ "label": "Retract Feed Rate",
+ "description": "New Retract Feed Rate (mm/s)",
+ "unit": "mm/s",
+ "type": "float",
+ "default_value": 40,
+ "minimum_value": "0",
+ "minimum_value_warning": "0",
+ "maximum_value_warning": "100",
+ "enabled": "caz_change_retractfeedrate"
+ },
+ "caz_change_retractlength": {
+ "label": "Change Retract Length",
+ "description": "Changes the retraction length during print",
+ "type": "bool",
+ "default_value": false,
+ "enabled": "caz_change_retract"
+ },
+ "caz_retractlength": {
+ "label": "Retract Length",
+ "description": "New Retract Length (mm)",
+ "unit": "mm",
+ "type": "float",
+ "default_value": 6,
+ "minimum_value": "0",
+ "minimum_value_warning": "0",
+ "maximum_value_warning": "20",
+ "enabled": "caz_change_retractlength"
+ }
}
}"""
- 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 ";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 ";ChangeAtZ" in key:
- m = re.search("^[0-4]", subPart)
- elif ";LAYER:" in key:
- m = re.search("^[+-]?[0-9]*", subPart)
- else:
- #the minus at the beginning allows for negative values, e.g. for delta printers
- m = re.search("^[-]?[0-9]*\.?[0-9]*", subPart)
- if m == None:
- return default
- try:
- return float(m.group(0))
- except:
- return default
+ def __init__(self):
+ super().__init__()
def execute(self, data):
- #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",
- "bedTemp": "M140 S%f\n",
- "extruderOne": "M104 S%f T0\n",
- "extruderTwo": "M104 S%f T1\n",
- "fanSpeed": "M106 S%d\n"}
- target_values = {"speed": self.getSettingValueByKey("e2_speed"),
- "printspeed": self.getSettingValueByKey("f2_printspeed"),
- "flowrate": self.getSettingValueByKey("g2_flowrate"),
- "flowrateOne": self.getSettingValueByKey("g4_flowrateOne"),
- "flowrateTwo": self.getSettingValueByKey("g6_flowrateTwo"),
- "bedTemp": self.getSettingValueByKey("h2_bedTemp"),
- "extruderOne": self.getSettingValueByKey("i2_extruderOne"),
- "extruderTwo": self.getSettingValueByKey("i4_extruderTwo"),
- "fanSpeed": self.getSettingValueByKey("j2_fanSpeed")}
- old = {"speed": -1, "flowrate": 100, "flowrateOne": -1, "flowrateTwo": -1, "platformTemp": -1, "extruderOne": -1,
- "extruderTwo": -1, "bedTemp": -1, "fanSpeed": -1, "state": -1}
- twLayers = self.getSettingValueByKey("d_twLayers")
- if self.getSettingValueByKey("c_behavior") == "single_layer":
- behavior = 1
- else:
- behavior = 0
- try:
- twLayers = max(int(twLayers),1) #for the case someone entered something as "funny" as -1
- except:
- twLayers = 1
- pres_ext = 0
- done_layers = 0
- z = 0
- x = None
- y = None
- layer = -100000 #layer no. may be negative (raft) but never that low
- # state 0: deactivated, state 1: activated, state 2: active, but below z,
- # state 3: active and partially executed (multi layer), state 4: active and passed z
- state = 1
- # IsUM2: Used for reset of values (ok for Marlin/Sprinter),
- # has to be set to 1 for UltiGCode (work-around for missing default values)
- IsUM2 = False
- oldValueUnknown = False
- TWinstances = 0
- if self.getSettingValueByKey("a_trigger") == "layer_no":
- targetL_i = int(self.getSettingValueByKey("b_targetL"))
- targetZ = 100000
+ caz_instance = ChangeAtZProcessor()
+
+ caz_instance.TargetValues = {}
+
+ # copy over our settings to our change z class
+ self.setIntSettingIfEnabled(caz_instance, "e1_Change_speed", "speed", "e2_speed")
+ self.setIntSettingIfEnabled(caz_instance, "f1_Change_printspeed", "printspeed", "f2_printspeed")
+ self.setIntSettingIfEnabled(caz_instance, "g1_Change_flowrate", "flowrate", "g2_flowrate")
+ self.setIntSettingIfEnabled(caz_instance, "g3_Change_flowrateOne", "flowrateOne", "g4_flowrateOne")
+ self.setIntSettingIfEnabled(caz_instance, "g5_Change_flowrateTwo", "flowrateTwo", "g6_flowrateTwo")
+ self.setFloatSettingIfEnabled(caz_instance, "h1_Change_bedTemp", "bedTemp", "h2_bedTemp")
+ self.setFloatSettingIfEnabled(caz_instance, "i1_Change_extruderOne", "extruderOne", "i2_extruderOne")
+ self.setFloatSettingIfEnabled(caz_instance, "i3_Change_extruderTwo", "extruderTwo", "i4_extruderTwo")
+ self.setIntSettingIfEnabled(caz_instance, "j1_Change_fanSpeed", "fanSpeed", "j2_fanSpeed")
+ self.setFloatSettingIfEnabled(caz_instance, "caz_change_retractfeedrate", "retractfeedrate", "caz_retractfeedrate")
+ self.setFloatSettingIfEnabled(caz_instance, "caz_change_retractlength", "retractlength", "caz_retractlength")
+
+ # is this mod enabled?
+ caz_instance.IsEnabled = self.getSettingValueByKey("caz_enabled")
+
+ # are we emitting data to the LCD?
+ caz_instance.IsDisplayingChangesToLcd = self.getSettingValueByKey("caz_output_to_display")
+
+ # are we doing linear move retractions?
+ caz_instance.IsLinearRetraction = self.getSettingValueByKey("caz_retractstyle") == "linear"
+
+ # see if we're applying to a single layer or to all layers hence forth
+ caz_instance.IsApplyToSingleLayer = self.getSettingValueByKey("c_behavior") == "single_layer"
+
+ # used for easy reference of layer or height targeting
+ caz_instance.IsTargetByLayer = self.getSettingValueByKey("a_trigger") == "layer_no"
+
+ # change our target based on what we're targeting
+ caz_instance.TargetLayer = self.getIntSettingByKey("b_targetL", None)
+ caz_instance.TargetZ = self.getFloatSettingByKey("b_targetZ", None)
+
+ # run our script
+ return caz_instance.execute(data)
+
+ # Sets the given TargetValue in the ChangeAtZ instance if the trigger is specified
+ def setIntSettingIfEnabled(self, caz_instance, trigger, target, setting):
+
+ # stop here if our trigger isn't enabled
+ if not self.getSettingValueByKey(trigger):
+ return
+
+ # get our value from the settings
+ value = self.getIntSettingByKey(setting, None)
+
+ # skip if there's no value or we can't interpret it
+ if value is None:
+ return
+
+ # set our value in the target settings
+ caz_instance.TargetValues[target] = value
+
+ # Sets the given TargetValue in the ChangeAtZ instance if the trigger is specified
+ def setFloatSettingIfEnabled(self, caz_instance, trigger, target, setting):
+
+ # stop here if our trigger isn't enabled
+ if not self.getSettingValueByKey(trigger):
+ return
+
+ # get our value from the settings
+ value = self.getFloatSettingByKey(setting, None)
+
+ # skip if there's no value or we can't interpret it
+ if value is None:
+ return
+
+ # set our value in the target settings
+ caz_instance.TargetValues[target] = value
+
+ # Returns the given settings value as an integer or the default if it cannot parse it
+ def getIntSettingByKey(self, key, default):
+
+ # change our target based on what we're targeting
+ try:
+ return int(self.getSettingValueByKey(key))
+ except:
+ return default
+
+ # Returns the given settings value as an integer or the default if it cannot parse it
+ def getFloatSettingByKey(self, key, default):
+
+ # change our target based on what we're targeting
+ try:
+ return float(self.getSettingValueByKey(key))
+ except:
+ return default
+
+
+# This is a utility class for getting details of gcodes from a given line
+class GCodeCommand:
+
+ # The GCode command itself (ex: G10)
+ Command = None,
+
+ # Contains any arguments passed to the command. The key is the argument name, the value is the value of the argument.
+ Arguments = {}
+
+ # Contains the components of the command broken into pieces
+ Components = []
+
+ # Constructor. Sets up defaults
+ def __init__(self):
+ self.reset()
+
+ # Gets a GCode Command from the given single line of GCode
+ @staticmethod
+ def getFromLine(line: str):
+
+ # obviously if we don't have a command, we can't return anything
+ if line is None or len(line) == 0:
+ return None
+
+ # we only support G or M commands
+ if line[0] != "G" and line[0] != "M":
+ return None
+
+ # remove any comments
+ line = re.sub(r";.*$", "", line)
+
+ # break into the individual components
+ command_pieces = line.strip().split(" ")
+
+ # our return command details
+ command = GCodeCommand()
+
+ # stop here if we don't even have something to interpret
+ if len(command_pieces) == 0:
+ return None
+
+ # stores all the components of the command within the class for later
+ command.Components = command_pieces
+
+ # set the actual command
+ command.Command = command_pieces[0]
+
+ # stop here if we don't have any parameters
+ if len(command_pieces) == 1:
+ return None
+
+ # return our indexed command
+ return command
+
+ # Handy function for reading a linear move command
+ @staticmethod
+ def getLinearMoveCommand(line: str):
+
+ # get our command from the line
+ linear_command = GCodeCommand.getFromLine(line)
+
+ # if it's not a linear move, we don't care
+ if linear_command is None or (linear_command.Command != "G0" and linear_command.Command != "G1"):
+ return None
+
+ # convert our values to floats (or defaults)
+ linear_command.Arguments["F"] = linear_command.getArgumentAsFloat("F", None)
+ linear_command.Arguments["X"] = linear_command.getArgumentAsFloat("X", None)
+ linear_command.Arguments["Y"] = linear_command.getArgumentAsFloat("Y", None)
+ linear_command.Arguments["Z"] = linear_command.getArgumentAsFloat("Z", None)
+ linear_command.Arguments["E"] = linear_command.getArgumentAsFloat("E", None)
+
+ # return our new command
+ return linear_command
+
+ # Gets the value of a parameter or returns the default if there is none
+ def getArgument(self, name: str, default: str = None) -> str:
+
+ # parse our arguments (only happens once)
+ self.parseArguments()
+
+ # if we don't have the parameter, return the default
+ if name not in self.Arguments:
+ return default
+
+ # otherwise return the value
+ return self.Arguments[name]
+
+ # Gets the value of a parameter as a float or returns the default
+ def getArgumentAsFloat(self, name: str, default: float = None) -> float:
+
+ # try to parse as a float, otherwise return the default
+ try:
+ return float(self.getArgument(name, default))
+ except:
+ return default
+
+ # Gets the value of a parameter as an integer or returns the default
+ def getArgumentAsInt(self, name: str, default: int = None) -> int:
+
+ # try to parse as a integer, otherwise return the default
+ try:
+ return int(self.getArgument(name, default))
+ except:
+ return default
+
+ # Allows retrieving values from the given GCODE line
+ @staticmethod
+ def getDirectArgument(line: str, key: str, default: str = None) -> str:
+
+ if key not in line or (";" in line and line.find(key) > line.find(";") and ";ChangeAtZ" not in key and ";LAYER:" not in key):
+ return default
+
+ # allows for string lengths larger than 1
+ sub_part = line[line.find(key) + len(key):]
+
+ if ";ChangeAtZ" in key:
+ m = re.search("^[0-4]", sub_part)
+ elif ";LAYER:" in key:
+ m = re.search("^[+-]?[0-9]*", sub_part)
else:
- targetL_i = -100000
- targetZ = self.getSettingValueByKey("b_targetZ")
+ # the minus at the beginning allows for negative values, e.g. for delta printers
+ m = re.search(r"^[-]?[0-9]*\.?[0-9]*", sub_part)
+ if m is None:
+ return default
+
+ try:
+ return m.group(0)
+ except:
+ return default
+
+ # Converts the command parameter to a int or returns the default
+ @staticmethod
+ def getDirectArgumentAsFloat(line: str, key: str, default: float = None) -> float:
+
+ # get the value from the command
+ value = GCodeCommand.getDirectArgument(line, key, default)
+
+ # stop here if it's the default
+ if value == default:
+ return value
+
+ try:
+ return float(value)
+ except:
+ return default
+
+ # Converts the command parameter to a int or returns the default
+ @staticmethod
+ def getDirectArgumentAsInt(line: str, key: str, default: int = None) -> int:
+
+ # get the value from the command
+ value = GCodeCommand.getDirectArgument(line, key, default)
+
+ # stop here if it's the default
+ if value == default:
+ return value
+
+ try:
+ return int(value)
+ except:
+ return default
+
+ # Parses the arguments of the command on demand, only once
+ def parseArguments(self):
+
+ # stop here if we don't have any remaining components
+ if len(self.Components) <= 1:
+ return None
+
+ # iterate and index all of our parameters, skip the first component as it's the command
+ for i in range(1, len(self.Components)):
+
+ # get our component
+ component = self.Components[i]
+
+ # get the first character of the parameter, which is the name
+ component_name = component[0]
+
+ # get the value of the parameter (the rest of the string
+ component_value = None
+
+ # get our value if we have one
+ if len(component) > 1:
+ component_value = component[1:]
+
+ # index the argument
+ self.Arguments[component_name] = component_value
+
+ # clear the components to we don't process again
+ self.Components = []
+
+ # Easy function for replacing any GCODE parameter variable in a given GCODE command
+ @staticmethod
+ def replaceDirectArgument(line: str, key: str, value: str) -> str:
+ return re.sub(r"(^|\s)" + key + r"[\d\.]+(\s|$)", r"\1" + key + str(value) + r"\2", line)
+
+ # Resets the model back to defaults
+ def reset(self):
+ self.Command = None
+ self.Arguments = {}
+
+
+# The primary ChangeAtZ class that does all the gcode editing. This was broken out into an
+# independent class so it could be debugged using a standard IDE
+class ChangeAtZProcessor:
+
+ # Holds our current height
+ CurrentZ = None
+
+ # Holds our current layer number
+ CurrentLayer = None
+
+ # Indicates if we're only supposed to apply our settings to a single layer or multiple layers
+ IsApplyToSingleLayer = False
+
+ # Indicates if this should emit the changes as they happen to the LCD
+ IsDisplayingChangesToLcd = False
+
+ # Indicates that this mod is still enabled (or not)
+ IsEnabled = True
+
+ # Indicates if we're processing inside the target layer or not
+ IsInsideTargetLayer = False
+
+ # Indicates if we have restored the previous values from before we started our pass
+ IsLastValuesRestored = False
+
+ # Indicates if the user has opted for linear move retractions or firmware retractions
+ IsLinearRetraction = True
+
+ # Indicates if we're targetting by layer or height value
+ IsTargetByLayer = True
+
+ # Indicates if we have injected our changed values for the given layer yet
+ IsTargetValuesInjected = False
+
+ # Holds the last extrusion value, used with detecting when a retraction is made
+ LastE = None
+
+ # An index of our gcodes which we're monitoring
+ LastValues = {}
+
+ # The detected layer height from the gcode
+ LayerHeight = None
+
+ # The target layer
+ TargetLayer = None
+
+ # Holds the values the user has requested to change
+ TargetValues = {}
+
+ # The target height in mm
+ TargetZ = None
+
+ # Used to track if we've been inside our target layer yet
+ WasInsideTargetLayer = False
+
+ # boots up the class with defaults
+ def __init__(self):
+ self.reset()
+
+ # Modifies the given GCODE and injects the commands at the various targets
+ def execute(self, data):
+
+ # short cut the whole thing if we're not enabled
+ if not self.IsEnabled:
+ return data
+
+ # our layer cursor
index = 0
+
for active_layer in data:
+
+ # will hold our updated gcode
modified_gcode = ""
+
+ # mark all the defaults for deletion
+ active_layer = self.markChangesForDeletion(active_layer)
+
+ # break apart the layer into commands
lines = active_layer.split("\n")
+
+ # evaluate each command individually
for line in lines:
- if line.strip() == "":
+
+ # trim or command
+ line = line.strip()
+
+ # skip empty lines
+ if len(line) == 0:
continue
- if ";Generated with Cura_SteamEngine" in line:
- TWinstances += 1
- 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 ";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:
- tempTWi = TWinstances
- TWinstances = tempTWi
- if ";Small layer" in line: #checks for begin of Cool Head Lift
- old["state"] = state
- state = 0
- if ";LAYER:" in line: #new layer no. found
- if state == 0:
- 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 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
- pres_ext = self.getValue(line, "T", pres_ext)
- if "M190" in line or "M140" in line and state < 3: #looking for bed temp, stops after target z is passed
- old["bedTemp"] = self.getValue(line, "S", old["bedTemp"])
- if "M109" in line or "M104" in line and state < 3: #looking for extruder temp, stops after target z is passed
- if self.getValue(line, "T", pres_ext) == 0:
- old["extruderOne"] = self.getValue(line, "S", old["extruderOne"])
- elif self.getValue(line, "T", pres_ext) == 1:
- old["extruderTwo"] = self.getValue(line, "S", old["extruderTwo"])
- if "M107" in line: #fan is stopped; is always updated in order not to miss switch off for next object
- old["fanSpeed"] = 0
- if "M106" in line and state < 3: #looking for fan speed
- old["fanSpeed"] = self.getValue(line, "S", old["fanSpeed"])
- if "M221" in line and state < 3: #looking for flow rate
- tmp_extruder = self.getValue(line, "T", None)
- if tmp_extruder == None: #check if extruder is specified
- old["flowrate"] = self.getValue(line, "S", old["flowrate"])
- if old["flowrate"] == -1:
- old["flowrate"] = 100.0
- elif tmp_extruder == 0: #first extruder
- old["flowrateOne"] = self.getValue(line, "S", old["flowrateOne"])
- elif tmp_extruder == 1: #second extruder
- old["flowrateTwo"] = self.getValue(line, "S", old["flowrateTwo"])
- if ("M84" in line or "M25" in line):
- 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"
- if "G1" in line or "G0" in line:
- newZ = self.getValue(line, "Z", z)
- x = self.getValue(line, "X", None)
- y = self.getValue(line, "Y", None)
- e = self.getValue(line, "E", None)
- f = self.getValue(line, "F", None)
- 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 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:
- state = 2
- if z >= targetZ and state == 2:
- state = 3
- done_layers = 0
- for key in ChangeProp:
- if ChangeProp[key] and old[key]==-1: #old value is not known
- oldValueUnknown = True
- 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 changing\n" % (TWinstances-1)
- if behavior == 1: #single layer change only and then reset
- twLayers = 1
- 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 += ";ChangeAtZ V%s: executed at Layer %d\n" % (self.version,layer)
- modified_gcode += "M117 Printing... ch@L%4d\n" % layer
- else:
- 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 += ";ChangeAtZ V%s: reset on Layer %d\n" % (self.version,layer)
- else:
- 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 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 change level or at level 0
- state = 2
- done_layers = 0
- if targetL_i > -100000:
- modified_gcode += ";ChangeAtZ V%s: reset below Layer %d\n" % (self.version, targetL_i)
- else:
- 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 ChangeProp:
- if ChangeProp[key]:
- modified_gcode += ChangeStrings[key] % float(old[key])
+
+ # update our layer number if applicable
+ self.processLayerNumber(line)
+
+ # update our layer height if applicable
+ self.processLayerHeight(line)
+
+ # check if we're at the target layer or not
+ self.processTargetLayer()
+
+ # process any changes to the gcode
+ modified_gcode += self.processLine(line)
+
+ # remove any marked defaults
+ modified_gcode = self.removeMarkedChanges(modified_gcode)
+
+ # append our modified line
data[index] = modified_gcode
+
index += 1
+
+ # return our modified gcode
return data
+
+ # Builds the restored layer settings based on the previous settings and returns the relevant GCODE lines
+ def getChangedLastValues(self) -> Dict[str, any]:
+
+ # capture the values that we've changed
+ changed = {}
+
+ # for each of our target values, get the value to restore
+ # no point in restoring values we haven't changed
+ for key in self.TargetValues:
+
+ # skip target values we can't restore
+ if key not in self.LastValues:
+ continue
+
+ # save into our changed
+ changed[key] = self.LastValues[key]
+
+ # return our collection of changed values
+ return changed
+
+ # Builds the relevant display feedback for each of the values
+ def getDisplayChangesFromValues(self, values: Dict[str, any]) -> str:
+
+ # stop here if we're not outputting data
+ if not self.IsDisplayingChangesToLcd:
+ return ""
+
+ # will hold all the default settings for the target layer
+ codes = []
+
+ # looking for wait for bed temp
+ if "bedTemp" in values:
+ codes.append("BedTemp: " + str(values["bedTemp"]))
+
+ # set our extruder one temp (if specified)
+ if "extruderOne" in values:
+ codes.append("Extruder 1 Temp: " + str(values["extruderOne"]))
+
+ # set our extruder two temp (if specified)
+ if "extruderTwo" in values:
+ codes.append("Extruder 2 Temp: " + str(values["extruderTwo"]))
+
+ # set global flow rate
+ if "flowrate" in values:
+ codes.append("Extruder A Flow Rate: " + str(values["flowrate"]))
+
+ # set extruder 0 flow rate
+ if "flowrateOne" in values:
+ codes.append("Extruder 1 Flow Rate: " + str(values["flowrateOne"]))
+
+ # set second extruder flow rate
+ if "flowrateTwo" in values:
+ codes.append("Extruder 2 Flow Rate: " + str(values["flowrateTwo"]))
+
+ # set our fan speed
+ if "fanSpeed" in values:
+ codes.append("Fan Speed: " + str(values["fanSpeed"]))
+
+ # set feedrate percentage
+ if "speed" in values:
+ codes.append("Print Speed: " + str(values["speed"]))
+
+ # set print rate percentage
+ if "printspeed" in values:
+ codes.append("Linear Print Speed: " + str(values["printspeed"]))
+
+ # set retract rate
+ if "retractfeedrate" in values:
+ codes.append("Retract Feed Rate: " + str(values["retractfeedrate"]))
+
+ # set retract length
+ if "retractlength" in values:
+ codes.append("Retract Length: " + str(values["retractlength"]))
+
+ # stop here if there's nothing to output
+ if len(codes) == 0:
+ return ""
+
+ # output our command to display the data
+ return "M117 " + ", ".join(codes) + "\n"
+
+ # Converts the last values to something that can be output on the LCD
+ def getLastDisplayValues(self) -> str:
+
+ # convert our last values to something we can output
+ return self.getDisplayChangesFromValues(self.getChangedLastValues())
+
+ # Converts the target values to something that can be output on the LCD
+ def getTargetDisplayValues(self) -> str:
+
+ # convert our target values to something we can output
+ return self.getDisplayChangesFromValues(self.TargetValues)
+
+ # Builds the the relevant GCODE lines from the given collection of values
+ def getCodeFromValues(self, values: Dict[str, any]) -> str:
+
+ # will hold all the desired settings for the target layer
+ codes = self.getCodeLinesFromValues(values)
+
+ # stop here if there are no values that require changing
+ if len(codes) == 0:
+ return ""
+
+ # return our default block for this layer
+ return ";[CAZD:\n" + "\n".join(codes) + "\n;:CAZD]"
+
+ # Builds the relevant GCODE lines from the given collection of values
+ def getCodeLinesFromValues(self, values: Dict[str, any]) -> List[str]:
+
+ # will hold all the default settings for the target layer
+ codes = []
+
+ # looking for wait for bed temp
+ if "bedTemp" in values:
+ codes.append("M140 S" + str(values["bedTemp"]))
+
+ # set our extruder one temp (if specified)
+ if "extruderOne" in values:
+ codes.append("M104 S" + str(values["extruderOne"]) + " T0")
+
+ # set our extruder two temp (if specified)
+ if "extruderTwo" in values:
+ codes.append("M104 S" + str(values["extruderTwo"]) + " T1")
+
+ # set our fan speed
+ if "fanSpeed" in values:
+
+ # convert our fan speed percentage to PWM
+ fan_speed = int((float(values["fanSpeed"]) / 100.0) * 255)
+
+ # add our fan speed to the defaults
+ codes.append("M106 S" + str(fan_speed))
+
+ # set global flow rate
+ if "flowrate" in values:
+ codes.append("M221 S" + str(values["flowrate"]))
+
+ # set extruder 0 flow rate
+ if "flowrateOne" in values:
+ codes.append("M221 S" + str(values["flowrateOne"]) + " T0")
+
+ # set second extruder flow rate
+ if "flowrateTwo" in values:
+ codes.append("M221 S" + str(values["flowrateTwo"]) + " T1")
+
+ # set feedrate percentage
+ if "speed" in values:
+ codes.append("M220 S" + str(values["speed"]) + " T1")
+
+ # set print rate percentage
+ if "printspeed" in values:
+ codes.append(";PRINTSPEED " + str(values["printspeed"]) + "")
+
+ # set retract rate
+ if "retractfeedrate" in values:
+
+ if self.IsLinearRetraction:
+ codes.append(";RETRACTFEEDRATE " + str(values["retractfeedrate"] * 60) + "")
+ else:
+ codes.append("M207 F" + str(values["retractfeedrate"] * 60) + "")
+
+ # set retract length
+ if "retractlength" in values:
+
+ if self.IsLinearRetraction:
+ codes.append(";RETRACTLENGTH " + str(values["retractlength"]) + "")
+ else:
+ codes.append("M207 S" + str(values["retractlength"]) + "")
+
+ return codes
+
+ # Builds the restored layer settings based on the previous settings and returns the relevant GCODE lines
+ def getLastValues(self) -> str:
+
+ # build the gcode to restore our last values
+ return self.getCodeFromValues(self.getChangedLastValues())
+
+ # Builds the gcode to inject either the changed values we want or restore the previous values
+ def getInjectCode(self) -> str:
+
+ # if we're now outside of our target layer and haven't restored our last values, do so now
+ if not self.IsInsideTargetLayer and self.WasInsideTargetLayer and not self.IsLastValuesRestored:
+
+ # mark that we've injected the last values
+ self.IsLastValuesRestored = True
+
+ # inject the defaults
+ return self.getLastValues() + "\n" + self.getLastDisplayValues()
+
+ # if we're inside our target layer but haven't added our values yet, do so now
+ if self.IsInsideTargetLayer and not self.IsTargetValuesInjected:
+
+ # mark that we've injected the target values
+ self.IsTargetValuesInjected = True
+
+ # inject the defaults
+ return self.getTargetValues() + "\n" + self.getTargetDisplayValues()
+
+ # nothing to do
+ return ""
+
+ # Returns the unmodified GCODE line from previous ChangeZ edits
+ @staticmethod
+ def getOriginalLine(line: str) -> str:
+
+ # get the change at z original (cazo) details
+ original_line = re.search(r"\[CAZO:(.*?):CAZO\]", line)
+
+ # if we didn't get a hit, this is the original line
+ if original_line is None:
+ return line
+
+ return original_line.group(1)
+
+ # Builds the target layer settings based on the specified values and returns the relevant GCODE lines
+ def getTargetValues(self) -> str:
+
+ # build the gcode to change our current values
+ return self.getCodeFromValues(self.TargetValues)
+
+ # Determines if the current line is at or below the target required to start modifying
+ def isTargetLayerOrHeight(self) -> bool:
+
+ # target selected by layer no.
+ if self.IsTargetByLayer:
+
+ # if we don't have a current layer, we're not there yet
+ if self.CurrentLayer is None:
+ return False
+
+ # if we're applying to a single layer, stop if our layer is not identical
+ if self.IsApplyToSingleLayer:
+ return self.CurrentLayer == self.TargetLayer
+ else:
+ return self.CurrentLayer >= self.TargetLayer
+
+ else:
+
+ # if we don't have a current Z, we're not there yet
+ if self.CurrentZ is None:
+ return False
+
+ # if we're applying to a single layer, stop if our Z is not identical
+ if self.IsApplyToSingleLayer:
+ return self.CurrentZ == self.TargetZ
+ else:
+ return self.CurrentZ >= self.TargetZ
+
+ # Marks any current ChangeZ layer defaults in the layer for deletion
+ @staticmethod
+ def markChangesForDeletion(layer: str):
+ return re.sub(r";\[CAZD:", ";[CAZD:DELETE:", layer)
+
+ # Grabs the current height
+ def processLayerHeight(self, line: str):
+
+ # stop here if we haven't entered a layer yet
+ if self.CurrentLayer is None:
+ return
+
+ # get our gcode command
+ command = GCodeCommand.getFromLine(line)
+
+ # skip if it's not a command we're interested in
+ if command is None:
+ return
+
+ # stop here if this isn't a linear move command
+ if command.Command != "G0" and command.Command != "G1":
+ return
+
+ # get our value from the command
+ current_z = command.getArgumentAsFloat("Z", None)
+
+ # stop here if we don't have a Z value defined, we can't get the height from this command
+ if current_z is None:
+ return
+
+ # stop if there's no change
+ if current_z == self.CurrentZ:
+ return
+
+ # set our current Z value
+ self.CurrentZ = current_z
+
+ # if we don't have a layer height yet, set it based on the current Z value
+ if self.LayerHeight is None:
+ self.LayerHeight = self.CurrentZ
+
+ # Grabs the current layer number
+ def processLayerNumber(self, line: str):
+
+ # if this isn't a layer comment, stop here, nothing to update
+ if ";LAYER:" not in line:
+ return
+
+ # get our current layer number
+ current_layer = GCodeCommand.getDirectArgumentAsInt(line, ";LAYER:", None)
+
+ # this should never happen, but if our layer number hasn't changed, stop here
+ if current_layer == self.CurrentLayer:
+ return
+
+ # update our current layer
+ self.CurrentLayer = current_layer
+
+ # Makes any linear move changes and also injects either target or restored values depending on the plugin state
+ def processLine(self, line: str) -> str:
+
+ # used to change the given line of code
+ modified_gcode = ""
+
+ # track any values that we may be interested in
+ self.trackChangeableValues(line)
+
+ # if we're not inside the target layer, simply read the any
+ # settings we can and revert any ChangeAtZ deletions
+ if not self.IsInsideTargetLayer:
+
+ # read any settings if we haven't hit our target layer yet
+ if not self.WasInsideTargetLayer:
+ self.processSetting(line)
+
+ # if we haven't hit our target yet, leave the defaults as is (unmark them for deletion)
+ if "[CAZD:DELETE:" in line:
+ line = line.replace("[CAZD:DELETE:", "[CAZD:")
+
+ # if we're targeting by Z, we want to add our values before the first linear move
+ if "G1 " in line or "G0 " in line:
+ modified_gcode += self.getInjectCode()
+
+ # modify our command if we're still inside our target layer, otherwise pass unmodified
+ if self.IsInsideTargetLayer:
+ modified_gcode += self.processLinearMove(line) + "\n"
+ else:
+ modified_gcode += line + "\n"
+
+ # if we're targetting by layer we want to add our values just after the layer label
+ if ";LAYER:" in line:
+ modified_gcode += self.getInjectCode()
+
+ # return our changed code
+ return modified_gcode
+
+ # Handles any linear moves in the current line
+ def processLinearMove(self, line: str) -> str:
+
+ # if it's not a linear motion command we're not interested
+ if not ("G1 " in line or "G0 " in line):
+ return line
+
+ # always get our original line, otherwise the effect will be cumulative
+ line = self.getOriginalLine(line)
+
+ # get our command from the line
+ linear_command = GCodeCommand.getLinearMoveCommand(line)
+
+ # if it's not a linear move, we don't care
+ if linear_command is None:
+ return
+
+ # get our linear move parameters
+ feed_rate = linear_command.Arguments["F"]
+ x_coord = linear_command.Arguments["X"]
+ y_coord = linear_command.Arguments["Y"]
+ z_coord = linear_command.Arguments["Z"]
+ extrude_length = linear_command.Arguments["E"]
+
+ # set our new line to our old line
+ new_line = line
+
+ # handle retract length
+ new_line = self.processRetractLength(extrude_length, feed_rate, new_line, x_coord, y_coord, z_coord)
+
+ # handle retract feed rate
+ new_line = self.processRetractFeedRate(extrude_length, feed_rate, new_line, x_coord, y_coord, z_coord)
+
+ # handle print speed adjustments
+ new_line = self.processPrintSpeed(feed_rate, new_line)
+
+ # set our current extrude position
+ self.LastE = extrude_length if extrude_length is not None else self.LastE
+
+ # if no changes have been made, stop here
+ if new_line == line:
+ return line
+
+ # return our updated command
+ return self.setOriginalLine(new_line, line)
+
+ # Handles any changes to print speed for the given linear motion command
+ def processPrintSpeed(self, feed_rate: float, new_line: str) -> str:
+
+ # if we're not setting print speed or we don't have a feed rate, stop here
+ if "printspeed" not in self.TargetValues or feed_rate is None:
+ return new_line
+
+ # get our requested print speed
+ print_speed = int(self.TargetValues["printspeed"])
+
+ # if they requested no change to print speed (ie: 100%), stop here
+ if print_speed == 100:
+ return new_line
+
+ # get our feed rate from the command
+ feed_rate = GCodeCommand.getDirectArgumentAsFloat(new_line, "F") * (float(print_speed) / 100.0)
+
+ # change our feed rate
+ return GCodeCommand.replaceDirectArgument(new_line, "F", feed_rate)
+
+ # Handles any changes to retraction length for the given linear motion command
+ def processRetractLength(self, extrude_length: float, feed_rate: float, new_line: str, x_coord: float, y_coord: float, z_coord: float) -> str:
+
+ # if we don't have a retract length in the file we can't add one
+ if "retractlength" not in self.LastValues or self.LastValues["retractlength"] == 0:
+ return new_line
+
+ # if we're not changing retraction length, stop here
+ if "retractlength" not in self.TargetValues:
+ return new_line
+
+ # retractions are only F (feed rate) and E (extrude), at least in cura
+ if x_coord is not None or y_coord is not None or z_coord is not None:
+ return new_line
+
+ # since retractions require both F and E, and we don't have either, we can't process
+ if feed_rate is None or extrude_length is None:
+ return new_line
+
+ # stop here if we don't know our last extrude value
+ if self.LastE is None:
+ return new_line
+
+ # if there's no change in extrude we have nothing to change
+ if self.LastE == extrude_length:
+ return new_line
+
+ # if our last extrude was lower than our current, we're restoring, so skip
+ if self.LastE < extrude_length:
+ return new_line
+
+ # get our desired retract length
+ retract_length = float(self.TargetValues["retractlength"])
+
+ # subtract the difference between the default and the desired
+ extrude_length -= (retract_length - self.LastValues["retractlength"])
+
+ # replace our extrude amount
+ return GCodeCommand.replaceDirectArgument(new_line, "E", extrude_length)
+
+ # Used for picking out the retract length set by Cura
+ def processRetractLengthSetting(self, line: str):
+
+ # skip if we're not doing linear retractions
+ if not self.IsLinearRetraction:
+ return
+
+ # get our command from the line
+ linear_command = GCodeCommand.getLinearMoveCommand(line)
+
+ # if it's not a linear move, we don't care
+ if linear_command is None:
+ return
+
+ # get our linear move parameters
+ feed_rate = linear_command.Arguments["F"]
+ x_coord = linear_command.Arguments["X"]
+ y_coord = linear_command.Arguments["Y"]
+ z_coord = linear_command.Arguments["Z"]
+ extrude_length = linear_command.Arguments["E"]
+
+ # the command we're looking for only has extrude and feed rate
+ if x_coord is not None or y_coord is not None or z_coord is not None:
+ return
+
+ # if either extrude or feed is missing we're likely looking at the wrong command
+ if extrude_length is None or feed_rate is None:
+ return
+
+ # cura stores the retract length as a negative E just before it starts printing
+ extrude_length = extrude_length * -1
+
+ # if it's a negative extrude after being inverted, it's not our retract length
+ if extrude_length < 0:
+ return
+
+ # what ever the last negative retract length is it wins
+ self.LastValues["retractlength"] = extrude_length
+
+ # Handles any changes to retraction feed rate for the given linear motion command
+ def processRetractFeedRate(self, extrude_length: float, feed_rate: float, new_line: str, x_coord: float, y_coord: float, z_coord: float) -> str:
+
+ # skip if we're not doing linear retractions
+ if not self.IsLinearRetraction:
+ return new_line
+
+ # if we're not changing retraction length, stop here
+ if "retractfeedrate" not in self.TargetValues:
+ return new_line
+
+ # retractions are only F (feed rate) and E (extrude), at least in cura
+ if x_coord is not None or y_coord is not None or z_coord is not None:
+ return new_line
+
+ # since retractions require both F and E, and we don't have either, we can't process
+ if feed_rate is None or extrude_length is None:
+ return new_line
+
+ # get our desired retract feed rate
+ retract_feed_rate = float(self.TargetValues["retractfeedrate"])
+
+ # convert to units/min
+ retract_feed_rate *= 60
+
+ # replace our feed rate
+ return GCodeCommand.replaceDirectArgument(new_line, "F", retract_feed_rate)
+
+ # Used for finding settings in the print file before we process anything else
+ def processSetting(self, line: str):
+
+ # if we're in layers already we're out of settings
+ if self.CurrentLayer is not None:
+ return
+
+ # check our retract length
+ self.processRetractLengthSetting(line)
+
+ # Sets the flags if we're at the target layer or not
+ def processTargetLayer(self):
+
+ # skip this line if we're not there yet
+ if not self.isTargetLayerOrHeight():
+
+ # flag that we're outside our target layer
+ self.IsInsideTargetLayer = False
+
+ # skip to the next line
+ return
+
+ # flip if we hit our target layer
+ self.WasInsideTargetLayer = True
+
+ # flag that we're inside our target layer
+ self.IsInsideTargetLayer = True
+
+ # Removes all the ChangeZ layer defaults from the given layer
+ @staticmethod
+ def removeMarkedChanges(layer: str) -> str:
+ return re.sub(r";\[CAZD:DELETE:[\s\S]+?:CAZD\](\n|$)", "", layer)
+
+ # Resets the class contents to defaults
+ def reset(self):
+
+ self.TargetValues = {}
+ self.IsApplyToSingleLayer = False
+ self.LastE = None
+ self.CurrentZ = None
+ self.CurrentLayer = None
+ self.IsTargetByLayer = True
+ self.TargetLayer = None
+ self.TargetZ = None
+ self.LayerHeight = None
+ self.LastValues = {}
+ self.IsLinearRetraction = True
+ self.IsInsideTargetLayer = False
+ self.IsTargetValuesInjected = False
+ self.IsLastValuesRestored = False
+ self.WasInsideTargetLayer = False
+ self.IsEnabled = True
+
+ # Sets the original GCODE line in a given GCODE command
+ @staticmethod
+ def setOriginalLine(line, original) -> str:
+ return line + ";[CAZO:" + original + ":CAZO]"
+
+ # Tracks the change in gcode values we're interested in
+ def trackChangeableValues(self, line: str):
+
+ # simulate a print speed command
+ if ";PRINTSPEED" in line:
+ line = line.replace(";PRINTSPEED ", "M220 S")
+
+ # simulate a retract feedrate command
+ if ";RETRACTFEEDRATE" in line:
+ line = line.replace(";RETRACTFEEDRATE ", "M207 F")
+
+ # simulate a retract length command
+ if ";RETRACTLENGTH" in line:
+ line = line.replace(";RETRACTLENGTH ", "M207 S")
+
+ # get our gcode command
+ command = GCodeCommand.getFromLine(line)
+
+ # stop here if it isn't a G or M command
+ if command is None:
+ return
+
+ # handle retract length changes
+ if command.Command == "M207":
+
+ # get our retract length if provided
+ if "S" in command.Arguments:
+ self.LastValues["retractlength"] = command.getArgumentAsFloat("S")
+
+ # get our retract feedrate if provided, convert from mm/m to mm/s
+ if "F" in command.Arguments:
+ self.LastValues["retractfeedrate"] = command.getArgumentAsFloat("F") / 60.0
+
+ # move to the next command
+ return
+
+ # handle bed temp changes
+ if command.Command == "M140" or command.Command == "M190":
+
+ # get our bed temp if provided
+ if "S" in command.Arguments:
+ self.LastValues["bedTemp"] = command.getArgumentAsFloat("S")
+
+ # move to the next command
+ return
+
+ # handle extruder temp changes
+ if command.Command == "M104" or command.Command == "M109":
+
+ # get our tempurature
+ tempurature = command.getArgumentAsFloat("S")
+
+ # don't bother if we don't have a tempurature
+ if tempurature is None:
+ return
+
+ # get our extruder, default to extruder one
+ extruder = command.getArgumentAsInt("T", None)
+
+ # set our extruder temp based on the extruder
+ if extruder is None or extruder == 0:
+ self.LastValues["extruderOne"] = tempurature
+
+ if extruder is None or extruder == 1:
+ self.LastValues["extruderTwo"] = tempurature
+
+ # move to the next command
+ return
+
+ # handle fan speed changes
+ if command.Command == "M106":
+
+ # get our bed temp if provided
+ if "S" in command.Arguments:
+ self.LastValues["fanSpeed"] = (command.getArgumentAsInt("S") / 255.0) * 100
+
+ # move to the next command
+ return
+
+ # handle flow rate changes
+ if command.Command == "M221":
+
+ # get our flow rate
+ tempurature = command.getArgumentAsFloat("S")
+
+ # don't bother if we don't have a flow rate (for some reason)
+ if tempurature is None:
+ return
+
+ # get our extruder, default to global
+ extruder = command.getArgumentAsInt("T", None)
+
+ # set our extruder temp based on the extruder
+ if extruder is None:
+ self.LastValues["flowrate"] = tempurature
+ elif extruder == 1:
+ self.LastValues["flowrateOne"] = tempurature
+ elif extruder == 1:
+ self.LastValues["flowrateTwo"] = tempurature
+
+ # move to the next command
+ return
+
+ # handle print speed changes
+ if command.Command == "M220":
+
+ # get our speed if provided
+ if "S" in command.Arguments:
+ self.LastValues["speed"] = command.getArgumentAsInt("S")
+
+ # move to the next command
+ return
diff --git a/plugins/PrepareStage/plugin.json b/plugins/PrepareStage/plugin.json
index 3c2f72dc53..49c6ba873d 100644
--- a/plugins/PrepareStage/plugin.json
+++ b/plugins/PrepareStage/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides a prepare stage in Cura.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/PreviewStage/plugin.json b/plugins/PreviewStage/plugin.json
index daa0ba8748..813a28d245 100644
--- a/plugins/PreviewStage/plugin.json
+++ b/plugins/PreviewStage/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides a preview stage in Cura.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/RemovableDriveOutputDevice/plugin.json b/plugins/RemovableDriveOutputDevice/plugin.json
index df47fdeeff..e70be24dda 100644
--- a/plugins/RemovableDriveOutputDevice/plugin.json
+++ b/plugins/RemovableDriveOutputDevice/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"description": "Provides removable drive hotplugging and writing support.",
"version": "1.0.1",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/SentryLogger/plugin.json b/plugins/SentryLogger/plugin.json
index 03d7afbf5d..0419e70d25 100644
--- a/plugins/SentryLogger/plugin.json
+++ b/plugins/SentryLogger/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Logs certain events so that they can be used by the crash reporter",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/SimulationView/plugin.json b/plugins/SimulationView/plugin.json
index a6dc8052d7..9a0f322888 100644
--- a/plugins/SimulationView/plugin.json
+++ b/plugins/SimulationView/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides the Simulation view.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/SliceInfoPlugin/plugin.json b/plugins/SliceInfoPlugin/plugin.json
index 15e4b6fa97..b5b8d48713 100644
--- a/plugins/SliceInfoPlugin/plugin.json
+++ b/plugins/SliceInfoPlugin/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Submits anonymous slice info. Can be disabled through preferences.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/SolidView/SolidView.py b/plugins/SolidView/SolidView.py
index 8c9967be03..bfe803f224 100644
--- a/plugins/SolidView/SolidView.py
+++ b/plugins/SolidView/SolidView.py
@@ -149,6 +149,7 @@ class SolidView(View):
theme = Application.getInstance().getTheme()
self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb()))
self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb()))
+ self._xray_composite_shader.setUniformValue("u_flat_error_color_mix", 0.) # Don't show flat error color in solid-view.
renderer = self.getRenderer()
if not self._composite_pass or not 'xray' in self._composite_pass.getLayerBindings():
@@ -267,13 +268,23 @@ class SolidView(View):
Class that ducktypes to be a Numpy ndarray.
"""
def __init__(self, qimage):
- self.__array_interface__ = {
- "shape": (qimage.height(), qimage.width()),
- "typestr": "|u4", # Use 4 bytes per pixel rather than 3, since Numpy doesn't support 3.
- "data": (int(qimage.bits()), False),
- "strides": (qimage.bytesPerLine(), 3), # This does the magic: For each line, skip the correct number of bytes. Bytes per pixel is always 3 due to QImage.Format.Format_RGB888.
- "version": 3
- }
+ bits_pointer = qimage.bits()
+ if bits_pointer is None: # If this happens before there is a window.
+ self.__array_interface__ = {
+ "shape": (0, 0),
+ "typestr": "|u4",
+ "data": (0, False),
+ "strides": (1, 3),
+ "version": 3
+ }
+ else:
+ self.__array_interface__ = {
+ "shape": (qimage.height(), qimage.width()),
+ "typestr": "|u4", # Use 4 bytes per pixel rather than 3, since Numpy doesn't support 3.
+ "data": (int(bits_pointer), False),
+ "strides": (qimage.bytesPerLine(), 3), # This does the magic: For each line, skip the correct number of bytes. Bytes per pixel is always 3 due to QImage.Format.Format_RGB888.
+ "version": 3
+ }
array = np.asarray(QImageArrayView(xray_img)).view(np.dtype({
"r": (np.uint8, 0, "red"),
"g": (np.uint8, 1, "green"),
@@ -286,25 +297,6 @@ class SolidView(View):
Logger.log("i", "X-Ray overlay found non-manifold pixels.")
def event(self, event):
- if event.type == Event.ViewActivateEvent:
- # FIX: on Max OS X, somehow QOpenGLContext.currentContext() can become None during View switching.
- # This can happen when you do the following steps:
- # 1. Start Cura
- # 2. Load a model
- # 3. Switch to Custom mode
- # 4. Select the model and click on the per-object tool icon
- # 5. Switch view to Layer view or X-Ray
- # 6. Cura will very likely crash
- # It seems to be a timing issue that the currentContext can somehow be empty, but I have no clue why.
- # This fix tries to reschedule the view changing event call on the Qt thread again if the current OpenGL
- # context is None.
- if Platform.isOSX():
- if QOpenGLContext.currentContext() is None:
- Logger.log("d", "current context of OpenGL is empty on Mac OS X, will try to create shaders later")
- Application.getInstance().callLater(lambda e = event: self.event(e))
- return
-
-
if event.type == Event.ViewDeactivateEvent:
if self._composite_pass and 'xray' in self._composite_pass.getLayerBindings():
self.getRenderer().removeRenderPass(self._xray_pass)
diff --git a/plugins/SolidView/plugin.json b/plugins/SolidView/plugin.json
index e30f7f56c6..1619ced52f 100644
--- a/plugins/SolidView/plugin.json
+++ b/plugins/SolidView/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides a normal solid mesh view.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/SupportEraser/plugin.json b/plugins/SupportEraser/plugin.json
index f6f21e94e3..5686995eac 100644
--- a/plugins/SupportEraser/plugin.json
+++ b/plugins/SupportEraser/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Creates an eraser mesh to block the printing of support in certain places",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/Toolbox/plugin.json b/plugins/Toolbox/plugin.json
index 742b25422b..f1243d2166 100644
--- a/plugins/Toolbox/plugin.json
+++ b/plugins/Toolbox/plugin.json
@@ -2,6 +2,6 @@
"name": "Toolbox",
"author": "Ultimaker B.V.",
"version": "1.0.1",
- "api": "7.1",
+ "api": "7.2.0",
"description": "Find, manage and install new Cura packages."
}
diff --git a/plugins/Toolbox/resources/images/logobot.svg b/plugins/Toolbox/resources/images/logobot.svg
deleted file mode 100644
index 8234f66887..0000000000
--- a/plugins/Toolbox/resources/images/logobot.svg
+++ /dev/null
@@ -1,161 +0,0 @@
-
-
-
-
diff --git a/plugins/Toolbox/resources/qml/pages/WelcomePage.qml b/plugins/Toolbox/resources/qml/pages/WelcomePage.qml
index cbfdf8f402..04110cbc0f 100644
--- a/plugins/Toolbox/resources/qml/pages/WelcomePage.qml
+++ b/plugins/Toolbox/resources/qml/pages/WelcomePage.qml
@@ -16,19 +16,10 @@ Column
height: childrenRect.height
anchors.centerIn: parent
- Image
- {
- id: profileImage
- fillMode: Image.PreserveAspectFit
- source: "../../images/logobot.svg"
- anchors.horizontalCenter: parent.horizontalCenter
- width: Math.round(parent.width / 4)
- }
-
Label
{
id: welcomeTextLabel
- text: catalog.i18nc("@description", "Get plugins and materials verified by Ultimaker")
+ text: catalog.i18nc("@description", "Please sign in to get verified plugins and materials for Ultimaker Cura Enterprise")
width: Math.round(parent.width / 2)
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
diff --git a/plugins/TrimeshReader/plugin.json b/plugins/TrimeshReader/plugin.json
index e9b18946bb..1761628ac8 100644
--- a/plugins/TrimeshReader/plugin.json
+++ b/plugins/TrimeshReader/plugin.json
@@ -3,5 +3,5 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides support for reading model files.",
- "api": "7.1.0"
+ "api": "7.2.0"
}
diff --git a/plugins/UFPReader/plugin.json b/plugins/UFPReader/plugin.json
index 1468380035..cd1126c84b 100644
--- a/plugins/UFPReader/plugin.json
+++ b/plugins/UFPReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Provides support for reading Ultimaker Format Packages.",
- "supported_sdk_versions": ["7.1.0"],
+ "supported_sdk_versions": ["7.2.0"],
"i18n-catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/UFPWriter/plugin.json b/plugins/UFPWriter/plugin.json
index 34586554b8..2aa46f7830 100644
--- a/plugins/UFPWriter/plugin.json
+++ b/plugins/UFPWriter/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides support for writing Ultimaker Format Packages.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
\ No newline at end of file
diff --git a/plugins/UM3NetworkPrinting/plugin.json b/plugins/UM3NetworkPrinting/plugin.json
index 7de542404a..5d98658cd9 100644
--- a/plugins/UM3NetworkPrinting/plugin.json
+++ b/plugins/UM3NetworkPrinting/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"description": "Manages network connections to Ultimaker networked printers.",
"version": "2.0.0",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py
index ccc64f8073..cae585ffa4 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py
+++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py
@@ -1,26 +1,29 @@
# Copyright (c) 2019 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-
+import os
from typing import Dict, List, Optional
+
from PyQt5.QtCore import QTimer
from UM import i18nCatalog
from UM.Logger import Logger # To log errors talking to the API.
+from UM.Message import Message
from UM.Signal import Signal
from cura.API import Account
from cura.CuraApplication import CuraApplication
from cura.Settings.CuraStackBuilder import CuraStackBuilder
from cura.Settings.GlobalStack import GlobalStack
-
from .CloudApiClient import CloudApiClient
from .CloudOutputDevice import CloudOutputDevice
from ..Models.Http.CloudClusterResponse import CloudClusterResponse
-## The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters.
-# Keeping all cloud related logic in this class instead of the UM3OutputDevicePlugin results in more readable code.
-# API spec is available on https://api.ultimaker.com/docs/connect/spec/.
class CloudOutputDeviceManager:
+ """The cloud output device manager is responsible for using the Ultimaker Cloud APIs to manage remote clusters.
+
+ Keeping all cloud related logic in this class instead of the UM3OutputDevicePlugin results in more readable code.
+ API spec is available on https://api.ultimaker.com/docs/connect/spec/.
+ """
META_CLUSTER_ID = "um_cloud_cluster_id"
META_NETWORK_KEY = "um_network_key"
@@ -44,14 +47,16 @@ class CloudOutputDeviceManager:
# Create a timer to update the remote cluster list
self._update_timer = QTimer()
self._update_timer.setInterval(int(self.CHECK_CLUSTER_INTERVAL * 1000))
- self._update_timer.setSingleShot(False)
+ # The timer is restarted explicitly after an update was processed. This prevents 2 concurrent updates
+ self._update_timer.setSingleShot(True)
self._update_timer.timeout.connect(self._getRemoteClusters)
# Ensure we don't start twice.
self._running = False
- ## Starts running the cloud output device manager, thus periodically requesting cloud data.
def start(self):
+ """Starts running the cloud output device manager, thus periodically requesting cloud data."""
+
if self._running:
return
if not self._account.isLoggedIn:
@@ -61,8 +66,9 @@ class CloudOutputDeviceManager:
self._update_timer.start()
self._getRemoteClusters()
- ## Stops running the cloud output device manager.
def stop(self):
+ """Stops running the cloud output device manager."""
+
if not self._running:
return
self._running = False
@@ -70,87 +76,164 @@ class CloudOutputDeviceManager:
self._update_timer.stop()
self._onGetRemoteClustersFinished([]) # Make sure we remove all cloud output devices.
- ## Force refreshing connections.
def refreshConnections(self) -> None:
+ """Force refreshing connections."""
+
self._connectToActiveMachine()
- ## Called when the uses logs in or out
def _onLoginStateChanged(self, is_logged_in: bool) -> None:
+ """Called when the uses logs in or out"""
+
if is_logged_in:
self.start()
else:
self.stop()
- ## Gets all remote clusters from the API.
def _getRemoteClusters(self) -> None:
+ """Gets all remote clusters from the API."""
+
self._api.getClusters(self._onGetRemoteClustersFinished)
- ## Callback for when the request for getting the clusters is finished.
def _onGetRemoteClustersFinished(self, clusters: List[CloudClusterResponse]) -> None:
+ """Callback for when the request for getting the clusters is finished."""
+
+ new_clusters = []
online_clusters = {c.cluster_id: c for c in clusters if c.is_online} # type: Dict[str, CloudClusterResponse]
+
for device_id, cluster_data in online_clusters.items():
if device_id not in self._remote_clusters:
- self._onDeviceDiscovered(cluster_data)
- else:
- self._onDiscoveredDeviceUpdated(cluster_data)
+ new_clusters.append(cluster_data)
+
+ self._onDevicesDiscovered(new_clusters)
+
+ # Inform whether new cloud printers have been detected. If they have, the welcome wizard can close.
+ self._account._new_cloud_printers_detected = len(new_clusters) > 0
+ self._account.cloudPrintersDetectedChanged.emit(len(new_clusters) > 0)
removed_device_keys = set(self._remote_clusters.keys()) - set(online_clusters.keys())
for device_id in removed_device_keys:
self._onDiscoveredDeviceRemoved(device_id)
- def _onDeviceDiscovered(self, cluster_data: CloudClusterResponse) -> None:
- device = CloudOutputDevice(self._api, cluster_data)
- CuraApplication.getInstance().getDiscoveredPrintersModel().addDiscoveredPrinter(
- ip_address=device.key,
- key=device.getId(),
- name=device.getName(),
- create_callback=self._createMachineFromDiscoveredDevice,
- machine_type=device.printerType,
- device=device
- )
- self._remote_clusters[device.getId()] = device
- self.discoveredDevicesChanged.emit()
- self._connectToActiveMachine()
+ if new_clusters or removed_device_keys:
+ self.discoveredDevicesChanged.emit()
+ if removed_device_keys:
+ # If the removed device was active we should connect to the new active device
+ self._connectToActiveMachine()
+ # Schedule a new update
+ self._update_timer.start()
- def _onDiscoveredDeviceUpdated(self, cluster_data: CloudClusterResponse) -> None:
- device = self._remote_clusters.get(cluster_data.cluster_id)
- if not device:
+ def _onDevicesDiscovered(self, clusters: List[CloudClusterResponse]) -> None:
+ """**Synchronously** create machines for discovered devices
+
+ Any new machines are made available to the user.
+ May take a long time to complete. As this code needs access to the Application
+ and blocks the GIL, creating a Job for this would not make sense.
+ Shows a Message informing the user of progress.
+ """
+ new_devices = []
+ remote_clusters_added = False
+ for cluster_data in clusters:
+ device = CloudOutputDevice(self._api, cluster_data)
+ # Create a machine if we don't already have it. Do not make it the active machine.
+ machine_manager = CuraApplication.getInstance().getMachineManager()
+
+ # We only need to add it if it wasn't already added by "local" network or by cloud.
+ if machine_manager.getMachine(device.printerType, {self.META_CLUSTER_ID: device.key}) is None \
+ and machine_manager.getMachine(device.printerType, {self.META_NETWORK_KEY: cluster_data.host_name + "*"}) is None: # The host name is part of the network key.
+ new_devices.append(device)
+ elif device.getId() not in self._remote_clusters:
+ self._remote_clusters[device.getId()] = device
+ remote_clusters_added = True
+
+ if not new_devices:
+ if remote_clusters_added:
+ self._connectToActiveMachine()
return
- CuraApplication.getInstance().getDiscoveredPrintersModel().updateDiscoveredPrinter(
- ip_address=device.key,
- name=cluster_data.friendly_name,
- machine_type=device.printerType
+
+ new_devices.sort(key = lambda x: x.name.lower())
+
+ image_path = os.path.join(
+ CuraApplication.getInstance().getPluginRegistry().getPluginPath("UM3NetworkPrinting") or "",
+ "resources", "svg", "cloud-flow-completed.svg"
)
- self.discoveredDevicesChanged.emit()
+
+ message = Message(
+ title = self.I18N_CATALOG.i18ncp(
+ "info:status",
+ "New printer detected from your Ultimaker account",
+ "New printers detected from your Ultimaker account",
+ len(new_devices)
+ ),
+ progress = 0,
+ lifetime = 0,
+ image_source = image_path
+ )
+ message.show()
+
+ for idx, device in enumerate(new_devices):
+ message_text = self.I18N_CATALOG.i18nc(
+ "info:status", "Adding printer {} ({}) from your account",
+ device.name,
+ device.printerTypeName
+ )
+ message.setText(message_text)
+ if len(new_devices) > 1:
+ message.setProgress((idx / len(new_devices)) * 100)
+ CuraApplication.getInstance().processEvents()
+ self._remote_clusters[device.getId()] = device
+
+ # If there is no active machine, activate the first available cloud printer
+ activate = not CuraApplication.getInstance().getMachineManager().activeMachine
+ self._createMachineFromDiscoveredDevice(device.getId(), activate = activate)
+
+ message.setProgress(None)
+
+ max_disp_devices = 3
+ if len(new_devices) > max_disp_devices:
+ num_hidden = len(new_devices) - max_disp_devices + 1
+ device_name_list = ["- {} ({})".format(device.name, device.printerTypeName) for device in new_devices[0:num_hidden]]
+ device_name_list.append(self.I18N_CATALOG.i18nc("info:hidden list items", "- and {} others", num_hidden))
+ device_names = "\n".join(device_name_list)
+ else:
+ device_names = "\n".join(["- {} ({})".format(device.name, device.printerTypeName) for device in new_devices])
+
+ message_text = self.I18N_CATALOG.i18nc(
+ "info:status",
+ "Cloud printers added from your account:\n{}",
+ device_names
+ )
+ message.setText(message_text)
def _onDiscoveredDeviceRemoved(self, device_id: str) -> None:
device = self._remote_clusters.pop(device_id, None) # type: Optional[CloudOutputDevice]
if not device:
return
device.close()
- CuraApplication.getInstance().getDiscoveredPrintersModel().removeDiscoveredPrinter(device.key)
output_device_manager = CuraApplication.getInstance().getOutputDeviceManager()
if device.key in output_device_manager.getOutputDeviceIds():
output_device_manager.removeOutputDevice(device.key)
- self.discoveredDevicesChanged.emit()
- def _createMachineFromDiscoveredDevice(self, key: str) -> None:
+ def _createMachineFromDiscoveredDevice(self, key: str, activate: bool = True) -> None:
device = self._remote_clusters[key]
if not device:
return
- # Create a new machine and activate it.
+ # Create a new machine.
# We do not use use MachineManager.addMachine here because we need to set the cluster ID before activating it.
new_machine = CuraStackBuilder.createMachine(device.name, device.printerType)
if not new_machine:
Logger.log("e", "Failed creating a new machine")
return
new_machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key)
- CuraApplication.getInstance().getMachineManager().setActiveMachine(new_machine.getId())
- self._connectToOutputDevice(device, new_machine)
- ## Callback for when the active machine was changed by the user or a new remote cluster was found.
+ self._setOutputDeviceMetadata(device, new_machine)
+
+ if activate:
+ CuraApplication.getInstance().getMachineManager().setActiveMachine(new_machine.getId())
+
def _connectToActiveMachine(self) -> None:
+ """Callback for when the active machine was changed by the user"""
+
active_machine = CuraApplication.getInstance().getGlobalContainerStack()
if not active_machine:
return
@@ -169,13 +252,17 @@ class CloudOutputDeviceManager:
# Remove device if it is not meant for the active machine.
output_device_manager.removeOutputDevice(device.key)
- ## Connects to an output device and makes sure it is registered in the output device manager.
- def _connectToOutputDevice(self, device: CloudOutputDevice, machine: GlobalStack) -> None:
+ def _setOutputDeviceMetadata(self, device: CloudOutputDevice, machine: GlobalStack):
machine.setName(device.name)
machine.setMetaDataEntry(self.META_CLUSTER_ID, device.key)
machine.setMetaDataEntry("group_name", device.name)
machine.addConfiguredConnectionType(device.connectionType.value)
+ def _connectToOutputDevice(self, device: CloudOutputDevice, machine: GlobalStack) -> None:
+ """Connects to an output device and makes sure it is registered in the output device manager."""
+
+ self._setOutputDeviceMetadata(device, machine)
+
if not device.isConnected():
device.connect()
diff --git a/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py b/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py
index d5de7fe10a..6aa341c0e5 100644
--- a/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py
+++ b/plugins/UM3NetworkPrinting/src/Cloud/ToolPathUploader.py
@@ -125,7 +125,10 @@ class ToolPathUploader:
if self._retries < self.MAX_RETRIES and status_code in self.RETRY_HTTP_CODES:
self._retries += 1
Logger.log("i", "Retrying %s/%s request %s", self._retries, self.MAX_RETRIES, reply.url().toString())
- self._uploadChunk()
+ try:
+ self._uploadChunk()
+ except ValueError: # Asynchronously it could have completed in the meanwhile.
+ pass
return
# Http codes that are not to be retried are assumed to be errors.
diff --git a/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobStatus.py b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobStatus.py
index 9794da1bbb..22fb9bb37a 100644
--- a/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobStatus.py
+++ b/plugins/UM3NetworkPrinting/src/Models/Http/ClusterPrintJobStatus.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2019 Ultimaker B.V.
+# Copyright (c) 2020 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
from typing import List, Optional, Union, Dict, Any
@@ -44,6 +44,7 @@ class ClusterPrintJobStatus(BaseModel):
# \param compatible_machine_families: Family names of machines suitable for this print job
# \param impediments_to_printing: A list of reasons that prevent this job from being printed on the associated
# printer
+ # \param preview_url: URL to the preview image (same as wou;d've been included in the ufp).
def __init__(self, created_at: str, force: bool, machine_variant: str, name: str, started: bool, status: str,
time_total: int, uuid: str,
configuration: List[Union[Dict[str, Any], ClusterPrintCoreConfiguration]],
@@ -57,6 +58,7 @@ class ClusterPrintJobStatus(BaseModel):
build_plate: Union[Dict[str, Any], ClusterBuildPlate] = None,
compatible_machine_families: List[str] = None,
impediments_to_printing: List[Union[Dict[str, Any], ClusterPrintJobImpediment]] = None,
+ preview_url: Optional[str] = None,
**kwargs) -> None:
self.assigned_to = assigned_to
self.configuration = self.parseModels(ClusterPrintCoreConfiguration, configuration)
@@ -76,6 +78,7 @@ class ClusterPrintJobStatus(BaseModel):
self.uuid = uuid
self.deleted_at = deleted_at
self.printed_on_uuid = printed_on_uuid
+ self.preview_url = preview_url
self.configuration_changes_required = self.parseModels(ClusterPrintJobConfigurationChange,
configuration_changes_required) \
diff --git a/plugins/UM3NetworkPrinting/src/Models/UM3PrintJobOutputModel.py b/plugins/UM3NetworkPrinting/src/Models/UM3PrintJobOutputModel.py
index bfde233a35..b063a2bf5b 100644
--- a/plugins/UM3NetworkPrinting/src/Models/UM3PrintJobOutputModel.py
+++ b/plugins/UM3NetworkPrinting/src/Models/UM3PrintJobOutputModel.py
@@ -1,10 +1,13 @@
-# Copyright (c) 2019 Ultimaker B.V.
+# Copyright (c) 2020 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
-from typing import List
+from typing import List, Optional
from PyQt5.QtCore import pyqtProperty, pyqtSignal
from PyQt5.QtGui import QImage
+from PyQt5.QtNetwork import QNetworkReply, QNetworkRequest
+from UM.Logger import Logger
+from UM.TaskManagement.HttpRequestManager import HttpRequestManager
from cura.PrinterOutput.Models.PrintJobOutputModel import PrintJobOutputModel
from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
@@ -32,3 +35,13 @@ class UM3PrintJobOutputModel(PrintJobOutputModel):
image = QImage()
image.loadFromData(data)
self.updatePreviewImage(image)
+
+ def loadPreviewImageFromUrl(self, url: str) -> None:
+ HttpRequestManager.getInstance().get(url=url, callback=self._onImageLoaded, error_callback=self._onImageLoaded)
+
+ def _onImageLoaded(self, reply: QNetworkReply, error: Optional["QNetworkReply.NetworkError"] = None) -> None:
+ if not HttpRequestManager.replyIndicatesSuccess(reply, error):
+ Logger.warning("Requesting preview image failed, response code {0} while trying to connect to {1}".format(
+ reply.attribute(QNetworkRequest.HttpStatusCodeAttribute), reply.url()))
+ return
+ self.updatePreviewImageData(reply.readAll())
diff --git a/plugins/UM3NetworkPrinting/src/Network/SendMaterialJob.py b/plugins/UM3NetworkPrinting/src/Network/SendMaterialJob.py
index 5abc3cfde4..49e088100d 100644
--- a/plugins/UM3NetworkPrinting/src/Network/SendMaterialJob.py
+++ b/plugins/UM3NetworkPrinting/src/Network/SendMaterialJob.py
@@ -92,9 +92,13 @@ class SendMaterialJob(Job):
parts = []
# Add the material file.
- with open(file_path, "rb") as f:
- parts.append(self.device.createFormPart("name=\"file\"; filename=\"{file_name}\""
- .format(file_name = file_name), f.read()))
+ try:
+ with open(file_path, "rb") as f:
+ parts.append(self.device.createFormPart("name=\"file\"; filename=\"{file_name}\""
+ .format(file_name = file_name), f.read()))
+ except FileNotFoundError:
+ Logger.error("Unable to send material {material_id}, since it has been deleted in the meanwhile.".format(material_id = material_id))
+ return
# Add the material signature file if needed.
signature_file_path = "{}.sig".format(file_path)
diff --git a/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterOutputDevice.py b/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterOutputDevice.py
index c0d9029c52..f50bab8a1f 100644
--- a/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterOutputDevice.py
+++ b/plugins/UM3NetworkPrinting/src/UltimakerNetworkedPrinterOutputDevice.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2019 Ultimaker B.V.
+# Copyright (c) 2020 Ultimaker B.V.
# Cura is released under the terms of the LGPLv3 or higher.
import os
from time import time
@@ -52,7 +52,6 @@ class UltimakerNetworkedPrinterOutputDevice(NetworkedPrinterOutputDevice):
super().__init__(device_id=device_id, address=address, properties=properties, connection_type=connection_type,
parent=parent)
-
# Trigger the printersChanged signal when the private signal is triggered.
self.printersChanged.connect(self._clusterPrintersChanged)
@@ -330,6 +329,8 @@ class UltimakerNetworkedPrinterOutputDevice(NetworkedPrinterOutputDevice):
self._updateAssignedPrinter(model, remote_job.printer_uuid)
if remote_job.assigned_to:
self._updateAssignedPrinter(model, remote_job.assigned_to)
+ if remote_job.preview_url:
+ model.loadPreviewImageFromUrl(remote_job.preview_url)
return model
## Updates the printer assignment for the given print job model.
diff --git a/plugins/USBPrinting/USBPrinterOutputDevice.py b/plugins/USBPrinting/USBPrinterOutputDevice.py
index adb3b03700..cf07b98ca1 100644
--- a/plugins/USBPrinting/USBPrinterOutputDevice.py
+++ b/plugins/USBPrinting/USBPrinterOutputDevice.py
@@ -191,7 +191,10 @@ class USBPrinterOutputDevice(PrinterOutputDevice):
try:
self._serial = Serial(str(self._serial_port), self._baud_rate, timeout=self._timeout, writeTimeout=self._timeout)
except SerialException:
- Logger.log("w", "An exception occurred while trying to create serial connection")
+ Logger.warning("An exception occurred while trying to create serial connection.")
+ return
+ except OSError as e:
+ Logger.warning("The serial device is suddenly unavailable while trying to create a serial connection: {err}".format(err = str(e)))
return
CuraApplication.getInstance().globalContainerStackChanged.connect(self._onGlobalContainerStackChanged)
self._onGlobalContainerStackChanged()
diff --git a/plugins/USBPrinting/plugin.json b/plugins/USBPrinting/plugin.json
index 841c8b16a5..7d947061cf 100644
--- a/plugins/USBPrinting/plugin.json
+++ b/plugins/USBPrinting/plugin.json
@@ -2,7 +2,7 @@
"name": "USB printing",
"author": "Ultimaker B.V.",
"version": "1.0.2",
- "api": "7.1",
+ "api": "7.2.0",
"description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.",
"i18n-catalog": "cura"
}
diff --git a/plugins/UltimakerMachineActions/plugin.json b/plugins/UltimakerMachineActions/plugin.json
index 3fd504681a..607597a8c8 100644
--- a/plugins/UltimakerMachineActions/plugin.json
+++ b/plugins/UltimakerMachineActions/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.).",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py b/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py
index 536385b19d..c66f61596a 100644
--- a/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py
+++ b/plugins/VersionUpgrade/VersionUpgrade21to22/VersionUpgrade21to22.py
@@ -236,23 +236,11 @@ _variant_translations_materials = {
}
} # type: Dict[str, Dict[str, str]]
+
## Converts configuration from Cura 2.1's file formats to Cura 2.2's.
#
# It converts the machine instances and profiles.
class VersionUpgrade21to22(VersionUpgrade):
- ## Gets the version number from a config file.
- #
- # In all config files that concern this version upgrade, the version
- # number is stored in general/version, so get the data from that key.
- #
- # \param serialised The contents of a config file.
- # \return The version number of that config file.
- def getCfgVersion(self, serialised: str) -> int:
- 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
## Gets the fallback quality to use for a specific machine-variant-material
# combination.
diff --git a/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json b/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json
index 222d276463..96e2dace32 100644
--- a/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade21to22/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 2.1 to Cura 2.2.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json b/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json
index dde19da7a3..06f03f1760 100644
--- a/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade22to24/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 2.2 to Cura 2.4.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade25to26/VersionUpgrade25to26.py b/plugins/VersionUpgrade/VersionUpgrade25to26/VersionUpgrade25to26.py
index 6dbcfebc46..2cb0cf3ba4 100644
--- a/plugins/VersionUpgrade/VersionUpgrade25to26/VersionUpgrade25to26.py
+++ b/plugins/VersionUpgrade/VersionUpgrade25to26/VersionUpgrade25to26.py
@@ -19,6 +19,7 @@ _split_settings = { #These settings should be copied to all settings it was spli
"support_interface_line_distance": {"support_roof_line_distance", "support_bottom_line_distance"}
} # type: Dict[str, Set[str]]
+
## A collection of functions that convert the configuration of the user in Cura
# 2.5 to a configuration for Cura 2.6.
#
@@ -28,24 +29,6 @@ class VersionUpgrade25to26(VersionUpgrade):
super().__init__()
self._current_fdm_printer_count = 2
- ## Gets the version number from a CFG file in Uranium's 2.5 format.
- #
- # Since the format may change, this is implemented for the 2.5 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: str) -> int:
- 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 the preferences file from version 2.5 to 2.6.
#
# \param serialised The serialised form of a preferences file.
diff --git a/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json b/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json
index d6470fc0e5..952586764e 100644
--- a/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade25to26/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 2.5 to Cura 2.6.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py b/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py
index 45cdaebe87..0c5b983b14 100644
--- a/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py
+++ b/plugins/VersionUpgrade/VersionUpgrade25to26/tests/TestVersionUpgrade25to26.py
@@ -63,74 +63,6 @@ setting_version = -3
}
]
-## Tests the technique that gets the version number from CFG files.
-#
-# \param data The parametrised data to test with. It contains a test name
-# to debug with, the serialised contents of a CFG file and the correct
-# version number in that CFG file.
-# \param upgrader The instance of the upgrade class to test.
-@pytest.mark.parametrize("data", test_cfg_version_good_data)
-def test_cfgVersionGood(data, upgrader):
- version = upgrader.getCfgVersion(data["file_data"])
- assert version == data["version"]
-
-test_cfg_version_bad_data = [
- {
- "test_name": "Empty",
- "file_data": "",
- "exception": configparser.Error #Explicitly not specified further which specific error we're getting, because that depends on the implementation of configparser.
- },
- {
- "test_name": "No General",
- "file_data": """[values]
-layer_height = 0.1337
-""",
- "exception": configparser.Error
- },
- {
- "test_name": "No Version",
- "file_data": """[general]
-true = false
-""",
- "exception": configparser.Error
- },
- {
- "test_name": "Not a Number",
- "file_data": """[general]
-version = not-a-text-version-number
-""",
- "exception": ValueError
- },
- {
- "test_name": "Setting Value NaN",
- "file_data": """[general]
-version = 4
-[metadata]
-setting_version = latest_or_something
-""",
- "exception": ValueError
- },
- {
- "test_name": "Major-Minor",
- "file_data": """[general]
-version = 1.2
-""",
- "exception": ValueError
- }
-]
-
-## Tests whether getting a version number from bad CFG files gives an
-# exception.
-#
-# \param data The parametrised data to test with. It contains a test name
-# to debug with, the serialised contents of a CFG file and the class of
-# exception it needs to throw.
-# \param upgrader The instance of the upgrader to test.
-@pytest.mark.parametrize("data", test_cfg_version_bad_data)
-def test_cfgVersionBad(data, upgrader):
- with pytest.raises(data["exception"]):
- upgrader.getCfgVersion(data["file_data"])
-
test_upgrade_preferences_removed_settings_data = [
{
"test_name": "Removed Setting",
diff --git a/plugins/VersionUpgrade/VersionUpgrade26to27/VersionUpgrade26to27.py b/plugins/VersionUpgrade/VersionUpgrade26to27/VersionUpgrade26to27.py
index 39e3dea4ed..a4a6182ea0 100644
--- a/plugins/VersionUpgrade/VersionUpgrade26to27/VersionUpgrade26to27.py
+++ b/plugins/VersionUpgrade/VersionUpgrade26to27/VersionUpgrade26to27.py
@@ -64,29 +64,12 @@ _renamed_quality_profiles = {
"um3_bb0.8_TPU_Not_Supported_Superdraft_Quality": "um3_bb0.8_TPU_Superdraft_Print",
} # type: Dict[str, str]
+
## A collection of functions that convert the configuration of the user in Cura
# 2.6 to a configuration for Cura 2.7.
#
# All of these methods are essentially stateless.
class VersionUpgrade26to27(VersionUpgrade):
- ## Gets the version number from a CFG file in Uranium's 2.6 format.
- #
- # Since the format may change, this is implemented for the 2.6 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: str) -> int:
- 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 a preferences file from version 2.6 to 2.7.
#
# \param serialised The serialised form of a preferences file.
diff --git a/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json b/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json
index ba7000ea3d..fe5f70baed 100644
--- a/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade26to27/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 2.6 to Cura 2.7.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py b/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py
index 6235578238..1465df01e7 100644
--- a/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py
+++ b/plugins/VersionUpgrade/VersionUpgrade26to27/tests/TestVersionUpgrade26to27.py
@@ -35,13 +35,6 @@ infill_sparse_density = 42
""",
"version": 3000000
},
- {
- "test_name": "Negative Version", #Why not?
- "file_data": """[general]
-version = -20
-""",
- "version": -20000000
- },
{
"test_name": "Setting Version",
"file_data": """[general]
@@ -50,15 +43,6 @@ version = 1
setting_version = 1
""",
"version": 1000001
- },
- {
- "test_name": "Negative Setting Version",
- "file_data": """[general]
-version = 1
-[metadata]
-setting_version = -3
-""",
- "version": 999997
}
]
@@ -73,62 +57,6 @@ def test_cfgVersionGood(data, upgrader):
version = upgrader.getCfgVersion(data["file_data"])
assert version == data["version"]
-test_cfg_version_bad_data = [
- {
- "test_name": "Empty",
- "file_data": "",
- "exception": configparser.Error #Explicitly not specified further which specific error we're getting, because that depends on the implementation of configparser.
- },
- {
- "test_name": "No General",
- "file_data": """[values]
-layer_height = 0.1337
-""",
- "exception": configparser.Error
- },
- {
- "test_name": "No Version",
- "file_data": """[general]
-true = false
-""",
- "exception": configparser.Error
- },
- {
- "test_name": "Not a Number",
- "file_data": """[general]
-version = not-a-text-version-number
-""",
- "exception": ValueError
- },
- {
- "test_name": "Setting Value NaN",
- "file_data": """[general]
-version = 4
-[metadata]
-setting_version = latest_or_something
-""",
- "exception": ValueError
- },
- {
- "test_name": "Major-Minor",
- "file_data": """[general]
-version = 1.2
-""",
- "exception": ValueError
- }
-]
-
-## Tests whether getting a version number from bad CFG files gives an
-# exception.
-#
-# \param data The parametrised data to test with. It contains a test name
-# to debug with, the serialised contents of a CFG file and the class of
-# exception it needs to throw.
-# \param upgrader The instance of the upgrader to test.
-@pytest.mark.parametrize("data", test_cfg_version_bad_data)
-def test_cfgVersionBad(data, upgrader):
- with pytest.raises(data["exception"]):
- upgrader.getCfgVersion(data["file_data"])
test_upgrade_stacks_with_not_supported_data = [
{
diff --git a/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json b/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json
index 94293284bf..c4dba30510 100644
--- a/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade27to30/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 2.7 to Cura 3.0.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py b/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py
index f0b2e939b9..0b2e1d83f7 100644
--- a/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py
+++ b/plugins/VersionUpgrade/VersionUpgrade30to31/VersionUpgrade30to31.py
@@ -62,24 +62,6 @@ _RENAMED_DEFINITION_DICT = {
class VersionUpgrade30to31(VersionUpgrade):
- ## Gets the version number from a CFG file in Uranium's 3.0 format.
- #
- # Since the format may change, this is implemented for the 3.0 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: str) -> int:
- 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 a preferences file from version 3.0 to 3.1.
#
# \param serialised The serialised form of a preferences file.
diff --git a/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json b/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json
index e3f77dd5f4..48cea8dd1f 100644
--- a/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade30to31/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 3.0 to Cura 3.1.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade32to33/VersionUpgrade32to33.py b/plugins/VersionUpgrade/VersionUpgrade32to33/VersionUpgrade32to33.py
index 83cb15c864..68854041ae 100644
--- a/plugins/VersionUpgrade/VersionUpgrade32to33/VersionUpgrade32to33.py
+++ b/plugins/VersionUpgrade/VersionUpgrade32to33/VersionUpgrade32to33.py
@@ -68,24 +68,6 @@ _RENAMED_QUALITY_TYPES = {
class VersionUpgrade32to33(VersionUpgrade):
temporary_group_name_counter = 1
- ## 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: str) -> int:
- 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 a preferences file from version 3.2 to 3.3.
#
# \param serialised The serialised form of a preferences file.
diff --git a/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json b/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json
index baed818b83..2208294b81 100644
--- a/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade32to33/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 3.2 to Cura 3.3.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py b/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py
index 704ede02d6..acca39942d 100644
--- a/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py
+++ b/plugins/VersionUpgrade/VersionUpgrade33to34/VersionUpgrade33to34.py
@@ -14,24 +14,6 @@ _renamed_settings = {
## Upgrades configurations from the state they were in at version 3.3 to the
# state they should be in at version 3.4.
class VersionUpgrade33to34(VersionUpgrade):
- ## Gets the version number from a CFG file in Uranium's 3.3 format.
- #
- # Since the format may change, this is implemented for the 3.3 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: str) -> int:
- 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 instance containers to have the new version
# number.
def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
diff --git a/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json b/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json
index b536747c7d..3ecb32071d 100644
--- a/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade33to34/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 3.3 to Cura 3.4.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py b/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py
index 8e45d7cf73..30dae3883f 100644
--- a/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py
+++ b/plugins/VersionUpgrade/VersionUpgrade34to35/VersionUpgrade34to35.py
@@ -63,24 +63,6 @@ _RENAMED_MATERIAL_PROFILES = {
## Upgrades configurations from the state they were in at version 3.4 to the
# state they should be in at version 3.5.
class VersionUpgrade34to35(VersionUpgrade):
- ## Gets the version number from a CFG file in Uranium's 3.4 format.
- #
- # Since the format may change, this is implemented for the 3.4 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: str) -> int:
- 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 Preferences to have the new version number.
def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
parser = configparser.ConfigParser(interpolation = None)
diff --git a/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json b/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json
index 0b58abee95..e47d4dce72 100644
--- a/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade34to35/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 3.4 to Cura 3.5.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade35to40/VersionUpgrade35to40.py b/plugins/VersionUpgrade/VersionUpgrade35to40/VersionUpgrade35to40.py
index 71ce2e4fd0..fdca7d15df 100644
--- a/plugins/VersionUpgrade/VersionUpgrade35to40/VersionUpgrade35to40.py
+++ b/plugins/VersionUpgrade/VersionUpgrade35to40/VersionUpgrade35to40.py
@@ -34,13 +34,6 @@ class VersionUpgrade35to40(VersionUpgrade):
parser.write(result)
return [filename], [result.getvalue()]
- def getCfgVersion(self, serialised: str) -> int:
- 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 Preferences to have the new version number.
def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
parser = configparser.ConfigParser(interpolation=None)
diff --git a/plugins/VersionUpgrade/VersionUpgrade35to40/plugin.json b/plugins/VersionUpgrade/VersionUpgrade35to40/plugin.json
index 169d7748f5..01ff9b81c5 100644
--- a/plugins/VersionUpgrade/VersionUpgrade35to40/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade35to40/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 3.5 to Cura 4.0.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py b/plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py
index b63d1842b7..1cccbef7da 100644
--- a/plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py
+++ b/plugins/VersionUpgrade/VersionUpgrade40to41/VersionUpgrade40to41.py
@@ -23,24 +23,6 @@ _renamed_quality_profiles = {
## Upgrades configurations from the state they were in at version 4.0 to the
# state they should be in at version 4.1.
class VersionUpgrade40to41(VersionUpgrade):
- ## Gets the version number from a CFG file in Uranium's 4.0 format.
- #
- # Since the format may change, this is implemented for the 4.0 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: str) -> int:
- 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 instance containers to have the new version
# number.
def upgradeInstanceContainer(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
diff --git a/plugins/VersionUpgrade/VersionUpgrade40to41/plugin.json b/plugins/VersionUpgrade/VersionUpgrade40to41/plugin.json
index 49d2f4131c..d321c71e02 100644
--- a/plugins/VersionUpgrade/VersionUpgrade40to41/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade40to41/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Upgrades configurations from Cura 4.0 to Cura 4.1.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade41to42/VersionUpgrade41to42.py b/plugins/VersionUpgrade/VersionUpgrade41to42/VersionUpgrade41to42.py
index 4b7e291482..43d8561567 100644
--- a/plugins/VersionUpgrade/VersionUpgrade41to42/VersionUpgrade41to42.py
+++ b/plugins/VersionUpgrade/VersionUpgrade41to42/VersionUpgrade41to42.py
@@ -213,27 +213,10 @@ _creality_limited_quality_type = {
"extra_coarse": "draft"
}
+
## Upgrades configurations from the state they were in at version 4.1 to the
# state they should be in at version 4.2.
class VersionUpgrade41to42(VersionUpgrade):
- ## Gets the version number from a CFG file in Uranium's 4.1 format.
- #
- # Since the format may change, this is implemented for the 4.1 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: str) -> int:
- 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 instance containers to have the new version
# number.
#
diff --git a/plugins/VersionUpgrade/VersionUpgrade41to42/plugin.json b/plugins/VersionUpgrade/VersionUpgrade41to42/plugin.json
index 42ffafe5ec..f59a5b3861 100644
--- a/plugins/VersionUpgrade/VersionUpgrade41to42/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade41to42/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 4.1 to Cura 4.2.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade42to43/VersionUpgrade42to43.py b/plugins/VersionUpgrade/VersionUpgrade42to43/VersionUpgrade42to43.py
index 4142053047..b139ede83c 100644
--- a/plugins/VersionUpgrade/VersionUpgrade42to43/VersionUpgrade42to43.py
+++ b/plugins/VersionUpgrade/VersionUpgrade42to43/VersionUpgrade42to43.py
@@ -56,27 +56,10 @@ _renamed_settings = {
"support_infill_angle": "support_infill_angles"
} # type: Dict[str, str]
+
## Upgrades configurations from the state they were in at version 4.2 to the
# state they should be in at version 4.3.
class VersionUpgrade42to43(VersionUpgrade):
- ## Gets the version number from a CFG file in Uranium's 4.2 format.
- #
- # Since the format may change, this is implemented for the 4.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: str) -> int:
- 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
-
def upgradePreferences(self, serialized: str, filename: str):
parser = configparser.ConfigParser(interpolation = None)
parser.read_string(serialized)
diff --git a/plugins/VersionUpgrade/VersionUpgrade42to43/plugin.json b/plugins/VersionUpgrade/VersionUpgrade42to43/plugin.json
index e429e73d1c..86a3ea607e 100644
--- a/plugins/VersionUpgrade/VersionUpgrade42to43/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade42to43/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 4.2 to Cura 4.3.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py b/plugins/VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py
index f3453527bc..b5825af62e 100644
--- a/plugins/VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py
+++ b/plugins/VersionUpgrade/VersionUpgrade43to44/VersionUpgrade43to44.py
@@ -26,12 +26,6 @@ _renamed_container_id_map = {
class VersionUpgrade43to44(VersionUpgrade):
- def getCfgVersion(self, serialised: str) -> int:
- 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 Preferences to have the new version number.
#
diff --git a/plugins/VersionUpgrade/VersionUpgrade43to44/plugin.json b/plugins/VersionUpgrade/VersionUpgrade43to44/plugin.json
index 85cbd5a3e7..f08b5a50bb 100644
--- a/plugins/VersionUpgrade/VersionUpgrade43to44/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade43to44/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 4.3 to Cura 4.4.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade44to45/VersionUpgrade44to45.py b/plugins/VersionUpgrade/VersionUpgrade44to45/VersionUpgrade44to45.py
index f300cb1c2d..0747ad280b 100644
--- a/plugins/VersionUpgrade/VersionUpgrade44to45/VersionUpgrade44to45.py
+++ b/plugins/VersionUpgrade/VersionUpgrade44to45/VersionUpgrade44to45.py
@@ -122,13 +122,6 @@ class VersionUpgrade44to45(VersionUpgrade):
except OSError: # Is a directory, file not found, or insufficient rights.
continue
- def getCfgVersion(self, serialised: str) -> int:
- 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 Preferences to have the new version number.
#
# This renames the renamed settings in the list of visible settings.
diff --git a/plugins/VersionUpgrade/VersionUpgrade44to45/plugin.json b/plugins/VersionUpgrade/VersionUpgrade44to45/plugin.json
index 01d970e1ef..ce98c9f94a 100644
--- a/plugins/VersionUpgrade/VersionUpgrade44to45/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade44to45/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 4.4 to Cura 4.5.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade45to46/VersionUpgrade45to46.py b/plugins/VersionUpgrade/VersionUpgrade45to46/VersionUpgrade45to46.py
index 2234dd35f5..a399c79535 100644
--- a/plugins/VersionUpgrade/VersionUpgrade45to46/VersionUpgrade45to46.py
+++ b/plugins/VersionUpgrade/VersionUpgrade45to46/VersionUpgrade45to46.py
@@ -10,14 +10,8 @@ _removed_settings = {
"machine_filament_park_distance",
}
-class VersionUpgrade45to46(VersionUpgrade):
- def getCfgVersion(self, serialised: str) -> int:
- 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
+class VersionUpgrade45to46(VersionUpgrade):
def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
"""
Upgrades preferences to have the new version number.
@@ -35,11 +29,12 @@ class VersionUpgrade45to46(VersionUpgrade):
parser["metadata"]["setting_version"] = "12"
# Remove deleted settings from the visible settings list.
- visible_settings = set(parser["general"]["visible_settings"].split(";"))
- for removed in _removed_settings:
- if removed in visible_settings:
- visible_settings.remove(removed)
- parser["general"]["visible_settings"] = ";".join(visible_settings)
+ if "general" in parser and "visible_settings" in parser["general"]:
+ visible_settings = set(parser["general"]["visible_settings"].split(";"))
+ for removed in _removed_settings:
+ if removed in visible_settings:
+ visible_settings.remove(removed)
+ parser["general"]["visible_settings"] = ";".join(visible_settings)
result = io.StringIO()
parser.write(result)
diff --git a/plugins/VersionUpgrade/VersionUpgrade45to46/plugin.json b/plugins/VersionUpgrade/VersionUpgrade45to46/plugin.json
index ceabdb6d9d..08c3c57ed1 100644
--- a/plugins/VersionUpgrade/VersionUpgrade45to46/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade45to46/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 4.5 to Cura 4.6.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/VersionUpgrade/VersionUpgrade46to47/VersionUpgrade46to47.py b/plugins/VersionUpgrade/VersionUpgrade46to47/VersionUpgrade46to47.py
index a8a4142dfc..52ae10a122 100644
--- a/plugins/VersionUpgrade/VersionUpgrade46to47/VersionUpgrade46to47.py
+++ b/plugins/VersionUpgrade/VersionUpgrade46to47/VersionUpgrade46to47.py
@@ -6,14 +6,8 @@ from typing import Tuple, List
import io
from UM.VersionUpgrade import VersionUpgrade
-class VersionUpgrade46to47(VersionUpgrade):
- def getCfgVersion(self, serialised: str) -> int:
- 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
+class VersionUpgrade46to47(VersionUpgrade):
def upgradePreferences(self, serialized: str, filename: str) -> Tuple[List[str], List[str]]:
"""
Upgrades preferences to have the new version number.
diff --git a/plugins/VersionUpgrade/VersionUpgrade46to47/plugin.json b/plugins/VersionUpgrade/VersionUpgrade46to47/plugin.json
index 33df516ea0..5a92355d0a 100644
--- a/plugins/VersionUpgrade/VersionUpgrade46to47/plugin.json
+++ b/plugins/VersionUpgrade/VersionUpgrade46to47/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.0",
"description": "Upgrades configurations from Cura 4.6 to Cura 4.7.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/X3DReader/plugin.json b/plugins/X3DReader/plugin.json
index 052acf1e5f..0d523a1bf6 100644
--- a/plugins/X3DReader/plugin.json
+++ b/plugins/X3DReader/plugin.json
@@ -3,6 +3,6 @@
"author": "Seva Alekseyev, Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides support for reading X3D files.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/XRayView/XRayView.py b/plugins/XRayView/XRayView.py
index e12bd9b9ea..0144f4c176 100644
--- a/plugins/XRayView/XRayView.py
+++ b/plugins/XRayView/XRayView.py
@@ -93,6 +93,7 @@ class XRayView(CuraView):
theme = Application.getInstance().getTheme()
self._xray_composite_shader.setUniformValue("u_background_color", Color(*theme.getColor("viewport_background").getRgb()))
self._xray_composite_shader.setUniformValue("u_outline_color", Color(*theme.getColor("model_selection_outline").getRgb()))
+ self._xray_composite_shader.setUniformValue("u_flat_error_color_mix", 1.) # Show flat error color _only_ in xray-view.
if not self._composite_pass:
self._composite_pass = self.getRenderer().getRenderPass("composite")
diff --git a/plugins/XRayView/plugin.json b/plugins/XRayView/plugin.json
index 64fe71e0c1..344c5e660f 100644
--- a/plugins/XRayView/plugin.json
+++ b/plugins/XRayView/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides the X-Ray view.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/plugins/XmlMaterialProfile/plugin.json b/plugins/XmlMaterialProfile/plugin.json
index 1128afbeeb..121ada7b84 100644
--- a/plugins/XmlMaterialProfile/plugin.json
+++ b/plugins/XmlMaterialProfile/plugin.json
@@ -3,6 +3,6 @@
"author": "Ultimaker B.V.",
"version": "1.0.1",
"description": "Provides capabilities to read and write XML-based material profiles.",
- "api": "7.1",
+ "api": "7.2.0",
"i18n-catalog": "cura"
}
diff --git a/resources/bundled_packages/cura.json b/resources/bundled_packages/cura.json
index 1378ed2b9c..0f43889d8d 100644
--- a/resources/bundled_packages/cura.json
+++ b/resources/bundled_packages/cura.json
@@ -6,7 +6,7 @@
"display_name": "3MF Reader",
"description": "Provides support for reading 3MF files.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -23,7 +23,7 @@
"display_name": "3MF Writer",
"description": "Provides support for writing 3MF files.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -40,7 +40,7 @@
"display_name": "AMF Reader",
"description": "Provides support for reading AMF files.",
"package_version": "1.0.0",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "fieldOfView",
@@ -57,7 +57,7 @@
"display_name": "Cura Backups",
"description": "Backup and restore your configuration.",
"package_version": "1.2.0",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -74,7 +74,7 @@
"display_name": "CuraEngine Backend",
"description": "Provides the link to the CuraEngine slicing backend.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -91,7 +91,7 @@
"display_name": "Cura Profile Reader",
"description": "Provides support for importing Cura profiles.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -108,7 +108,7 @@
"display_name": "Cura Profile Writer",
"description": "Provides support for exporting Cura profiles.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -125,7 +125,7 @@
"display_name": "Firmware Update Checker",
"description": "Checks for firmware updates.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -142,7 +142,7 @@
"display_name": "Firmware Updater",
"description": "Provides a machine actions for updating firmware.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -159,7 +159,7 @@
"display_name": "Compressed G-code Reader",
"description": "Reads g-code from a compressed archive.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -176,7 +176,7 @@
"display_name": "Compressed G-code Writer",
"description": "Writes g-code to a compressed archive.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -193,7 +193,7 @@
"display_name": "G-Code Profile Reader",
"description": "Provides support for importing profiles from g-code files.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -210,7 +210,7 @@
"display_name": "G-Code Reader",
"description": "Allows loading and displaying G-code files.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "VictorLarchenko",
@@ -227,7 +227,7 @@
"display_name": "G-Code Writer",
"description": "Writes g-code to a file.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -244,7 +244,7 @@
"display_name": "Image Reader",
"description": "Enables ability to generate printable geometry from 2D image files.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -261,7 +261,7 @@
"display_name": "Legacy Cura Profile Reader",
"description": "Provides support for importing profiles from legacy Cura versions.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -278,7 +278,7 @@
"display_name": "Machine Settings Action",
"description": "Provides a way to change machine settings (such as build volume, nozzle size, etc.).",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "fieldOfView",
@@ -295,7 +295,7 @@
"display_name": "Model Checker",
"description": "Checks models and print configuration for possible printing issues and give suggestions.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -312,7 +312,7 @@
"display_name": "Monitor Stage",
"description": "Provides a monitor stage in Cura.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -329,7 +329,7 @@
"display_name": "Per-Object Settings Tool",
"description": "Provides the per-model settings.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -346,7 +346,7 @@
"display_name": "Post Processing",
"description": "Extension that allows for user created scripts for post processing.",
"package_version": "2.2.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -363,7 +363,7 @@
"display_name": "Prepare Stage",
"description": "Provides a prepare stage in Cura.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -380,7 +380,7 @@
"display_name": "Preview Stage",
"description": "Provides a preview stage in Cura.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -397,7 +397,7 @@
"display_name": "Removable Drive Output Device",
"description": "Provides removable drive hotplugging and writing support.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -414,7 +414,7 @@
"display_name": "Sentry Logger",
"description": "Logs certain events so that they can be used by the crash reporter",
"package_version": "1.0.0",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -431,7 +431,7 @@
"display_name": "Simulation View",
"description": "Provides the Simulation view.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -448,7 +448,7 @@
"display_name": "Slice Info",
"description": "Submits anonymous slice info. Can be disabled through preferences.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -465,7 +465,7 @@
"display_name": "Solid View",
"description": "Provides a normal solid mesh view.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -482,7 +482,7 @@
"display_name": "Support Eraser Tool",
"description": "Creates an eraser mesh to block the printing of support in certain places.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -499,7 +499,7 @@
"display_name": "Trimesh Reader",
"description": "Provides support for reading model files.",
"package_version": "1.0.0",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -516,7 +516,7 @@
"display_name": "Toolbox",
"description": "Find, manage and install new Cura packages.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -533,7 +533,7 @@
"display_name": "UFP Reader",
"description": "Provides support for reading Ultimaker Format Packages.",
"package_version": "1.0.0",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -550,7 +550,7 @@
"display_name": "UFP Writer",
"description": "Provides support for writing Ultimaker Format Packages.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -567,7 +567,7 @@
"display_name": "Ultimaker Machine Actions",
"description": "Provides machine actions for Ultimaker machines (such as bed leveling wizard, selecting upgrades, etc.).",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -584,7 +584,7 @@
"display_name": "UM3 Network Printing",
"description": "Manages network connections to Ultimaker 3 printers.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -601,7 +601,7 @@
"display_name": "USB Printing",
"description": "Accepts G-Code and sends them to a printer. Plugin can also update firmware.",
"package_version": "1.0.2",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -618,7 +618,7 @@
"display_name": "Version Upgrade 2.1 to 2.2",
"description": "Upgrades configurations from Cura 2.1 to Cura 2.2.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -635,7 +635,7 @@
"display_name": "Version Upgrade 2.2 to 2.4",
"description": "Upgrades configurations from Cura 2.2 to Cura 2.4.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -652,7 +652,7 @@
"display_name": "Version Upgrade 2.5 to 2.6",
"description": "Upgrades configurations from Cura 2.5 to Cura 2.6.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -669,7 +669,7 @@
"display_name": "Version Upgrade 2.6 to 2.7",
"description": "Upgrades configurations from Cura 2.6 to Cura 2.7.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -686,7 +686,7 @@
"display_name": "Version Upgrade 2.7 to 3.0",
"description": "Upgrades configurations from Cura 2.7 to Cura 3.0.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -703,7 +703,7 @@
"display_name": "Version Upgrade 3.0 to 3.1",
"description": "Upgrades configurations from Cura 3.0 to Cura 3.1.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -720,7 +720,7 @@
"display_name": "Version Upgrade 3.2 to 3.3",
"description": "Upgrades configurations from Cura 3.2 to Cura 3.3.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -737,7 +737,7 @@
"display_name": "Version Upgrade 3.3 to 3.4",
"description": "Upgrades configurations from Cura 3.3 to Cura 3.4.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -754,7 +754,7 @@
"display_name": "Version Upgrade 3.4 to 3.5",
"description": "Upgrades configurations from Cura 3.4 to Cura 3.5.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -771,7 +771,7 @@
"display_name": "Version Upgrade 3.5 to 4.0",
"description": "Upgrades configurations from Cura 3.5 to Cura 4.0.",
"package_version": "1.0.0",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -788,7 +788,7 @@
"display_name": "Version Upgrade 4.0 to 4.1",
"description": "Upgrades configurations from Cura 4.0 to Cura 4.1.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -805,7 +805,7 @@
"display_name": "Version Upgrade 4.1 to 4.2",
"description": "Upgrades configurations from Cura 4.1 to Cura 4.2.",
"package_version": "1.0.0",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -822,7 +822,7 @@
"display_name": "Version Upgrade 4.2 to 4.3",
"description": "Upgrades configurations from Cura 4.2 to Cura 4.3.",
"package_version": "1.0.0",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -839,7 +839,7 @@
"display_name": "Version Upgrade 4.3 to 4.4",
"description": "Upgrades configurations from Cura 4.3 to Cura 4.4.",
"package_version": "1.0.0",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -856,7 +856,7 @@
"display_name": "Version Upgrade 4.4 to 4.5",
"description": "Upgrades configurations from Cura 4.4 to Cura 4.5.",
"package_version": "1.0.0",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -873,7 +873,7 @@
"display_name": "Version Upgrade 4.5 to 4.6",
"description": "Upgrades configurations from Cura 4.5 to Cura 4.6.",
"package_version": "1.0.0",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -890,7 +890,7 @@
"display_name": "Version Upgrade 4.6 to 4.7",
"description": "Upgrades configurations from Cura 4.6 to Cura 4.7.",
"package_version": "1.0.0",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -907,7 +907,7 @@
"display_name": "X3D Reader",
"description": "Provides support for reading X3D files.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "SevaAlekseyev",
@@ -924,7 +924,7 @@
"display_name": "XML Material Profiles",
"description": "Provides capabilities to read and write XML-based material profiles.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -941,7 +941,7 @@
"display_name": "X-Ray View",
"description": "Provides the X-Ray view.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com",
"author": {
"author_id": "UltimakerPackages",
@@ -958,7 +958,7 @@
"display_name": "Generic ABS",
"description": "The generic ABS profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -976,7 +976,7 @@
"display_name": "Generic BAM",
"description": "The generic BAM profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -994,7 +994,7 @@
"display_name": "Generic CFF CPE",
"description": "The generic CFF CPE profile which other profiles can be based upon.",
"package_version": "1.1.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1012,7 +1012,7 @@
"display_name": "Generic CFF PA",
"description": "The generic CFF PA profile which other profiles can be based upon.",
"package_version": "1.1.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1030,7 +1030,7 @@
"display_name": "Generic CPE",
"description": "The generic CPE profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1048,7 +1048,7 @@
"display_name": "Generic CPE+",
"description": "The generic CPE+ profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1066,7 +1066,7 @@
"display_name": "Generic GFF CPE",
"description": "The generic GFF CPE profile which other profiles can be based upon.",
"package_version": "1.1.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1084,7 +1084,7 @@
"display_name": "Generic GFF PA",
"description": "The generic GFF PA profile which other profiles can be based upon.",
"package_version": "1.1.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1102,7 +1102,7 @@
"display_name": "Generic HIPS",
"description": "The generic HIPS profile which other profiles can be based upon.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1120,7 +1120,7 @@
"display_name": "Generic Nylon",
"description": "The generic Nylon profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1138,7 +1138,7 @@
"display_name": "Generic PC",
"description": "The generic PC profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1156,7 +1156,7 @@
"display_name": "Generic PETG",
"description": "The generic PETG profile which other profiles can be based upon.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1174,7 +1174,7 @@
"display_name": "Generic PLA",
"description": "The generic PLA profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1192,7 +1192,7 @@
"display_name": "Generic PP",
"description": "The generic PP profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1210,7 +1210,7 @@
"display_name": "Generic PVA",
"description": "The generic PVA profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1228,7 +1228,7 @@
"display_name": "Generic Tough PLA",
"description": "The generic Tough PLA profile which other profiles can be based upon.",
"package_version": "1.0.2",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1246,7 +1246,7 @@
"display_name": "Generic TPU",
"description": "The generic TPU profile which other profiles can be based upon.",
"package_version": "1.2.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://github.com/Ultimaker/fdm_materials",
"author": {
"author_id": "Generic",
@@ -1264,7 +1264,7 @@
"display_name": "Dagoma Chromatik PLA",
"description": "Filament testé et approuvé pour les imprimantes 3D Dagoma. Chromatik est l'idéal pour débuter et suivre les tutoriels premiers pas. Il vous offre qualité et résistance pour chacune de vos impressions.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://dagoma.fr/boutique/filaments.html",
"author": {
"author_id": "Dagoma",
@@ -1281,7 +1281,7 @@
"display_name": "FABtotum ABS",
"description": "This material is easy to be extruded but it is not the simplest to use. It is one of the most used in 3D printing to get very well finished objects. It is not sustainable and its smoke can be dangerous if inhaled. The reason to prefer this filament to PLA is mainly because of its precision and mechanical specs. ABS (for plastic) stands for Acrylonitrile Butadiene Styrene and it is a thermoplastic which is widely used in everyday objects. It can be printed with any FFF 3D printer which can get to high temperatures as it must be extruded in a range between 220° and 245°, so it’s compatible with all versions of the FABtotum Personal fabricator.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=40",
"author": {
"author_id": "FABtotum",
@@ -1298,7 +1298,7 @@
"display_name": "FABtotum Nylon",
"description": "When 3D printing started this material was not listed among the extrudable filaments. It is flexible as well as resistant to tractions. It is well known for its uses in textile but also in industries which require a strong and flexible material. There are different kinds of Nylon: 3D printing mostly uses Nylon 6 and Nylon 6.6, which are the most common. It requires higher temperatures to be printed, so a 3D printer must be able to reach them (around 240°C): the FABtotum, of course, can.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=53",
"author": {
"author_id": "FABtotum",
@@ -1315,7 +1315,7 @@
"display_name": "FABtotum PLA",
"description": "It is the most common filament used for 3D printing. It is studied to be bio-degradable as it comes from corn starch’s sugar mainly. It is completely made of renewable sources and has no footprint on polluting. PLA stands for PolyLactic Acid and it is a thermoplastic that today is still considered the easiest material to be 3D printed. It can be extruded at lower temperatures: the standard range of FABtotum’s one is between 185° and 195°.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=39",
"author": {
"author_id": "FABtotum",
@@ -1332,7 +1332,7 @@
"display_name": "FABtotum TPU Shore 98A",
"description": "",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://store.fabtotum.com/eu/products/filaments.html?filament_type=66",
"author": {
"author_id": "FABtotum",
@@ -1349,7 +1349,7 @@
"display_name": "Fiberlogy HD PLA",
"description": "With our HD PLA you have many more options. You can use this material in two ways. Choose the one you like best. You can use it as a normal PLA and get prints characterized by a very good adhesion between the layers and high precision. You can also make your prints acquire similar properties to that of ABS – better impact resistance and high temperature resistance. All you need is an oven. Yes, an oven! By annealing our HD PLA in an oven, in accordance with the manual, you will avoid all the inconveniences of printing with ABS, such as unpleasant odour or hazardous fumes.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "http://fiberlogy.com/en/fiberlogy-filaments/filament-hd-pla/",
"author": {
"author_id": "Fiberlogy",
@@ -1366,7 +1366,7 @@
"display_name": "Filo3D PLA",
"description": "Fast, safe and reliable printing. PLA is ideal for the fast and reliable printing of parts and prototypes with a great surface quality.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://dagoma.fr",
"author": {
"author_id": "Dagoma",
@@ -1383,7 +1383,7 @@
"display_name": "IMADE3D JellyBOX PETG",
"description": "",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "http://shop.imade3d.com/filament.html",
"author": {
"author_id": "IMADE3D",
@@ -1400,7 +1400,7 @@
"display_name": "IMADE3D JellyBOX PLA",
"description": "",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "http://shop.imade3d.com/filament.html",
"author": {
"author_id": "IMADE3D",
@@ -1417,7 +1417,7 @@
"display_name": "Octofiber PLA",
"description": "PLA material from Octofiber.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://nl.octofiber.com/3d-printing-filament/pla.html",
"author": {
"author_id": "Octofiber",
@@ -1434,7 +1434,7 @@
"display_name": "PolyFlex™ PLA",
"description": "PolyFlex™ is a highly flexible yet easy to print 3D printing material. Featuring good elasticity and a large strain-to- failure, PolyFlex™ opens up a completely new realm of applications.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "http://www.polymaker.com/shop/polyflex/",
"author": {
"author_id": "Polymaker",
@@ -1451,7 +1451,7 @@
"display_name": "PolyMax™ PLA",
"description": "PolyMax™ PLA is a 3D printing material with excellent mechanical properties and printing quality. PolyMax™ PLA has an impact resistance of up to nine times that of regular PLA, and better overall mechanical properties than ABS.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "http://www.polymaker.com/shop/polymax/",
"author": {
"author_id": "Polymaker",
@@ -1468,7 +1468,7 @@
"display_name": "PolyPlus™ PLA True Colour",
"description": "PolyPlus™ PLA is a premium PLA designed for all desktop FDM/FFF 3D printers. It is produced with our patented Jam-Free™ technology that ensures consistent extrusion and prevents jams.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "http://www.polymaker.com/shop/polyplus-true-colour/",
"author": {
"author_id": "Polymaker",
@@ -1485,7 +1485,7 @@
"display_name": "PolyWood™ PLA",
"description": "PolyWood™ is a wood mimic printing material that contains no actual wood ensuring a clean Jam-Free™ printing experience.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "http://www.polymaker.com/shop/polywood/",
"author": {
"author_id": "Polymaker",
@@ -1502,7 +1502,7 @@
"display_name": "Ultimaker ABS",
"description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.2",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com/products/materials/abs",
"author": {
"author_id": "UltimakerPackages",
@@ -1521,7 +1521,7 @@
"display_name": "Ultimaker Breakaway",
"description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com/products/materials/breakaway",
"author": {
"author_id": "UltimakerPackages",
@@ -1540,7 +1540,7 @@
"display_name": "Ultimaker CPE",
"description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.2",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com/products/materials/abs",
"author": {
"author_id": "UltimakerPackages",
@@ -1559,7 +1559,7 @@
"display_name": "Ultimaker CPE+",
"description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.2",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com/products/materials/cpe",
"author": {
"author_id": "UltimakerPackages",
@@ -1578,7 +1578,7 @@
"display_name": "Ultimaker Nylon",
"description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.2",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com/products/materials/abs",
"author": {
"author_id": "UltimakerPackages",
@@ -1597,7 +1597,7 @@
"display_name": "Ultimaker PC",
"description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.2",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com/products/materials/pc",
"author": {
"author_id": "UltimakerPackages",
@@ -1616,7 +1616,7 @@
"display_name": "Ultimaker PLA",
"description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.2",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com/products/materials/abs",
"author": {
"author_id": "UltimakerPackages",
@@ -1635,7 +1635,7 @@
"display_name": "Ultimaker PP",
"description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.2",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com/products/materials/pp",
"author": {
"author_id": "UltimakerPackages",
@@ -1654,7 +1654,7 @@
"display_name": "Ultimaker PVA",
"description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com/products/materials/abs",
"author": {
"author_id": "UltimakerPackages",
@@ -1673,7 +1673,7 @@
"display_name": "Ultimaker TPU 95A",
"description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.2.2",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com/products/materials/tpu-95a",
"author": {
"author_id": "UltimakerPackages",
@@ -1692,7 +1692,7 @@
"display_name": "Ultimaker Tough PLA",
"description": "Example package for material and quality profiles for Ultimaker materials.",
"package_version": "1.0.3",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://ultimaker.com/products/materials/tough-pla",
"author": {
"author_id": "UltimakerPackages",
@@ -1711,7 +1711,7 @@
"display_name": "Vertex Delta ABS",
"description": "ABS material and quality files for the Delta Vertex K8800.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://vertex3dprinter.eu",
"author": {
"author_id": "Velleman",
@@ -1728,7 +1728,7 @@
"display_name": "Vertex Delta PET",
"description": "ABS material and quality files for the Delta Vertex K8800.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://vertex3dprinter.eu",
"author": {
"author_id": "Velleman",
@@ -1745,7 +1745,7 @@
"display_name": "Vertex Delta PLA",
"description": "ABS material and quality files for the Delta Vertex K8800.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://vertex3dprinter.eu",
"author": {
"author_id": "Velleman",
@@ -1762,7 +1762,7 @@
"display_name": "Vertex Delta TPU",
"description": "ABS material and quality files for the Delta Vertex K8800.",
"package_version": "1.0.1",
- "sdk_version": "7.1.0",
+ "sdk_version": "7.2.0",
"website": "https://vertex3dprinter.eu",
"author": {
"author_id": "Velleman",
diff --git a/resources/definitions/Mark2_for_Ultimaker2.def.json b/resources/definitions/Mark2_for_Ultimaker2.def.json
index 6867183081..55f2f1611e 100644
--- a/resources/definitions/Mark2_for_Ultimaker2.def.json
+++ b/resources/definitions/Mark2_for_Ultimaker2.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "TheUltimakerCommunity",
"manufacturer": "Foehnsturm",
- "category": "Other",
"weight": 0,
"has_variants": true,
"has_materials": true,
diff --git a/resources/definitions/alya3dp.def.json b/resources/definitions/alya3dp.def.json
index 3010cfb67c..4c220fb98b 100644
--- a/resources/definitions/alya3dp.def.json
+++ b/resources/definitions/alya3dp.def.json
@@ -7,7 +7,6 @@
"visible": true,
"author": "ALYA",
"manufacturer": "Kati Hal ARGE",
- "category": "Other",
"file_formats": "text/x-gcode",
"platform": "alya_platform.3mf",
"platform_offset": [-60, -45, 75 ],
diff --git a/resources/definitions/alyanx3dp.def.json b/resources/definitions/alyanx3dp.def.json
index 10e42884c9..627b251706 100644
--- a/resources/definitions/alyanx3dp.def.json
+++ b/resources/definitions/alyanx3dp.def.json
@@ -7,7 +7,6 @@
"visible": true,
"author": "ALYA",
"manufacturer": "Kati Hal ARGE",
- "category": "Other",
"file_formats": "text/x-gcode",
"platform": "alya_nx_platform.3mf",
"platform_offset": [-104, 0, 93 ],
diff --git a/resources/definitions/anet3d.def.json b/resources/definitions/anet3d.def.json
index 1381a6c6ee..990be55463 100644
--- a/resources/definitions/anet3d.def.json
+++ b/resources/definitions/anet3d.def.json
@@ -5,7 +5,6 @@
"metadata": {
"author": "Tiger.He",
"manufacturer": "Anet",
- "category": "anet3d",
"visible": false,
"file_formats": "text/x-gcode",
"first_start_actions": ["MachineSettingsAction"],
diff --git a/resources/definitions/anycubic_4max.def.json b/resources/definitions/anycubic_4max.def.json
index 24b625e754..19e733c5a7 100644
--- a/resources/definitions/anycubic_4max.def.json
+++ b/resources/definitions/anycubic_4max.def.json
@@ -7,7 +7,6 @@
"visible": true,
"author": "Jason Scurtu",
"manufacturer": "Anycubic",
- "category": "Other",
"file_formats": "text/x-gcode",
"icon": "icon_ultimaker2",
"platform": "anycubic_4max_platform.3mf",
diff --git a/resources/definitions/anycubic_chiron.def.json b/resources/definitions/anycubic_chiron.def.json
index 1b18a936a7..97d39b439c 100644
--- a/resources/definitions/anycubic_chiron.def.json
+++ b/resources/definitions/anycubic_chiron.def.json
@@ -7,7 +7,6 @@
"visible": true,
"author": "Patrick Glatt",
"manufacturer": "Anycubic",
- "category": "Other",
"file_formats": "text/x-gcode",
"icon": "icon_ultimaker2",
"platform": "anycubic_chiron_platform.obj",
diff --git a/resources/definitions/bibo2_dual.def.json b/resources/definitions/bibo2_dual.def.json
index a644185915..b9b1164e9d 100644
--- a/resources/definitions/bibo2_dual.def.json
+++ b/resources/definitions/bibo2_dual.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "unknown",
"manufacturer": "BIBO",
- "category": "Other",
"file_formats": "text/x-gcode",
"has_materials": true,
"machine_extruder_trains": {
diff --git a/resources/definitions/builder_premium_large.def.json b/resources/definitions/builder_premium_large.def.json
index 9c1db3acd7..f0e64921e7 100644
--- a/resources/definitions/builder_premium_large.def.json
+++ b/resources/definitions/builder_premium_large.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "Builder SZ",
"manufacturer": "Builder",
- "category": "Other",
"quality_definition": "builder_premium_small",
"file_formats": "text/x-gcode",
"platform": "builder_premium_platform.3mf",
diff --git a/resources/definitions/builder_premium_medium.def.json b/resources/definitions/builder_premium_medium.def.json
index ebfa1a870e..e85c654fa2 100644
--- a/resources/definitions/builder_premium_medium.def.json
+++ b/resources/definitions/builder_premium_medium.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "Builder SZ",
"manufacturer": "Builder",
- "category": "Other",
"quality_definition": "builder_premium_small",
"file_formats": "text/x-gcode",
"platform": "builder_premium_platform.3mf",
diff --git a/resources/definitions/builder_premium_small.def.json b/resources/definitions/builder_premium_small.def.json
index 3406543c0e..c89b01566b 100644
--- a/resources/definitions/builder_premium_small.def.json
+++ b/resources/definitions/builder_premium_small.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "Builder SZ",
"manufacturer": "Builder",
- "category": "Other",
"file_formats": "text/x-gcode",
"platform": "builder_premium_platform.3mf",
"platform_offset": [-126, -36, 117],
diff --git a/resources/definitions/creality_cr-x.def.json b/resources/definitions/creality_cr-x.def.json
index 6c1563ff14..fd6cb9eda5 100644
--- a/resources/definitions/creality_cr-x.def.json
+++ b/resources/definitions/creality_cr-x.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "SRC",
"manufacturer": "Creality3D",
- "category": "Other",
"file_formats": "text/x-gcode",
"platform": "cr-x.3mf",
"has_variants": false,
diff --git a/resources/definitions/creality_cr10spro.def.json b/resources/definitions/creality_cr10spro.def.json
index f20dfa5a09..62ee8eb777 100644
--- a/resources/definitions/creality_cr10spro.def.json
+++ b/resources/definitions/creality_cr10spro.def.json
@@ -4,7 +4,7 @@
"inherits": "creality_cr10",
"overrides": {
"machine_name": { "default_value": "Creality CR-10S Pro" },
- "machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\nM420 S1 Z2 ;Enable ABL using saved Mesh and Fade Height\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n"},
+ "machine_start_gcode": { "default_value": "M201 X500.00 Y500.00 Z100.00 E5000.00 ;Setup machine max acceleration\nM203 X500.00 Y500.00 Z10.00 E50.00 ;Setup machine max feedrate\nM204 P500.00 R1000.00 T500.00 ;Setup Print/Retract/Travel acceleration\nM205 X8.00 Y8.00 Z0.40 E5.00 ;Setup Jerk\nM220 S100 ;Reset Feedrate\nM221 S100 ;Reset Flowrate\n\nG28 ;Home\nG29 ;Auto bed Level\n\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\nG1 X10.1 Y20 Z0.28 F5000.0 ;Move to start position\nG1 X10.1 Y200.0 Z0.28 F1500.0 E15 ;Draw the first line\nG1 X10.4 Y200.0 Z0.28 F5000.0 ;Move to side a little\nG1 X10.4 Y20 Z0.28 F1500.0 E30 ;Draw the second line\nG92 E0 ;Reset Extruder\nG1 Z2.0 F3000 ;Move Z Axis up\n"},
"machine_head_with_fans_polygon": { "default_value": [
[-44, 34],
[-44, -34],
@@ -21,4 +21,4 @@
"platform": "creality_cr10spro.3mf",
"platform_offset": [ -150, 0, 150]
}
-}
\ No newline at end of file
+}
diff --git a/resources/definitions/creality_ender3pro.def.json b/resources/definitions/creality_ender3pro.def.json
index 9f4fa787c1..e8d7548fcf 100644
--- a/resources/definitions/creality_ender3pro.def.json
+++ b/resources/definitions/creality_ender3pro.def.json
@@ -9,8 +9,8 @@
},
"overrides": {
"machine_name": { "default_value": "Creality Ender-3 Pro" },
- "machine_width": { "default_value": 235 },
- "machine_depth": { "default_value": 235 },
+ "machine_width": { "default_value": 220 },
+ "machine_depth": { "default_value": 220 },
"machine_height": { "default_value": 250 },
"machine_head_with_fans_polygon": { "default_value": [
[-26, 34],
diff --git a/resources/definitions/custom.def.json b/resources/definitions/custom.def.json
index d0d9e904c5..88cc3c8821 100644
--- a/resources/definitions/custom.def.json
+++ b/resources/definitions/custom.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "Ultimaker",
"manufacturer": "Custom",
- "category": "Custom",
"file_formats": "text/x-gcode",
"has_materials": true,
"machine_extruder_trains":
diff --git a/resources/definitions/deltacomb.def.json b/resources/definitions/deltacomb.def.json
index fb0580f49d..7fa2b5a7c7 100644
--- a/resources/definitions/deltacomb.def.json
+++ b/resources/definitions/deltacomb.def.json
@@ -7,7 +7,6 @@
"author": "Gabriele Rossetti",
"visible": true,
"manufacturer": "Deltacomb 3D",
- "category": "Other",
"file_formats": "text/x-gcode",
"icon": "icon_ultimaker2",
"platform": "deltacomb.3mf",
diff --git a/resources/definitions/dxu.def.json b/resources/definitions/dxu.def.json
index e39cbba126..e911a8eed6 100644
--- a/resources/definitions/dxu.def.json
+++ b/resources/definitions/dxu.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "TheUltimakerCommunity",
"manufacturer": "DXU",
- "category": "Other",
"has_variants": true,
"has_materials": true,
"has_machine_materials": false,
diff --git a/resources/definitions/erzay3d.def.json b/resources/definitions/erzay3d.def.json
index 875aea708e..1fe777091f 100644
--- a/resources/definitions/erzay3d.def.json
+++ b/resources/definitions/erzay3d.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "Alexander Kirsanov",
"manufacturer": "Robokinetika",
- "category": "Other",
"file_formats": "text/x-gcode",
"machine_extruder_trains":
{
diff --git a/resources/definitions/fabtotum.def.json b/resources/definitions/fabtotum.def.json
index 4a99125615..957dffaef9 100644
--- a/resources/definitions/fabtotum.def.json
+++ b/resources/definitions/fabtotum.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "FABtotum",
"manufacturer": "FABtotum",
- "category": "Other",
"file_formats": "text/x-gcode",
"platform": "fabtotum_platform.3mf",
"has_machine_quality": true,
diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json
index 3077089f8e..afaa39f648 100644
--- a/resources/definitions/fdmprinter.def.json
+++ b/resources/definitions/fdmprinter.def.json
@@ -5,7 +5,6 @@
{
"type": "machine",
"author": "Ultimaker",
- "category": "Other",
"manufacturer": "Unknown",
"setting_version": 13,
"file_formats": "text/x-gcode;application/x-stl-ascii;application/x-stl-binary;application/x-wavefront-obj;application/x3g",
diff --git a/resources/definitions/flsun_qq_s.def.json b/resources/definitions/flsun_qq_s.def.json
index 9c3bf571ae..70be206f8b 100644
--- a/resources/definitions/flsun_qq_s.def.json
+++ b/resources/definitions/flsun_qq_s.def.json
@@ -4,8 +4,9 @@
"inherits": "fdmprinter",
"metadata": {
"visible": true,
- "author": "Cataldo URSO",
+ "author": "Cataldo URSO & Eddy Emck ",
"manufacturer": "FLSUN",
+ "platform": "FLSUN-QQ-S.stl",
"file_formats": "text/x-gcode",
"has_materials": true,
"preferred_quality_type": "draft",
@@ -42,7 +43,7 @@
"default_value": 1.75
},
"machine_start_gcode": {
- "default_value": "G21\nG90\nM82\nM107 T0\nM190 S{material_bed_temperature}\nM109 S{material_print_temperature} T0\nG28\nG92 E0\nG0 E3 F200\nG92 E0\n"
+ "default_value": "G21\nG90\nM82\nM107 T0\nM190 S{material_bed_temperature_layer_0}\nM109 S{material_print_temperature_layer_0} T0\nG28\nG92 E0\nG0 E3 F200\nG92 E0\n"
},
"machine_end_gcode": {
"default_value": "M107 T0\nM104 S0\nM104 S0 T1\nM140 S0\nG92 E0\nG91\nG1 E-1 F300 \nG1 Z+0.5 E-5 X-20 Y-20 F9000\nG28 X0 Y0\nM84 ;steppers off\nG90 ;absolute positioning\n"
diff --git a/resources/definitions/gmax15plus.def.json b/resources/definitions/gmax15plus.def.json
index 6a15626a9c..6cbdce221a 100644
--- a/resources/definitions/gmax15plus.def.json
+++ b/resources/definitions/gmax15plus.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "gcreate",
"manufacturer": "gcreate",
- "category": "Other",
"file_formats": "text/x-gcode",
"platform": "gmax_1-5_xt-plus_s3d_full model_150707.3mf",
"has_machine_quality": true,
diff --git a/resources/definitions/gmax15plus_dual.def.json b/resources/definitions/gmax15plus_dual.def.json
index f128abd46d..ea84858760 100644
--- a/resources/definitions/gmax15plus_dual.def.json
+++ b/resources/definitions/gmax15plus_dual.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "GTL_180109",
"manufacturer": "gCreate",
- "category": "Other",
"file_formats": "text/x-gcode",
"platform": "gmax_1-5_xt-plus_s3d_full model_150707.3mf",
"has_variants": true,
diff --git a/resources/definitions/hms434.def.json b/resources/definitions/hms434.def.json
index db5b0ab62f..4266a9b924 100644
--- a/resources/definitions/hms434.def.json
+++ b/resources/definitions/hms434.def.json
@@ -69,7 +69,7 @@
"material_bed_temp_wait": {"default_value": false },
"machine_max_feedrate_z": {"default_value": 10 },
"machine_acceleration": {"default_value": 180 },
- "machine_start_gcode": {"default_value": "\n;Neither Hybrid AM Systems nor any of Hybrid AM Systems representatives has any liabilities or gives any warranties on this .gcode file, or on any or all objects made with this .gcode file.\n\nM140 S{material_bed_temperature_layer_0}\n\nM117 Homing Y ......\nG28 Y\nM117 Homing X ......\nG28 X\nM117 Homing Z ......\nG28 Z F100\n\nG1 Z10 F900\nG1 X-30 Y100 F12000\n\nM190 S{material_bed_temperature_layer_0}\nM117 HMS434 Printing ...\n\nM42 P10 S255 ; chamberfans on" },
+ "machine_start_gcode": {"default_value": "\n;Neither Hybrid AM Systems nor any of Hybrid AM Systems representatives has any liabilities or gives any warranties on this .gcode file, or on any or all objects made with this .gcode file.\n\nM140 S{material_bed_temperature_layer_0}\n\nM117 Homing Y ......\nG28 Y\nM117 Homing X ......\nG28 X\nM117 Homing Z ......\nG28 Z F100\n\nG1 Z10 F900\nG1 X-25 Y20 F12000\n\nM190 S{material_bed_temperature_layer_0}\nM117 HMS434 Printing ...\n\nM42 P10 S255 ; chamberfans on" },
"machine_end_gcode": {"default_value": "" },
"retraction_extra_prime_amount": {"minimum_value_warning": "-2.0" },
@@ -81,18 +81,19 @@
"layer_height": {"maximum_value": "(0.8 * min(extruderValues('machine_nozzle_size')))" },
"layer_height_0": {"maximum_value": "(0.8 * min(extruderValues('machine_nozzle_size')))" },
"line_width": {"value": "(machine_nozzle_size + 0.2)" },
- "wall_line_width_0": {"value": "(machine_nozzle_size - 0.05)" },
+ "wall_line_width_0": {"value": "(machine_nozzle_size)" },
"infill_line_width": {"value": "(line_width)" },
"initial_layer_line_width_factor": {"value": 110 },
"wall_thickness": {"value": "(line_width * 3) if infill_sparse_density < 95 else line_width" },
- "roofing_layer_count": {"value": "4" },
- "top_bottom_thickness": {"value": "(layer_height_0 + (layer_height * 3))" },
- "top_layers": {"value": "4" },
+ "roofing_layer_count": {"value": "0" },
+ "top_bottom_thickness": {"value": "(layer_height_0 + (layer_height * (top_layers - 1)))" },
+ "top_layers": {"value": "4 if infill_sparse_density < 95 else 1" },
"bottom_layers": {"value": "(top_layers)" },
"wall_0_inset": {"value": "0" },
"outer_inset_first": {"value": true },
"alternate_extra_perimeter": {"value": false },
+ "travel_compensate_overlapping_walls_enabled": {"value": false },
"filter_out_tiny_gaps": {"value": true },
"fill_outline_gaps": {"value": true },
"z_seam_type": {"value": "'shortest'"},
@@ -107,7 +108,7 @@
"infill_sparse_density": {"value": 30},
"infill_pattern": {"value": "'lines'"},
- "infill_before_walls": {"value": false},
+ "infill_before_walls": {"value": true},
"material_print_temperature_layer_0": {"value": "material_print_temperature"},
"material_initial_print_temperature": {"value": "material_print_temperature",
@@ -116,7 +117,7 @@
"material_bed_temperature_layer_0": {"value": "material_bed_temperature"},
"material_flow_layer_0": {"value": "material_flow"},
"retraction_enable": {"value": true },
- "retract_at_layer_change": {"value": true },
+ "retract_at_layer_change": {"value": false },
"retraction_min_travel": {"value": "(round(line_width * 10))"},
"switch_extruder_retraction_speeds": {"value": "(retraction_speed)"},
"switch_extruder_prime_speed": {"value": "(retraction_prime_speed)"},
diff --git a/resources/definitions/imade3d_jellybox_root.def.json b/resources/definitions/imade3d_jellybox_root.def.json
index 52f541f1d4..f631fcb673 100644
--- a/resources/definitions/imade3d_jellybox_root.def.json
+++ b/resources/definitions/imade3d_jellybox_root.def.json
@@ -5,7 +5,6 @@
"metadata": {
"author": "IMADE3D",
"manufacturer": "IMADE3D",
- "category": "Ultimaker",
"visible": false,
"file_formats": "text/x-gcode",
"exclude_materials": [
diff --git a/resources/definitions/kupido.def.json b/resources/definitions/kupido.def.json
index ad0182a5f6..bee92ac282 100644
--- a/resources/definitions/kupido.def.json
+++ b/resources/definitions/kupido.def.json
@@ -7,7 +7,6 @@
"visible": true,
"author": "ALYA",
"manufacturer": "Kati Hal ARGE",
- "category": "Other",
"file_formats": "text/x-gcode",
"platform_offset": [ 0, 0, 0],
"exclude_materials": ["chromatik_pla", "dsm_arnitel2045_175", "dsm_novamid1070_175", "fabtotum_abs", "fabtotum_nylon", "fabtotum_pla", "fabtotum_tpu", "fiberlogy_hd_pla", "filo3d_pla", "filo3d_pla_green", "filo3d_pla_red", "generic_bam", "generic_cpe", "generic_cpe_175", "generic_cpe_plus", "generic_hips", "generic_hips_175", "generic_nylon", "generic_nylon_175", "generic_pc", "generic_pc_175", "generic_petg", "generic_petg_175", "generic_pp", "generic_pva", "generic_pva_175", "generic_tough_pla", "generic_tpu", "generic_tpu_175", "imade3d_petg_green", "imade3d_petg_pink", "imade3d_pla_green", "imade3d_pla_pink", "innofill_innoflex60_175", "octofiber_pla", "polyflex_pla", "polymax_pla", "polyplus_pla", "polywood_pla", "ultimaker_abs_black", "ultimaker_abs_blue", "ultimaker_abs_green", "ultimaker_abs_grey", "ultimaker_abs_orange", "ultimaker_abs_pearl-gold", "ultimaker_abs_red", "ultimaker_abs_silver-metallic", "ultimaker_abs_white", "ultimaker_abs_yellow", "ultimaker_bam", "ultimaker_cpe_black", "ultimaker_cpe_blue", "ultimaker_cpe_dark-grey", "ultimaker_cpe_green", "ultimaker_cpe_light-grey", "ultimaker_cpe_plus_black", "ultimaker_cpe_plus_transparent", "ultimaker_cpe_plus_white", "ultimaker_cpe_red", "ultimaker_cpe_transparent", "ultimaker_cpe_white", "ultimaker_cpe_yellow", "ultimaker_nylon_black", "ultimaker_nylon_transparent", "ultimaker_pc_black", "ultimaker_pc_transparent", "ultimaker_pc_white", "ultimaker_pla_black", "ultimaker_pla_blue", "ultimaker_pla_green", "ultimaker_pla_magenta", "ultimaker_pla_orange", "ultimaker_pla_pearl-white", "ultimaker_pla_red", "ultimaker_pla_silver-metallic", "ultimaker_pla_transparent", "ultimaker_pla_white", "ultimaker_pla_yellow", "ultimaker_pp_transparent", "ultimaker_pva", "ultimaker_tough_pla_black", "ultimaker_tough_pla_green", "ultimaker_tough_pla_red", "ultimaker_tough_pla_white", "ultimaker_tpu_black", "ultimaker_tpu_blue", "ultimaker_tpu_red", "ultimaker_tpu_white", "verbatim_bvoh_175", "Vertex_Delta_ABS", "Vertex_Delta_PET", "Vertex_Delta_PLA", "Vertex_Delta_TPU", "zyyx_pro_flex", "zyyx_pro_pla","tizyx_pla","tizyx_abs","tizyx_pla_bois" ],
diff --git a/resources/definitions/leapfrog_bolt_pro.def.json b/resources/definitions/leapfrog_bolt_pro.def.json
index cc23277b86..904215853b 100644
--- a/resources/definitions/leapfrog_bolt_pro.def.json
+++ b/resources/definitions/leapfrog_bolt_pro.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "Karan and Vincent 20191104",
"manufacturer": "Leapfrog B.V.",
- "category": "Other",
"platform": "leapfrog_bolt_pro_platform.3mf",
"platform_offset": [0, 0, -14],
"file_formats": "text/x-gcode",
diff --git a/resources/definitions/malyan_m200.def.json b/resources/definitions/malyan_m200.def.json
index 7ea24dc916..c853f8f772 100644
--- a/resources/definitions/malyan_m200.def.json
+++ b/resources/definitions/malyan_m200.def.json
@@ -5,7 +5,6 @@
"metadata": {
"author": "Brian Corbino, Tyler Gibson",
"manufacturer": "Malyan",
- "category": "Other",
"file_formats": "text/x-gcode",
"platform": "malyan_m200_platform.3mf",
"platform_offset": [0, -0.25, 0],
diff --git a/resources/definitions/mbot3d_grid4.def.json b/resources/definitions/mbot3d_grid4.def.json
index a895415dda..fa2deda027 100644
--- a/resources/definitions/mbot3d_grid4.def.json
+++ b/resources/definitions/mbot3d_grid4.def.json
@@ -5,7 +5,6 @@
"metadata": {
"author": "Magicfirm",
"manufacturer": "Magicfirm",
- "category": "Other",
"visible": true,
"file_formats": "text/x-gcode",
"platform_offset": [
diff --git a/resources/definitions/mbot3d_grid4_dual.def.json b/resources/definitions/mbot3d_grid4_dual.def.json
index d32590ff3e..891f5dc51f 100644
--- a/resources/definitions/mbot3d_grid4_dual.def.json
+++ b/resources/definitions/mbot3d_grid4_dual.def.json
@@ -5,7 +5,6 @@
"metadata": {
"author": "Magicfirm",
"manufacturer": "Magicfirm",
- "category": "Other",
"visible": true,
"file_formats": "text/x-gcode",
"platform_offset": [
@@ -14,7 +13,7 @@
0
],
"has_materials": true,
- "machine_extruder_trains": {
+ "machine_extruder_trains": {
"0": "mbot3d_grid4_extruder_left",
"1": "mbot3d_grid4_extruder_right"
}
diff --git a/resources/definitions/monoprice_select_mini_v1.def.json b/resources/definitions/monoprice_select_mini_v1.def.json
index 4fe67fc92e..21497b13bc 100644
--- a/resources/definitions/monoprice_select_mini_v1.def.json
+++ b/resources/definitions/monoprice_select_mini_v1.def.json
@@ -5,7 +5,6 @@
"metadata": {
"author": "Brian Corbino, Tyler Gibson",
"manufacturer": "Monoprice",
- "category": "Other",
"file_formats": "text/x-gcode",
"quality_definition": "malyan_m200",
"visible": true,
diff --git a/resources/definitions/monoprice_select_mini_v2.def.json b/resources/definitions/monoprice_select_mini_v2.def.json
index 2364e49383..d671f319ad 100644
--- a/resources/definitions/monoprice_select_mini_v2.def.json
+++ b/resources/definitions/monoprice_select_mini_v2.def.json
@@ -5,7 +5,6 @@
"metadata": {
"author": "Tyler Gibson",
"manufacturer": "Monoprice",
- "category": "Other",
"file_formats": "text/x-gcode",
"has_machine_quality": true,
"has_materials": true,
diff --git a/resources/definitions/mp_mini_delta.def.json b/resources/definitions/mp_mini_delta.def.json
index 991367bd51..bbdca2c8f8 100644
--- a/resources/definitions/mp_mini_delta.def.json
+++ b/resources/definitions/mp_mini_delta.def.json
@@ -5,7 +5,6 @@
"metadata": {
"author": "MPMD Facebook Group",
"manufacturer": "Monoprice",
- "category": "Other",
"file_formats": "text/x-gcode",
"platform": "mp_mini_delta_platform.3mf",
"supports_usb_connection": true,
diff --git a/resources/definitions/predator.def.json b/resources/definitions/predator.def.json
new file mode 100644
index 0000000000..a8f4e56fe1
--- /dev/null
+++ b/resources/definitions/predator.def.json
@@ -0,0 +1,72 @@
+{
+ "version": 2,
+ "name": "Anycubic Predator",
+ "inherits": "fdmprinter",
+ "metadata": {
+ "author": "ksihota",
+ "manufacturer": "Anycubic",
+ "file_formats": "text/x-gcode",
+ "platform": "predator_platform.stl",
+ "platform_texture": "anycubic_predator.png",
+ "supports_usb_connection": true,
+ "visible": true,
+ "platform_offset": [0, 0, 0],
+ "has_materials": true,
+ "has_variants": false,
+ "has_machine_materials": false,
+ "has_variant_materials": false,
+ "has_machine_quality": true,
+ "quality_definition": "predator",
+ "preferred_quality_type": "normal",
+ "machine_extruder_trains":
+ {
+ "0": "predator_extruder_0"
+ }
+ },
+
+ "overrides": {
+ "machine_start_gcode":
+ {
+ "default_value": "G21 ;metric values \nG90 ;absolute positioning \nM82 ;set extruder to absolute mode \nM107 ;start with the fan off \nG28 ;Home \nG1 Z15.0 F1000;short move \nG92 E0 ;zero the extruded length \nG1 F200 E3 ;extrude 3mm of feed stock adjust so I don't have to remove any filament \nG92 E0 ;zero the extruded length again \nG1 F4000 ;move to bed \n;Put printing message on LCD screen \nM117 Printing... \n;G5; this is in order to resume on Power failure (only works on SD prints)"
+ },
+ "machine_end_gcode":
+ {
+ "default_value": "M104 S0 ;extruder heater off \nM140 S0 ;heated bed heater off \nG91 ;relative positioning \nG92 E0 ;zero the extruded length \nG1 E-2 F300 ;retract the filament a bit before lifting the nozzle, to release some of the pressure \nG92 E0 ;zero the extruded length \n;M107 ;fan off \nG1 Z+0.5 E-5 ;move Z up a bit and retract filament even more \n;G1 X0.0 Y0.0 Z455.0 F4500 \nG28 ;Home all axes (max endstops) \nG90 ;absolute positioning \n;M109 S60 ; wait for extruder temp to drop to 60 \n;M84 ;steppers off \n;M81 ;turn off printer"
+ },
+ "gantry_height": {
+ "value": 455
+ },
+ "machine_width": { "default_value": 370 },
+ "machine_depth": { "default_value": 370 },
+ "machine_height": { "default_value": 455 },
+ "machine_heated_bed": { "default_value": true },
+ "machine_shape": { "default_value": "elliptic" },
+ "machine_center_is_zero": { "default_value": true },
+ "machine_nozzle_size": {
+ "default_value": 0.4,
+ "minimum_value": 0.15,
+ "maximum_value": 0.80
+ },
+ "line_width": { "value": "round(machine_nozzle_size * 0.875, 2)" },
+ "material_print_temperature_layer_0": { "value": "material_print_temperature + 5" },
+ "material_bed_temperature_layer_0": { "value": "material_bed_temperature + 5" },
+ "machine_gcode_flavor": { "default_value": "RepRap (Marlin/Sprinter)" },
+ "machine_max_feedrate_x": { "default_value": 150 },
+ "machine_max_feedrate_y": { "default_value": 150 },
+ "machine_max_feedrate_z": { "default_value": 150 },
+ "machine_max_feedrate_e": { "default_value": 50 },
+ "machine_max_acceleration_x": { "default_value": 800 },
+ "machine_max_acceleration_y": { "default_value": 800 },
+ "machine_max_acceleration_z": { "default_value": 800 },
+ "machine_max_acceleration_e": { "default_value": 10000 },
+ "machine_acceleration": { "default_value": 3000 },
+ "machine_max_jerk_xy": { "default_value": 20 },
+ "machine_max_jerk_z": { "default_value": 20 },
+ "machine_max_jerk_e": { "default_value": 5},
+ "retraction_amount": { "default_value": 4 },
+ "retraction_speed": { "default_value": 50 },
+ "retraction_hop_enabled": { "default_value": false },
+ "retract_at_layer_change": { "default_value": true },
+ "coasting_enable": { "default_value": true }
+ }
+}
\ No newline at end of file
diff --git a/resources/definitions/raise3D_N2_dual.def.json b/resources/definitions/raise3D_N2_dual.def.json
index 530ad79d19..f5246f6bb6 100644
--- a/resources/definitions/raise3D_N2_dual.def.json
+++ b/resources/definitions/raise3D_N2_dual.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "Raise3D",
"manufacturer": "Raise3D",
- "category": "Other",
"file_formats": "text/x-gcode",
"has_materials": true,
"machine_extruder_trains":
diff --git a/resources/definitions/raise3D_N2_plus_dual.def.json b/resources/definitions/raise3D_N2_plus_dual.def.json
index ffc4afec16..02f5fd4e11 100644
--- a/resources/definitions/raise3D_N2_plus_dual.def.json
+++ b/resources/definitions/raise3D_N2_plus_dual.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "Raise3D",
"manufacturer": "Raise3D",
- "category": "Other",
"file_formats": "text/x-gcode",
"has_materials": true,
"machine_extruder_trains":
diff --git a/resources/definitions/raise3D_N2_plus_single.def.json b/resources/definitions/raise3D_N2_plus_single.def.json
index ccb169efb1..7ffdf08767 100644
--- a/resources/definitions/raise3D_N2_plus_single.def.json
+++ b/resources/definitions/raise3D_N2_plus_single.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "Raise3D",
"manufacturer": "Raise3D",
- "category": "Other",
"file_formats": "text/x-gcode",
"has_materials": true,
"machine_extruder_trains":
diff --git a/resources/definitions/raise3D_N2_single.def.json b/resources/definitions/raise3D_N2_single.def.json
index f0915d1a31..c4e346ae90 100644
--- a/resources/definitions/raise3D_N2_single.def.json
+++ b/resources/definitions/raise3D_N2_single.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "Raise3D",
"manufacturer": "Raise3D",
- "category": "Other",
"file_formats": "text/x-gcode",
"has_materials": true,
"machine_extruder_trains":
diff --git a/resources/definitions/skriware_2.def.json b/resources/definitions/skriware_2.def.json
index 721d4f8b2b..7c4db94e02 100644
--- a/resources/definitions/skriware_2.def.json
+++ b/resources/definitions/skriware_2.def.json
@@ -1,727 +1,726 @@
{
- "name": "Skriware 2",
- "version": 2,
- "inherits": "fdmprinter",
- "metadata": {
- "visible": true,
- "author": "Skriware",
- "manufacturer": "Skriware",
- "category": "Other",
- "file_formats": "text/x-gcode",
- "platform_offset": [
- 0,
- 0,
- 0
- ],
- "supports_usb_connection": false,
- "platform": "skriware_2_platform.3mf",
- "machine_extruder_trains": {
- "0": "skriware_2_extruder_0",
- "1": "skriware_2_extruder_1"
- }
- },
- "overrides": {
- "raft_interface_thickness": {
- "value": "0.2"
- },
- "wipe_retraction_prime_speed": {
- "value": "30"
- },
- "support_skip_zag_per_mm": {
- "default_value": 10
- },
- "material_bed_temperature": {
- "value": "50"
- },
- "raft_airgap": {
- "default_value": 0.2
- },
- "top_layers": {
- "value": "4"
- },
- "machine_extruder_count": {
- "default_value": 2
- },
- "raft_surface_acceleration": {
- "value": "400"
- },
- "meshfix_maximum_travel_resolution": {
- "value": "0.8"
- },
- "machine_end_gcode": {
- "default_value": "M59\nG92 E0\nG1 E-10 F300\nM104 T0 S0\nM104 T1 S0\nM140 S0\nG28 X0 Y0\nM84\nM106 S0\nM107"
- },
- "wall_material_flow": {
- "value": "99"
- },
- "raft_interface_jerk": {
- "value": "10"
- },
- "acceleration_topbottom": {
- "value": "400"
- },
- "prime_tower_size": {
- "default_value": 1
- },
- "max_skin_angle_for_expansion": {
- "default_value": 50
- },
- "raft_acceleration": {
- "value": "400"
- },
- "support_xy_distance": {
- "default_value": 0.6
- },
- "xy_offset_layer_0": {
- "value": "-0.16"
- },
- "raft_interface_fan_speed": {
- "value": "40"
- },
- "retraction_speed": {
- "default_value": 30
- },
- "speed_print": {
- "default_value": 20
- },
- "travel_avoid_supports": {
- "default_value": true
- },
- "infill_overlap_mm": {
- "value": "0.0"
- },
- "support_roof_height": {
- "value": "0.4"
- },
- "speed_travel_layer_0": {
- "value": "120"
- },
- "speed_wall_0": {
- "value": "20"
- },
- "acceleration_wall_x": {
- "value": "400"
- },
- "layer_0_z_overlap": {
- "value": "0.1"
- },
- "switch_extruder_retraction_speed": {
- "value": "30"
- },
- "travel_compensate_overlapping_walls_enabled": {
- "default_value": false
- },
- "raft_base_acceleration": {
- "value": "400"
- },
- "raft_base_speed": {
- "value": "60"
- },
- "wall_0_material_flow": {
- "value": "99"
- },
- "support_infill_rate": {
- "value": "20"
- },
- "raft_surface_layers": {
- "default_value": 1
- },
- "machine_height": {
- "default_value": 210
- },
- "retraction_prime_speed": {
- "value": "60"
- },
- "support_interface_material_flow": {
- "value": "99"
- },
- "raft_surface_fan_speed": {
- "value": "80"
- },
- "raft_base_line_width": {
- "value": "0.4"
- },
- "infill_line_distance": {
- "value": "5.33"
- },
- "default_material_print_temperature": {
- "default_value": 200
- },
- "speed_roofing": {
- "value": "20"
- },
- "skin_material_flow": {
- "value": "99"
- },
- "cool_fan_full_layer": {
- "value": "1"
- },
- "material_break_preparation_temperature": {
- "value": "195"
- },
- "support_roof_density": {
- "value": "70"
- },
- "support_infill_sparse_thickness": {
- "value": "0.2"
- },
- "retraction_retract_speed": {
- "value": "30"
- },
- "speed_slowdown_layers": {
- "default_value": 1
- },
- "support_line_distance": {
- "value": "2"
- },
- "cool_lift_head": {
- "default_value": true
- },
- "min_skin_width_for_expansion": {
- "value": "0.67"
- },
- "cool_min_speed": {
- "default_value": 5
- },
- "switch_extruder_retraction_speeds": {
- "default_value": 30
- },
- "raft_base_line_spacing": {
- "value": "0.8"
- },
- "speed_support": {
- "value": "50"
- },
- "skirt_brim_material_flow": {
- "value": "99"
- },
- "speed_infill": {
- "value": "80"
- },
- "support_initial_layer_line_distance": {
- "value": "2"
- },
- "support_use_towers": {
- "default_value": false
- },
- "skin_no_small_gaps_heuristic": {
- "default_value": true
- },
- "acceleration_roofing": {
- "value": "400"
- },
- "material_initial_print_temperature": {
- "value": "195"
- },
- "material_diameter": {
- "default_value": 1.75
- },
- "xy_offset": {
- "default_value": -0.16
- },
- "support_extruder_nr": {
- "value": "0"
- },
- "support_brim_line_count": {
- "value": "16"
- },
- "support_interface_extruder_nr": {
- "value": "0"
- },
- "support_roof_extruder_nr": {
- "value": "0"
- },
- "material_adhesion_tendency": {
- "default_value": 0
- },
- "material_standby_temperature": {
- "default_value": 195
- },
- "cool_fan_speed_0": {
- "default_value": 100
- },
- "brim_line_count": {
- "value": "17"
- },
- "adhesion_type": {
- "default_value": "raft"
- },
- "switch_extruder_retraction_amount": {
- "value": "16"
- },
- "retraction_amount": {
- "default_value": 3
- },
- "acceleration_travel": {
- "value": "400"
- },
- "jerk_print_layer_0": {
- "value": "10"
- },
- "raft_surface_thickness": {
- "value": "0.2"
- },
- "raft_base_jerk": {
- "value": "10"
- },
- "bottom_thickness": {
- "value": "0.8"
- },
- "roofing_material_flow": {
- "value": "99"
- },
- "top_skin_expand_distance": {
- "value": "0.8"
- },
- "speed_wall_x": {
- "value": "20"
- },
- "support_enable": {
- "default_value": true
- },
- "acceleration_print_layer_0": {
- "value": "400"
- },
- "jerk_prime_tower": {
- "value": "5"
- },
- "infill_before_walls": {
- "default_value": false
- },
- "raft_interface_line_spacing": {
- "value": "0.4"
- },
- "gantry_height": {
- "value": "210"
- },
- "material_print_temperature_layer_0": {
- "value": "195"
- },
- "raft_interface_line_width": {
- "value": "0.4"
- },
- "skirt_brim_line_width": {
- "value": "0.5"
- },
- "z_seam_y": {
- "value": "180"
- },
- "roofing_layer_count": {
- "value": "1"
- },
- "raft_margin": {
- "default_value": 4
- },
- "cool_fan_full_at_height": {
- "value": "0"
- },
- "acceleration_support_interface": {
- "value": "250"
- },
- "retraction_min_travel": {
- "value": "1"
- },
- "acceleration_layer_0": {
- "value": "400"
- },
- "support_z_distance": {
- "default_value": 0.2
- },
- "machine_heated_bed": {
- "default_value": true
- },
- "raft_jerk": {
- "value": "10"
- },
- "raft_surface_speed": {
- "value": "60"
- },
- "initial_layer_line_width_factor": {
- "default_value": 120
- },
- "machine_start_gcode": {
- "default_value": "G90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM420 S1 Z0.6 ;enable bed levelling\nG1 Z10 F250 ;move the platform down 10mm\nM107 ;fan off\nM42 P11 S255 ;turn on front fan\nM140 S{material_bed_temperature}\nM104 T0 S{material_print_temperature, 0}\nM104 T1 S{material_print_temperature, 1}\nG1 F2500 Y260 X0\nM190 S{material_bed_temperature}\nM109 T0 S{material_print_temperature, 0}\nM109 T1 S{material_print_temperature, 1}\nM60 ;enable E-FADE Algorithm\nM62 A ;filament sensor off\nG92 E0 ;zero the extruded length\nT1\nG92 E0;zero the extruded length\nG1 F300 Z0.3\nG1 F1200 X20\nG1 F1200 X180 E21 ;extrude 21 mm of feed stock\nG1 F1200 E15 ;retracting 6 mm\nG1 F2000 E21\nG1 F2000 E11\nG1 F300 Z1.5\nG92 E0 ;zero the extruded length again\nT0\nG92 E0 ;zero the extruded length\nG1 F1200 Y258\nG1 F300 Z0.3\nG1 F1200 X40 E21 ;extrude 21 mm of feed stock\nG1 F1200 E15 ;retracting 6 mm\nG1 F2000 E21\nG1 F2000 E11\nG1 Z1.5\nM61 A ;filament sensor reset\nM63 A ;filament sensor on\nG92 E0 ;zero the extruded length again\nM58 ;end of Start G-Code and signal retract management\nT{initial_extruder_nr}"
- },
- "bottom_skin_preshrink": {
- "value": "0.8"
- },
- "ironing_inset": {
- "value": "0.2"
- },
- "jerk_travel": {
- "value": "10"
- },
- "machine_depth": {
- "default_value": 260
- },
- "jerk_skirt_brim": {
- "value": "5"
- },
- "infill_wipe_dist": {
- "value": "0"
- },
- "raft_interface_acceleration": {
- "value": "400"
- },
- "z_seam_x": {
- "value": "115"
- },
- "material_print_temperature": {
- "value": "195"
- },
- "material_bed_temperature_layer_0": {
- "value": "50"
- },
- "wipe_retraction_retract_speed": {
- "value": "30"
- },
- "jerk_travel_layer_0": {
- "value": "10"
- },
- "infill_overlap": {
- "value": "0"
- },
- "acceleration_support_infill": {
- "value": "400"
- },
- "travel_compensate_overlapping_walls_0_enabled": {
- "value": "False"
- },
- "support_bottom_material_flow": {
- "value": "99"
- },
- "jerk_support_roof": {
- "value": "5"
- },
- "wall_x_material_flow": {
- "value": "99"
- },
- "speed_support_interface": {
- "value": "33.33"
- },
- "jerk_layer_0": {
- "value": "10"
- },
- "support_angle": {
- "default_value": 60
- },
- "infill_sparse_thickness": {
- "value": "0.2"
- },
- "prime_tower_position_y": {
- "value": "1"
- },
- "retraction_combing": {
- "default_value": "infill"
- },
- "acceleration_prime_tower": {
- "value": "250"
- },
- "acceleration_print": {
- "default_value": 400
- },
- "acceleration_infill": {
- "value": "500"
- },
- "bridge_wall_speed": {
- "value": "10.0"
- },
- "acceleration_wall_0": {
- "value": "400"
- },
- "support_offset": {
- "default_value": 0.2
- },
- "build_volume_temperature": {
- "default_value": 28
- },
- "switch_extruder_prime_speed": {
- "value": "60"
- },
- "speed_prime_tower": {
- "value": "20"
- },
- "top_skin_preshrink": {
- "value": "0.8"
- },
- "jerk_ironing": {
- "value": "5"
- },
- "skin_outline_count": {
- "default_value": 0
- },
- "skirt_brim_speed": {
- "value": "10.0"
- },
- "raft_base_thickness": {
- "value": "0.2"
- },
- "infill_sparse_density": {
- "default_value": 15
- },
- "support_bottom_extruder_nr": {
- "value": "0"
- },
- "support_material_flow": {
- "value": "98"
- },
- "min_infill_area": {
- "default_value": 1
- },
- "jerk_support": {
- "value": "10"
- },
- "bottom_skin_expand_distance": {
- "value": "0.8"
- },
- "retract_at_layer_change": {
- "default_value": true
- },
- "jerk_support_interface": {
- "value": "5"
- },
- "jerk_support_bottom": {
- "value": "5"
- },
- "optimize_wall_printing_order": {
- "default_value": true
- },
- "skirt_brim_minimal_length": {
- "default_value": 50
- },
- "jerk_support_infill": {
- "value": "10"
- },
- "initial_bottom_layers": {
- "value": "3"
- },
- "prime_tower_position_x": {
- "value": "1"
- },
- "acceleration_support_bottom": {
- "value": "250"
- },
- "speed_support_roof": {
- "value": "33.33"
- },
- "speed_support_infill": {
- "value": "80"
- },
- "bridge_skin_speed_2": {
- "value": "15"
- },
- "raft_fan_speed": {
- "default_value": 100
- },
- "wipe_retraction_amount": {
- "value": "3"
- },
- "skin_edge_support_thickness": {
- "value": "0"
- },
- "bottom_layers": {
- "value": "3"
- },
- "retraction_extrusion_window": {
- "value": "3"
- },
- "acceleration_ironing": {
- "value": "250"
- },
- "support_top_distance": {
- "value": "0.2"
- },
- "travel_retract_before_outer_wall": {
- "default_value": true
- },
- "material_flow": {
- "default_value": 99
- },
- "support_bottom_distance": {
- "value": "0.2"
- },
- "expand_skins_expand_distance": {
- "value": "0.8"
- },
- "jerk_wall": {
- "value": "10"
- },
- "support_zag_skip_count": {
- "value": "8"
- },
- "connect_infill_polygons": {
- "value": "False"
- },
- "acceleration_skirt_brim": {
- "value": "250"
- },
- "z_seam_corner": {
- "default_value": "z_seam_corner_weighted"
- },
- "raft_surface_jerk": {
- "value": "10"
- },
- "cross_infill_pocket_size": {
- "value": "5.33"
- },
- "support_infill_extruder_nr": {
- "value": "0"
- },
- "acceleration_enabled": {
- "default_value": true
- },
- "jerk_wall_x": {
- "value": "10"
- },
- "skin_overlap": {
- "value": "15"
- },
- "infill_material_flow": {
- "value": "99"
- },
- "speed_equalize_flow_max": {
- "default_value": 40
- },
- "skin_preshrink": {
- "value": "0.8"
- },
- "speed_wall": {
- "value": "20"
- },
- "support_tree_collision_resolution": {
- "value": "0.2"
- },
- "meshfix_maximum_deviation": {
- "default_value": 0.005
- },
- "jerk_roofing": {
- "value": "10"
- },
- "fill_outline_gaps": {
- "default_value": true
- },
- "layer_height": {
- "default_value": 0.2
- },
- "remove_empty_first_layers": {
- "default_value": false
- },
- "prime_tower_flow": {
- "value": "99"
- },
- "support_roof_line_distance": {
- "value": "0.57"
- },
- "wipe_retraction_speed": {
- "value": "30"
- },
- "support_extruder_nr_layer_0": {
- "value": "0"
- },
- "layer_height_0": {
- "default_value": 0.2
- },
- "multiple_mesh_overlap": {
- "default_value": 0
- },
- "ooze_shield_dist": {
- "default_value": 4
- },
- "jerk_enabled": {
- "default_value": true
- },
- "acceleration_support": {
- "value": "400"
- },
- "adhesion_extruder_nr": {
- "value": "0"
- },
- "skirt_line_count": {
- "default_value": 2
- },
- "travel_compensate_overlapping_walls_x_enabled": {
- "value": "False"
- },
- "jerk_wall_0": {
- "value": "10"
- },
- "raft_speed": {
- "value": "60"
- },
- "speed_layer_0": {
- "value": "10.0"
- },
- "machine_width": {
- "default_value": 210
- },
- "acceleration_wall": {
- "value": "400"
- },
- "jerk_infill": {
- "value": "10"
- },
- "wipe_hop_enable": {
- "value": "False"
- },
- "acceleration_travel_layer_0": {
- "value": "400"
- },
- "raft_interface_speed": {
- "value": "60"
- },
- "skin_edge_support_layers": {
- "value": "0"
- },
- "support_xy_distance_overhang": {
- "value": "0.5"
- },
- "brim_width": {
- "default_value": 10
- },
- "coasting_enable": {
- "default_value": true
- },
- "jerk_print": {
- "default_value": 10
- },
- "acceleration_support_roof": {
- "value": "250"
- },
- "prime_tower_min_volume": {
- "default_value": 4
- },
- "support_roof_material_flow": {
- "value": "99"
- },
- "wall_0_wipe_dist": {
- "value": "0"
- },
- "jerk_topbottom": {
- "value": "10"
- },
- "retraction_count_max": {
- "default_value": 30
- },
- "skin_overlap_mm": {
- "value": "0.06"
- },
- "extruders_enabled_count": {
- "value": "2"
- },
- "speed_support_bottom": {
- "value": "33.33"
- },
- "support_skip_some_zags": {
- "default_value": true
- },
- "ooze_shield_angle": {
- "default_value": 50
- },
- "wall_thickness": {
- "value": "1.2"
- },
- "speed_print_layer_0": {
- "value": "10.0"
- }
- }
-}
\ No newline at end of file
+ "name": "Skriware 2",
+ "version": 2,
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": true,
+ "author": "Skriware",
+ "manufacturer": "Skriware",
+ "file_formats": "text/x-gcode",
+ "platform_offset": [
+ 0,
+ 0,
+ 0
+ ],
+ "supports_usb_connection": false,
+ "platform": "skriware_2_platform.3mf",
+ "machine_extruder_trains": {
+ "0": "skriware_2_extruder_0",
+ "1": "skriware_2_extruder_1"
+ }
+ },
+ "overrides": {
+ "raft_interface_thickness": {
+ "value": "0.2"
+ },
+ "wipe_retraction_prime_speed": {
+ "value": "30"
+ },
+ "support_skip_zag_per_mm": {
+ "default_value": 10
+ },
+ "material_bed_temperature": {
+ "value": "50"
+ },
+ "raft_airgap": {
+ "default_value": 0.2
+ },
+ "top_layers": {
+ "value": "4"
+ },
+ "machine_extruder_count": {
+ "default_value": 2
+ },
+ "raft_surface_acceleration": {
+ "value": "400"
+ },
+ "meshfix_maximum_travel_resolution": {
+ "value": "0.8"
+ },
+ "machine_end_gcode": {
+ "default_value": "M59\nG92 E0\nG1 E-10 F300\nM104 T0 S0\nM104 T1 S0\nM140 S0\nG28 X0 Y0\nM84\nM106 S0\nM107"
+ },
+ "wall_material_flow": {
+ "value": "99"
+ },
+ "raft_interface_jerk": {
+ "value": "10"
+ },
+ "acceleration_topbottom": {
+ "value": "400"
+ },
+ "prime_tower_size": {
+ "default_value": 1
+ },
+ "max_skin_angle_for_expansion": {
+ "default_value": 50
+ },
+ "raft_acceleration": {
+ "value": "400"
+ },
+ "support_xy_distance": {
+ "default_value": 0.6
+ },
+ "xy_offset_layer_0": {
+ "value": "-0.16"
+ },
+ "raft_interface_fan_speed": {
+ "value": "40"
+ },
+ "retraction_speed": {
+ "default_value": 30
+ },
+ "speed_print": {
+ "default_value": 20
+ },
+ "travel_avoid_supports": {
+ "default_value": true
+ },
+ "infill_overlap_mm": {
+ "value": "0.0"
+ },
+ "support_roof_height": {
+ "value": "0.4"
+ },
+ "speed_travel_layer_0": {
+ "value": "120"
+ },
+ "speed_wall_0": {
+ "value": "20"
+ },
+ "acceleration_wall_x": {
+ "value": "400"
+ },
+ "layer_0_z_overlap": {
+ "value": "0.1"
+ },
+ "switch_extruder_retraction_speed": {
+ "value": "30"
+ },
+ "travel_compensate_overlapping_walls_enabled": {
+ "default_value": false
+ },
+ "raft_base_acceleration": {
+ "value": "400"
+ },
+ "raft_base_speed": {
+ "value": "60"
+ },
+ "wall_0_material_flow": {
+ "value": "99"
+ },
+ "support_infill_rate": {
+ "value": "20"
+ },
+ "raft_surface_layers": {
+ "default_value": 1
+ },
+ "machine_height": {
+ "default_value": 210
+ },
+ "retraction_prime_speed": {
+ "value": "60"
+ },
+ "support_interface_material_flow": {
+ "value": "99"
+ },
+ "raft_surface_fan_speed": {
+ "value": "80"
+ },
+ "raft_base_line_width": {
+ "value": "0.4"
+ },
+ "infill_line_distance": {
+ "value": "5.33"
+ },
+ "default_material_print_temperature": {
+ "default_value": 200
+ },
+ "speed_roofing": {
+ "value": "20"
+ },
+ "skin_material_flow": {
+ "value": "99"
+ },
+ "cool_fan_full_layer": {
+ "value": "1"
+ },
+ "material_break_preparation_temperature": {
+ "value": "195"
+ },
+ "support_roof_density": {
+ "value": "70"
+ },
+ "support_infill_sparse_thickness": {
+ "value": "0.2"
+ },
+ "retraction_retract_speed": {
+ "value": "30"
+ },
+ "speed_slowdown_layers": {
+ "default_value": 1
+ },
+ "support_line_distance": {
+ "value": "2"
+ },
+ "cool_lift_head": {
+ "default_value": true
+ },
+ "min_skin_width_for_expansion": {
+ "value": "0.67"
+ },
+ "cool_min_speed": {
+ "default_value": 5
+ },
+ "switch_extruder_retraction_speeds": {
+ "default_value": 30
+ },
+ "raft_base_line_spacing": {
+ "value": "0.8"
+ },
+ "speed_support": {
+ "value": "50"
+ },
+ "skirt_brim_material_flow": {
+ "value": "99"
+ },
+ "speed_infill": {
+ "value": "80"
+ },
+ "support_initial_layer_line_distance": {
+ "value": "2"
+ },
+ "support_use_towers": {
+ "default_value": false
+ },
+ "skin_no_small_gaps_heuristic": {
+ "default_value": true
+ },
+ "acceleration_roofing": {
+ "value": "400"
+ },
+ "material_initial_print_temperature": {
+ "value": "195"
+ },
+ "material_diameter": {
+ "default_value": 1.75
+ },
+ "xy_offset": {
+ "default_value": -0.16
+ },
+ "support_extruder_nr": {
+ "value": "0"
+ },
+ "support_brim_line_count": {
+ "value": "16"
+ },
+ "support_interface_extruder_nr": {
+ "value": "0"
+ },
+ "support_roof_extruder_nr": {
+ "value": "0"
+ },
+ "material_adhesion_tendency": {
+ "default_value": 0
+ },
+ "material_standby_temperature": {
+ "default_value": 195
+ },
+ "cool_fan_speed_0": {
+ "default_value": 100
+ },
+ "brim_line_count": {
+ "value": "17"
+ },
+ "adhesion_type": {
+ "default_value": "raft"
+ },
+ "switch_extruder_retraction_amount": {
+ "value": "16"
+ },
+ "retraction_amount": {
+ "default_value": 3
+ },
+ "acceleration_travel": {
+ "value": "400"
+ },
+ "jerk_print_layer_0": {
+ "value": "10"
+ },
+ "raft_surface_thickness": {
+ "value": "0.2"
+ },
+ "raft_base_jerk": {
+ "value": "10"
+ },
+ "bottom_thickness": {
+ "value": "0.8"
+ },
+ "roofing_material_flow": {
+ "value": "99"
+ },
+ "top_skin_expand_distance": {
+ "value": "0.8"
+ },
+ "speed_wall_x": {
+ "value": "20"
+ },
+ "support_enable": {
+ "default_value": true
+ },
+ "acceleration_print_layer_0": {
+ "value": "400"
+ },
+ "jerk_prime_tower": {
+ "value": "5"
+ },
+ "infill_before_walls": {
+ "default_value": false
+ },
+ "raft_interface_line_spacing": {
+ "value": "0.4"
+ },
+ "gantry_height": {
+ "value": "210"
+ },
+ "material_print_temperature_layer_0": {
+ "value": "195"
+ },
+ "raft_interface_line_width": {
+ "value": "0.4"
+ },
+ "skirt_brim_line_width": {
+ "value": "0.5"
+ },
+ "z_seam_y": {
+ "value": "180"
+ },
+ "roofing_layer_count": {
+ "value": "1"
+ },
+ "raft_margin": {
+ "default_value": 4
+ },
+ "cool_fan_full_at_height": {
+ "value": "0"
+ },
+ "acceleration_support_interface": {
+ "value": "250"
+ },
+ "retraction_min_travel": {
+ "value": "1"
+ },
+ "acceleration_layer_0": {
+ "value": "400"
+ },
+ "support_z_distance": {
+ "default_value": 0.2
+ },
+ "machine_heated_bed": {
+ "default_value": true
+ },
+ "raft_jerk": {
+ "value": "10"
+ },
+ "raft_surface_speed": {
+ "value": "60"
+ },
+ "initial_layer_line_width_factor": {
+ "default_value": 120
+ },
+ "machine_start_gcode": {
+ "default_value": "G90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM420 S1 Z0.6 ;enable bed levelling\nG1 Z10 F250 ;move the platform down 10mm\nM107 ;fan off\nM42 P11 S255 ;turn on front fan\nM140 S{material_bed_temperature}\nM104 T0 S{material_print_temperature, 0}\nM104 T1 S{material_print_temperature, 1}\nG1 F2500 Y260 X0\nM190 S{material_bed_temperature}\nM109 T0 S{material_print_temperature, 0}\nM109 T1 S{material_print_temperature, 1}\nM60 ;enable E-FADE Algorithm\nM62 A ;filament sensor off\nG92 E0 ;zero the extruded length\nT1\nG92 E0;zero the extruded length\nG1 F300 Z0.3\nG1 F1200 X20\nG1 F1200 X180 E21 ;extrude 21 mm of feed stock\nG1 F1200 E15 ;retracting 6 mm\nG1 F2000 E21\nG1 F2000 E11\nG1 F300 Z1.5\nG92 E0 ;zero the extruded length again\nT0\nG92 E0 ;zero the extruded length\nG1 F1200 Y258\nG1 F300 Z0.3\nG1 F1200 X40 E21 ;extrude 21 mm of feed stock\nG1 F1200 E15 ;retracting 6 mm\nG1 F2000 E21\nG1 F2000 E11\nG1 Z1.5\nM61 A ;filament sensor reset\nM63 A ;filament sensor on\nG92 E0 ;zero the extruded length again\nM58 ;end of Start G-Code and signal retract management\nT{initial_extruder_nr}"
+ },
+ "bottom_skin_preshrink": {
+ "value": "0.8"
+ },
+ "ironing_inset": {
+ "value": "0.2"
+ },
+ "jerk_travel": {
+ "value": "10"
+ },
+ "machine_depth": {
+ "default_value": 260
+ },
+ "jerk_skirt_brim": {
+ "value": "5"
+ },
+ "infill_wipe_dist": {
+ "value": "0"
+ },
+ "raft_interface_acceleration": {
+ "value": "400"
+ },
+ "z_seam_x": {
+ "value": "115"
+ },
+ "material_print_temperature": {
+ "value": "195"
+ },
+ "material_bed_temperature_layer_0": {
+ "value": "50"
+ },
+ "wipe_retraction_retract_speed": {
+ "value": "30"
+ },
+ "jerk_travel_layer_0": {
+ "value": "10"
+ },
+ "infill_overlap": {
+ "value": "0"
+ },
+ "acceleration_support_infill": {
+ "value": "400"
+ },
+ "travel_compensate_overlapping_walls_0_enabled": {
+ "value": "False"
+ },
+ "support_bottom_material_flow": {
+ "value": "99"
+ },
+ "jerk_support_roof": {
+ "value": "5"
+ },
+ "wall_x_material_flow": {
+ "value": "99"
+ },
+ "speed_support_interface": {
+ "value": "33.33"
+ },
+ "jerk_layer_0": {
+ "value": "10"
+ },
+ "support_angle": {
+ "default_value": 60
+ },
+ "infill_sparse_thickness": {
+ "value": "0.2"
+ },
+ "prime_tower_position_y": {
+ "value": "1"
+ },
+ "retraction_combing": {
+ "default_value": "infill"
+ },
+ "acceleration_prime_tower": {
+ "value": "250"
+ },
+ "acceleration_print": {
+ "default_value": 400
+ },
+ "acceleration_infill": {
+ "value": "500"
+ },
+ "bridge_wall_speed": {
+ "value": "10.0"
+ },
+ "acceleration_wall_0": {
+ "value": "400"
+ },
+ "support_offset": {
+ "default_value": 0.2
+ },
+ "build_volume_temperature": {
+ "default_value": 28
+ },
+ "switch_extruder_prime_speed": {
+ "value": "60"
+ },
+ "speed_prime_tower": {
+ "value": "20"
+ },
+ "top_skin_preshrink": {
+ "value": "0.8"
+ },
+ "jerk_ironing": {
+ "value": "5"
+ },
+ "skin_outline_count": {
+ "default_value": 0
+ },
+ "skirt_brim_speed": {
+ "value": "10.0"
+ },
+ "raft_base_thickness": {
+ "value": "0.2"
+ },
+ "infill_sparse_density": {
+ "default_value": 15
+ },
+ "support_bottom_extruder_nr": {
+ "value": "0"
+ },
+ "support_material_flow": {
+ "value": "98"
+ },
+ "min_infill_area": {
+ "default_value": 1
+ },
+ "jerk_support": {
+ "value": "10"
+ },
+ "bottom_skin_expand_distance": {
+ "value": "0.8"
+ },
+ "retract_at_layer_change": {
+ "default_value": true
+ },
+ "jerk_support_interface": {
+ "value": "5"
+ },
+ "jerk_support_bottom": {
+ "value": "5"
+ },
+ "optimize_wall_printing_order": {
+ "default_value": true
+ },
+ "skirt_brim_minimal_length": {
+ "default_value": 50
+ },
+ "jerk_support_infill": {
+ "value": "10"
+ },
+ "initial_bottom_layers": {
+ "value": "3"
+ },
+ "prime_tower_position_x": {
+ "value": "1"
+ },
+ "acceleration_support_bottom": {
+ "value": "250"
+ },
+ "speed_support_roof": {
+ "value": "33.33"
+ },
+ "speed_support_infill": {
+ "value": "80"
+ },
+ "bridge_skin_speed_2": {
+ "value": "15"
+ },
+ "raft_fan_speed": {
+ "default_value": 100
+ },
+ "wipe_retraction_amount": {
+ "value": "3"
+ },
+ "skin_edge_support_thickness": {
+ "value": "0"
+ },
+ "bottom_layers": {
+ "value": "3"
+ },
+ "retraction_extrusion_window": {
+ "value": "3"
+ },
+ "acceleration_ironing": {
+ "value": "250"
+ },
+ "support_top_distance": {
+ "value": "0.2"
+ },
+ "travel_retract_before_outer_wall": {
+ "default_value": true
+ },
+ "material_flow": {
+ "default_value": 99
+ },
+ "support_bottom_distance": {
+ "value": "0.2"
+ },
+ "expand_skins_expand_distance": {
+ "value": "0.8"
+ },
+ "jerk_wall": {
+ "value": "10"
+ },
+ "support_zag_skip_count": {
+ "value": "8"
+ },
+ "connect_infill_polygons": {
+ "value": "False"
+ },
+ "acceleration_skirt_brim": {
+ "value": "250"
+ },
+ "z_seam_corner": {
+ "default_value": "z_seam_corner_weighted"
+ },
+ "raft_surface_jerk": {
+ "value": "10"
+ },
+ "cross_infill_pocket_size": {
+ "value": "5.33"
+ },
+ "support_infill_extruder_nr": {
+ "value": "0"
+ },
+ "acceleration_enabled": {
+ "default_value": true
+ },
+ "jerk_wall_x": {
+ "value": "10"
+ },
+ "skin_overlap": {
+ "value": "15"
+ },
+ "infill_material_flow": {
+ "value": "99"
+ },
+ "speed_equalize_flow_max": {
+ "default_value": 40
+ },
+ "skin_preshrink": {
+ "value": "0.8"
+ },
+ "speed_wall": {
+ "value": "20"
+ },
+ "support_tree_collision_resolution": {
+ "value": "0.2"
+ },
+ "meshfix_maximum_deviation": {
+ "default_value": 0.005
+ },
+ "jerk_roofing": {
+ "value": "10"
+ },
+ "fill_outline_gaps": {
+ "default_value": true
+ },
+ "layer_height": {
+ "default_value": 0.2
+ },
+ "remove_empty_first_layers": {
+ "default_value": false
+ },
+ "prime_tower_flow": {
+ "value": "99"
+ },
+ "support_roof_line_distance": {
+ "value": "0.57"
+ },
+ "wipe_retraction_speed": {
+ "value": "30"
+ },
+ "support_extruder_nr_layer_0": {
+ "value": "0"
+ },
+ "layer_height_0": {
+ "default_value": 0.2
+ },
+ "multiple_mesh_overlap": {
+ "default_value": 0
+ },
+ "ooze_shield_dist": {
+ "default_value": 4
+ },
+ "jerk_enabled": {
+ "default_value": true
+ },
+ "acceleration_support": {
+ "value": "400"
+ },
+ "adhesion_extruder_nr": {
+ "value": "0"
+ },
+ "skirt_line_count": {
+ "default_value": 2
+ },
+ "travel_compensate_overlapping_walls_x_enabled": {
+ "value": "False"
+ },
+ "jerk_wall_0": {
+ "value": "10"
+ },
+ "raft_speed": {
+ "value": "60"
+ },
+ "speed_layer_0": {
+ "value": "10.0"
+ },
+ "machine_width": {
+ "default_value": 210
+ },
+ "acceleration_wall": {
+ "value": "400"
+ },
+ "jerk_infill": {
+ "value": "10"
+ },
+ "wipe_hop_enable": {
+ "value": "False"
+ },
+ "acceleration_travel_layer_0": {
+ "value": "400"
+ },
+ "raft_interface_speed": {
+ "value": "60"
+ },
+ "skin_edge_support_layers": {
+ "value": "0"
+ },
+ "support_xy_distance_overhang": {
+ "value": "0.5"
+ },
+ "brim_width": {
+ "default_value": 10
+ },
+ "coasting_enable": {
+ "default_value": true
+ },
+ "jerk_print": {
+ "default_value": 10
+ },
+ "acceleration_support_roof": {
+ "value": "250"
+ },
+ "prime_tower_min_volume": {
+ "default_value": 4
+ },
+ "support_roof_material_flow": {
+ "value": "99"
+ },
+ "wall_0_wipe_dist": {
+ "value": "0"
+ },
+ "jerk_topbottom": {
+ "value": "10"
+ },
+ "retraction_count_max": {
+ "default_value": 30
+ },
+ "skin_overlap_mm": {
+ "value": "0.06"
+ },
+ "extruders_enabled_count": {
+ "value": "2"
+ },
+ "speed_support_bottom": {
+ "value": "33.33"
+ },
+ "support_skip_some_zags": {
+ "default_value": true
+ },
+ "ooze_shield_angle": {
+ "default_value": 50
+ },
+ "wall_thickness": {
+ "value": "1.2"
+ },
+ "speed_print_layer_0": {
+ "value": "10.0"
+ }
+ }
+}
diff --git a/resources/definitions/stereotech_ste320.def.json b/resources/definitions/stereotech_ste320.def.json
index 3eb114324b..3aa89effc5 100644
--- a/resources/definitions/stereotech_ste320.def.json
+++ b/resources/definitions/stereotech_ste320.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "Stereotech",
"manufacturer": "Stereotech LLC.",
- "category": "Other",
"platform": "stereotech_ste320_platform.obj",
"platform_texture": "StereotechSte320backplate.png",
"platform_offset": [
diff --git a/resources/definitions/strateo3d.def.json b/resources/definitions/strateo3d.def.json
index 2ee3650404..4b1e4a3fbd 100644
--- a/resources/definitions/strateo3d.def.json
+++ b/resources/definitions/strateo3d.def.json
@@ -6,7 +6,6 @@
{
"author": "M.K",
"manufacturer": "eMotionTech",
- "category": "Other",
"visible": true,
"file_formats": "text/x-gcode",
"has_machine_quality": true,
diff --git a/resources/definitions/ubuild-3d_mr_bot_280.def.json b/resources/definitions/ubuild-3d_mr_bot_280.def.json
index 255d8f032b..f1c7bc7581 100644
--- a/resources/definitions/ubuild-3d_mr_bot_280.def.json
+++ b/resources/definitions/ubuild-3d_mr_bot_280.def.json
@@ -6,7 +6,6 @@
"visible": true,
"author": "uBuild-3D",
"manufacturer": "uBuild-3D",
- "category": "Other",
"file_formats": "text/x-gcode",
"has_materials": true,
"preferred_quality_type": "draft",
diff --git a/resources/definitions/ultimaker.def.json b/resources/definitions/ultimaker.def.json
index 7a60ff35c8..ff9a75c40c 100644
--- a/resources/definitions/ultimaker.def.json
+++ b/resources/definitions/ultimaker.def.json
@@ -5,7 +5,6 @@
"metadata": {
"author": "Ultimaker",
"manufacturer": "Ultimaker B.V.",
- "category": "Ultimaker",
"visible": false,
"exclude_materials": [ "generic_hips", "generic_petg", "structur3d_dap100silicone" ]
},
diff --git a/resources/definitions/ultimaker_s3.def.json b/resources/definitions/ultimaker_s3.def.json
index 620de59373..824a0e3a92 100644
--- a/resources/definitions/ultimaker_s3.def.json
+++ b/resources/definitions/ultimaker_s3.def.json
@@ -5,7 +5,6 @@
"metadata": {
"author": "Ultimaker",
"manufacturer": "Ultimaker B.V.",
- "category": "Ultimaker",
"visible": true,
"file_formats": "application/x-ufp;text/x-gcode",
"platform": "ultimaker_s3_platform.obj",
diff --git a/resources/definitions/ultimaker_s5.def.json b/resources/definitions/ultimaker_s5.def.json
index d21edb0843..ded94a2747 100644
--- a/resources/definitions/ultimaker_s5.def.json
+++ b/resources/definitions/ultimaker_s5.def.json
@@ -5,7 +5,6 @@
"metadata": {
"author": "Ultimaker",
"manufacturer": "Ultimaker B.V.",
- "category": "Ultimaker",
"visible": true,
"file_formats": "application/x-ufp;text/x-gcode",
"platform": "ultimaker_s5_platform.obj",
diff --git a/resources/definitions/uni_200.def.json b/resources/definitions/uni_200.def.json
new file mode 100644
index 0000000000..9fdb008213
--- /dev/null
+++ b/resources/definitions/uni_200.def.json
@@ -0,0 +1,18 @@
+{
+ "name": "UNI 200",
+ "version": 2,
+ "inherits": "uni_base",
+ "metadata": {
+ "author": "Nail` Gimadeev (C)",
+ "visible": true,
+ "quality_definition": "uni_base",
+ "platform": "uni_200_platform.stl",
+ "platform_texture": "uni.png"
+ },
+ "overrides": {
+ "machine_name": {"default_value": "uni_200"},
+ "machine_width": {"default_value": 220},
+ "machine_depth": {"default_value": 220},
+ "machine_height": {"default_value": 250}
+ }
+}
diff --git a/resources/definitions/uni_250.def.json b/resources/definitions/uni_250.def.json
new file mode 100644
index 0000000000..65ceddf8c7
--- /dev/null
+++ b/resources/definitions/uni_250.def.json
@@ -0,0 +1,18 @@
+{
+ "name": "UNI 250",
+ "version": 2,
+ "inherits": "uni_base",
+ "metadata": {
+ "author": "Nail` Gimadeev (C)",
+ "visible": true,
+ "quality_definition": "uni_base",
+ "platform": "uni_250_platform.stl",
+ "platform_texture": "uni.png"
+ },
+ "overrides": {
+ "machine_name": {"default_value": "uni_250"},
+ "machine_width": {"default_value": 270},
+ "machine_depth": {"default_value": 220},
+ "machine_height": {"default_value": 250}
+ }
+}
diff --git a/resources/definitions/uni_300.def.json b/resources/definitions/uni_300.def.json
new file mode 100644
index 0000000000..11d1ed0591
--- /dev/null
+++ b/resources/definitions/uni_300.def.json
@@ -0,0 +1,18 @@
+{
+ "name": "UNI 300",
+ "version": 2,
+ "inherits": "uni_base",
+ "metadata": {
+ "author": "Nail` Gimadeev (C)",
+ "visible": true,
+ "quality_definition": "uni_base",
+ "platform": "uni_300_platform.stl",
+ "platform_texture": "uni.png"
+ },
+ "overrides": {
+ "machine_name": {"default_value": "uni_300"},
+ "machine_width": {"default_value": 320},
+ "machine_depth": {"default_value": 220},
+ "machine_height": {"default_value": 250}
+ }
+}
diff --git a/resources/definitions/uni_base.def.json b/resources/definitions/uni_base.def.json
new file mode 100644
index 0000000000..6f40abfbee
--- /dev/null
+++ b/resources/definitions/uni_base.def.json
@@ -0,0 +1,210 @@
+{
+ "name": "UNI Base Printer",
+ "version": 2,
+ "inherits": "fdmprinter",
+ "metadata": {
+ "visible": false,
+ "author": "Nail` Gimadeev (C)",
+ "manufacturer": "UNI 3D",
+ "file_formats": "text/x-gcode",
+ "first_start_actions": ["MachineSettingsAction"],
+ "machine_extruder_trains": {
+ "0": "uni_extruder_1st",
+ "1": "uni_extruder_2nd"
+ },
+ "has_materials": true,
+ "preferred_material": "generic_abs_175",
+ "has_variants": true,
+ "variants_name": "Nozzle Size",
+ "preferred_variant_name": "0.40mm Nozzle",
+ "has_machine_quality": true,
+ "preferred_quality_type": "q020",
+ "exclude_materials": [
+ "chromatik_pla",
+ "dsm_arnitel2045_175",
+ "dsm_novamid1070_175",
+ "emotiontech_abs",
+ "emotiontech_asax",
+ "emotiontech_hips",
+ "emotiontech_petg",
+ "emotiontech_pla",
+ "emotiontech_pva-m",
+ "emotiontech_pva-oks",
+ "emotiontech_pva-s",
+ "emotiontech_tpu98a",
+ "eSUN_PETG_Black",
+ "eSUN_PETG_Grey",
+ "eSUN_PETG_Purple",
+ "eSUN_PLA_PRO_Black",
+ "eSUN_PLA_PRO_Grey",
+ "eSUN_PLA_PRO_Purple",
+ "eSUN_PLA_PRO_White",
+ "fabtotum_abs",
+ "fabtotum_nylon",
+ "fabtotum_pla",
+ "fabtotum_tpu",
+ "fiberlogy_hd_pla",
+ "filo3d_pla",
+ "filo3d_pla_green",
+ "filo3d_pla_red",
+ "generic_abs",
+ "generic_bam",
+ "generic_cffcpe",
+ "generic_cffpa",
+ "generic_cpe",
+ "generic_cpe_175",
+ "generic_cpe_plus",
+ "generic_gffcpe",
+ "generic_gffpa",
+ "generic_hips",
+ "generic_nylon",
+ "generic_pc",
+ "generic_petg",
+ "generic_pla",
+ "generic_pp",
+ "generic_pva",
+ "generic_tough_pla",
+ "generic_tpu",
+ "imade3d_petg_175",
+ "imade3d_pla_175",
+ "innofill_innoflex60_175",
+ "leapfrog_abs_natural",
+ "leapfrog_epla_natural",
+ "leapfrog_pva_natural",
+ "octofiber_pla",
+ "polyflex_pla",
+ "polymax_pla",
+ "polyplus_pla",
+ "polywood_pla",
+ "structur3d_dap100silicone",
+ "tizyx_abs",
+ "tizyx_flex",
+ "tizyx_petg",
+ "tizyx_pla",
+ "tizyx_pla_bois",
+ "tizyx_pva",
+ "ultimaker_abs_black",
+ "ultimaker_abs_blue",
+ "ultimaker_abs_green",
+ "ultimaker_abs_grey",
+ "ultimaker_abs_orange",
+ "ultimaker_abs_pearl-gold",
+ "ultimaker_abs_red",
+ "ultimaker_abs_silver-metallic",
+ "ultimaker_abs_white",
+ "ultimaker_abs_yellow",
+ "ultimaker_bam",
+ "ultimaker_cpe_black",
+ "ultimaker_cpe_blue",
+ "ultimaker_cpe_dark-grey",
+ "ultimaker_cpe_green",
+ "ultimaker_cpe_light-grey",
+ "ultimaker_cpe_plus_black",
+ "ultimaker_cpe_plus_transparent",
+ "ultimaker_cpe_plus_white",
+ "ultimaker_cpe_red",
+ "ultimaker_cpe_transparent",
+ "ultimaker_cpe_white",
+ "ultimaker_cpe_yellow",
+ "ultimaker_nylon_black",
+ "ultimaker_nylon_transparent",
+ "ultimaker_pc_black",
+ "ultimaker_pc_transparent",
+ "ultimaker_pc_white",
+ "ultimaker_pla_black",
+ "ultimaker_pla_blue",
+ "ultimaker_pla_green",
+ "ultimaker_pla_magenta",
+ "ultimaker_pla_orange",
+ "ultimaker_pla_pearl-white",
+ "ultimaker_pla_red",
+ "ultimaker_pla_silver-metallic",
+ "ultimaker_pla_transparent",
+ "ultimaker_pla_white",
+ "ultimaker_pla_yellow",
+ "ultimaker_pp_transparent",
+ "ultimaker_pva",
+ "ultimaker_tough_pla_black",
+ "ultimaker_tough_pla_green",
+ "ultimaker_tough_pla_red",
+ "ultimaker_tough_pla_white",
+ "ultimaker_tpu_black",
+ "ultimaker_tpu_blue",
+ "ultimaker_tpu_red",
+ "ultimaker_tpu_white",
+ "verbatim_bvoh_175",
+ "Vertex_Delta_ABS",
+ "Vertex_Delta_PET",
+ "Vertex_Delta_PLA",
+ "Vertex_Delta_PLA_Glitter",
+ "Vertex_Delta_PLA_Mat",
+ "Vertex_Delta_PLA_Satin",
+ "Vertex_Delta_PLA_Wood",
+ "Vertex_Delta_TPU",
+ "zyyx_pro_flex",
+ "zyyx_pro_pla"]
+ },
+ "overrides": {
+ "machine_name": {"default_value": "UNI Base Printer"},
+ "machine_start_gcode": {"default_value": "G90 ;absolute positioning\nM82 ;set extruder to absolute mode\nM107 ;start with the fan off\nG28 Z0 ;move Z to min endstops\nG28 X0 Y0 ;move X/Y to min endstops\nG92 E0 ;zero the extruded length\nG1 F5000 ;set speed\nG1 Z15 F5000 ;move to start position Y\nM117 Printing..."},
+ "machine_end_gcode": {"default_value": "M104 S0 ;extruder heater off\nM140 S0 ;heated bed heater off\nG91 ;relative positioning\nG1 E-4 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 F5000 ;move Z up a bit and retract filament even more\nG28 Z0 ;move bed down\nG28 X0 Y0 ;move X/Y to min endstops so the head is out of the way\nM84 ;steppers off\nG90 ;absolute positioning\nM107 ;switch off cooling fan"},
+ "machine_heated_bed": {"default_value": true},
+ "material_diameter": {"default_value": 1.75},
+ "machine_shape": {"default_value": "rectangular"},
+ "machine_width": {"default_value": 270},
+ "machine_depth": {"default_value": 220},
+ "machine_height": {"default_value": 250},
+ "machine_extruder_count": {"value": 2},
+ "machine_buildplate_type": {"value": "glass"},
+ "machine_heated_bed": {"default_value": true},
+ "machine_center_is_zero": {"default_value": false},
+ "machine_gcode_flavor": {"default_value": "RepRap (Marlin/Sprinter)"},
+ "machine_head_with_fans_polygon": {"default_value": [
+ [-10,10],
+ [-10,-10],
+ [10,-10],
+ [10,10]
+ ]
+ },
+ "gantry_height": {"value": 55},
+ "layer_height_0": {"value": "layer_height"},
+ "line_width": {"value": "machine_nozzle_size"},
+ "skin_line_width": {"value": "round(line_width * 1.0, 2)"},
+ "infill_line_width": {"value": "round(line_width * 1.1, 2)"},
+ "skirt_brim_line_width": {"value": "round(line_width * 1.1, 2)"},
+ "initial_layer_line_width_factor": {"value": "100"},
+ "bottom_thickness": {"value": "layer_height*3 if layer_height > 0.15 else 0.8"},
+ "top_bottom_pattern": {"value": "'zigzag'"},
+ "top_bottom_pattern_0": {"value": "'zigzag'"},
+ "optimize_wall_printing_order": {"value": "True" },
+ "z_seam_type": {"value": "'shortest'"},
+ "skin_outline_count": {"value": "0"},
+ "infill_pattern": {"value": "'gyroid'"},
+ "zig_zaggify_infill": {"value": "True"},
+ "infill_before_walls": {"value": "False"},
+ "infill_enable_travel_optimization": {"value": "True"},
+ "expand_skins_expand_distance": {"value": "3"},
+ "retraction_min_travel": {"value": "3"},
+ "retraction_amount": {"value": "4"},
+ "speed_print": {"value": "80"},
+ "speed_topbottom": {"value": "50"},
+ "speed_layer_0": {"value": "25"},
+ "speed_travel_layer_0": {"value": "40"},
+ "retraction_combing": {"value": "'all'"},
+ "retraction_combing_max_distance": {"value": "10"},
+ "travel_avoid_other_parts": {"value": "False"},
+ "cool_min_layer_time_fan_speed_max": {"value": "20"},
+ "cool_fan_full_at_height": {"value": "layer_height*2"},
+ "cool_min_layer_time": {"value": "5"},
+ "cool_min_speed": {"value": "15"},
+ "cool_lift_head": {"value": "True"},
+ "support_enable": {"value": "True"},
+ "support_angle": {"value": "65"},
+ "support_brim_enable": {"value": "True"},
+ "support_infill_rate": {"value": "20"},
+ "support_offset": {"value": "2"},
+ "adhesion_type": {"value": "'brim'"},
+ "brim_width": {"value": "5"},
+ "bridge_settings_enabled": {"value": "True"}
+ }
+}
diff --git a/resources/definitions/uni_mini.def.json b/resources/definitions/uni_mini.def.json
new file mode 100644
index 0000000000..138e2ee183
--- /dev/null
+++ b/resources/definitions/uni_mini.def.json
@@ -0,0 +1,18 @@
+{
+ "name": "UNI MINI",
+ "version": 2,
+ "inherits": "uni_base",
+ "metadata": {
+ "author": "Nail` Gimadeev (C)",
+ "visible": true,
+ "quality_definition": "uni_base",
+ "platform": "uni_mini_platform.stl",
+ "platform_texture": "uni.png"
+ },
+ "overrides": {
+ "machine_name": {"default_value": "uni_mini"},
+ "machine_width": {"default_value": 180},
+ "machine_depth": {"default_value": 180},
+ "machine_height": {"default_value": 175}
+ }
+}
diff --git a/resources/definitions/uni_print_3d.def.json b/resources/definitions/uni_print_3d.def.json
index c2ba44b62e..0ad937e594 100644
--- a/resources/definitions/uni_print_3d.def.json
+++ b/resources/definitions/uni_print_3d.def.json
@@ -6,7 +6,6 @@
{
"visible": true,
"author": "Alexander Rössler",
- "category": "Other",
"manufacturer": "TheCoolTool",
"file_formats": "text/x-ngc;text/x-gcode",
"platform": "uni_print_3d_platform.3mf",
diff --git a/resources/definitions/winbo_dragonl4.def.json b/resources/definitions/winbo_dragonl4.def.json
index f89d592be1..754a1a77a2 100644
--- a/resources/definitions/winbo_dragonl4.def.json
+++ b/resources/definitions/winbo_dragonl4.def.json
@@ -5,7 +5,6 @@
"metadata": {
"author": "Winbo",
"manufacturer": "Winbo Smart Tech Co., Ltd.",
- "category": "Other",
"visible": true,
"file_formats": "text/x-gcode",
"supports_usb_connection": false,
diff --git a/resources/definitions/winbo_mini2.def.json b/resources/definitions/winbo_mini2.def.json
index 49afd18ba8..c2d2d9b7f4 100644
--- a/resources/definitions/winbo_mini2.def.json
+++ b/resources/definitions/winbo_mini2.def.json
@@ -5,7 +5,6 @@
"metadata": {
"author": "Winbo",
"manufacturer": "Winbo Smart Tech Co., Ltd.",
- "category": "Other",
"visible": true,
"file_formats": "text/x-gcode",
"supports_usb_connection": true,
diff --git a/resources/definitions/winbo_superhelper105.def.json b/resources/definitions/winbo_superhelper105.def.json
index fab2e9f45f..576398551b 100644
--- a/resources/definitions/winbo_superhelper105.def.json
+++ b/resources/definitions/winbo_superhelper105.def.json
@@ -5,7 +5,6 @@
"metadata": {
"author": "Winbo",
"manufacturer": "Winbo Smart Tech Co., Ltd.",
- "category": "Other",
"visible": true,
"file_formats": "text/x-gcode",
"supports_usb_connection": true,
diff --git a/resources/definitions/winbo_superhelper155.def.json b/resources/definitions/winbo_superhelper155.def.json
index 65bb4e7b73..77b4bc31c5 100644
--- a/resources/definitions/winbo_superhelper155.def.json
+++ b/resources/definitions/winbo_superhelper155.def.json
@@ -5,7 +5,6 @@
"metadata": {
"author": "Winbo",
"manufacturer": "Winbo Smart Tech Co., Ltd.",
- "category": "Other",
"visible": true,
"file_formats": "text/x-gcode",
"supports_usb_connection": true,
diff --git a/resources/extruders/hms434_tool_1.def.json b/resources/extruders/hms434_tool_1.def.json
index 619d286716..ea094abea6 100644
--- a/resources/extruders/hms434_tool_1.def.json
+++ b/resources/extruders/hms434_tool_1.def.json
@@ -16,10 +16,10 @@
"machine_nozzle_offset_y": { "default_value": 0.0 },
"material_diameter": { "default_value": 1.75 },
"machine_extruder_start_code": {
- "default_value": "\n;changing to tool1\nM83\nM109 T0 S{material_print_temperature}\nG1 E{switch_extruder_retraction_amount} F300\nG1 E{switch_extruder_retraction_amount} F300\nG1 E{switch_extruder_retraction_amount} F300\nG1 E{switch_extruder_retraction_amount} F300\nG1 E-{switch_extruder_retraction_amount} F2400\nG1 Y120 F3000\nG1 X10 F12000\n\n"
+ "default_value": "\n;changing to tool1\nM83\nM109 T0 S{material_print_temperature}\nG1 E{switch_extruder_retraction_amount} F300\nG1 E{switch_extruder_retraction_amount} F300\nG1 E{switch_extruder_retraction_amount} F300\nG1 E{switch_extruder_retraction_amount} F300\nG1 E-{switch_extruder_retraction_amount} F2400\nG1 Y40 F3000\nG1 X10 F12000\n\n"
},
"machine_extruder_end_code": {
- "default_value": "\nG1 X10 Y120 F12000\nG1 X-40 F12000\nM109 T0 R{material_standby_temperature}\nG1 Y100 F3000\n; ending tool1\n\n"
+ "default_value": "\nG1 X10 Y120 F12000\nG1 X-25 F12000\nM109 T0 R{material_standby_temperature}\nG1 Y20 F3000\n; ending tool1\n\n"
}
}
}
diff --git a/resources/extruders/hms434_tool_2.def.json b/resources/extruders/hms434_tool_2.def.json
index 20e940df3b..64bc93c693 100644
--- a/resources/extruders/hms434_tool_2.def.json
+++ b/resources/extruders/hms434_tool_2.def.json
@@ -16,10 +16,10 @@
"machine_nozzle_offset_y": { "default_value": 0.0 },
"material_diameter": { "default_value": 1.75 },
"machine_extruder_start_code": {
- "default_value": "\n;changing to tool2\nM83\nM109 T1 S{material_print_temperature}\nG1 E{switch_retraction_prime_amount} F300\nG1 E{switch_extruder_retraction_amount} F300\nG1 E{switch_extruder_retraction_amount} F300\nG1 E{switch_extruder_retraction_amount} F300\nG1 E-{switch_extruder_retraction_amount} F2400\nG1 Y120 F3000\nG1 X10 F12000\n\n"
+ "default_value": "\n;changing to tool2\nM83\nM109 T1 S{material_print_temperature}\nG1 E{switch_extruder_retraction_amount} F300\nG1 E{switch_extruder_retraction_amount} F300\nG1 E{switch_extruder_retraction_amount} F300\nG1 E{switch_extruder_retraction_amount} F300\nG1 E-{switch_extruder_retraction_amount} F2400\nG1 Y40 F3000\nG1 X10 F12000\n\n"
},
"machine_extruder_end_code": {
- "default_value": "\nG1 X10 Y120 F12000\nG1 X-40 F12000\nM109 T1 R{material_standby_temperature}\nG1 Y100 F3000\n; ending tool2\n\n"
+ "default_value": "\nG1 X10 Y120 F12000\nG1 X-25 F12000\nM109 T1 R{material_standby_temperature}\nG1 Y20 F3000\n; ending tool2\n\n"
}
}
}
diff --git a/resources/extruders/predator_extruder_0.def.json b/resources/extruders/predator_extruder_0.def.json
new file mode 100644
index 0000000000..59574ae69f
--- /dev/null
+++ b/resources/extruders/predator_extruder_0.def.json
@@ -0,0 +1,15 @@
+{
+ "version": 2,
+ "name": "Extruder 0",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "predator",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0 },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 }
+ }
+}
diff --git a/resources/extruders/uni_extruder_1st.def.json b/resources/extruders/uni_extruder_1st.def.json
new file mode 100644
index 0000000000..5f6b819599
--- /dev/null
+++ b/resources/extruders/uni_extruder_1st.def.json
@@ -0,0 +1,25 @@
+{
+ "version": 2,
+ "name": "Extruder 1",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "uni_base",
+ "position": "0"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 0, "maximum_value": "1" },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 },
+ "machine_nozzle_offset_x": { "default_value": 0.0 },
+ "machine_nozzle_offset_y": { "default_value": 0.0 },
+ "machine_extruder_start_code":
+ {
+ "default_value": "T0 ;switch to extruder 1\nG92 E0 ;reset extruder distance\nG1 F2000 E93 ;load filament\nG92 E0 ;reset extruder distance\nM104 S{material_print_temperature}\n;"
+ },
+ "machine_extruder_end_code":
+ {
+ "default_value": "G92 E0 ;reset extruder distance\nG1 F800 E-5 ;short retract\nG1 F2400 X5 Y5 ;move near prime tower\nG1 F2000 E-93 ;long retract for filament removal\nG92 E0 ;reset extruder distance\nG90 ;absolute coordinate\n;"
+ }
+ }
+}
diff --git a/resources/extruders/uni_extruder_2nd.def.json b/resources/extruders/uni_extruder_2nd.def.json
new file mode 100644
index 0000000000..7b92b2f987
--- /dev/null
+++ b/resources/extruders/uni_extruder_2nd.def.json
@@ -0,0 +1,25 @@
+{
+ "version": 2,
+ "name": "Extruder 2",
+ "inherits": "fdmextruder",
+ "metadata": {
+ "machine": "uni_base",
+ "position": "1"
+ },
+
+ "overrides": {
+ "extruder_nr": { "default_value": 1, "maximum_value": "1" },
+ "machine_nozzle_size": { "default_value": 0.4 },
+ "material_diameter": { "default_value": 1.75 },
+ "machine_nozzle_offset_x": { "default_value": 17.7 },
+ "machine_nozzle_offset_y": { "default_value": 0.0 },
+ "machine_extruder_start_code":
+ {
+ "default_value": "T1 ;switch to extruder 2\nG92 E0 ;reset extruder distance\nG1 F2000 E93 ;load filament\nG92 E0 ;reset extruder distance\nM104 S{material_print_temperature}\n;"
+ },
+ "machine_extruder_end_code":
+ {
+ "default_value": "G92 E0 ;reset extruder distance\nG1 F800 E-5 ;short retract\nG1 F2400 X5 Y5 ;move near prime tower\nG1 F2000 E-93 ;long retract for filament removal\nG92 E0 ;reset extruder distance\nG90 ;absolute coordinate\n;"
+ }
+ }
+}
diff --git a/resources/i18n/de_DE/fdmprinter.def.json.po b/resources/i18n/de_DE/fdmprinter.def.json.po
index c5157b5792..f68a80c40b 100644
--- a/resources/i18n/de_DE/fdmprinter.def.json.po
+++ b/resources/i18n/de_DE/fdmprinter.def.json.po
@@ -5118,7 +5118,7 @@ msgstr "Merkmale, die noch nicht vollständig ausgearbeitet wurden."
#: fdmprinter.def.json
msgctxt "support_tree_enable label"
msgid "Tree Support"
-msgstr "Baumstruktur"
+msgstr "Baumstützstruktur"
#: fdmprinter.def.json
msgctxt "support_tree_enable description"
diff --git a/resources/i18n/zh_TW/cura.po b/resources/i18n/zh_TW/cura.po
index ec292072ff..6aa4de644f 100644
--- a/resources/i18n/zh_TW/cura.po
+++ b/resources/i18n/zh_TW/cura.po
@@ -8,7 +8,7 @@ msgstr ""
"Project-Id-Version: Cura 4.6\n"
"Report-Msgid-Bugs-To: r.dulek@ultimaker.com\n"
"POT-Creation-Date: 2020-04-06 16:33+0200\n"
-"PO-Revision-Date: 2020-02-16 18:19+0800\n"
+"PO-Revision-Date: 2020-04-18 17:49+0800\n"
"Last-Translator: Zhang Heh Ji \n"
"Language-Team: Zhang Heh Ji \n"
"Language: zh_TW\n"
@@ -347,7 +347,7 @@ msgstr "正在設定場景..."
#: /home/trin/Gedeeld/Projects/Cura/cura/CuraApplication.py:868
msgctxt "@info:progress"
msgid "Loading interface..."
-msgstr "正在載入介面…"
+msgstr "正在載入介面..."
#: /home/trin/Gedeeld/Projects/Cura/cura/CuraApplication.py:873
msgctxt "@info:progress"
@@ -730,13 +730,13 @@ msgstr "3MF 檔案"
#: /home/trin/Gedeeld/Projects/Cura/plugins/3MFWriter/ThreeMFWorkspaceWriter.py:31
msgctxt "@error:zip"
msgid "3MF Writer plug-in is corrupt."
-msgstr ""
+msgstr "3MF 寫入器外掛已損壞。"
#: /home/trin/Gedeeld/Projects/Cura/plugins/3MFWriter/ThreeMFWorkspaceWriter.py:59
#: /home/trin/Gedeeld/Projects/Cura/plugins/3MFWriter/ThreeMFWorkspaceWriter.py:92
msgctxt "@error:zip"
msgid "No permission to write the workspace here."
-msgstr ""
+msgstr "沒有寫入此處工作區的權限。"
#: /home/trin/Gedeeld/Projects/Cura/plugins/3MFWriter/ThreeMFWriter.py:181
msgctxt "@error:zip"
@@ -771,12 +771,12 @@ msgstr "上傳你的備份時發生錯誤。"
#: /home/trin/Gedeeld/Projects/Cura/plugins/CuraDrive/src/CreateBackupJob.py:47
msgctxt "@info:backup_status"
msgid "Creating your backup..."
-msgstr ""
+msgstr "正在建立備份..."
#: /home/trin/Gedeeld/Projects/Cura/plugins/CuraDrive/src/CreateBackupJob.py:54
msgctxt "@info:backup_status"
msgid "There was an error while creating your backup."
-msgstr ""
+msgstr "建立備份時發生了錯誤。"
#: /home/trin/Gedeeld/Projects/Cura/plugins/CuraDrive/src/CreateBackupJob.py:58
msgctxt "@info:backup_status"
@@ -791,7 +791,7 @@ msgstr "你的備份上傳完成。"
#: /home/trin/Gedeeld/Projects/Cura/plugins/CuraDrive/src/CreateBackupJob.py:107
msgctxt "@error:file_size"
msgid "The backup exceeds the maximum file size."
-msgstr ""
+msgstr "備份超過了最大檔案大小。"
#: /home/trin/Gedeeld/Projects/Cura/plugins/CuraDrive/src/DriveApiService.py:82
#: /home/trin/Gedeeld/Projects/Cura/plugins/CuraDrive/src/RestoreBackupJob.py:23
@@ -850,6 +850,10 @@ msgid ""
"- Are assigned to an enabled extruder\n"
"- Are not all set as modifier meshes"
msgstr ""
+"請檢查設定並檢查你的模型是否:\n"
+"- 適合列印範圍\n"
+"- 分配了一個已啟用的擠出機\n"
+"- 沒有全部設定成修改網格"
#: /home/trin/Gedeeld/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:50
#: /home/trin/Gedeeld/Projects/Cura/plugins/CuraEngineBackend/ProcessSlicedLayersJob.py:256
@@ -1156,7 +1160,7 @@ msgstr "建立一塊不列印支撐的空間。"
#: /home/trin/Gedeeld/Projects/Cura/plugins/Toolbox/src/CloudSync/CloudPackageChecker.py:101
msgctxt "@info:generic"
msgid "Do you want to sync material and software packages with your account?"
-msgstr ""
+msgstr "你要使用你的帳號同步耗材資料和軟體套件嗎?"
#: /home/trin/Gedeeld/Projects/Cura/plugins/Toolbox/src/CloudSync/CloudPackageChecker.py:102
#: /home/trin/Gedeeld/Projects/Cura/plugins/Toolbox/src/CloudSync/DownloadPresenter.py:91
@@ -1172,7 +1176,7 @@ msgstr "同步"
#: /home/trin/Gedeeld/Projects/Cura/plugins/Toolbox/src/CloudSync/DownloadPresenter.py:87
msgctxt "@info:generic"
msgid "Syncing..."
-msgstr ""
+msgstr "同步中..."
#: /home/trin/Gedeeld/Projects/Cura/plugins/Toolbox/src/CloudSync/LicenseModel.py:9
msgctxt "@button"
@@ -2070,12 +2074,12 @@ msgstr "重疊處不建立支撐"
#: /home/trin/Gedeeld/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:142
msgctxt "@item:inlistbox"
msgid "Infill mesh only"
-msgstr ""
+msgstr "只填充網格"
#: /home/trin/Gedeeld/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:143
msgctxt "@item:inlistbox"
msgid "Cutting mesh"
-msgstr ""
+msgstr "切割網格"
#: /home/trin/Gedeeld/Projects/Cura/plugins/PerObjectSettingsTool/PerObjectSettingsPanel.qml:373
msgctxt "@action:button"
@@ -2091,7 +2095,7 @@ msgstr "選擇對此模型的自訂設定"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Preferences/SettingVisibilityPage.qml:94
msgctxt "@label:textbox"
msgid "Filter..."
-msgstr "篩選…"
+msgstr "篩選..."
#: /home/trin/Gedeeld/Projects/Cura/plugins/PerObjectSettingsTool/SettingPickDialog.qml:70
msgctxt "@label:checkbox"
@@ -2121,13 +2125,13 @@ msgstr "設定"
#: /home/trin/Gedeeld/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:499
msgctxt "@info:tooltip"
msgid "Change active post-processing scripts."
-msgstr ""
+msgstr "更改目前啟用的後處理腳本。"
#: /home/trin/Gedeeld/Projects/Cura/plugins/PostProcessingPlugin/PostProcessingPlugin.qml:503
msgctxt "@info:tooltip"
msgid "The following script is active:"
msgid_plural "The following scripts are active:"
-msgstr[0] ""
+msgstr[0] "下列為啟用中的腳本:"
#: /home/trin/Gedeeld/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:20
#: /home/trin/Gedeeld/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:49
@@ -2148,7 +2152,7 @@ msgstr "線條類型"
#: /home/trin/Gedeeld/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:115
msgctxt "@label:listbox"
msgid "Speed"
-msgstr ""
+msgstr "速度"
#: /home/trin/Gedeeld/Projects/Cura/plugins/SimulationView/SimulationViewMenuComponent.qml:119
msgctxt "@label:listbox"
@@ -2354,7 +2358,7 @@ msgstr "需重新啟動 Cura,套件的更動才能生效。"
#: /home/trin/Gedeeld/Projects/Cura/plugins/Toolbox/resources/qml/components/ToolboxFooter.qml:46
msgctxt "@info:button, %1 is the application name"
msgid "Quit %1"
-msgstr ""
+msgstr "結束 %1"
#: /home/trin/Gedeeld/Projects/Cura/plugins/Toolbox/resources/qml/components/ToolboxHeader.qml:30
#: /home/trin/Gedeeld/Projects/Cura/plugins/Toolbox/resources/qml/pages/ToolboxInstalledPage.qml:34
@@ -2960,7 +2964,7 @@ msgstr "登入"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Account/GeneralOperations.qml:40
msgctxt "@label"
msgid "Your key to connected 3D printing"
-msgstr ""
+msgstr "連線 3D 列印的金鑰"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Account/GeneralOperations.qml:51
msgctxt "@text"
@@ -2969,6 +2973,9 @@ msgid ""
"- Stay flexible by syncing your setup and loading it anywhere\n"
"- Increase efficiency with a remote workflow on Ultimaker printers"
msgstr ""
+"- 使用更多的列印參數設定和外掛訂做你的使用體驗\n"
+"- 通過同步設定可在任何地方將其載入以保持靈活性\n"
+"- 透過 Ultimaker 印表機上的遠端工作流程提高效率"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Account/GeneralOperations.qml:78
msgctxt "@button"
@@ -3113,12 +3120,12 @@ msgstr "右視圖"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Actions.qml:167
msgctxt "@action:inmenu"
msgid "Configure Cura..."
-msgstr "設定 Cura…"
+msgstr "設定 Cura..."
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Actions.qml:174
msgctxt "@action:inmenu menubar:printer"
msgid "&Add Printer..."
-msgstr "新增印表機(&A)…"
+msgstr "新增印表機(&A)..."
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Actions.qml:180
msgctxt "@action:inmenu menubar:printer"
@@ -3128,7 +3135,7 @@ msgstr "管理印表機(&I)..."
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Actions.qml:187
msgctxt "@action:inmenu"
msgid "Manage Materials..."
-msgstr "管理耗材…"
+msgstr "管理耗材..."
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Actions.qml:195
msgctxt "@action:inmenu"
@@ -3148,7 +3155,7 @@ msgstr "捨棄目前更改(&D)"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Actions.qml:222
msgctxt "@action:inmenu menubar:profile"
msgid "&Create profile from current settings/overrides..."
-msgstr "從目前設定 / 覆寫值建立列印參數(&C)…"
+msgstr "從目前設定 / 覆寫值建立列印參數(&C)..."
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Actions.qml:228
msgctxt "@action:inmenu menubar:profile"
@@ -3173,7 +3180,7 @@ msgstr "新功能"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Actions.qml:258
msgctxt "@action:inmenu menubar:help"
msgid "About..."
-msgstr "關於…"
+msgstr "關於..."
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Actions.qml:265
msgctxt "@action:inmenu menubar:edit"
@@ -3266,12 +3273,12 @@ msgstr "重置所有模型旋轉"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Actions.qml:419
msgctxt "@action:inmenu menubar:file"
msgid "&Open File(s)..."
-msgstr "開啟檔案(&O)…"
+msgstr "開啟檔案(&O)..."
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Actions.qml:427
msgctxt "@action:inmenu menubar:file"
msgid "&New Project..."
-msgstr "新建專案(&N)…"
+msgstr "新建專案(&N)..."
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Actions.qml:434
msgctxt "@action:inmenu menubar:help"
@@ -3320,13 +3327,13 @@ msgstr "列印參數"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Cura.qml:563
msgctxt "@title:window %1 is the application name"
msgid "Closing %1"
-msgstr ""
+msgstr "關閉 %1 中"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Cura.qml:564
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Cura.qml:576
msgctxt "@label %1 is the application name"
msgid "Are you sure you want to exit %1?"
-msgstr ""
+msgstr "是否確定要離開 %1 ?"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Cura.qml:614
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Dialogs/OpenFilesIncludingProjectsDialog.qml:19
@@ -3362,7 +3369,7 @@ msgstr "新功能"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:15
msgctxt "@title:window The argument is the application name."
msgid "About %1"
-msgstr ""
+msgstr "關於 %1"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Dialogs/AboutDialog.qml:57
msgctxt "@label"
@@ -3782,7 +3789,7 @@ msgstr "匯出(&E)"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Menus/FileMenu.qml:65
msgctxt "@action:inmenu menubar:file"
msgid "Export Selection..."
-msgstr "匯出選擇…"
+msgstr "匯出選擇..."
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Menus/MaterialMenu.qml:13
msgctxt "@label:category menu label"
@@ -4787,7 +4794,7 @@ msgstr "這個設定是所有擠出機共用的。修改它會同時更動到所
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Settings/SettingItem.qml:191
msgctxt "@label"
msgid "This setting is resolved from conflicting extruder-specific values:"
-msgstr ""
+msgstr "此設定是透過解決擠出機設定值衝突獲得:"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/Settings/SettingItem.qml:230
msgctxt "@label"
@@ -4940,7 +4947,7 @@ msgstr "無法連接到裝置。"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:212
msgctxt "@label"
msgid "Can't connect to your Ultimaker printer?"
-msgstr ""
+msgstr "無法連接到 Ultimaker 印表機?"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/WelcomePages/AddPrinterByIpContent.qml:211
msgctxt "@label"
@@ -4965,27 +4972,27 @@ msgstr "連接"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:36
msgctxt "@label"
msgid "Ultimaker Account"
-msgstr ""
+msgstr "Ultimaker 帳號"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:77
msgctxt "@text"
msgid "Your key to connected 3D printing"
-msgstr ""
+msgstr "連線 3D 列印的金鑰"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:94
msgctxt "@text"
msgid "- Customize your experience with more print profiles and plugins"
-msgstr ""
+msgstr "- 使用更多的列印參數設定和外掛訂做你的使用體驗"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:97
msgctxt "@text"
msgid "- Stay flexible by syncing your setup and loading it anywhere"
-msgstr ""
+msgstr "- 通過同步設定可在任何地方將其載入以保持靈活性"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:100
msgctxt "@text"
msgid "- Increase efficiency with a remote workflow on Ultimaker printers"
-msgstr ""
+msgstr "- 透過 Ultimaker 印表機上的遠端工作流程提高效率"
#: /home/trin/Gedeeld/Projects/Cura/resources/qml/WelcomePages/CloudContent.qml:119
msgctxt "@button"
@@ -5254,7 +5261,7 @@ msgstr "提供更改機器設定的方法(如列印範圍,噴頭大小等)
#: MachineSettingsAction/plugin.json
msgctxt "name"
msgid "Machine Settings Action"
-msgstr ""
+msgstr "印表機設定操作"
#: MonitorStage/plugin.json
msgctxt "description"
@@ -5589,12 +5596,12 @@ msgstr "升級版本 4.4 到 4.5"
#: VersionUpgrade/VersionUpgrade45to46/plugin.json
msgctxt "description"
msgid "Upgrades configurations from Cura 4.5 to Cura 4.6."
-msgstr ""
+msgstr "將設定從 Cura 4.5 版本升級至 4.6 版本。"
#: VersionUpgrade/VersionUpgrade45to46/plugin.json
msgctxt "name"
msgid "Version Upgrade 4.5 to 4.6"
-msgstr ""
+msgstr "升級版本 4.5 到 4.6"
#: X3DReader/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 9f001d6ae9..76a8becd31 100644
--- a/resources/i18n/zh_TW/fdmprinter.def.json.po
+++ b/resources/i18n/zh_TW/fdmprinter.def.json.po
@@ -83,7 +83,7 @@ msgstr "耗材 GUID"
#: fdmprinter.def.json
msgctxt "material_guid description"
msgid "GUID of the material. This is set automatically."
-msgstr ""
+msgstr "耗材的 GUID,此項為自動設定。"
#: fdmprinter.def.json
msgctxt "material_diameter label"
@@ -1253,12 +1253,12 @@ msgstr "套用到第一層所有多邊形的偏移量。負數值可以補償第
#: fdmprinter.def.json
msgctxt "hole_xy_offset label"
msgid "Hole Horizontal Expansion"
-msgstr ""
+msgstr "孔洞水平擴展"
#: fdmprinter.def.json
msgctxt "hole_xy_offset description"
msgid "Amount of offset applied to all holes in each layer. Positive values increase the size of the holes, negative values reduce the size of the holes."
-msgstr ""
+msgstr "套用到每一層孔洞的偏移量。正值增加孔洞的大小,負值減小孔洞的大小。"
#: fdmprinter.def.json
msgctxt "z_seam_type label"
@@ -2192,7 +2192,7 @@ msgstr "沖洗速度"
#: fdmprinter.def.json
msgctxt "material_flush_purge_speed description"
msgid "How fast to prime the material after switching to a different material."
-msgstr ""
+msgstr "切換到另一耗材後,用多快的速度擠出耗材做沖洗。"
#: fdmprinter.def.json
msgctxt "material_flush_purge_length label"
@@ -2202,27 +2202,27 @@ msgstr "沖洗長度"
#: fdmprinter.def.json
msgctxt "material_flush_purge_length description"
msgid "How much material to use to purge the previous material out of the nozzle (in length of filament) when switching to a different material."
-msgstr ""
+msgstr "切換到另一耗材時,要使用多少耗材(以耗材長度計算)將噴頭內先前的耗材沖洗出來。"
#: fdmprinter.def.json
msgctxt "material_end_of_filament_purge_speed label"
msgid "End of Filament Purge Speed"
-msgstr ""
+msgstr "耗材更換沖洗速度"
#: fdmprinter.def.json
msgctxt "material_end_of_filament_purge_speed description"
msgid "How fast to prime the material after replacing an empty spool with a fresh spool of the same material."
-msgstr ""
+msgstr "更換新的一捲相同耗材後,用多快的速度擠出耗材做沖洗。"
#: fdmprinter.def.json
msgctxt "material_end_of_filament_purge_length label"
msgid "End of Filament Purge Length"
-msgstr ""
+msgstr "耗材更換沖洗長度"
#: fdmprinter.def.json
msgctxt "material_end_of_filament_purge_length description"
msgid "How much material to use to purge the previous material out of the nozzle (in length of filament) when replacing an empty spool with a fresh spool of the same material."
-msgstr ""
+msgstr "更換新的一捲相同耗材時,要使用多少耗材(以耗材長度計算)將噴頭內先前的耗材沖洗出來。"
#: fdmprinter.def.json
msgctxt "material_maximum_park_duration label"
@@ -2232,7 +2232,7 @@ msgstr "最長停放時間"
#: fdmprinter.def.json
msgctxt "material_maximum_park_duration description"
msgid "How long the material can be kept out of dry storage safely."
-msgstr ""
+msgstr "耗材可在乾燥箱外安全的存放多久。"
#: fdmprinter.def.json
msgctxt "material_no_load_move_factor label"
@@ -2242,7 +2242,7 @@ msgstr "空載移動係數"
#: fdmprinter.def.json
msgctxt "material_no_load_move_factor description"
msgid "A factor indicating how much the filament gets compressed between the feeder and the nozzle chamber, used to determine how far to move the material for a filament switch."
-msgstr ""
+msgstr "一個用來表示耗材在進料器和噴頭腔室之間能被壓縮多少的係數,用來決定耗材切換時需要移動多長。"
#: fdmprinter.def.json
msgctxt "material_flow label"
@@ -3022,7 +3022,7 @@ msgstr "啟用回抽"
#: fdmprinter.def.json
msgctxt "retraction_enable description"
msgid "Retract the filament when the nozzle is moving over a non-printed area."
-msgstr ""
+msgstr "當噴頭移動經過非列印區域時回抽耗材。"
#: fdmprinter.def.json
msgctxt "retract_at_layer_change label"
@@ -3717,7 +3717,7 @@ msgstr "最小支撐 X/Y 間距"
#: fdmprinter.def.json
msgctxt "support_xy_distance_overhang description"
msgid "Distance of the support structure from the overhang in the X/Y directions."
-msgstr ""
+msgstr "支撐結構在 X/Y 方向與突出部分的間距。 "
#: fdmprinter.def.json
msgctxt "support_bottom_stair_step_height label"
@@ -4816,7 +4816,7 @@ msgstr "網格修復"
#: fdmprinter.def.json
msgctxt "meshfix description"
msgid "Make the meshes more suited for 3D printing."
-msgstr ""
+msgstr "讓網格更適合 3D 列印。"
#: fdmprinter.def.json
msgctxt "meshfix_union_all label"
@@ -4936,7 +4936,7 @@ msgstr "特殊模式"
#: fdmprinter.def.json
msgctxt "blackmagic description"
msgid "Non-traditional ways to print your models."
-msgstr ""
+msgstr "以非傳統的方式列印你的模型。"
#: fdmprinter.def.json
msgctxt "print_sequence label"
@@ -5111,7 +5111,7 @@ msgstr "實驗性"
#: fdmprinter.def.json
msgctxt "experimental description"
msgid "Features that haven't completely been fleshed out yet."
-msgstr ""
+msgstr "尚未完全的功能。"
#: fdmprinter.def.json
msgctxt "support_tree_enable label"
diff --git a/resources/images/anycubic_predator.png b/resources/images/anycubic_predator.png
new file mode 100644
index 0000000000..2ab214826a
Binary files /dev/null and b/resources/images/anycubic_predator.png differ
diff --git a/resources/images/uni.png b/resources/images/uni.png
new file mode 100644
index 0000000000..265de834d5
Binary files /dev/null and b/resources/images/uni.png differ
diff --git a/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.10_visual.inst.inst.cfg b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.10_visual.inst.inst.cfg
new file mode 100644
index 0000000000..1ec458dae1
--- /dev/null
+++ b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.10_visual.inst.inst.cfg
@@ -0,0 +1,22 @@
+[general]
+version = 4
+name = Visual
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+quality_type = q010
+intent_category = visual
+material = generic_abs
+variant = 0.40mm Nozzle
+
+[values]
+speed_print = 50
+speed_infill = =speed_print
+speed_layer_0 = 20
+speed_topbottom = 35
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+adaptive_layer_height_enabled = true
diff --git a/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.15_eng.inst.inst.cfg b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.15_eng.inst.inst.cfg
new file mode 100644
index 0000000000..a510eb8bb9
--- /dev/null
+++ b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.15_eng.inst.inst.cfg
@@ -0,0 +1,21 @@
+[general]
+version = 4
+name = Accurate
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+intent_category = engineering
+quality_type = q015
+material = generic_abs
+variant = 0.40mm Nozzle
+
+[values]
+speed_print = 70
+speed_infill = =speed_print
+speed_layer_0 = 25
+speed_topbottom = 40
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
diff --git a/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.15_visual.inst.inst.cfg b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.15_visual.inst.inst.cfg
new file mode 100644
index 0000000000..8c71e5d841
--- /dev/null
+++ b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.15_visual.inst.inst.cfg
@@ -0,0 +1,22 @@
+[general]
+version = 4
+name = Visual
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+quality_type = q015
+intent_category = visual
+material = generic_abs
+variant = 0.40mm Nozzle
+
+[values]
+speed_print = 50
+speed_infill = =speed_print
+speed_layer_0 = 20
+speed_topbottom = 35
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+adaptive_layer_height_enabled = true
diff --git a/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.20_eng.inst.inst.cfg b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.20_eng.inst.inst.cfg
new file mode 100644
index 0000000000..f51e3be26a
--- /dev/null
+++ b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.20_eng.inst.inst.cfg
@@ -0,0 +1,21 @@
+[general]
+version = 4
+name = Accurate
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+intent_category = engineering
+quality_type = q020
+material = generic_abs
+variant = 0.40mm Nozzle
+
+[values]
+speed_print = 70
+speed_infill = =speed_print
+speed_layer_0 = 25
+speed_topbottom = 40
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
diff --git a/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.20_quick.inst.cfg b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.20_quick.inst.cfg
new file mode 100644
index 0000000000..ab7a50b7f3
--- /dev/null
+++ b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.20_quick.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+version = 4
+name = Quick
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+intent_category = quick
+quality_type = q020
+material = generic_abs
+variant = 0.40mm Nozzle
+
+[values]
+jerk_print = 30
+jerk_infill = =jerk_print
+jerk_topbottom = =jerk_print
+jerk_wall = =jerk_print
+jerk_wall_0 = =jerk_wall
+jerk_wall_x = =jerk_wall
+jerk_layer_0 = 5
+speed_print = 100
+speed_infill = =speed_print
+speed_layer_0 = 25
+speed_topbottom = 65
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
diff --git a/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.20_visual.inst.inst.cfg b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.20_visual.inst.inst.cfg
new file mode 100644
index 0000000000..1895419cc4
--- /dev/null
+++ b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.20_visual.inst.inst.cfg
@@ -0,0 +1,22 @@
+[general]
+version = 4
+name = Visual
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+quality_type = q020
+intent_category = visual
+material = generic_abs
+variant = 0.40mm Nozzle
+
+[values]
+speed_print = 50
+speed_infill = =speed_print
+speed_layer_0 = 20
+speed_topbottom = 35
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+adaptive_layer_height_enabled = true
diff --git a/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.25_quick.inst.cfg b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.25_quick.inst.cfg
new file mode 100644
index 0000000000..2c233efe19
--- /dev/null
+++ b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.25_quick.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+version = 4
+name = Quick
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+intent_category = quick
+quality_type = q025
+material = generic_abs
+variant = 0.40mm Nozzle
+
+[values]
+jerk_print = 30
+jerk_infill = =jerk_print
+jerk_topbottom = =jerk_print
+jerk_wall = =jerk_print
+jerk_wall_0 = =jerk_wall
+jerk_wall_x = =jerk_wall
+jerk_layer_0 = 5
+speed_print = 100
+speed_infill = =speed_print
+speed_layer_0 = 25
+speed_topbottom = 65
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
diff --git a/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.30_quick.inst.cfg b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.30_quick.inst.cfg
new file mode 100644
index 0000000000..5bc8b789dc
--- /dev/null
+++ b/resources/intent/uni_base/abs/abs_nozzle_0.40_layer_0.30_quick.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+version = 4
+name = Quick
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+intent_category = quick
+quality_type = q030
+material = generic_abs
+variant = 0.40mm Nozzle
+
+[values]
+jerk_print = 30
+jerk_infill = =jerk_print
+jerk_topbottom = =jerk_print
+jerk_wall = =jerk_print
+jerk_wall_0 = =jerk_wall
+jerk_wall_x = =jerk_wall
+jerk_layer_0 = 5
+speed_print = 100
+speed_infill = =speed_print
+speed_layer_0 = 25
+speed_topbottom = 65
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
diff --git a/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.10_visual.inst.inst.cfg b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.10_visual.inst.inst.cfg
new file mode 100644
index 0000000000..90bce20eb2
--- /dev/null
+++ b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.10_visual.inst.inst.cfg
@@ -0,0 +1,22 @@
+[general]
+version = 4
+name = Visual
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+quality_type = q010
+intent_category = visual
+material = generic_petg
+variant = 0.40mm Nozzle
+
+[values]
+speed_print = 50
+speed_infill = =speed_print
+speed_layer_0 = 20
+speed_topbottom = 35
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+adaptive_layer_height_enabled = true
diff --git a/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.15_eng.inst.inst.cfg b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.15_eng.inst.inst.cfg
new file mode 100644
index 0000000000..07e8e8cd07
--- /dev/null
+++ b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.15_eng.inst.inst.cfg
@@ -0,0 +1,21 @@
+[general]
+version = 4
+name = Accurate
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+intent_category = engineering
+quality_type = q015
+material = generic_petg
+variant = 0.40mm Nozzle
+
+[values]
+speed_print = 70
+speed_infill = =speed_print
+speed_layer_0 = 25
+speed_topbottom = 40
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
diff --git a/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.15_visual.inst.inst.cfg b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.15_visual.inst.inst.cfg
new file mode 100644
index 0000000000..4a6bb15f3d
--- /dev/null
+++ b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.15_visual.inst.inst.cfg
@@ -0,0 +1,22 @@
+[general]
+version = 4
+name = Visual
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+quality_type = q015
+intent_category = visual
+material = generic_petg
+variant = 0.40mm Nozzle
+
+[values]
+speed_print = 50
+speed_infill = =speed_print
+speed_layer_0 = 20
+speed_topbottom = 35
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+adaptive_layer_height_enabled = true
diff --git a/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.20_eng.inst.inst.cfg b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.20_eng.inst.inst.cfg
new file mode 100644
index 0000000000..03db44228d
--- /dev/null
+++ b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.20_eng.inst.inst.cfg
@@ -0,0 +1,21 @@
+[general]
+version = 4
+name = Accurate
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+intent_category = engineering
+quality_type = q020
+material = generic_petg
+variant = 0.40mm Nozzle
+
+[values]
+speed_print = 70
+speed_infill = =speed_print
+speed_layer_0 = 25
+speed_topbottom = 40
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
diff --git a/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.20_quick.inst.cfg b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.20_quick.inst.cfg
new file mode 100644
index 0000000000..3927310450
--- /dev/null
+++ b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.20_quick.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+version = 4
+name = Quick
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+intent_category = quick
+quality_type = q020
+material = generic_petg
+variant = 0.40mm Nozzle
+
+[values]
+jerk_print = 30
+jerk_infill = =jerk_print
+jerk_topbottom = =jerk_print
+jerk_wall = =jerk_print
+jerk_wall_0 = =jerk_wall
+jerk_wall_x = =jerk_wall
+jerk_layer_0 = 5
+speed_print = 100
+speed_infill = =speed_print
+speed_layer_0 = 25
+speed_topbottom = 65
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
diff --git a/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.20_visual.inst.inst.cfg b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.20_visual.inst.inst.cfg
new file mode 100644
index 0000000000..03b2f5c0f2
--- /dev/null
+++ b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.20_visual.inst.inst.cfg
@@ -0,0 +1,22 @@
+[general]
+version = 4
+name = Visual
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+quality_type = q020
+intent_category = visual
+material = generic_petg
+variant = 0.40mm Nozzle
+
+[values]
+speed_print = 50
+speed_infill = =speed_print
+speed_layer_0 = 20
+speed_topbottom = 35
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+adaptive_layer_height_enabled = true
diff --git a/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.25_quick.inst.cfg b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.25_quick.inst.cfg
new file mode 100644
index 0000000000..c1405a9546
--- /dev/null
+++ b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.25_quick.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+version = 4
+name = Quick
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+intent_category = quick
+quality_type = q025
+material = generic_petg
+variant = 0.40mm Nozzle
+
+[values]
+jerk_print = 30
+jerk_infill = =jerk_print
+jerk_topbottom = =jerk_print
+jerk_wall = =jerk_print
+jerk_wall_0 = =jerk_wall
+jerk_wall_x = =jerk_wall
+jerk_layer_0 = 5
+speed_print = 100
+speed_infill = =speed_print
+speed_layer_0 = 25
+speed_topbottom = 65
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
diff --git a/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.30_quick.inst.cfg b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.30_quick.inst.cfg
new file mode 100644
index 0000000000..c3a0ed1ac0
--- /dev/null
+++ b/resources/intent/uni_base/petg/petg_nozzle_0.40_layer_0.30_quick.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+version = 4
+name = Quick
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+intent_category = quick
+quality_type = q030
+material = generic_petg
+variant = 0.40mm Nozzle
+
+[values]
+jerk_print = 30
+jerk_infill = =jerk_print
+jerk_topbottom = =jerk_print
+jerk_wall = =jerk_print
+jerk_wall_0 = =jerk_wall
+jerk_wall_x = =jerk_wall
+jerk_layer_0 = 5
+speed_print = 100
+speed_infill = =speed_print
+speed_layer_0 = 25
+speed_topbottom = 65
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
diff --git a/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.10_visual.inst.inst.cfg b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.10_visual.inst.inst.cfg
new file mode 100644
index 0000000000..87ca58fdb8
--- /dev/null
+++ b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.10_visual.inst.inst.cfg
@@ -0,0 +1,22 @@
+[general]
+version = 4
+name = Visual
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+quality_type = q010
+intent_category = visual
+material = generic_pla
+variant = 0.40mm Nozzle
+
+[values]
+speed_print = 50
+speed_infill = =speed_print
+speed_layer_0 = 20
+speed_topbottom = 35
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+adaptive_layer_height_enabled = true
diff --git a/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.15_eng.inst.inst.cfg b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.15_eng.inst.inst.cfg
new file mode 100644
index 0000000000..52e62680e3
--- /dev/null
+++ b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.15_eng.inst.inst.cfg
@@ -0,0 +1,21 @@
+[general]
+version = 4
+name = Accurate
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+intent_category = engineering
+quality_type = q015
+material = generic_pla
+variant = 0.40mm Nozzle
+
+[values]
+speed_print = 70
+speed_infill = =speed_print
+speed_layer_0 = 25
+speed_topbottom = 40
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
diff --git a/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.15_visual.inst.inst.cfg b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.15_visual.inst.inst.cfg
new file mode 100644
index 0000000000..ecd61a1aa7
--- /dev/null
+++ b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.15_visual.inst.inst.cfg
@@ -0,0 +1,22 @@
+[general]
+version = 4
+name = Visual
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+quality_type = q015
+intent_category = visual
+material = generic_pla
+variant = 0.40mm Nozzle
+
+[values]
+speed_print = 50
+speed_infill = =speed_print
+speed_layer_0 = 20
+speed_topbottom = 35
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+adaptive_layer_height_enabled = true
diff --git a/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.20_eng.inst.inst.cfg b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.20_eng.inst.inst.cfg
new file mode 100644
index 0000000000..cc5e0a7e3b
--- /dev/null
+++ b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.20_eng.inst.inst.cfg
@@ -0,0 +1,21 @@
+[general]
+version = 4
+name = Accurate
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+intent_category = engineering
+quality_type = q020
+material = generic_pla
+variant = 0.40mm Nozzle
+
+[values]
+speed_print = 70
+speed_infill = =speed_print
+speed_layer_0 = 25
+speed_topbottom = 40
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
diff --git a/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.20_quick.inst.cfg b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.20_quick.inst.cfg
new file mode 100644
index 0000000000..2cfe1fed96
--- /dev/null
+++ b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.20_quick.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+version = 4
+name = Quick
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+intent_category = quick
+quality_type = q020
+material = generic_pla
+variant = 0.40mm Nozzle
+
+[values]
+jerk_print = 30
+jerk_infill = =jerk_print
+jerk_topbottom = =jerk_print
+jerk_wall = =jerk_print
+jerk_wall_0 = =jerk_wall
+jerk_wall_x = =jerk_wall
+jerk_layer_0 = 5
+speed_print = 100
+speed_infill = =speed_print
+speed_layer_0 = 25
+speed_topbottom = 65
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
diff --git a/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.20_visual.inst.inst.cfg b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.20_visual.inst.inst.cfg
new file mode 100644
index 0000000000..b28aad39d6
--- /dev/null
+++ b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.20_visual.inst.inst.cfg
@@ -0,0 +1,22 @@
+[general]
+version = 4
+name = Visual
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+quality_type = q020
+intent_category = visual
+material = generic_pla
+variant = 0.40mm Nozzle
+
+[values]
+speed_print = 50
+speed_infill = =speed_print
+speed_layer_0 = 20
+speed_topbottom = 35
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
+adaptive_layer_height_enabled = true
diff --git a/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.25_quick.inst.cfg b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.25_quick.inst.cfg
new file mode 100644
index 0000000000..55d646d256
--- /dev/null
+++ b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.25_quick.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+version = 4
+name = Quick
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+intent_category = quick
+quality_type = q025
+material = generic_pla
+variant = 0.40mm Nozzle
+
+[values]
+jerk_print = 30
+jerk_infill = =jerk_print
+jerk_topbottom = =jerk_print
+jerk_wall = =jerk_print
+jerk_wall_0 = =jerk_wall
+jerk_wall_x = =jerk_wall
+jerk_layer_0 = 5
+speed_print = 100
+speed_infill = =speed_print
+speed_layer_0 = 25
+speed_topbottom = 65
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
diff --git a/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.30_quick.inst.cfg b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.30_quick.inst.cfg
new file mode 100644
index 0000000000..8fe10fbd0e
--- /dev/null
+++ b/resources/intent/uni_base/pla/pla_nozzle_0.40_layer_0.30_quick.inst.cfg
@@ -0,0 +1,28 @@
+[general]
+version = 4
+name = Quick
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = intent
+intent_category = quick
+quality_type = q030
+material = generic_pla
+variant = 0.40mm Nozzle
+
+[values]
+jerk_print = 30
+jerk_infill = =jerk_print
+jerk_topbottom = =jerk_print
+jerk_wall = =jerk_print
+jerk_wall_0 = =jerk_wall
+jerk_wall_x = =jerk_wall
+jerk_layer_0 = 5
+speed_print = 100
+speed_infill = =speed_print
+speed_layer_0 = 25
+speed_topbottom = 65
+speed_wall = =speed_topbottom
+speed_wall_0 = =speed_wall
+speed_wall_x = =speed_wall
diff --git a/resources/meshes/FLSUN-QQ-S.stl b/resources/meshes/FLSUN-QQ-S.stl
new file mode 100644
index 0000000000..d4fe2fbfbe
Binary files /dev/null and b/resources/meshes/FLSUN-QQ-S.stl differ
diff --git a/resources/meshes/predator_platform.stl b/resources/meshes/predator_platform.stl
new file mode 100644
index 0000000000..ae65da7c52
Binary files /dev/null and b/resources/meshes/predator_platform.stl differ
diff --git a/resources/meshes/uni_200_platform.stl b/resources/meshes/uni_200_platform.stl
new file mode 100644
index 0000000000..382380e6e4
Binary files /dev/null and b/resources/meshes/uni_200_platform.stl differ
diff --git a/resources/meshes/uni_250_platform.stl b/resources/meshes/uni_250_platform.stl
new file mode 100644
index 0000000000..a7d76d2699
Binary files /dev/null and b/resources/meshes/uni_250_platform.stl differ
diff --git a/resources/meshes/uni_300_platform.stl b/resources/meshes/uni_300_platform.stl
new file mode 100644
index 0000000000..596d9847a9
Binary files /dev/null and b/resources/meshes/uni_300_platform.stl differ
diff --git a/resources/meshes/uni_mini_platform.stl b/resources/meshes/uni_mini_platform.stl
new file mode 100644
index 0000000000..43924c1230
Binary files /dev/null and b/resources/meshes/uni_mini_platform.stl differ
diff --git a/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml b/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml
index a7701cf059..b7fe022d78 100644
--- a/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml
+++ b/resources/qml/Dialogs/DiscardOrKeepProfileChangesDialog.qml
@@ -54,7 +54,7 @@ UM.Dialog
Label
{
- text: catalog.i18nc("@text:window", "You have customized some profile settings.\nWould you like to keep or discard those settings?")
+ text: catalog.i18nc("@text:window, %1 is a profile name", "You have customized some profile settings.\nWould you like to Keep these changed settings after switching profiles?\nAlternatively, you can Discard the changes to load the defaults from '%1'.").arg(Cura.MachineManager.activeQualityDisplayNameMap["main"])
anchors.margins: UM.Theme.getSize("default_margin").width
wrapMode: Text.WordWrap
}
@@ -113,14 +113,14 @@ UM.Dialog
TableViewColumn
{
role: "original_value"
- title: catalog.i18nc("@title:column", "Default")
+ title: Cura.MachineManager.activeQualityDisplayNameMap["main"]
width: (tableView.width * 0.3) | 0
delegate: defaultDelegate
}
TableViewColumn
{
role: "user_value"
- title: catalog.i18nc("@title:column", "Customized")
+ title: catalog.i18nc("@title:column", "Current changes")
width: (tableView.width * 0.3) | 0
}
section.property: "category"
@@ -192,7 +192,7 @@ UM.Dialog
Button
{
id: discardButton
- text: catalog.i18nc("@action:button", "Discard");
+ text: catalog.i18nc("@action:button", "Discard changes");
anchors.right: parent.right
onClicked:
{
@@ -205,7 +205,7 @@ UM.Dialog
Button
{
id: keepButton
- text: catalog.i18nc("@action:button", "Keep");
+ text: catalog.i18nc("@action:button", "Keep changes");
anchors.right: discardButton.left
anchors.rightMargin: UM.Theme.getSize("default_margin").width
onClicked:
diff --git a/resources/qml/ObjectItemButton.qml b/resources/qml/ObjectItemButton.qml
index b454fd929a..9244fa6391 100644
--- a/resources/qml/ObjectItemButton.qml
+++ b/resources/qml/ObjectItemButton.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2018 Ultimaker B.V.
+// Copyright (c) 2020 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
@@ -14,33 +14,11 @@ Button
width: parent.width
height: UM.Theme.getSize("action_button").height
leftPadding: UM.Theme.getSize("thin_margin").width
- rightPadding: UM.Theme.getSize("thin_margin").width
+ rightPadding: perObjectSettingsInfo.visible ? UM.Theme.getSize("default_lining").width : UM.Theme.getSize("thin_margin").width
checkable: true
hoverEnabled: true
- contentItem: Item
- {
- width: objectItemButton.width - objectItemButton.leftPadding
- height: UM.Theme.getSize("action_button").height
-
- Label
- {
- id: buttonText
- anchors
- {
- left: parent.left
- right: parent.right
- verticalCenter: parent.verticalCenter
- }
- text: objectItemButton.text
- font: UM.Theme.getFont("default")
- color: UM.Theme.getColor("text_scene")
- visible: text != ""
- renderType: Text.NativeRendering
- verticalAlignment: Text.AlignVCenter
- elide: Text.ElideRight
- }
- }
+ onClicked: Cura.SceneController.changeSelection(index)
background: Rectangle
{
@@ -51,6 +29,149 @@ Button
border.color: objectItemButton.checked ? UM.Theme.getColor("primary") : "transparent"
}
+ contentItem: Item
+ {
+ width: objectItemButton.width - objectItemButton.leftPadding
+ height: UM.Theme.getSize("action_button").height
+
+ UM.RecolorImage
+ {
+ id: swatch
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.left: parent.left
+ width: height
+ height: parent.height - UM.Theme.getSize("narrow_margin").height
+ source: UM.Theme.getIcon("extruder_button")
+ color: extruderColor
+ visible: showExtruderSwatches && extruderColor != ""
+ }
+
+ Label
+ {
+ id: buttonText
+ anchors
+ {
+ left: showExtruderSwatches ? swatch.right : parent.left
+ leftMargin: showExtruderSwatches ? UM.Theme.getSize("narrow_margin").width : 0
+ right: perObjectSettingsInfo.visible ? perObjectSettingsInfo.left : parent.right
+ verticalCenter: parent.verticalCenter
+ }
+ text: objectItemButton.text
+ font: UM.Theme.getFont("default")
+ color: UM.Theme.getColor("text_scene")
+ opacity: (outsideBuildArea) ? 0.5 : 1.0
+ visible: text != ""
+ renderType: Text.NativeRendering
+ verticalAlignment: Text.AlignVCenter
+ elide: Text.ElideRight
+ }
+
+ Button
+ {
+ id: perObjectSettingsInfo
+
+ anchors
+ {
+ right: parent.right
+ rightMargin: 0
+ }
+ width: childrenRect.width
+ height: parent.height
+ padding: 0
+ leftPadding: UM.Theme.getSize("thin_margin").width
+ visible: meshType != "" || perObjectSettingsCount > 0
+
+ onClicked:
+ {
+ Cura.SceneController.changeSelection(index)
+ UM.Controller.setActiveTool("PerObjectSettingsTool")
+ }
+
+ property string tooltipText:
+ {
+ var result = "";
+ if (!visible)
+ {
+ return result;
+ }
+ if (meshType != "")
+ {
+ result += "
";
+ switch (meshType) {
+ case "support_mesh":
+ result += catalog.i18nc("@label", "Is printed as support.");
+ break;
+ case "cutting_mesh":
+ result += catalog.i18nc("@label", "Other models overlapping with this model are modified.");
+ break;
+ case "infill_mesh":
+ result += catalog.i18nc("@label", "Infill overlapping with this model is modified.");
+ break;
+ case "anti_overhang_mesh":
+ result += catalog.i18nc("@label", "Overlaps with this model are not supported.");
+ break;
+ }
+ }
+ if (perObjectSettingsCount != "")
+ {
+ result += "
" + catalog.i18ncp(
+ "@label", "Overrides %1 setting.", "Overrides %1 settings.", perObjectSettingsCount
+ ).arg(perObjectSettingsCount);
+ }
+ return result;
+ }
+
+ contentItem: Item
+ {
+ height: parent.height
+ width: meshTypeIcon.width + perObjectSettingsCountLabel.width + UM.Theme.getSize("narrow_margin").width
+
+ Cura.NotificationIcon
+ {
+ id: perObjectSettingsCountLabel
+ anchors
+ {
+ right: parent.right
+ rightMargin: 0
+ }
+ visible: perObjectSettingsCount > 0
+ color: UM.Theme.getColor("text_scene")
+ labelText: perObjectSettingsCount.toString()
+ }
+
+ UM.RecolorImage
+ {
+ id: meshTypeIcon
+ anchors
+ {
+ right: perObjectSettingsCountLabel.left
+ rightMargin: UM.Theme.getSize("narrow_margin").width
+ }
+
+ width: parent.height
+ height: parent.height
+ color: UM.Theme.getColor("text_scene")
+ visible: meshType != ""
+ source:
+ {
+ switch (meshType) {
+ case "support_mesh":
+ return UM.Theme.getIcon("pos_print_as_support");
+ case "cutting_mesh":
+ case "infill_mesh":
+ return UM.Theme.getIcon("pos_modify_overlaps");
+ case "anti_overhang_mesh":
+ return UM.Theme.getIcon("pos_modify_dont_support_overlap");
+ }
+ return "";
+ }
+ }
+ }
+
+ background: Item {}
+ }
+ }
+
TextMetrics
{
id: buttonTextMetrics
@@ -63,9 +184,13 @@ Button
Cura.ToolTip
{
id: tooltip
- tooltipText: objectItemButton.text
- visible: objectItemButton.hovered && buttonTextMetrics.elidedText != buttonText.text
+ tooltipText: objectItemButton.text + perObjectSettingsInfo.tooltipText
+ visible: objectItemButton.hovered && (buttonTextMetrics.elidedText != buttonText.text || perObjectSettingsInfo.visible)
}
- onClicked: Cura.SceneController.changeSelection(index)
+ UM.I18nCatalog
+ {
+ id: catalog
+ name: "cura"
+ }
}
diff --git a/resources/qml/ObjectSelector.qml b/resources/qml/ObjectSelector.qml
index 6757863e1c..15cb476e08 100644
--- a/resources/qml/ObjectSelector.qml
+++ b/resources/qml/ObjectSelector.qml
@@ -1,4 +1,4 @@
-// Copyright (c) 2019 Ultimaker B.V.
+// Copyright (c) 2020 Ultimaker B.V.
// Cura is released under the terms of the LGPLv3 or higher.
import QtQuick 2.10
@@ -87,6 +87,17 @@ Item
anchors.bottom: parent.bottom
+ property var extrudersModel: CuraApplication.getExtrudersModel()
+ UM.SettingPropertyProvider
+ {
+ id: machineExtruderCount
+
+ containerStack: Cura.MachineManager.activeMachine
+ key: "machine_extruder_count"
+ watchedProperties: [ "value" ]
+ storeIndex: 0
+ }
+
ListView
{
id: listView
@@ -120,6 +131,19 @@ Item
}
text: model.name
width: listView.width
+ property bool outsideBuildArea: model.outside_build_area
+ property int perObjectSettingsCount: model.per_object_settings_count
+ property string meshType: model.mesh_type
+ property int extruderNumber: model.extruder_number
+ property string extruderColor:
+ {
+ if (model.extruder_number == -1)
+ {
+ return "";
+ }
+ return contents.extrudersModel.getItem(model.extruder_number).color;
+ }
+ property bool showExtruderSwatches: machineExtruderCount.properties.value > 1
}
}
}
diff --git a/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml b/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml
index e3018a6825..6a2accf97d 100644
--- a/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml
+++ b/resources/qml/WelcomePages/AddNetworkOrLocalPrinterContent.qml
@@ -143,8 +143,9 @@ Item
const networkPrinterItem = addNetworkPrinterDropDown.contentItem.currentItem
CuraApplication.getDiscoveredPrintersModel().createMachineFromDiscoveredPrinter(networkPrinterItem)
- // If we have created a machine, go to the last page, which is the "cloud" page.
- base.goToPage("cloud")
+ // If we have created a machine, end the wizard (since this is the last page)
+ base.endWizard()
+
}
else
{
diff --git a/resources/qml/WelcomePages/AddPrinterByIpContent.qml b/resources/qml/WelcomePages/AddPrinterByIpContent.qml
index c73aa3958e..97c71b37a4 100644
--- a/resources/qml/WelcomePages/AddPrinterByIpContent.qml
+++ b/resources/qml/WelcomePages/AddPrinterByIpContent.qml
@@ -130,7 +130,7 @@ Item
onTextEdited: invalidInputLabel.visible = false
- placeholderText: catalog.i18nc("@text", "Place enter your printer's IP address.")
+ placeholderText: catalog.i18nc("@text", "Enter your printer's IP address.")
enabled: { ! (addPrinterByIpScreen.hasRequestInProgress || addPrinterByIpScreen.isPrinterDiscovered) }
onAccepted: addPrinterButton.clicked()
diff --git a/resources/qml/WelcomePages/CloudContent.qml b/resources/qml/WelcomePages/CloudContent.qml
index b127dbfb3c..36a7b9a923 100644
--- a/resources/qml/WelcomePages/CloudContent.qml
+++ b/resources/qml/WelcomePages/CloudContent.qml
@@ -15,14 +15,20 @@ Item
{
UM.I18nCatalog { id: catalog; name: "cura" }
- property bool isLoggedIn: Cura.API.account.isLoggedIn
+ property bool newCloudPrintersDetected: Cura.API.account.newCloudPrintersDetected
+ signal cloudPrintersDetected(bool newCloudPrintersDetected)
- onIsLoggedInChanged:
+ Component.onCompleted: Cura.API.account.cloudPrintersDetectedChanged.connect(cloudPrintersDetected)
+ onCloudPrintersDetected:
{
- if(isLoggedIn)
+ // When the user signs in successfully, it will be checked whether he/she has cloud printers connected to
+ // the account. If he/she does, then the welcome wizard can close. If not, then proceed to the next page (if any)
+ if(newCloudPrintersDetected)
+ {
+ base.endWizard()
+ }
+ else
{
- // If the user created an account or logged in by pressing any button on this page, all the actions that
- // need / can be done by this page are completed, so we can just go to the next (if any).
base.showNextPage()
}
}
@@ -46,7 +52,7 @@ Item
anchors
{
top: titleLabel.bottom
- bottom: finishButton.top
+ bottom: skipButton.top
left: parent.left
right: parent.right
topMargin: UM.Theme.getSize("default_margin").height
@@ -107,35 +113,47 @@ Item
color: UM.Theme.getColor("text")
renderType: Text.NativeRendering
}
+
+ // "Sign in" and "Create an account" exist inside the column
+ Cura.PrimaryButton
+ {
+ id: signInButton
+ height: createAccountButton.height
+ width: createAccountButton.width
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: catalog.i18nc("@button", "Sign in")
+ onClicked: Cura.API.account.login()
+ // Content Item is used in order to align the text inside the button. Without it, when resizing the
+ // button, the text will be aligned on the left
+ contentItem: Text {
+ text: signInButton.text
+ font: UM.Theme.getFont("medium")
+ color: UM.Theme.getColor("primary_text")
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ }
+ }
+
+ Cura.SecondaryButton
+ {
+ id: createAccountButton
+ anchors.horizontalCenter: parent.horizontalCenter
+ text: catalog.i18nc("@button","Create account")
+ onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl + "/app/create")
+ }
}
+
+
}
- // Bottom buttons go here
- Cura.PrimaryButton
- {
- id: finishButton
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- text: catalog.i18nc("@button", "Finish")
- onClicked: base.showNextPage()
- }
-
- Cura.SecondaryButton
- {
- id: createAccountButton
- anchors.left: parent.left
- anchors.verticalCenter: finishButton.verticalCenter
- text: catalog.i18nc("@button", "Create an account")
- onClicked: Qt.openUrlExternally(CuraApplication.ultimakerCloudAccountRootUrl + "/app/create")
- }
-
+ // The "Skip" button exists on the bottom right
Label
{
- id: signInButton
- anchors.left: createAccountButton.right
- anchors.verticalCenter: finishButton.verticalCenter
+ id: skipButton
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
anchors.leftMargin: UM.Theme.getSize("default_margin").width
- text: catalog.i18nc("@button", "Sign in")
+ text: catalog.i18nc("@button", "Skip")
color: UM.Theme.getColor("secondary_button_text")
font: UM.Theme.getFont("medium")
renderType: Text.NativeRendering
@@ -144,7 +162,7 @@ Item
{
anchors.fill: parent
hoverEnabled: true
- onClicked: Cura.API.account.login()
+ onClicked: base.showNextPage()
onEntered: parent.font.underline = true
onExited: parent.font.underline = false
}
diff --git a/resources/quality/anycubic_predator/predator_coarse.inst.cfg b/resources/quality/anycubic_predator/predator_coarse.inst.cfg
new file mode 100644
index 0000000000..e8c6f72e8e
--- /dev/null
+++ b/resources/quality/anycubic_predator/predator_coarse.inst.cfg
@@ -0,0 +1,15 @@
+[general]
+version = 4
+name = Coarse
+definition = predator
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = coarse
+weight = -3
+global_quality = True
+
+[values]
+layer_height = 0.4
+layer_height_0 = 0.45
\ No newline at end of file
diff --git a/resources/quality/anycubic_predator/predator_draft.inst.cfg b/resources/quality/anycubic_predator/predator_draft.inst.cfg
new file mode 100644
index 0000000000..d94920785d
--- /dev/null
+++ b/resources/quality/anycubic_predator/predator_draft.inst.cfg
@@ -0,0 +1,15 @@
+[general]
+version = 4
+name = Draft
+definition = predator
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = draft
+weight = -2
+global_quality = True
+
+[values]
+layer_height = 0.30
+layer_height_0 = 0.35
\ No newline at end of file
diff --git a/resources/quality/anycubic_predator/predator_extra_coarse.inst.cfg b/resources/quality/anycubic_predator/predator_extra_coarse.inst.cfg
new file mode 100644
index 0000000000..bad550ee1f
--- /dev/null
+++ b/resources/quality/anycubic_predator/predator_extra_coarse.inst.cfg
@@ -0,0 +1,15 @@
+[general]
+version = 4
+name = Extra Coarse
+definition = predator
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = Xcoarse
+weight = -4
+global_quality = True
+
+[values]
+layer_height = 0.5
+layer_height_0 = 0.55
diff --git a/resources/quality/anycubic_predator/predator_extra_fine.inst.cfg b/resources/quality/anycubic_predator/predator_extra_fine.inst.cfg
new file mode 100644
index 0000000000..7e745c5454
--- /dev/null
+++ b/resources/quality/anycubic_predator/predator_extra_fine.inst.cfg
@@ -0,0 +1,15 @@
+[general]
+version = 4
+name = Extra Fine
+definition = predator
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = Xfine
+weight = 1
+global_quality = True
+
+[values]
+layer_height = 0.05
+layer_height_0 = 0.10
diff --git a/resources/quality/anycubic_predator/predator_fine.inst.cfg b/resources/quality/anycubic_predator/predator_fine.inst.cfg
new file mode 100644
index 0000000000..1c6d3555c9
--- /dev/null
+++ b/resources/quality/anycubic_predator/predator_fine.inst.cfg
@@ -0,0 +1,15 @@
+[general]
+version = 4
+name = Fine
+definition = predator
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = fine
+weight = 1
+global_quality = True
+
+[values]
+layer_height = 0.1
+layer_height_0 = 0.15
diff --git a/resources/quality/anycubic_predator/predator_normal.inst.cfg b/resources/quality/anycubic_predator/predator_normal.inst.cfg
new file mode 100644
index 0000000000..6f5db85938
--- /dev/null
+++ b/resources/quality/anycubic_predator/predator_normal.inst.cfg
@@ -0,0 +1,15 @@
+[general]
+version = 4
+name = Normal
+definition = predator
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = normal
+weight = 0
+global_quality = True
+
+[values]
+layer_height = 0.2
+layer_height_0 = 0.25
\ No newline at end of file
diff --git a/resources/quality/beamup_s/beamup_s_coarse.inst.cfg b/resources/quality/beamup_s/beamup_s_coarse.inst.cfg
index 9f82b7b138..20decc8ded 100644
--- a/resources/quality/beamup_s/beamup_s_coarse.inst.cfg
+++ b/resources/quality/beamup_s/beamup_s_coarse.inst.cfg
@@ -1,18 +1,18 @@
-[general]
-version = 4
-name = BeamUp S Coarse
-definition = beamup_s
-
-[metadata]
-setting_version = 10
-type = quality
-quality_type = coarse
-weight = -3
-material = generic_pla
-
-[values]
-layer_height = 0.30
-adhesion_type = brim
+[general]
+version = 4
+name = BeamUp S Coarse
+definition = beamup_s
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = coarse
+weight = -3
+material = generic_pla
+
+[values]
+layer_height = 0.30
+adhesion_type = brim
brim_line_count = 5
infill_before_walls = False
initial_layer_line_width_factor = 120.0
@@ -37,4 +37,4 @@ support_interface_skip_height = 0.30
support_offset = 0.8
support_z_distance = 0.2
wall_thickness = 0.8
-zig_zaggify_infill = True
+zig_zaggify_infill = True
diff --git a/resources/quality/beamup_s/beamup_s_draft.inst.cfg b/resources/quality/beamup_s/beamup_s_draft.inst.cfg
index a696fafd2b..d172ea3925 100644
--- a/resources/quality/beamup_s/beamup_s_draft.inst.cfg
+++ b/resources/quality/beamup_s/beamup_s_draft.inst.cfg
@@ -1,18 +1,18 @@
-[general]
-version = 4
-name = BeamUp S Draft
-definition = beamup_s
-
-[metadata]
-setting_version = 10
-type = quality
-quality_type = draft
-weight = -2
-material = generic_pla
-
-[values]
-layer_height = 0.2
-adhesion_type = brim
+[general]
+version = 4
+name = BeamUp S Draft
+definition = beamup_s
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = draft
+weight = -2
+material = generic_pla
+
+[values]
+layer_height = 0.2
+adhesion_type = brim
brim_line_count = 5
infill_before_walls = False
initial_layer_line_width_factor = 120.0
@@ -37,4 +37,4 @@ support_interface_skip_height = 0.20
support_offset = 0.8
support_z_distance = 0.2
wall_thickness = 0.8
-zig_zaggify_infill = True
+zig_zaggify_infill = True
diff --git a/resources/quality/beamup_s/beamup_s_extra_fine.inst.cfg b/resources/quality/beamup_s/beamup_s_extra_fine.inst.cfg
index ee1a1cb6a7..b6783bf8e8 100644
--- a/resources/quality/beamup_s/beamup_s_extra_fine.inst.cfg
+++ b/resources/quality/beamup_s/beamup_s_extra_fine.inst.cfg
@@ -1,18 +1,18 @@
-[general]
-version = 4
-name = BeamUp S Extra Fine
-definition = beamup_s
-
-[metadata]
-setting_version = 10
-type = quality
-quality_type = high
-weight = 1
-material = generic_pla
-
-[values]
-layer_height = 0.06
-adhesion_type = brim
+[general]
+version = 4
+name = BeamUp S Extra Fine
+definition = beamup_s
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = high
+weight = 1
+material = generic_pla
+
+[values]
+layer_height = 0.06
+adhesion_type = brim
brim_line_count = 5
infill_before_walls = False
initial_layer_line_width_factor = 120.0
@@ -37,4 +37,4 @@ support_interface_skip_height = 0.06
support_offset = 0.8
support_z_distance = 0.2
wall_thickness = 0.8
-zig_zaggify_infill = True
+zig_zaggify_infill = True
diff --git a/resources/quality/beamup_s/beamup_s_fine.inst.cfg b/resources/quality/beamup_s/beamup_s_fine.inst.cfg
index c68f854536..9f6686487e 100644
--- a/resources/quality/beamup_s/beamup_s_fine.inst.cfg
+++ b/resources/quality/beamup_s/beamup_s_fine.inst.cfg
@@ -1,18 +1,18 @@
-[general]
-version = 4
-name = BeamUp S Fine
-definition = beamup_s
-
-[metadata]
-setting_version = 10
-type = quality
-quality_type = normal
-weight = 0
-material = generic_pla
-
-[values]
-layer_height = 0.1
-adhesion_type = brim
+[general]
+version = 4
+name = BeamUp S Fine
+definition = beamup_s
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = normal
+weight = 0
+material = generic_pla
+
+[values]
+layer_height = 0.1
+adhesion_type = brim
brim_line_count = 5
infill_before_walls = False
initial_layer_line_width_factor = 120.0
@@ -37,4 +37,4 @@ support_interface_skip_height = 0.10
support_offset = 0.8
support_z_distance = 0.2
wall_thickness = 0.8
-zig_zaggify_infill = True
+zig_zaggify_infill = True
diff --git a/resources/quality/beamup_s/beamup_s_normal.inst.cfg b/resources/quality/beamup_s/beamup_s_normal.inst.cfg
index 7b692d2cb3..f926cb11a8 100644
--- a/resources/quality/beamup_s/beamup_s_normal.inst.cfg
+++ b/resources/quality/beamup_s/beamup_s_normal.inst.cfg
@@ -1,18 +1,18 @@
-[general]
-version = 4
-name = BeamUp S Normal
-definition = beamup_s
-
-[metadata]
-setting_version = 10
-type = quality
-quality_type = fast
-weight = -1
-material = generic_pla
-
-[values]
-layer_height = 0.15
-adhesion_type = brim
+[general]
+version = 4
+name = BeamUp S Normal
+definition = beamup_s
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = fast
+weight = -1
+material = generic_pla
+
+[values]
+layer_height = 0.15
+adhesion_type = brim
brim_line_count = 5
infill_before_walls = False
initial_layer_line_width_factor = 120.0
@@ -37,4 +37,4 @@ support_interface_skip_height = 0.15
support_offset = 0.8
support_z_distance = 0.2
wall_thickness = 0.8
-zig_zaggify_infill = True
+zig_zaggify_infill = True
diff --git a/resources/quality/katihal/alyanx3dp_normal_generic_pla.inst.cfg b/resources/quality/katihal/alyanx3dp_normal_generic_pla.inst.cfg
index 4c79a3ac78..009f6c89bc 100644
--- a/resources/quality/katihal/alyanx3dp_normal_generic_pla.inst.cfg
+++ b/resources/quality/katihal/alyanx3dp_normal_generic_pla.inst.cfg
@@ -4,7 +4,7 @@ definition = alyanx3dp
name = Normal
[metadata]
-setting_version = 6
+setting_version = 13
type = quality
quality_type = alyanx_normal
weight = 2
diff --git a/resources/quality/makeblock/makeblock_mcreate_pla_normal.inst.cfg b/resources/quality/makeblock/makeblock_mcreate_pla_normal.inst.cfg
index 661695cca0..7f3384a29f 100644
--- a/resources/quality/makeblock/makeblock_mcreate_pla_normal.inst.cfg
+++ b/resources/quality/makeblock/makeblock_mcreate_pla_normal.inst.cfg
@@ -4,7 +4,7 @@ name = Fine
definition = makeblock_mcreate
[metadata]
-setting_version = 6
+setting_version = 13
type = quality
quality_type = normal
weight = 0
diff --git a/resources/quality/rigid3d_base/abs/rigid3d_base_abs_adaptive.inst.cfg b/resources/quality/rigid3d_base/abs/rigid3d_base_abs_adaptive.inst.cfg
index de5c97f913..2428d5c64d 100644
--- a/resources/quality/rigid3d_base/abs/rigid3d_base_abs_adaptive.inst.cfg
+++ b/resources/quality/rigid3d_base/abs/rigid3d_base_abs_adaptive.inst.cfg
@@ -4,7 +4,7 @@ name = Dynamic Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = adaptive
material = generic_abs
diff --git a/resources/quality/rigid3d_base/abs/rigid3d_base_abs_good.inst.cfg b/resources/quality/rigid3d_base/abs/rigid3d_base_abs_good.inst.cfg
index 9a49399734..acccc5190b 100644
--- a/resources/quality/rigid3d_base/abs/rigid3d_base_abs_good.inst.cfg
+++ b/resources/quality/rigid3d_base/abs/rigid3d_base_abs_good.inst.cfg
@@ -4,7 +4,7 @@ name = Good Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = good
material = generic_abs
diff --git a/resources/quality/rigid3d_base/abs/rigid3d_base_abs_low.inst.cfg b/resources/quality/rigid3d_base/abs/rigid3d_base_abs_low.inst.cfg
index 2515cc32eb..2971e89ce2 100644
--- a/resources/quality/rigid3d_base/abs/rigid3d_base_abs_low.inst.cfg
+++ b/resources/quality/rigid3d_base/abs/rigid3d_base_abs_low.inst.cfg
@@ -4,7 +4,7 @@ name = Low Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = low
material = generic_abs
diff --git a/resources/quality/rigid3d_base/abs/rigid3d_base_abs_standard.inst.cfg b/resources/quality/rigid3d_base/abs/rigid3d_base_abs_standard.inst.cfg
index 9b140cbb75..95e19fb800 100644
--- a/resources/quality/rigid3d_base/abs/rigid3d_base_abs_standard.inst.cfg
+++ b/resources/quality/rigid3d_base/abs/rigid3d_base_abs_standard.inst.cfg
@@ -4,7 +4,7 @@ name = Standard Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = standard
material = generic_abs
diff --git a/resources/quality/rigid3d_base/abs/rigid3d_base_abs_super.inst.cfg b/resources/quality/rigid3d_base/abs/rigid3d_base_abs_super.inst.cfg
index 55dd8755fb..525a1dca8b 100644
--- a/resources/quality/rigid3d_base/abs/rigid3d_base_abs_super.inst.cfg
+++ b/resources/quality/rigid3d_base/abs/rigid3d_base_abs_super.inst.cfg
@@ -4,7 +4,7 @@ name = Super Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = super
material = generic_abs
diff --git a/resources/quality/rigid3d_base/abs/rigid3d_base_abs_ultra.inst.cfg b/resources/quality/rigid3d_base/abs/rigid3d_base_abs_ultra.inst.cfg
index 748b4d6c50..bb9ac9f1af 100644
--- a/resources/quality/rigid3d_base/abs/rigid3d_base_abs_ultra.inst.cfg
+++ b/resources/quality/rigid3d_base/abs/rigid3d_base_abs_ultra.inst.cfg
@@ -4,7 +4,7 @@ name = Ultra Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = ultra
material = generic_abs
diff --git a/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_adaptive.inst.cfg b/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_adaptive.inst.cfg
index cd2e5804cd..e1b98bdacf 100644
--- a/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_adaptive.inst.cfg
+++ b/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_adaptive.inst.cfg
@@ -4,7 +4,7 @@ name = Dynamic Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = adaptive
material = generic_nylon
diff --git a/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_good.inst.cfg b/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_good.inst.cfg
index 11ecdbf8d7..597f954879 100644
--- a/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_good.inst.cfg
+++ b/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_good.inst.cfg
@@ -4,7 +4,7 @@ name = Good Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = good
material = generic_nylon
diff --git a/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_low.inst.cfg b/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_low.inst.cfg
index d512935d05..d4f71ce09a 100644
--- a/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_low.inst.cfg
+++ b/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_low.inst.cfg
@@ -4,7 +4,7 @@ name = Low Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = low
material = generic_nylon
diff --git a/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_standard.inst.cfg b/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_standard.inst.cfg
index e936714f2c..cf2c326bde 100644
--- a/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_standard.inst.cfg
+++ b/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_standard.inst.cfg
@@ -4,7 +4,7 @@ name = Standard Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = standard
material = generic_nylon
diff --git a/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_super.inst.cfg b/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_super.inst.cfg
index b634af5a7f..76b0e03252 100644
--- a/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_super.inst.cfg
+++ b/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_super.inst.cfg
@@ -4,7 +4,7 @@ name = Super Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = super
material = generic_nylon
diff --git a/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_ultra.inst.cfg b/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_ultra.inst.cfg
index 583d8660f8..ea28a18bf6 100644
--- a/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_ultra.inst.cfg
+++ b/resources/quality/rigid3d_base/nylon/rigid3d_base_nylon_ultra.inst.cfg
@@ -4,7 +4,7 @@ name = Ultra Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = ultra
material = generic_nylon
diff --git a/resources/quality/rigid3d_base/petg/rigid3d_base_petg_adaptive.inst.cfg b/resources/quality/rigid3d_base/petg/rigid3d_base_petg_adaptive.inst.cfg
index ae8de691b7..4cbbac976c 100644
--- a/resources/quality/rigid3d_base/petg/rigid3d_base_petg_adaptive.inst.cfg
+++ b/resources/quality/rigid3d_base/petg/rigid3d_base_petg_adaptive.inst.cfg
@@ -4,7 +4,7 @@ name = Dynamic Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = adaptive
material = generic_petg
diff --git a/resources/quality/rigid3d_base/petg/rigid3d_base_petg_good.inst.cfg b/resources/quality/rigid3d_base/petg/rigid3d_base_petg_good.inst.cfg
index 7a97e15b90..085f63fd29 100644
--- a/resources/quality/rigid3d_base/petg/rigid3d_base_petg_good.inst.cfg
+++ b/resources/quality/rigid3d_base/petg/rigid3d_base_petg_good.inst.cfg
@@ -4,7 +4,7 @@ name = Good Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = good
material = generic_petg
diff --git a/resources/quality/rigid3d_base/petg/rigid3d_base_petg_low.inst.cfg b/resources/quality/rigid3d_base/petg/rigid3d_base_petg_low.inst.cfg
index c3153454b8..441223b259 100644
--- a/resources/quality/rigid3d_base/petg/rigid3d_base_petg_low.inst.cfg
+++ b/resources/quality/rigid3d_base/petg/rigid3d_base_petg_low.inst.cfg
@@ -4,7 +4,7 @@ name = Low Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = low
material = generic_petg
diff --git a/resources/quality/rigid3d_base/petg/rigid3d_base_petg_standard.inst.cfg b/resources/quality/rigid3d_base/petg/rigid3d_base_petg_standard.inst.cfg
index d583ab6514..6eb60cbe30 100644
--- a/resources/quality/rigid3d_base/petg/rigid3d_base_petg_standard.inst.cfg
+++ b/resources/quality/rigid3d_base/petg/rigid3d_base_petg_standard.inst.cfg
@@ -4,7 +4,7 @@ name = Standard Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = standard
material = generic_petg
diff --git a/resources/quality/rigid3d_base/petg/rigid3d_base_petg_super.inst.cfg b/resources/quality/rigid3d_base/petg/rigid3d_base_petg_super.inst.cfg
index cb77ab35d8..ab284f19bd 100644
--- a/resources/quality/rigid3d_base/petg/rigid3d_base_petg_super.inst.cfg
+++ b/resources/quality/rigid3d_base/petg/rigid3d_base_petg_super.inst.cfg
@@ -4,7 +4,7 @@ name = Super Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = super
material = generic_petg
diff --git a/resources/quality/rigid3d_base/petg/rigid3d_base_petg_ultra.inst.cfg b/resources/quality/rigid3d_base/petg/rigid3d_base_petg_ultra.inst.cfg
index 6ab237d97b..d4b0c58c70 100644
--- a/resources/quality/rigid3d_base/petg/rigid3d_base_petg_ultra.inst.cfg
+++ b/resources/quality/rigid3d_base/petg/rigid3d_base_petg_ultra.inst.cfg
@@ -4,7 +4,7 @@ name = Ultra Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = ultra
material = generic_petg
diff --git a/resources/quality/rigid3d_base/pla/rigid3d_base_pla_adaptive.inst.cfg b/resources/quality/rigid3d_base/pla/rigid3d_base_pla_adaptive.inst.cfg
index 67ece9b983..f88063ebd1 100644
--- a/resources/quality/rigid3d_base/pla/rigid3d_base_pla_adaptive.inst.cfg
+++ b/resources/quality/rigid3d_base/pla/rigid3d_base_pla_adaptive.inst.cfg
@@ -4,7 +4,7 @@ name = Dynamic Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = adaptive
material = generic_pla
diff --git a/resources/quality/rigid3d_base/pla/rigid3d_base_pla_good.inst.cfg b/resources/quality/rigid3d_base/pla/rigid3d_base_pla_good.inst.cfg
index ebc48e1e47..2eeed8c565 100644
--- a/resources/quality/rigid3d_base/pla/rigid3d_base_pla_good.inst.cfg
+++ b/resources/quality/rigid3d_base/pla/rigid3d_base_pla_good.inst.cfg
@@ -4,7 +4,7 @@ name = Good Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = good
material = generic_pla
diff --git a/resources/quality/rigid3d_base/pla/rigid3d_base_pla_low.inst.cfg b/resources/quality/rigid3d_base/pla/rigid3d_base_pla_low.inst.cfg
index a2cc3d8ada..6e62844cf4 100644
--- a/resources/quality/rigid3d_base/pla/rigid3d_base_pla_low.inst.cfg
+++ b/resources/quality/rigid3d_base/pla/rigid3d_base_pla_low.inst.cfg
@@ -4,7 +4,7 @@ name = Low Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = low
material = generic_pla
diff --git a/resources/quality/rigid3d_base/pla/rigid3d_base_pla_standard.inst.cfg b/resources/quality/rigid3d_base/pla/rigid3d_base_pla_standard.inst.cfg
index 6f30e132f4..4ffd5305c4 100644
--- a/resources/quality/rigid3d_base/pla/rigid3d_base_pla_standard.inst.cfg
+++ b/resources/quality/rigid3d_base/pla/rigid3d_base_pla_standard.inst.cfg
@@ -4,7 +4,7 @@ name = Standard Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = standard
material = generic_pla
diff --git a/resources/quality/rigid3d_base/pla/rigid3d_base_pla_super.inst.cfg b/resources/quality/rigid3d_base/pla/rigid3d_base_pla_super.inst.cfg
index 075aaa18e4..8487f78f55 100644
--- a/resources/quality/rigid3d_base/pla/rigid3d_base_pla_super.inst.cfg
+++ b/resources/quality/rigid3d_base/pla/rigid3d_base_pla_super.inst.cfg
@@ -4,7 +4,7 @@ name = Super Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = super
material = generic_pla
diff --git a/resources/quality/rigid3d_base/pla/rigid3d_base_pla_ultra.inst.cfg b/resources/quality/rigid3d_base/pla/rigid3d_base_pla_ultra.inst.cfg
index 7460b92cb3..e9886bf1b5 100644
--- a/resources/quality/rigid3d_base/pla/rigid3d_base_pla_ultra.inst.cfg
+++ b/resources/quality/rigid3d_base/pla/rigid3d_base_pla_ultra.inst.cfg
@@ -4,7 +4,7 @@ name = Ultra Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = ultra
material = generic_pla
diff --git a/resources/quality/rigid3d_base/rigid3d_base_global_adaptive.inst.cfg b/resources/quality/rigid3d_base/rigid3d_base_global_adaptive.inst.cfg
index 2ca4e97ba9..9aa132a769 100644
--- a/resources/quality/rigid3d_base/rigid3d_base_global_adaptive.inst.cfg
+++ b/resources/quality/rigid3d_base/rigid3d_base_global_adaptive.inst.cfg
@@ -4,7 +4,7 @@ name = Dynamic Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = adaptive
weight = -6
diff --git a/resources/quality/rigid3d_base/rigid3d_base_global_good.inst.cfg b/resources/quality/rigid3d_base/rigid3d_base_global_good.inst.cfg
index 1e5da51f73..8bc628eeec 100644
--- a/resources/quality/rigid3d_base/rigid3d_base_global_good.inst.cfg
+++ b/resources/quality/rigid3d_base/rigid3d_base_global_good.inst.cfg
@@ -4,7 +4,7 @@ name = Good Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = good
weight = -2
diff --git a/resources/quality/rigid3d_base/rigid3d_base_global_low.inst.cfg b/resources/quality/rigid3d_base/rigid3d_base_global_low.inst.cfg
index f93f3c83df..7de29f815d 100644
--- a/resources/quality/rigid3d_base/rigid3d_base_global_low.inst.cfg
+++ b/resources/quality/rigid3d_base/rigid3d_base_global_low.inst.cfg
@@ -4,7 +4,7 @@ name = Low Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = low
weight = -4
diff --git a/resources/quality/rigid3d_base/rigid3d_base_global_standard.inst.cfg b/resources/quality/rigid3d_base/rigid3d_base_global_standard.inst.cfg
index 0fce643397..6cb9e65c33 100644
--- a/resources/quality/rigid3d_base/rigid3d_base_global_standard.inst.cfg
+++ b/resources/quality/rigid3d_base/rigid3d_base_global_standard.inst.cfg
@@ -4,7 +4,7 @@ name = Standard Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = standard
weight = -3
diff --git a/resources/quality/rigid3d_base/rigid3d_base_global_super.inst.cfg b/resources/quality/rigid3d_base/rigid3d_base_global_super.inst.cfg
index 5ff420ea23..b160a086b9 100644
--- a/resources/quality/rigid3d_base/rigid3d_base_global_super.inst.cfg
+++ b/resources/quality/rigid3d_base/rigid3d_base_global_super.inst.cfg
@@ -4,7 +4,7 @@ name = Super Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = super
weight = -1
diff --git a/resources/quality/rigid3d_base/rigid3d_base_global_ultra.inst.cfg b/resources/quality/rigid3d_base/rigid3d_base_global_ultra.inst.cfg
index 6f96648312..9bc40461ee 100644
--- a/resources/quality/rigid3d_base/rigid3d_base_global_ultra.inst.cfg
+++ b/resources/quality/rigid3d_base/rigid3d_base_global_ultra.inst.cfg
@@ -4,7 +4,7 @@ name = Ultra Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = ultra
weight = 0
diff --git a/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_adaptive.inst.cfg b/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_adaptive.inst.cfg
index bc93daa751..e4dda56ce2 100644
--- a/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_adaptive.inst.cfg
+++ b/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_adaptive.inst.cfg
@@ -4,7 +4,7 @@ name = Dynamic Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = adaptive
material = generic_tpu
diff --git a/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_good.inst.cfg b/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_good.inst.cfg
index 0f0b3fad82..8cb55d02de 100644
--- a/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_good.inst.cfg
+++ b/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_good.inst.cfg
@@ -4,7 +4,7 @@ name = Good Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = good
material = generic_tpu
diff --git a/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_low.inst.cfg b/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_low.inst.cfg
index c0653ede27..3a7bfbf138 100644
--- a/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_low.inst.cfg
+++ b/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_low.inst.cfg
@@ -4,7 +4,7 @@ name = Low Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = low
material = generic_tpu
diff --git a/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_standard.inst.cfg b/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_standard.inst.cfg
index a0aa088d5b..392c3aa303 100644
--- a/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_standard.inst.cfg
+++ b/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_standard.inst.cfg
@@ -4,7 +4,7 @@ name = Standard Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = standard
material = generic_tpu
diff --git a/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_super.inst.cfg b/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_super.inst.cfg
index 23a6e77aca..29e1565547 100644
--- a/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_super.inst.cfg
+++ b/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_super.inst.cfg
@@ -4,7 +4,7 @@ name = Super Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = super
material = generic_tpu
diff --git a/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_ultra.inst.cfg b/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_ultra.inst.cfg
index 206a8c7c01..92f49140bd 100644
--- a/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_ultra.inst.cfg
+++ b/resources/quality/rigid3d_base/tpu/rigid3d_base_tpu_ultra.inst.cfg
@@ -4,7 +4,7 @@ name = Ultra Quality
definition = rigid3d_base
[metadata]
-setting_version = 9
+setting_version = 13
type = quality
quality_type = ultra
material = generic_tpu
diff --git a/resources/quality/uni_base/abs/nozzle_0.30/abs_nozzle_0.30_layer_0.10.inst.cfg b/resources/quality/uni_base/abs/nozzle_0.30/abs_nozzle_0.30_layer_0.10.inst.cfg
new file mode 100644
index 0000000000..fdac6ec6c3
--- /dev/null
+++ b/resources/quality/uni_base/abs/nozzle_0.30/abs_nozzle_0.30_layer_0.10.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = abs_n0.30_l0.10
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q010
+material = generic_abs
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/abs/nozzle_0.30/abs_nozzle_0.30_layer_0.15.inst.cfg b/resources/quality/uni_base/abs/nozzle_0.30/abs_nozzle_0.30_layer_0.15.inst.cfg
new file mode 100644
index 0000000000..fb87193d45
--- /dev/null
+++ b/resources/quality/uni_base/abs/nozzle_0.30/abs_nozzle_0.30_layer_0.15.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = abs_n0.30_l0.15
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q015
+material = generic_abs
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/abs/nozzle_0.30/abs_nozzle_0.30_layer_0.20.inst.cfg b/resources/quality/uni_base/abs/nozzle_0.30/abs_nozzle_0.30_layer_0.20.inst.cfg
new file mode 100644
index 0000000000..33aebeae33
--- /dev/null
+++ b/resources/quality/uni_base/abs/nozzle_0.30/abs_nozzle_0.30_layer_0.20.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = abs_n0.30_l0.20
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q020
+material = generic_abs
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/abs/nozzle_0.30/abs_nozzle_0.30_layer_0.25.inst.cfg b/resources/quality/uni_base/abs/nozzle_0.30/abs_nozzle_0.30_layer_0.25.inst.cfg
new file mode 100644
index 0000000000..833027057d
--- /dev/null
+++ b/resources/quality/uni_base/abs/nozzle_0.30/abs_nozzle_0.30_layer_0.25.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = abs_n0.30_l0.25
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q025
+material = generic_abs
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/abs/nozzle_0.40/abs_nozzle_0.40_layer_0.10.inst.cfg b/resources/quality/uni_base/abs/nozzle_0.40/abs_nozzle_0.40_layer_0.10.inst.cfg
new file mode 100644
index 0000000000..f77f2165f4
--- /dev/null
+++ b/resources/quality/uni_base/abs/nozzle_0.40/abs_nozzle_0.40_layer_0.10.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = abs_n0.40_l0.10
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q010
+material = generic_abs
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/abs/nozzle_0.40/abs_nozzle_0.40_layer_0.15.inst.cfg b/resources/quality/uni_base/abs/nozzle_0.40/abs_nozzle_0.40_layer_0.15.inst.cfg
new file mode 100644
index 0000000000..52abd3f603
--- /dev/null
+++ b/resources/quality/uni_base/abs/nozzle_0.40/abs_nozzle_0.40_layer_0.15.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = abs_n0.40_l0.15
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q015
+material = generic_abs
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/abs/nozzle_0.40/abs_nozzle_0.40_layer_0.20.inst.cfg b/resources/quality/uni_base/abs/nozzle_0.40/abs_nozzle_0.40_layer_0.20.inst.cfg
new file mode 100644
index 0000000000..380ec9ae1f
--- /dev/null
+++ b/resources/quality/uni_base/abs/nozzle_0.40/abs_nozzle_0.40_layer_0.20.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = abs_n0.40_l0.20
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q020
+material = generic_abs
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/abs/nozzle_0.40/abs_nozzle_0.40_layer_0.25.inst.cfg b/resources/quality/uni_base/abs/nozzle_0.40/abs_nozzle_0.40_layer_0.25.inst.cfg
new file mode 100644
index 0000000000..f9b302e720
--- /dev/null
+++ b/resources/quality/uni_base/abs/nozzle_0.40/abs_nozzle_0.40_layer_0.25.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = abs_n0.40_l0.25
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q025
+material = generic_abs
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/abs/nozzle_0.40/abs_nozzle_0.40_layer_0.30.inst.cfg b/resources/quality/uni_base/abs/nozzle_0.40/abs_nozzle_0.40_layer_0.30.inst.cfg
new file mode 100644
index 0000000000..c3bac2ae22
--- /dev/null
+++ b/resources/quality/uni_base/abs/nozzle_0.40/abs_nozzle_0.40_layer_0.30.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = abs_n0.40_l0.30
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q030
+material = generic_abs
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/abs/nozzle_0.50/abs_nozzle_0.50_layer_0.15.inst.cfg b/resources/quality/uni_base/abs/nozzle_0.50/abs_nozzle_0.50_layer_0.15.inst.cfg
new file mode 100644
index 0000000000..e37ee92fe0
--- /dev/null
+++ b/resources/quality/uni_base/abs/nozzle_0.50/abs_nozzle_0.50_layer_0.15.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = abs_n0.50_l0.15
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q015
+material = generic_abs
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/abs/nozzle_0.50/abs_nozzle_0.50_layer_0.20.inst.cfg b/resources/quality/uni_base/abs/nozzle_0.50/abs_nozzle_0.50_layer_0.20.inst.cfg
new file mode 100644
index 0000000000..ab2779ba3d
--- /dev/null
+++ b/resources/quality/uni_base/abs/nozzle_0.50/abs_nozzle_0.50_layer_0.20.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = abs_n0.50_l0.20
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q020
+material = generic_abs
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/abs/nozzle_0.50/abs_nozzle_0.50_layer_0.25.inst.cfg b/resources/quality/uni_base/abs/nozzle_0.50/abs_nozzle_0.50_layer_0.25.inst.cfg
new file mode 100644
index 0000000000..e68c61c60e
--- /dev/null
+++ b/resources/quality/uni_base/abs/nozzle_0.50/abs_nozzle_0.50_layer_0.25.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = abs_n0.50_l0.25
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q025
+material = generic_abs
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/abs/nozzle_0.50/abs_nozzle_0.50_layer_0.30.inst.cfg b/resources/quality/uni_base/abs/nozzle_0.50/abs_nozzle_0.50_layer_0.30.inst.cfg
new file mode 100644
index 0000000000..6a2b416ab1
--- /dev/null
+++ b/resources/quality/uni_base/abs/nozzle_0.50/abs_nozzle_0.50_layer_0.30.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = abs_n0.50_l0.30
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q030
+material = generic_abs
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/abs/nozzle_0.50/abs_nozzle_0.50_layer_0.35.inst.cfg b/resources/quality/uni_base/abs/nozzle_0.50/abs_nozzle_0.50_layer_0.35.inst.cfg
new file mode 100644
index 0000000000..7d4fbaafab
--- /dev/null
+++ b/resources/quality/uni_base/abs/nozzle_0.50/abs_nozzle_0.50_layer_0.35.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = abs_n0.50_l0.35
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q035
+material = generic_abs
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/hips/nozzle_0.30/hips_nozzle_0.30_layer_0.10.inst.cfg b/resources/quality/uni_base/hips/nozzle_0.30/hips_nozzle_0.30_layer_0.10.inst.cfg
new file mode 100644
index 0000000000..b1a1140f77
--- /dev/null
+++ b/resources/quality/uni_base/hips/nozzle_0.30/hips_nozzle_0.30_layer_0.10.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = hips_n0.30_l0.10
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q010
+material = generic_hips
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/hips/nozzle_0.30/hips_nozzle_0.30_layer_0.15.inst.cfg b/resources/quality/uni_base/hips/nozzle_0.30/hips_nozzle_0.30_layer_0.15.inst.cfg
new file mode 100644
index 0000000000..98f1627693
--- /dev/null
+++ b/resources/quality/uni_base/hips/nozzle_0.30/hips_nozzle_0.30_layer_0.15.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = hips_n0.30_l0.15
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q015
+material = generic_hips
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/hips/nozzle_0.30/hips_nozzle_0.30_layer_0.20.inst.cfg b/resources/quality/uni_base/hips/nozzle_0.30/hips_nozzle_0.30_layer_0.20.inst.cfg
new file mode 100644
index 0000000000..674b886d62
--- /dev/null
+++ b/resources/quality/uni_base/hips/nozzle_0.30/hips_nozzle_0.30_layer_0.20.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = hips_n0.30_l0.20
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q020
+material = generic_hips
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/hips/nozzle_0.30/hips_nozzle_0.30_layer_0.25.inst.cfg b/resources/quality/uni_base/hips/nozzle_0.30/hips_nozzle_0.30_layer_0.25.inst.cfg
new file mode 100644
index 0000000000..26c9fe9895
--- /dev/null
+++ b/resources/quality/uni_base/hips/nozzle_0.30/hips_nozzle_0.30_layer_0.25.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = hips_n0.30_l0.25
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q025
+material = generic_hips
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/hips/nozzle_0.40/hips_nozzle_0.40_layer_0.10.inst.cfg b/resources/quality/uni_base/hips/nozzle_0.40/hips_nozzle_0.40_layer_0.10.inst.cfg
new file mode 100644
index 0000000000..f74c43a9bb
--- /dev/null
+++ b/resources/quality/uni_base/hips/nozzle_0.40/hips_nozzle_0.40_layer_0.10.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = hips_n0.40_l0.10
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q010
+material = generic_hips
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/hips/nozzle_0.40/hips_nozzle_0.40_layer_0.15.inst.cfg b/resources/quality/uni_base/hips/nozzle_0.40/hips_nozzle_0.40_layer_0.15.inst.cfg
new file mode 100644
index 0000000000..9a86e6741e
--- /dev/null
+++ b/resources/quality/uni_base/hips/nozzle_0.40/hips_nozzle_0.40_layer_0.15.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = hips_n0.40_l0.15
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q015
+material = generic_hips
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/hips/nozzle_0.40/hips_nozzle_0.40_layer_0.20.inst.cfg b/resources/quality/uni_base/hips/nozzle_0.40/hips_nozzle_0.40_layer_0.20.inst.cfg
new file mode 100644
index 0000000000..d8eca51fb8
--- /dev/null
+++ b/resources/quality/uni_base/hips/nozzle_0.40/hips_nozzle_0.40_layer_0.20.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = hips_n0.40_l0.20
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q020
+material = generic_hips
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/hips/nozzle_0.40/hips_nozzle_0.40_layer_0.25.inst.cfg b/resources/quality/uni_base/hips/nozzle_0.40/hips_nozzle_0.40_layer_0.25.inst.cfg
new file mode 100644
index 0000000000..0e446cea8d
--- /dev/null
+++ b/resources/quality/uni_base/hips/nozzle_0.40/hips_nozzle_0.40_layer_0.25.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = hips_n0.40_l0.25
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q025
+material = generic_abs
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/hips/nozzle_0.40/hips_nozzle_0.40_layer_0.30.inst.cfg b/resources/quality/uni_base/hips/nozzle_0.40/hips_nozzle_0.40_layer_0.30.inst.cfg
new file mode 100644
index 0000000000..2dc24d840c
--- /dev/null
+++ b/resources/quality/uni_base/hips/nozzle_0.40/hips_nozzle_0.40_layer_0.30.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = hips_n0.40_l0.30
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q030
+material = generic_hips
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/hips/nozzle_0.50/hips_nozzle_0.50_layer_0.15.inst.cfg b/resources/quality/uni_base/hips/nozzle_0.50/hips_nozzle_0.50_layer_0.15.inst.cfg
new file mode 100644
index 0000000000..99334b26d0
--- /dev/null
+++ b/resources/quality/uni_base/hips/nozzle_0.50/hips_nozzle_0.50_layer_0.15.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = hips_n0.50_l0.15
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q015
+material = generic_hips
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/hips/nozzle_0.50/hips_nozzle_0.50_layer_0.20.inst.cfg b/resources/quality/uni_base/hips/nozzle_0.50/hips_nozzle_0.50_layer_0.20.inst.cfg
new file mode 100644
index 0000000000..5eb251edb9
--- /dev/null
+++ b/resources/quality/uni_base/hips/nozzle_0.50/hips_nozzle_0.50_layer_0.20.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = hips_n0.50_l0.20
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q020
+material = generic_hips
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/hips/nozzle_0.50/hips_nozzle_0.50_layer_0.25.inst.cfg b/resources/quality/uni_base/hips/nozzle_0.50/hips_nozzle_0.50_layer_0.25.inst.cfg
new file mode 100644
index 0000000000..1201588fa2
--- /dev/null
+++ b/resources/quality/uni_base/hips/nozzle_0.50/hips_nozzle_0.50_layer_0.25.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = hips_n0.50_l0.25
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q025
+material = generic_hips
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/hips/nozzle_0.50/hips_nozzle_0.50_layer_0.30.inst.cfg b/resources/quality/uni_base/hips/nozzle_0.50/hips_nozzle_0.50_layer_0.30.inst.cfg
new file mode 100644
index 0000000000..d3920eddfb
--- /dev/null
+++ b/resources/quality/uni_base/hips/nozzle_0.50/hips_nozzle_0.50_layer_0.30.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = hips_n0.50_l0.30
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q030
+material = generic_hips
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/hips/nozzle_0.50/hips_nozzle_0.50_layer_0.35.inst.cfg b/resources/quality/uni_base/hips/nozzle_0.50/hips_nozzle_0.50_layer_0.35.inst.cfg
new file mode 100644
index 0000000000..7c3fe1cba1
--- /dev/null
+++ b/resources/quality/uni_base/hips/nozzle_0.50/hips_nozzle_0.50_layer_0.35.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = hips_n0.50_l0.35
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q035
+material = generic_hips
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/layer_0.05.inst.cfg b/resources/quality/uni_base/layer_0.05.inst.cfg
new file mode 100644
index 0000000000..95f68941fd
--- /dev/null
+++ b/resources/quality/uni_base/layer_0.05.inst.cfg
@@ -0,0 +1,15 @@
+[general]
+version = 4
+name = Ultra Quality
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q005
+weight = -1
+global_quality = True
+
+[values]
+layer_height = 0.05
+layer_height_0 = 0.12
diff --git a/resources/quality/uni_base/layer_0.10.inst.cfg b/resources/quality/uni_base/layer_0.10.inst.cfg
new file mode 100644
index 0000000000..c91b1ef8ff
--- /dev/null
+++ b/resources/quality/uni_base/layer_0.10.inst.cfg
@@ -0,0 +1,15 @@
+[general]
+version = 4
+name = Super Quality
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q010
+weight = -2
+global_quality = True
+
+[values]
+layer_height = 0.10
+layer_height_0 = 0.12
diff --git a/resources/quality/uni_base/layer_0.15.inst.cfg b/resources/quality/uni_base/layer_0.15.inst.cfg
new file mode 100644
index 0000000000..5b4f06a56a
--- /dev/null
+++ b/resources/quality/uni_base/layer_0.15.inst.cfg
@@ -0,0 +1,15 @@
+[general]
+version = 4
+name = Fast Super Quality
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q015
+weight = -3
+global_quality = True
+
+[values]
+layer_height = 0.15
+layer_height_0 = 0.15
diff --git a/resources/quality/uni_base/layer_0.20.inst.cfg b/resources/quality/uni_base/layer_0.20.inst.cfg
new file mode 100644
index 0000000000..50b992190c
--- /dev/null
+++ b/resources/quality/uni_base/layer_0.20.inst.cfg
@@ -0,0 +1,15 @@
+[general]
+version = 4
+name = Standart Quality
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q020
+weight = -4
+global_quality = True
+
+[values]
+layer_height = 0.20
+layer_height_0 = 0.20
diff --git a/resources/quality/uni_base/layer_0.25.inst.cfg b/resources/quality/uni_base/layer_0.25.inst.cfg
new file mode 100644
index 0000000000..046e02400c
--- /dev/null
+++ b/resources/quality/uni_base/layer_0.25.inst.cfg
@@ -0,0 +1,15 @@
+[general]
+version = 4
+name = Fast Standart Quality
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q025
+weight = -5
+global_quality = True
+
+[values]
+layer_height = 0.25
+layer_height_0 = 0.25
diff --git a/resources/quality/uni_base/layer_0.30.inst.cfg b/resources/quality/uni_base/layer_0.30.inst.cfg
new file mode 100644
index 0000000000..3a1c687751
--- /dev/null
+++ b/resources/quality/uni_base/layer_0.30.inst.cfg
@@ -0,0 +1,15 @@
+[general]
+version = 4
+name = Fast Print Quality
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q030
+weight = -6
+global_quality = True
+
+[values]
+layer_height = 0.30
+layer_height_0 = 0.30
diff --git a/resources/quality/uni_base/layer_0.35.inst.cfg b/resources/quality/uni_base/layer_0.35.inst.cfg
new file mode 100644
index 0000000000..d101099eb8
--- /dev/null
+++ b/resources/quality/uni_base/layer_0.35.inst.cfg
@@ -0,0 +1,15 @@
+[general]
+version = 4
+name = Draft Quality
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q035
+weight = -7
+global_quality = True
+
+[values]
+layer_height = 0.35
+layer_height_0 = 0.35
diff --git a/resources/quality/uni_base/layer_0.40.inst.cfg b/resources/quality/uni_base/layer_0.40.inst.cfg
new file mode 100644
index 0000000000..058971e5e5
--- /dev/null
+++ b/resources/quality/uni_base/layer_0.40.inst.cfg
@@ -0,0 +1,15 @@
+[general]
+version = 4
+name = Poor Draft Quality
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q040
+weight = -8
+global_quality = True
+
+[values]
+layer_height = 0.40
+layer_height_0 = 0.40
diff --git a/resources/quality/uni_base/petg/nozzle_0.30/petg_nozzle_0.30_layer_0.10.inst.cfg b/resources/quality/uni_base/petg/nozzle_0.30/petg_nozzle_0.30_layer_0.10.inst.cfg
new file mode 100644
index 0000000000..b87ae27bae
--- /dev/null
+++ b/resources/quality/uni_base/petg/nozzle_0.30/petg_nozzle_0.30_layer_0.10.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = petg_n0.30_l0.10
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q010
+material = generic_petg
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/petg/nozzle_0.30/petg_nozzle_0.30_layer_0.15.inst.cfg b/resources/quality/uni_base/petg/nozzle_0.30/petg_nozzle_0.30_layer_0.15.inst.cfg
new file mode 100644
index 0000000000..59df30a066
--- /dev/null
+++ b/resources/quality/uni_base/petg/nozzle_0.30/petg_nozzle_0.30_layer_0.15.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = petg_n0.30_l0.15
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q015
+material = generic_petg
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/petg/nozzle_0.30/petg_nozzle_0.30_layer_0.20.inst.cfg b/resources/quality/uni_base/petg/nozzle_0.30/petg_nozzle_0.30_layer_0.20.inst.cfg
new file mode 100644
index 0000000000..5a014746da
--- /dev/null
+++ b/resources/quality/uni_base/petg/nozzle_0.30/petg_nozzle_0.30_layer_0.20.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = petg_n0.30_l0.20
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q020
+material = generic_petg
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/petg/nozzle_0.30/petg_nozzle_0.30_layer_0.25.inst.cfg b/resources/quality/uni_base/petg/nozzle_0.30/petg_nozzle_0.30_layer_0.25.inst.cfg
new file mode 100644
index 0000000000..19d2d3c419
--- /dev/null
+++ b/resources/quality/uni_base/petg/nozzle_0.30/petg_nozzle_0.30_layer_0.25.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = petg_n0.30_l0.25
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q025
+material = generic_petg
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/petg/nozzle_0.40/petg_nozzle_0.40_layer_0.10.inst.cfg b/resources/quality/uni_base/petg/nozzle_0.40/petg_nozzle_0.40_layer_0.10.inst.cfg
new file mode 100644
index 0000000000..cbe5123298
--- /dev/null
+++ b/resources/quality/uni_base/petg/nozzle_0.40/petg_nozzle_0.40_layer_0.10.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = petg_n0.40_l0.10
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q010
+material = generic_petg
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/petg/nozzle_0.40/petg_nozzle_0.40_layer_0.15.inst.cfg b/resources/quality/uni_base/petg/nozzle_0.40/petg_nozzle_0.40_layer_0.15.inst.cfg
new file mode 100644
index 0000000000..6a278850bb
--- /dev/null
+++ b/resources/quality/uni_base/petg/nozzle_0.40/petg_nozzle_0.40_layer_0.15.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = petg_n0.40_l0.15
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q015
+material = generic_petg
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/petg/nozzle_0.40/petg_nozzle_0.40_layer_0.20.inst.cfg b/resources/quality/uni_base/petg/nozzle_0.40/petg_nozzle_0.40_layer_0.20.inst.cfg
new file mode 100644
index 0000000000..a21993d92a
--- /dev/null
+++ b/resources/quality/uni_base/petg/nozzle_0.40/petg_nozzle_0.40_layer_0.20.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = petg_n0.40_l0.20
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q020
+material = generic_petg
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/petg/nozzle_0.40/petg_nozzle_0.40_layer_0.25.inst.cfg b/resources/quality/uni_base/petg/nozzle_0.40/petg_nozzle_0.40_layer_0.25.inst.cfg
new file mode 100644
index 0000000000..18c19dcc4d
--- /dev/null
+++ b/resources/quality/uni_base/petg/nozzle_0.40/petg_nozzle_0.40_layer_0.25.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = petg_n0.40_l0.25
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q025
+material = generic_petg
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/petg/nozzle_0.40/petg_nozzle_0.40_layer_0.30.inst.cfg b/resources/quality/uni_base/petg/nozzle_0.40/petg_nozzle_0.40_layer_0.30.inst.cfg
new file mode 100644
index 0000000000..1211f1839e
--- /dev/null
+++ b/resources/quality/uni_base/petg/nozzle_0.40/petg_nozzle_0.40_layer_0.30.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = petg_n0.40_l0.30
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q030
+material = generic_petg
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/petg/nozzle_0.50/petg_nozzle_0.50_layer_0.15.inst.cfg b/resources/quality/uni_base/petg/nozzle_0.50/petg_nozzle_0.50_layer_0.15.inst.cfg
new file mode 100644
index 0000000000..ecda33f21d
--- /dev/null
+++ b/resources/quality/uni_base/petg/nozzle_0.50/petg_nozzle_0.50_layer_0.15.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = petg_n0.50_l0.15
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q015
+material = generic_petg
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/petg/nozzle_0.50/petg_nozzle_0.50_layer_0.20.inst.cfg b/resources/quality/uni_base/petg/nozzle_0.50/petg_nozzle_0.50_layer_0.20.inst.cfg
new file mode 100644
index 0000000000..a1f01b23e1
--- /dev/null
+++ b/resources/quality/uni_base/petg/nozzle_0.50/petg_nozzle_0.50_layer_0.20.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = petg_n0.50_l0.20
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q020
+material = generic_petg
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/petg/nozzle_0.50/petg_nozzle_0.50_layer_0.25.inst.cfg b/resources/quality/uni_base/petg/nozzle_0.50/petg_nozzle_0.50_layer_0.25.inst.cfg
new file mode 100644
index 0000000000..a638db8517
--- /dev/null
+++ b/resources/quality/uni_base/petg/nozzle_0.50/petg_nozzle_0.50_layer_0.25.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = petg_n0.50_l0.25
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q025
+material = generic_petg
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/petg/nozzle_0.50/petg_nozzle_0.50_layer_0.30.inst.cfg b/resources/quality/uni_base/petg/nozzle_0.50/petg_nozzle_0.50_layer_0.30.inst.cfg
new file mode 100644
index 0000000000..3b501c6e67
--- /dev/null
+++ b/resources/quality/uni_base/petg/nozzle_0.50/petg_nozzle_0.50_layer_0.30.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = petg_n0.50_l0.30
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q030
+material = generic_petg
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/petg/nozzle_0.50/petg_nozzle_0.50_layer_0.35.inst.cfg b/resources/quality/uni_base/petg/nozzle_0.50/petg_nozzle_0.50_layer_0.35.inst.cfg
new file mode 100644
index 0000000000..2a6012fea1
--- /dev/null
+++ b/resources/quality/uni_base/petg/nozzle_0.50/petg_nozzle_0.50_layer_0.35.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = petg_n0.50_l0.35
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q035
+material = generic_petg
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/pla/nozzle_0.30/pla_nozzle_0.30_layer_0.10.inst.cfg b/resources/quality/uni_base/pla/nozzle_0.30/pla_nozzle_0.30_layer_0.10.inst.cfg
new file mode 100644
index 0000000000..2609251b2d
--- /dev/null
+++ b/resources/quality/uni_base/pla/nozzle_0.30/pla_nozzle_0.30_layer_0.10.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = pla_n0.30_l0.10
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q010
+material = generic_pla
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/pla/nozzle_0.30/pla_nozzle_0.30_layer_0.15.inst.cfg b/resources/quality/uni_base/pla/nozzle_0.30/pla_nozzle_0.30_layer_0.15.inst.cfg
new file mode 100644
index 0000000000..d595307edb
--- /dev/null
+++ b/resources/quality/uni_base/pla/nozzle_0.30/pla_nozzle_0.30_layer_0.15.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = pla_n0.30_l0.15
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q015
+material = generic_pla
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/pla/nozzle_0.30/pla_nozzle_0.30_layer_0.20.inst.cfg b/resources/quality/uni_base/pla/nozzle_0.30/pla_nozzle_0.30_layer_0.20.inst.cfg
new file mode 100644
index 0000000000..28e6d7c235
--- /dev/null
+++ b/resources/quality/uni_base/pla/nozzle_0.30/pla_nozzle_0.30_layer_0.20.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = pla_n0.30_l0.20
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q020
+material = generic_pla
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/pla/nozzle_0.30/pla_nozzle_0.30_layer_0.25.inst.cfg b/resources/quality/uni_base/pla/nozzle_0.30/pla_nozzle_0.30_layer_0.25.inst.cfg
new file mode 100644
index 0000000000..8dc25196d9
--- /dev/null
+++ b/resources/quality/uni_base/pla/nozzle_0.30/pla_nozzle_0.30_layer_0.25.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = pla_n0.30_l0.25
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q025
+material = generic_pla
+variant = 0.30mm Nozzle
+
+[values]
+wall_thickness = =line_width*4
diff --git a/resources/quality/uni_base/pla/nozzle_0.40/pla_nozzle_0.40_layer_0.10.inst.cfg b/resources/quality/uni_base/pla/nozzle_0.40/pla_nozzle_0.40_layer_0.10.inst.cfg
new file mode 100644
index 0000000000..50ea5e7b60
--- /dev/null
+++ b/resources/quality/uni_base/pla/nozzle_0.40/pla_nozzle_0.40_layer_0.10.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = pla_n0.40_l0.10
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q010
+material = generic_pla
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/pla/nozzle_0.40/pla_nozzle_0.40_layer_0.15.inst.cfg b/resources/quality/uni_base/pla/nozzle_0.40/pla_nozzle_0.40_layer_0.15.inst.cfg
new file mode 100644
index 0000000000..b2aa98d0fa
--- /dev/null
+++ b/resources/quality/uni_base/pla/nozzle_0.40/pla_nozzle_0.40_layer_0.15.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = pla_n0.40_l0.15
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q015
+material = generic_pla
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/pla/nozzle_0.40/pla_nozzle_0.40_layer_0.20.inst.cfg b/resources/quality/uni_base/pla/nozzle_0.40/pla_nozzle_0.40_layer_0.20.inst.cfg
new file mode 100644
index 0000000000..8b9e7cab27
--- /dev/null
+++ b/resources/quality/uni_base/pla/nozzle_0.40/pla_nozzle_0.40_layer_0.20.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = pla_n0.40_l0.20
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q020
+material = generic_pla
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/pla/nozzle_0.40/pla_nozzle_0.40_layer_0.25.inst.cfg b/resources/quality/uni_base/pla/nozzle_0.40/pla_nozzle_0.40_layer_0.25.inst.cfg
new file mode 100644
index 0000000000..41f81dd2bc
--- /dev/null
+++ b/resources/quality/uni_base/pla/nozzle_0.40/pla_nozzle_0.40_layer_0.25.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = pla_n0.40_l0.25
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q025
+material = generic_pla
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/pla/nozzle_0.40/pla_nozzle_0.40_layer_0.30.inst.cfg b/resources/quality/uni_base/pla/nozzle_0.40/pla_nozzle_0.40_layer_0.30.inst.cfg
new file mode 100644
index 0000000000..444b727330
--- /dev/null
+++ b/resources/quality/uni_base/pla/nozzle_0.40/pla_nozzle_0.40_layer_0.30.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = pla_n0.40_l0.30
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q030
+material = generic_pla
+variant = 0.40mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/pla/nozzle_0.50/pla_nozzle_0.50_layer_0.15.inst.cfg b/resources/quality/uni_base/pla/nozzle_0.50/pla_nozzle_0.50_layer_0.15.inst.cfg
new file mode 100644
index 0000000000..662f9d81f2
--- /dev/null
+++ b/resources/quality/uni_base/pla/nozzle_0.50/pla_nozzle_0.50_layer_0.15.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = pla_n0.50_l0.15
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q015
+material = generic_pla
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/pla/nozzle_0.50/pla_nozzle_0.50_layer_0.20.inst.cfg b/resources/quality/uni_base/pla/nozzle_0.50/pla_nozzle_0.50_layer_0.20.inst.cfg
new file mode 100644
index 0000000000..9358246ccb
--- /dev/null
+++ b/resources/quality/uni_base/pla/nozzle_0.50/pla_nozzle_0.50_layer_0.20.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = pla_n0.50_l0.20
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q020
+material = generic_pla
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/pla/nozzle_0.50/pla_nozzle_0.50_layer_0.25.inst.cfg b/resources/quality/uni_base/pla/nozzle_0.50/pla_nozzle_0.50_layer_0.25.inst.cfg
new file mode 100644
index 0000000000..836ba33cec
--- /dev/null
+++ b/resources/quality/uni_base/pla/nozzle_0.50/pla_nozzle_0.50_layer_0.25.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = pla_n0.50_l0.25
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q025
+material = generic_pla
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/pla/nozzle_0.50/pla_nozzle_0.50_layer_0.30.inst.cfg b/resources/quality/uni_base/pla/nozzle_0.50/pla_nozzle_0.50_layer_0.30.inst.cfg
new file mode 100644
index 0000000000..c75972b711
--- /dev/null
+++ b/resources/quality/uni_base/pla/nozzle_0.50/pla_nozzle_0.50_layer_0.30.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = pla_n0.50_l0.30
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q030
+material = generic_pla
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/quality/uni_base/pla/nozzle_0.50/pla_nozzle_0.50_layer_0.35.inst.cfg b/resources/quality/uni_base/pla/nozzle_0.50/pla_nozzle_0.50_layer_0.35.inst.cfg
new file mode 100644
index 0000000000..cfc8e68182
--- /dev/null
+++ b/resources/quality/uni_base/pla/nozzle_0.50/pla_nozzle_0.50_layer_0.35.inst.cfg
@@ -0,0 +1,14 @@
+[general]
+version = 4
+name = pla_n0.50_l0.35
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = quality
+quality_type = q035
+material = generic_pla
+variant = 0.50mm Nozzle
+
+[values]
+wall_thickness = =line_width*3
diff --git a/resources/shaders/overhang.shader b/resources/shaders/overhang.shader
index b73ed3c701..4add78b531 100644
--- a/resources/shaders/overhang.shader
+++ b/resources/shaders/overhang.shader
@@ -38,6 +38,8 @@ fragment =
varying highp vec3 f_vertex;
varying highp vec3 f_normal;
+ uniform lowp float u_renderError;
+
float round(float f)
{
return sign(f) * floor(abs(f) + 0.5);
@@ -66,8 +68,8 @@ fragment =
finalColor = (-normal.y > u_overhangAngle) ? u_overhangColor : finalColor;
- vec3 grid = vec3(f_vertex.x - round(f_vertex.x), f_vertex.y - round(f_vertex.y), f_vertex.z - round(f_vertex.z));
- finalColor.a = dot(grid, grid) < 0.245 ? 0.667 : 1.0;
+ vec3 grid = vec3(f_vertex.x - floor(f_vertex.x - 0.5), f_vertex.y - floor(f_vertex.y - 0.5), f_vertex.z - floor(f_vertex.z - 0.5));
+ finalColor.a = (u_renderError > 0.5) && dot(grid, grid) < 0.245 ? 0.667 : 1.0;
gl_FragColor = finalColor;
}
@@ -104,6 +106,7 @@ fragment41core =
uniform highp vec3 u_lightPosition;
uniform mediump float u_shininess;
uniform highp vec3 u_viewPosition;
+ uniform lowp float u_renderError;
uniform lowp float u_overhangAngle;
uniform lowp vec4 u_overhangColor;
@@ -139,9 +142,8 @@ fragment41core =
finalColor = (u_faceId != gl_PrimitiveID) ? ((-normal.y > u_overhangAngle) ? u_overhangColor : finalColor) : u_faceColor;
frag_color = finalColor;
-
vec3 grid = f_vertex - round(f_vertex);
- frag_color.a = dot(grid, grid) < 0.245 ? 0.667 : 1.0;
+ frag_color.a = (u_renderError > 0.5) && dot(grid, grid) < 0.245 ? 0.667 : 1.0;
}
[defaults]
@@ -151,6 +153,7 @@ u_specularColor = [0.4, 0.4, 0.4, 1.0]
u_overhangColor = [1.0, 0.0, 0.0, 1.0]
u_faceColor = [0.0, 0.0, 1.0, 1.0]
u_shininess = 20.0
+u_renderError = 1.0
[bindings]
u_modelMatrix = model_matrix
diff --git a/resources/shaders/xray_composite.shader b/resources/shaders/xray_composite.shader
index c955d4fc18..6619b00544 100644
--- a/resources/shaders/xray_composite.shader
+++ b/resources/shaders/xray_composite.shader
@@ -30,6 +30,7 @@ fragment =
uniform vec4 u_outline_color;
uniform vec4 u_background_color;
uniform float u_xray_error_strength;
+ uniform float u_flat_error_color_mix;
const vec3 x_axis = vec3(1.0, 0.0, 0.0);
const vec3 y_axis = vec3(0.0, 1.0, 0.0);
@@ -73,7 +74,7 @@ fragment =
float rest = mod(intersection_count + .01, 2.0);
if (rest > 1.0 && rest < 1.5 && intersection_count < 49.0)
{
- result = vec4(shiftHue(layer0.rgb, hue_shift), result.a);
+ result = mix(vec4(shiftHue(layer0.rgb, hue_shift), result.a), vec4(1.,0.,0.,1.), u_flat_error_color_mix);
}
vec4 sum = vec4(0.0);
@@ -122,6 +123,7 @@ fragment41core =
uniform vec4 u_outline_color;
uniform vec4 u_background_color;
uniform float u_xray_error_strength;
+ uniform float u_flat_error_color_mix;
const vec3 x_axis = vec3(1.0, 0.0, 0.0);
const vec3 y_axis = vec3(0.0, 1.0, 0.0);
@@ -166,7 +168,7 @@ fragment41core =
float rest = mod(intersection_count + .01, 2.0);
if (rest > 1.0 && rest < 1.5 && intersection_count < 49)
{
- result = vec4(shiftHue(layer0.rgb, hue_shift), result.a);
+ result = mix(vec4(shiftHue(layer0.rgb, hue_shift), result.a), vec4(1.,0.,0.,1.), u_flat_error_color_mix);
}
vec4 sum = vec4(0.0);
@@ -196,6 +198,7 @@ u_layer2 = 2
u_background_color = [0.965, 0.965, 0.965, 1.0]
u_outline_strength = 1.0
u_outline_color = [0.05, 0.66, 0.89, 1.0]
+u_flat_error_color_mix = 0.5
[bindings]
diff --git a/resources/texts/change_log.txt b/resources/texts/change_log.txt
index aebf21985b..4eef21b742 100644
--- a/resources/texts/change_log.txt
+++ b/resources/texts/change_log.txt
@@ -1,3 +1,13 @@
+[4.6.1]
+
+Patch release to fix some bugs that emerged with 4.6.0.
+
+* Z seam placement.
+Changes to the Simplify() algorithm in 4.6.0 caused Z seam placement issues, which resulted in less-than-perfect results. This has been fixed.
+
+* Ender 3 Pro nozzles missing.
+A lot of issue reports came in about nozzles missing for this machine definition, so we made a fix to stop this happening.
+
[4.6.0]
THANK YOU to all Ultimaker Cura users helping in the fight against COVID-19 – with 3D printing, volunteering, or just by staying home. Want to get involved? Find out more at https://ultimaker.com/in/cura/covid-19
@@ -42,7 +52,22 @@ Fixed a bug where comments were removed from Start/End G-codes when opening from
Values in the print monitor preheat fields were broken in previous versions, they have now been fixed by fieldOfview.
* Stepper motor disarming during pause at height.
-Some printers (like the Ultimaker S5) have a very heavy build platform. When the pause at height script was enabled, it would disarm the Z stepper motor at pause height. The weight of the build platform would cause the Z axis to lower by gravity and lose the Z position. ilyko96 has contributed a fix to the pause at height script so that the Z stepper motor now remains armed during a pause, locking the build plate in position.
+Some printers automatically disable their steppers after a pause after a certain time. This script makes it possible to set that in the pause script (instead of relying on default behavior of the firmware).
+
+* Crash if logging in on two instances at the same time.
+During the beta period we caught a critical bug where logging in to an Ultimaker account with two instances of Cura would crash the second instance. It crashes because while the web page is open, Cura opens a web server in the local host. The web page redirects to that web server when you've logged in, so that it knows that the log-in was successful and what the credentials are. Both instances try to create a web server on the same port, which is impossible.
+
+* "Changes detected from your Ultimaker account" message.
+We fixed a bug on MacOS where duplicate "Changes detected from your Ultimaker account" popups would appear at a single time.
+
+* Crashes when inactive.
+Some people reported experiencing crashes when the computer had been inactive for a long time, or when the laptop got suspended or went to sleep. This has been fixed.
+
+* Support blocker is not blocking support.
+Fixed an issue where the support blocker was not blocking support.
+
+* Sending slice message takes too long when using mesh helpers.
+Fixed an issue where it would take too long to trigger a slice when using the mesh helpers and support blocker.
* Flying Bear printers.
oducceu has contributed a machine definition for the Flying Bear Ghost 4S Printer.
diff --git a/resources/variants/creality_ender3pro_0.2.inst.cfg b/resources/variants/creality_ender3pro_0.2.inst.cfg
new file mode 100644
index 0000000000..b3dde4563b
--- /dev/null
+++ b/resources/variants/creality_ender3pro_0.2.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.2mm Nozzle
+version = 4
+definition = creality_ender3pro
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.2
diff --git a/resources/variants/creality_ender3pro_0.3.inst.cfg b/resources/variants/creality_ender3pro_0.3.inst.cfg
new file mode 100644
index 0000000000..a4c4c3c0f3
--- /dev/null
+++ b/resources/variants/creality_ender3pro_0.3.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.3mm Nozzle
+version = 4
+definition = creality_ender3pro
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.3
diff --git a/resources/variants/creality_ender3pro_0.4.inst.cfg b/resources/variants/creality_ender3pro_0.4.inst.cfg
new file mode 100644
index 0000000000..90b6260954
--- /dev/null
+++ b/resources/variants/creality_ender3pro_0.4.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.4mm Nozzle
+version = 4
+definition = creality_ender3pro
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.4
diff --git a/resources/variants/creality_ender3pro_0.5.inst.cfg b/resources/variants/creality_ender3pro_0.5.inst.cfg
new file mode 100644
index 0000000000..de12442da1
--- /dev/null
+++ b/resources/variants/creality_ender3pro_0.5.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.5mm Nozzle
+version = 4
+definition = creality_ender3pro
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.5
diff --git a/resources/variants/creality_ender3pro_0.6.inst.cfg b/resources/variants/creality_ender3pro_0.6.inst.cfg
new file mode 100644
index 0000000000..4bc4757ced
--- /dev/null
+++ b/resources/variants/creality_ender3pro_0.6.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.6mm Nozzle
+version = 4
+definition = creality_ender3pro
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.6
diff --git a/resources/variants/creality_ender3pro_0.8.inst.cfg b/resources/variants/creality_ender3pro_0.8.inst.cfg
new file mode 100644
index 0000000000..b881e6b680
--- /dev/null
+++ b/resources/variants/creality_ender3pro_0.8.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.8mm Nozzle
+version = 4
+definition = creality_ender3pro
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.8
diff --git a/resources/variants/creality_ender3pro_1.0.inst.cfg b/resources/variants/creality_ender3pro_1.0.inst.cfg
new file mode 100644
index 0000000000..6bd7eca50f
--- /dev/null
+++ b/resources/variants/creality_ender3pro_1.0.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 1.0mm Nozzle
+version = 4
+definition = creality_ender3pro
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 1.0
diff --git a/resources/variants/uni_200_0.30.inst.cfg b/resources/variants/uni_200_0.30.inst.cfg
new file mode 100644
index 0000000000..9026ac3ea9
--- /dev/null
+++ b/resources/variants/uni_200_0.30.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.30mm Nozzle
+version = 4
+definition = uni_200
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.3
diff --git a/resources/variants/uni_200_0.40.inst.cfg b/resources/variants/uni_200_0.40.inst.cfg
new file mode 100644
index 0000000000..7ab2bc62f5
--- /dev/null
+++ b/resources/variants/uni_200_0.40.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.40mm Nozzle
+version = 4
+definition = uni_200
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.4
diff --git a/resources/variants/uni_200_0.50.inst.cfg b/resources/variants/uni_200_0.50.inst.cfg
new file mode 100644
index 0000000000..bd2edaaf42
--- /dev/null
+++ b/resources/variants/uni_200_0.50.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.50mm Nozzle
+version = 4
+definition = uni_200
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.5
diff --git a/resources/variants/uni_250_0.30.inst.cfg b/resources/variants/uni_250_0.30.inst.cfg
new file mode 100644
index 0000000000..f9a94656bc
--- /dev/null
+++ b/resources/variants/uni_250_0.30.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.30mm Nozzle
+version = 4
+definition = uni_250
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.3
diff --git a/resources/variants/uni_250_0.40.inst.cfg b/resources/variants/uni_250_0.40.inst.cfg
new file mode 100644
index 0000000000..53575ba8c8
--- /dev/null
+++ b/resources/variants/uni_250_0.40.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.40mm Nozzle
+version = 4
+definition = uni_250
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.4
diff --git a/resources/variants/uni_250_0.50.inst.cfg b/resources/variants/uni_250_0.50.inst.cfg
new file mode 100644
index 0000000000..faf319bc08
--- /dev/null
+++ b/resources/variants/uni_250_0.50.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.50mm Nozzle
+version = 4
+definition = uni_250
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.5
diff --git a/resources/variants/uni_300_0.30.inst.cfg b/resources/variants/uni_300_0.30.inst.cfg
new file mode 100644
index 0000000000..11c6871faf
--- /dev/null
+++ b/resources/variants/uni_300_0.30.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.30mm Nozzle
+version = 4
+definition = uni_300
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.3
diff --git a/resources/variants/uni_300_0.40.inst.cfg b/resources/variants/uni_300_0.40.inst.cfg
new file mode 100644
index 0000000000..a149ceed88
--- /dev/null
+++ b/resources/variants/uni_300_0.40.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.40mm Nozzle
+version = 4
+definition = uni_300
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.4
diff --git a/resources/variants/uni_300_0.50.inst.cfg b/resources/variants/uni_300_0.50.inst.cfg
new file mode 100644
index 0000000000..bc37efc792
--- /dev/null
+++ b/resources/variants/uni_300_0.50.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.50mm Nozzle
+version = 4
+definition = uni_300
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.5
diff --git a/resources/variants/uni_base_0.30.inst.cfg b/resources/variants/uni_base_0.30.inst.cfg
new file mode 100644
index 0000000000..f6ea365bca
--- /dev/null
+++ b/resources/variants/uni_base_0.30.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.30mm Nozzle
+version = 4
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.3
diff --git a/resources/variants/uni_base_0.40.inst.cfg b/resources/variants/uni_base_0.40.inst.cfg
new file mode 100644
index 0000000000..838f3a588a
--- /dev/null
+++ b/resources/variants/uni_base_0.40.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.40mm Nozzle
+version = 4
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.4
diff --git a/resources/variants/uni_base_0.50.inst.cfg b/resources/variants/uni_base_0.50.inst.cfg
new file mode 100644
index 0000000000..7c513d6732
--- /dev/null
+++ b/resources/variants/uni_base_0.50.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.50mm Nozzle
+version = 4
+definition = uni_base
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.5
diff --git a/resources/variants/uni_mini_0.30.inst.cfg b/resources/variants/uni_mini_0.30.inst.cfg
new file mode 100644
index 0000000000..12a68781b3
--- /dev/null
+++ b/resources/variants/uni_mini_0.30.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.30mm Nozzle
+version = 4
+definition = uni_mini
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.3
diff --git a/resources/variants/uni_mini_0.40.inst.cfg b/resources/variants/uni_mini_0.40.inst.cfg
new file mode 100644
index 0000000000..16d6c4ee24
--- /dev/null
+++ b/resources/variants/uni_mini_0.40.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.40mm Nozzle
+version = 4
+definition = uni_mini
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.4
diff --git a/resources/variants/uni_mini_0.50.inst.cfg b/resources/variants/uni_mini_0.50.inst.cfg
new file mode 100644
index 0000000000..9ccd0bcc3a
--- /dev/null
+++ b/resources/variants/uni_mini_0.50.inst.cfg
@@ -0,0 +1,12 @@
+[general]
+name = 0.50mm Nozzle
+version = 4
+definition = uni_mini
+
+[metadata]
+setting_version = 13
+type = variant
+hardware_type = nozzle
+
+[values]
+machine_nozzle_size = 0.5
diff --git a/tests/Settings/TestDefinitionContainer.py b/tests/Settings/TestDefinitionContainer.py
index 9edf7f3d36..2f2b343338 100644
--- a/tests/Settings/TestDefinitionContainer.py
+++ b/tests/Settings/TestDefinitionContainer.py
@@ -45,6 +45,18 @@ def test_definitionIds(file_path):
definition_id = os.path.basename(file_path).split(".")[0]
assert " " not in definition_id # Definition IDs are not allowed to have spaces.
+@pytest.mark.parametrize("file_path", definition_filepaths)
+def test_noCategory(file_path):
+ """
+ Categories for definition files have been deprecated. Test that they are not
+ present.
+ :param file_path: The path of the machine definition to test.
+ """
+ with open(file_path, encoding = "utf-8") as f:
+ json = f.read()
+ metadata = DefinitionContainer.deserializeMetadata(json, "test_container_id")
+ assert "category" not in metadata[0]
+
## Tests all definition containers
@pytest.mark.parametrize("file_path", machine_filepaths)
def test_validateMachineDefinitionContainer(file_path, definition_container):
@@ -59,7 +71,6 @@ def test_validateMachineDefinitionContainer(file_path, definition_container):
with patch("UM.VersionUpgradeManager.VersionUpgradeManager.getInstance", MagicMock(return_value = mocked_vum)):
assertIsDefinitionValid(definition_container, file_path)
-
def assertIsDefinitionValid(definition_container, file_path):
with open(file_path, encoding = "utf-8") as data:
json = data.read()
diff --git a/tests/TestObjectsModel.py b/tests/TestObjectsModel.py
index caed4741bb..543334cea6 100644
--- a/tests/TestObjectsModel.py
+++ b/tests/TestObjectsModel.py
@@ -125,7 +125,16 @@ class Test_Update:
application_with_mocked_scene.getController().getScene().getRoot = MagicMock(return_value = group_scene_node)
with patch("UM.Application.Application.getInstance", MagicMock(return_value=application_with_mocked_scene)):
objects_model._update()
- assert objects_model.items == [{'name': 'Group #1', 'selected': False, 'outside_build_area': False, 'buildplate_number': None, 'node': group_scene_node}]
+ assert objects_model.items == [{
+ 'name': 'Group #1',
+ 'selected': False,
+ 'outside_build_area': False,
+ 'buildplate_number': None,
+ 'node': group_scene_node,
+ "extruder_number": -1,
+ "per_object_settings_count": 0,
+ "mesh_type": ""
+ }]
def test_updateWithNonGroup(self, objects_model, application_with_mocked_scene, slicable_scene_node):
objects_model._shouldNodeBeHandled = MagicMock(return_value=True)
@@ -133,7 +142,16 @@ class Test_Update:
application_with_mocked_scene.getController().getScene().getRoot = MagicMock(return_value=slicable_scene_node)
with patch("UM.Application.Application.getInstance", MagicMock(return_value=application_with_mocked_scene)):
objects_model._update()
- assert objects_model.items == [{'name': 'YAY(1)', 'selected': False, 'outside_build_area': False, 'buildplate_number': None, 'node': slicable_scene_node}]
+ assert objects_model.items == [{
+ 'name': 'YAY(1)',
+ 'selected': False,
+ 'outside_build_area': False,
+ 'buildplate_number': None,
+ 'node': slicable_scene_node,
+ "extruder_number": -1,
+ "per_object_settings_count": 0,
+ "mesh_type": ""
+ }]
def test_updateWithNonTwoNodes(self, objects_model, application_with_mocked_scene, slicable_scene_node):
objects_model._shouldNodeBeHandled = MagicMock(return_value=True)
@@ -143,7 +161,25 @@ class Test_Update:
application_with_mocked_scene.getController().getScene().getRoot = MagicMock(return_value=slicable_scene_node)
with patch("UM.Application.Application.getInstance", MagicMock(return_value=application_with_mocked_scene)):
objects_model._update()
- assert objects_model.items == [{'name': 'YAY', 'selected': False, 'outside_build_area': False, 'buildplate_number': None, 'node': slicable_scene_node}, {'name': 'YAY(1)', 'selected': False, 'outside_build_area': False, 'buildplate_number': None, 'node': copied_node}]
+ assert objects_model.items == [{
+ 'name': 'YAY',
+ 'selected': False,
+ 'outside_build_area': False,
+ 'buildplate_number': None,
+ 'node': slicable_scene_node,
+ "extruder_number": -1,
+ "per_object_settings_count": 0,
+ "mesh_type": ""
+ }, {
+ 'name': 'YAY(1)',
+ 'selected': False,
+ 'outside_build_area': False,
+ 'buildplate_number': None,
+ 'node': copied_node,
+ "extruder_number": -1,
+ "per_object_settings_count": 0,
+ "mesh_type": ""
+ }]
def test_updateWithNonTwoGroups(self, objects_model, application_with_mocked_scene, group_scene_node):
objects_model._shouldNodeBeHandled = MagicMock(return_value=True)
@@ -153,7 +189,25 @@ class Test_Update:
application_with_mocked_scene.getController().getScene().getRoot = MagicMock(return_value=group_scene_node)
with patch("UM.Application.Application.getInstance", MagicMock(return_value=application_with_mocked_scene)):
objects_model._update()
- assert objects_model.items == [{'name': 'Group #1', 'selected': False, 'outside_build_area': False, 'buildplate_number': None, 'node': group_scene_node}, {'name': 'Group #2', 'selected': False, 'outside_build_area': False, 'buildplate_number': None, 'node': copied_node}]
+ assert objects_model.items == [{
+ 'name': 'Group #1',
+ 'selected': False,
+ 'outside_build_area': False,
+ 'buildplate_number': None,
+ 'node': group_scene_node,
+ "extruder_number": -1,
+ "per_object_settings_count": 0,
+ "mesh_type": ""
+ }, {
+ 'name': 'Group #2',
+ 'selected': False,
+ 'outside_build_area': False,
+ 'buildplate_number': None,
+ 'node': copied_node,
+ "extruder_number": -1,
+ "per_object_settings_count": 0,
+ "mesh_type": ""
+ }]
def test_updateOutsideBuildplate(self, objects_model, application_with_mocked_scene, group_scene_node):
objects_model._shouldNodeBeHandled = MagicMock(return_value=True)
@@ -162,5 +216,14 @@ class Test_Update:
application_with_mocked_scene.getController().getScene().getRoot = MagicMock(return_value=group_scene_node)
with patch("UM.Application.Application.getInstance", MagicMock(return_value=application_with_mocked_scene)):
objects_model._update()
- assert objects_model.items == [{'name': 'Group #1', 'selected': False, 'outside_build_area': True, 'buildplate_number': None, 'node': group_scene_node}]
+ assert objects_model.items == [{
+ 'name': 'Group #1',
+ 'selected': False,
+ 'outside_build_area': True,
+ 'buildplate_number': None,
+ 'node': group_scene_node,
+ "extruder_number": -1,
+ "per_object_settings_count": 0,
+ "mesh_type": ""
+ }]