From 91ad5b84615a3c3b026786e98937561c7df91230 Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 1 Jul 2022 14:53:35 +0200 Subject: [PATCH 01/35] Hide some very difficult to explain (even to experts) settings. It'll just confuse users. It confused _us_ (both developers and materials experts) a lot of the time :-D CURA-9357 --- resources/definitions/fdmprinter.def.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index c33723ddfd..aec1103fb3 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1236,7 +1236,8 @@ "default_value": 50, "value": "max(1, min(99, 100 * (2 * min_even_wall_line_width - wall_line_width_0) / wall_line_width_0))", "minimum_value": "1", - "maximum_value": "99" + "maximum_value": "99", + "enabled": false } } }, @@ -1261,7 +1262,8 @@ "default_value": 75, "value": "max(1, min(99, 100 * min_odd_wall_line_width / wall_line_width_x))", "minimum_value": "1", - "maximum_value": "99" + "maximum_value": "99", + "enabled": false } } } From 5c81904aeeb70643a17d7514d88d4a01a54b440a Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Tue, 5 Jul 2022 17:58:57 +0200 Subject: [PATCH 02/35] Don't hide, just remove. Also updated in the engine, so anyone needs the corresponding branch there as well. CURA-9357 --- resources/definitions/fdmprinter.def.json | 34 ++--------------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index aec1103fb3..8f6e5cc037 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -1225,21 +1225,7 @@ "default_value": 0.3, "value": "min_wall_line_width", "type": "float", - "settable_per_mesh": true, - "children": - { - "wall_split_middle_threshold": { - "label": "Split Middle Line Threshold", - "description": "The smallest line width, as a factor of the normal line width, above which the middle line (if there is one) will be split into two. Reduce this setting to use more, thinner lines. Increase to use fewer, wider lines. Note that this applies -as if- the entire shape should be filled with wall, so the middle here refers to the middle of the object between two outer edges of the shape, even if there actually is fill or (other) skin in the print instead of wall.", - "type": "float", - "unit": "%", - "default_value": 50, - "value": "max(1, min(99, 100 * (2 * min_even_wall_line_width - wall_line_width_0) / wall_line_width_0))", - "minimum_value": "1", - "maximum_value": "99", - "enabled": false - } - } + "settable_per_mesh": true }, "min_odd_wall_line_width": { @@ -1251,21 +1237,7 @@ "default_value": 0.3, "value": "min_wall_line_width", "type": "float", - "settable_per_mesh": true, - "children": - { - "wall_add_middle_threshold": { - "label": "Add Middle Line Threshold", - "description": "The smallest line width, as a factor of the normal line width, above which a middle line (if there wasn't one already) will be added. Reduce this setting to use more, thinner lines. Increase to use fewer, wider lines. Note that this applies -as if- the entire shape should be filled with wall, so the middle here refers to the middle of the object between two outer edges of the shape, even if there actually is fill or (other) skin in the print instead of wall.", - "type": "float", - "unit": "%", - "default_value": 75, - "value": "max(1, min(99, 100 * min_odd_wall_line_width / wall_line_width_x))", - "minimum_value": "1", - "maximum_value": "99", - "enabled": false - } - } + "settable_per_mesh": true } } }, @@ -8051,7 +8023,7 @@ "label": "Remove Raft Inside Corners", "description": "Remove inside corners from the raft, causing the raft to become convex.", "type": "bool", - "default_value": false, + "default_value": true, "resolve": "any(extruderValues('raft_remove_inside_corners'))", "enabled": "resolveOrValue('adhesion_type') == 'raft'", "settable_per_mesh": false, From fd8d6498ee0f84f49996a427fdb4680ea3216ea2 Mon Sep 17 00:00:00 2001 From: joeydelarago Date: Wed, 10 Aug 2022 16:45:16 +0200 Subject: [PATCH 03/35] When changing to an intent with infillDensity > 100 in recommended settings the RecommendedInfillDensitySelector would set infillDensity=100. This is because the onValueChanged function checks if the slider has a different value from the settings and updates the settings if it does. The slider has a max value of 100, so when setting the sliders value to 1000 the slider would update to have a value of 100. This would then update the setting to value to 100. The fix is as follows. When updating the slider value > 100 just ignore the first onValueChanged. Following onValueChanged, which are triggered by the user sliding the slider, will still trigger. CURA-9488 --- .../RecommendedInfillDensitySelector.qml | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml index bb3b0cdbec..0317cb7814 100644 --- a/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml +++ b/resources/qml/PrintSetupSelector/Recommended/RecommendedInfillDensitySelector.qml @@ -51,7 +51,17 @@ Item { target: infillSlider property: "value" - value: parseInt(infillDensity.properties.value) + value: { + // The infill slider has a max value of 100. When it is given a value > 100 onValueChanged updates the setting to be 100. + // When changing to an intent with infillDensity > 100, it would always be clamped to 100. + // This will force the slider to ignore the first onValueChanged for values > 100 so higher values can be set. + var density = parseInt(infillDensity.properties.value) + if (density > 100) { + infillSlider.ignoreValueChange = true + } + + return density + } } // Here are the elements that are shown in the left column @@ -84,6 +94,8 @@ Item { id: infillSlider + property var ignoreValueChange: false + width: parent.width height: UM.Theme.getSize("print_setup_slider_handle").height // The handle is the widest element of the slider @@ -157,7 +169,13 @@ Item target: infillSlider function onValueChanged() { - // Don't round the value if it's already the same + if (infillSlider.ignoreValueChange) + { + infillSlider.ignoreValueChange = false + return + } + + // Don't update if the setting value, if the slider has the same value if (parseInt(infillDensity.properties.value) == infillSlider.value) { return From d92fd3d1e37b825e8cae87e34a92ef410ff9563e Mon Sep 17 00:00:00 2001 From: "j.spijker@ultimaker.com" Date: Fri, 12 Aug 2022 16:38:17 +0200 Subject: [PATCH 04/35] Make internal resources requirements Contributes to CURA-9528 --- conandata.yml | 26 ++++++++++++++++++++++++++ conanfile.py | 25 +++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/conandata.yml b/conandata.yml index 2933fd8437..4b9d8dd612 100644 --- a/conandata.yml +++ b/conandata.yml @@ -20,6 +20,9 @@ - "fdm_materials/(latest)@ultimaker/testing" - "cura_binary_data/(latest)@ultimaker/testing" - "cpython/3.10.4" + internal_requirements: + - "fdm_materials_private/(latest)@ultimaker/testing" + - "cura_private_data/(latest)@ultimaker/testing" runinfo: entrypoint: "cura_app.py" pyinstaller: @@ -32,6 +35,11 @@ package: "cura" src: "resources" dst: "share/cura/resources" + cura_private_data: + package: "cura_private_data" + src: "resources" + dst: "share/cura/resources" + internal: true uranium_plugins: package: "uranium" src: "plugins" @@ -60,6 +68,11 @@ package: "fdm_materials" src: "materials" dst: "share/cura/resources/materials" + fdm_materials_private: + package: "fdm_materials_private" + src: "resources/materials" + dst: "share/cura/resources/materials" + internal: true tcl: package: "tcl" src: "lib/tcl8.6" @@ -112,6 +125,9 @@ - "fdm_materials/(latest)@ultimaker/testing" - "cura_binary_data/(latest)@ultimaker/testing" - "cpython/3.10.4" + internal_requirements: + - "fdm_materials_private/(latest)@ultimaker/testing" + - "cura_private_data/(latest)@ultimaker/testing" runinfo: entrypoint: "cura_app.py" pyinstaller: @@ -124,6 +140,11 @@ package: "cura" src: "resources" dst: "share/cura/resources" + cura_private_data: + package: "cura_private_data" + src: "resources" + dst: "share/cura/resources" + internal: true uranium_plugins: package: "uranium" src: "plugins" @@ -152,6 +173,11 @@ package: "fdm_materials" src: "materials" dst: "share/cura/resources/materials" + fdm_materials_private: + package: "fdm_materials_private" + src: "resources/materials" + dst: "share/cura/resources/materials" + internal: true tcl: package: "tcl" src: "lib/tcl8.6" diff --git a/conanfile.py b/conanfile.py index ee7446483d..543911d541 100644 --- a/conanfile.py +++ b/conanfile.py @@ -167,6 +167,9 @@ class CuraConan(ConanFile): pyinstaller_metadata = self._um_data()["pyinstaller"] datas = [(str(self._base_dir.joinpath("conan_install_info.json")), ".")] for data in pyinstaller_metadata["datas"].values(): + if not self.options.internal and ("internal" not in data or not data["internal"]): + continue + if "package" in data: # get the paths from conan package if data["package"] == self.name: if self.in_local_cache: @@ -248,6 +251,9 @@ class CuraConan(ConanFile): def requirements(self): for req in self._um_data()["requirements"]: self.requires(req) + if self.options.internal: + for req in self._um_data()["internal_requirements"]: + self.requires(req) def layout(self): self.folders.source = "." @@ -286,11 +292,17 @@ class CuraConan(ConanFile): self.copy("*.fdm_material", root_package = "fdm_materials", src = "@resdirs", dst = "resources/materials", keep_path = False) self.copy("*.sig", root_package = "fdm_materials", src = "@resdirs", dst = "resources/materials", keep_path = False) + if self.options.internal: + self.copy("*.fdm_material", root_package = "fdm_materials_private", src = "@resdirs", dst = "resources/materials", keep_path = False) + self.copy("*.sig", root_package = "fdm_materials_private", src = "@resdirs", dst = "resources/materials", keep_path = False) + self.copy("*", root_package = "cura_private_data", src = self.deps_cpp_info["cura_private_data"].resdirs[0], + dst = self._share_dir.joinpath("cura", "resources"), keep_path = True) + # Copy resources of cura_binary_data self.copy("*", root_package = "cura_binary_data", src = self.deps_cpp_info["cura_binary_data"].resdirs[0], - dst = "venv/share/cura", keep_path = True) + dst = self._share_dir.joinpath("cura", "resources"), keep_path = True) self.copy("*", root_package = "cura_binary_data", src = self.deps_cpp_info["cura_binary_data"].resdirs[1], - dst = "venv/share/uranium", keep_path = True) + dst =self._share_dir.joinpath("uranium", "resources"), keep_path = True) self.copy("*.dll", src = "@bindirs", dst = self._site_packages) self.copy("*.pyd", src = "@libdirs", dst = self._site_packages) @@ -318,6 +330,15 @@ class CuraConan(ConanFile): self.copy_deps("*.sig", root_package = "fdm_materials", src = self.deps_cpp_info["fdm_materials"].resdirs[0], dst = self._share_dir.joinpath("cura", "resources", "materials"), keep_path = False) + # Copy internal resources + if self.options.internal: + self.copy_deps("*.fdm_material", root_package = "fdm_materials_private", src = self.deps_cpp_info["fdm_materials_private"].resdirs[0], + dst = self._share_dir.joinpath("cura", "resources", "materials"), keep_path = False) + self.copy_deps("*.sig", root_package = "fdm_materials_private", src = self.deps_cpp_info["fdm_materials_private"].resdirs[0], + dst = self._share_dir.joinpath("cura", "resources", "materials"), keep_path = False) + self.copy_deps("*", root_package = "cura_private_data", src = self.deps_cpp_info["cura_private_data"].resdirs[0], + dst = self._share_dir.joinpath("cura", "resources"), keep_path = True) + # Copy resources of Uranium (keep folder structure) self.copy_deps("*", root_package = "uranium", src = self.deps_cpp_info["uranium"].resdirs[0], dst = self._share_dir.joinpath("uranium", "resources"), keep_path = True) From 37077a7823f10d237b94e9c25ad9b735b0b34b91 Mon Sep 17 00:00:00 2001 From: "j.spijker@ultimaker.com" Date: Fri, 12 Aug 2022 17:08:25 +0200 Subject: [PATCH 05/35] Fix not internal builds Contributes to CURA-9528 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 543911d541..20f2f8f2bd 100644 --- a/conanfile.py +++ b/conanfile.py @@ -167,7 +167,7 @@ class CuraConan(ConanFile): pyinstaller_metadata = self._um_data()["pyinstaller"] datas = [(str(self._base_dir.joinpath("conan_install_info.json")), ".")] for data in pyinstaller_metadata["datas"].values(): - if not self.options.internal and ("internal" not in data or not data["internal"]): + if not self.options.internal and "internal" in data and not data["internal"]: continue if "package" in data: # get the paths from conan package From 1d4ee4dd96cc5598b5e46dbdf46d332e26f180b7 Mon Sep 17 00:00:00 2001 From: "j.spijker@ultimaker.com" Date: Fri, 12 Aug 2022 17:47:28 +0200 Subject: [PATCH 06/35] Fix not internal builds Contributes to CURA-9528 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 20f2f8f2bd..f731402700 100644 --- a/conanfile.py +++ b/conanfile.py @@ -167,7 +167,7 @@ class CuraConan(ConanFile): pyinstaller_metadata = self._um_data()["pyinstaller"] datas = [(str(self._base_dir.joinpath("conan_install_info.json")), ".")] for data in pyinstaller_metadata["datas"].values(): - if not self.options.internal and "internal" in data and not data["internal"]: + if self.options.internal and "internal" in data and not data["internal"]: continue if "package" in data: # get the paths from conan package From 830adcea1bef4b4ff05273d22e3c0f1f27e978f9 Mon Sep 17 00:00:00 2001 From: "j.spijker@ultimaker.com" Date: Fri, 12 Aug 2022 18:00:16 +0200 Subject: [PATCH 07/35] Fix not internal builds Contributes to CURA-9528 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index f731402700..a07500e17a 100644 --- a/conanfile.py +++ b/conanfile.py @@ -167,7 +167,7 @@ class CuraConan(ConanFile): pyinstaller_metadata = self._um_data()["pyinstaller"] datas = [(str(self._base_dir.joinpath("conan_install_info.json")), ".")] for data in pyinstaller_metadata["datas"].values(): - if self.options.internal and "internal" in data and not data["internal"]: + if not self.options.internal and data.get("internal", False): continue if "package" in data: # get the paths from conan package From 57d739a848dc96a4d38b7ae6f8d3a61b69c2467c Mon Sep 17 00:00:00 2001 From: joeydelarago Date: Mon, 15 Aug 2022 15:43:37 +0200 Subject: [PATCH 08/35] Move source of truth for latest.json url into ApplicationMetadata.py and out of the Uranium repository. CURA-9272 --- cura/ApplicationMetadata.py | 8 ++++++++ cura/CuraApplication.py | 1 + 2 files changed, 9 insertions(+) diff --git a/cura/ApplicationMetadata.py b/cura/ApplicationMetadata.py index 60d9201d8e..678f8b7e4a 100644 --- a/cura/ApplicationMetadata.py +++ b/cura/ApplicationMetadata.py @@ -9,12 +9,20 @@ DEFAULT_CURA_DISPLAY_NAME = "Ultimaker Cura" DEFAULT_CURA_VERSION = "dev" DEFAULT_CURA_BUILD_TYPE = "" DEFAULT_CURA_DEBUG_MODE = False +DEFAULT_CURA_LATEST_URL = "https://raw.githubusercontent.com/Ultimaker/Uranium/CURA-9272_semver_postfix/tests/latest.json" # 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 = "8.1.0" +try: + from cura.CuraVersion import CuraLatestURL + if CuraLatestURL == "": + CuraLatestURL = DEFAULT_CURA_LATEST_URL +except ImportError: + CuraLatestURL = DEFAULT_CURA_LATEST_URL + try: from cura.CuraVersion import CuraAppName # type: ignore if CuraAppName == "": diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index eeaead4f71..94492d22c8 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -152,6 +152,7 @@ class CuraApplication(QtApplication): super().__init__(name = ApplicationMetadata.CuraAppName, app_display_name = ApplicationMetadata.CuraAppDisplayName, version = ApplicationMetadata.CuraVersion if not ApplicationMetadata.IsAlternateVersion else ApplicationMetadata.CuraBuildType, + latest_url = ApplicationMetadata.CuraLatestURL, api_version = ApplicationMetadata.CuraSDKVersion, build_type = ApplicationMetadata.CuraBuildType, is_debug_mode = ApplicationMetadata.CuraDebugMode, From a20e7bf8d9792c81e655c2003e55d7f12daa6ff2 Mon Sep 17 00:00:00 2001 From: joeydelarago Date: Mon, 15 Aug 2022 15:59:08 +0200 Subject: [PATCH 09/35] Add cura latest.json url to template so it can be set from the conanfile. CURA-9272 --- CuraVersion.py.jinja | 1 + conanfile.py | 7 ++++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CuraVersion.py.jinja b/CuraVersion.py.jinja index 1c30a0b5af..1c8ff0551c 100644 --- a/CuraVersion.py.jinja +++ b/CuraVersion.py.jinja @@ -11,3 +11,4 @@ CuraCloudAPIVersion = "{{ cura_cloud_api_version }}" CuraCloudAccountAPIRoot = "{{ cura_cloud_account_api_root }}" CuraMarketplaceRoot = "{{ cura_marketplace_root }}" CuraDigitalFactoryURL = "{{ cura_digital_factory_url }}" +CuraLatestURL = "{{ cura_latest_url }}" diff --git a/conanfile.py b/conanfile.py index a07500e17a..87dfd175ad 100644 --- a/conanfile.py +++ b/conanfile.py @@ -100,6 +100,10 @@ class CuraConan(ConanFile): def _digital_factory_url(self): return "https://digitalfactory-staging.ultimaker.com" if self._staging else "https://digitalfactory.ultimaker.com" + @property + def _cura_latest_url(self): + return "https://raw.githubusercontent.com/Ultimaker/Uranium/CURA-9272_semver_postfix/tests/latest.json" + @property def requirements_txts(self): if self.options.devtools: @@ -161,7 +165,8 @@ class CuraConan(ConanFile): cura_cloud_api_version = self.options.cloud_api_version, cura_cloud_account_api_root = self._cloud_account_api_root, cura_marketplace_root = self._marketplace_root, - cura_digital_factory_url = self._digital_factory_url)) + cura_digital_factory_url = self._digital_factory_url, + cura_latest_url = self._cura_latest_url)) def _generate_pyinstaller_spec(self, location, entrypoint_location, icon_path, entitlements_file): pyinstaller_metadata = self._um_data()["pyinstaller"] From 5900cac9c8b7bd7a7885a221084e7b41140a61de Mon Sep 17 00:00:00 2001 From: joeydelarago Date: Mon, 15 Aug 2022 16:00:14 +0200 Subject: [PATCH 10/35] Default the prerelease number to 1 when it is not set in the github tags. CURA-9272 --- .github/workflows/conan-recipe-version.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/conan-recipe-version.yml b/.github/workflows/conan-recipe-version.yml index 5a24754f03..3ab3d59547 100644 --- a/.github/workflows/conan-recipe-version.yml +++ b/.github/workflows/conan-recipe-version.yml @@ -135,6 +135,9 @@ jobs: user = "_" channel = "_" else: + if not latest_branch_version.prerelease.contains("."): + # The prerealese did not contain a version number, default it to 1 + latest_branch_version.prerelease.append(".1") if event_name == "pull_request": actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{latest_branch_version.patch}-{latest_branch_version.prerelease.lower()}+{buildmetadata}pr_{issue_number}_{no_commits}" else: From 4667373cb4624dfb512528b2fd8966fb4206a2cd Mon Sep 17 00:00:00 2001 From: joeydelarago Date: Mon, 15 Aug 2022 17:17:40 +0200 Subject: [PATCH 11/35] Fix recipes not being uploaded to community conan repository. These booleans were strings because of a github runners bug, but that bug is fixed now so these changes are being reverted. --- .github/workflows/conan-package-create.yml | 2 +- .github/workflows/conan-recipe-export.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/conan-package-create.yml b/.github/workflows/conan-package-create.yml index f9fbbef6f7..3e5f3dbe1c 100644 --- a/.github/workflows/conan-package-create.yml +++ b/.github/workflows/conan-package-create.yml @@ -149,5 +149,5 @@ jobs: run: conan upload "*" -r cura --all -c - name: Upload the Package(s) community - if: ${{ always() && inputs.conan_upload_community == 'true' }} + if: ${{ always() && inputs.conan_upload_community == true }} run: conan upload "*" -r cura-ce -c diff --git a/.github/workflows/conan-recipe-export.yml b/.github/workflows/conan-recipe-export.yml index cab21604fe..f38c0046c9 100644 --- a/.github/workflows/conan-recipe-export.yml +++ b/.github/workflows/conan-recipe-export.yml @@ -102,5 +102,5 @@ jobs: run: conan upload "*" -r cura --all -c - name: Upload the Package(s) community - if: ${{ always() && inputs.conan_upload_community == 'true' }} + if: ${{ always() && inputs.conan_upload_community == true }} run: conan upload "*" -r cura-ce -c From 0e99a0029d40bff0c59e48094f8af00fff7dbbd1 Mon Sep 17 00:00:00 2001 From: Joey de l'Arago Date: Fri, 19 Aug 2022 12:52:40 +0200 Subject: [PATCH 12/35] Update minimum conan version --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index a07500e17a..1250683926 100644 --- a/conanfile.py +++ b/conanfile.py @@ -9,7 +9,7 @@ from conan.tools import files from conan.tools.env import VirtualRunEnv, Environment from conan.errors import ConanInvalidConfiguration -required_conan_version = ">=1.47.0" +required_conan_version = ">=1.48.0" class CuraConan(ConanFile): From b82f1f4a8c66fbe0a587d1f0cc6a15b0ee55d421 Mon Sep 17 00:00:00 2001 From: joeydelarago Date: Fri, 19 Aug 2022 13:53:43 +0200 Subject: [PATCH 13/35] Add new Abstract machine stack type. This represents a type of printers (ultimaker_s3 etc). These are created whenever a cloud printer of a new printer type is added. CURA-9277 Co-authored-by: casperlamboo --- cura/Settings/AbstractMachine.py | 16 ++++ cura/Settings/CuraContainerRegistry.py | 1 + cura/Settings/CuraStackBuilder.py | 77 +++++++++++++++++-- .../src/Cloud/CloudOutputDeviceManager.py | 2 + 4 files changed, 88 insertions(+), 8 deletions(-) create mode 100644 cura/Settings/AbstractMachine.py diff --git a/cura/Settings/AbstractMachine.py b/cura/Settings/AbstractMachine.py new file mode 100644 index 0000000000..0dd4dfb1c0 --- /dev/null +++ b/cura/Settings/AbstractMachine.py @@ -0,0 +1,16 @@ +from typing import List + +from cura.Settings.GlobalStack import GlobalStack + + +class AbstractMachine(GlobalStack): + """ Behaves as a type of machine, represents multiple machines of the same type """ + + def __init__(self): + super(self) + self.setMetaDataEntry("type", "abstract_machine") + + def getMachinesOfType(self) -> List[GlobalStack]: + pass + + diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 6ff856efcb..f65697277e 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -108,6 +108,7 @@ class CuraContainerRegistry(ContainerRegistry): :param container_type: :type{string} Type of the container (machine, quality, ...) :param container_name: :type{string} Name to check """ + # FIXME: this should check for abstract machine container_class = ContainerStack if container_type == "machine" else InstanceContainer return self.findContainersMetadata(container_type = container_class, id = container_name, type = container_type, ignore_case = True) or \ diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index ff9a795c43..bc02fd6cd1 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -9,6 +9,7 @@ from UM.Settings.Interfaces import DefinitionContainerInterface from UM.Settings.InstanceContainer import InstanceContainer from cura.Machines.ContainerTree import ContainerTree +from .AbstractMachine import AbstractMachine from .GlobalStack import GlobalStack from .ExtruderStack import ExtruderStack @@ -199,17 +200,25 @@ class CuraStackBuilder: :return: A new Global stack instance with the specified parameters. """ - - from cura.CuraApplication import CuraApplication - application = CuraApplication.getInstance() - registry = application.getContainerRegistry() - stack = GlobalStack(new_stack_id) stack.setDefinition(definition) + cls.createUserContainer(new_stack_id, definition, stack, variant_container, material_container, quality_container) + return stack + + @classmethod + def createUserContainer(cls, new_stack_id: str, definition: DefinitionContainerInterface, + stack: GlobalStack, + variant_container: "InstanceContainer", + material_container: "InstanceContainer", + quality_container: "InstanceContainer"): + from cura.CuraApplication import CuraApplication + application = CuraApplication.getInstance() + + registry = application.getContainerRegistry() # Create user container user_container = cls.createUserChangesContainer(new_stack_id + "_user", definition.getId(), new_stack_id, - is_global_stack = True) + is_global_stack=True) stack.definitionChanges = cls.createDefinitionChangesContainer(stack, new_stack_id + "_settings") stack.variant = variant_container @@ -221,8 +230,6 @@ class CuraStackBuilder: registry.addContainer(user_container) - return stack - @classmethod def createUserChangesContainer(cls, container_name: str, definition_id: str, stack_id: str, is_global_stack: bool) -> "InstanceContainer": @@ -259,3 +266,57 @@ class CuraStackBuilder: container_stack.definitionChanges = definition_changes_container return definition_changes_container + + @classmethod + def createAbstractMachine(cls, name, definition_id): + # cls.createMachine(definition_id, definition_id) + """Create a new instance of a machine. + + :param name: The name of the new machine. + :param definition_id: The ID of the machine definition to use. + :param machine_extruder_count: The number of extruders in the machine. + + :return: The new global stack or None if an error occurred. + """ + + from cura.CuraApplication import CuraApplication + application = CuraApplication.getInstance() + registry = application.getContainerRegistry() + container_tree = ContainerTree.getInstance() + + if registry.findContainerStacks(type="abstract_machine", id=definition_id): + # This abstract machine already exists + return + + match registry.findDefinitionContainers(id=definition_id): + case []: + # It should not be possible for the definition to be missing since an abstract machine will only + # be created as a result of a machine with definition_id being created. + Logger.error("w", "Definition {definition} was not found!", definition=definition_id) + return None + case [machine_definition, *_definitions]: + machine_node = container_tree.machines[machine_definition.getId()] + + generated_name = registry.createUniqueName("machine", "", name, machine_definition.getName()) + # Make sure the new name does not collide with any definition or (quality) profile + # createUniqueName() only looks at other stacks, but not at definitions or quality profiles + # Note that we don't go for uniqueName() immediately because that function matches with ignore_case set to true + if registry.findContainersMetadata(id=generated_name): + generated_name = registry.uniqueName(generated_name) + + stack = AbstractMachine(generated_name) + stack.setDefinition(machine_definition) + cls.createUserContainer( + generated_name, + machine_definition, + application.empty_variant_container, + application.empty_material_container, + machine_node.preferredGlobalQuality().container, + ) + + # FIXME: This should have a pretty name + stack.setName(generated_name) + + registry.addContainer(stack) + + return stack diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index f7f659124c..f5ede7c0d1 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -405,6 +405,8 @@ class CloudOutputDeviceManager: self._setOutputDeviceMetadata(device, new_machine) + CuraStackBuilder.createAbstractMachine(new_machine) + if activate: CuraApplication.getInstance().getMachineManager().setActiveMachine(new_machine.getId()) From 761bf3b8fab02b8884d1780b211abfd92b8ced53 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Fri, 19 Aug 2022 14:44:19 +0200 Subject: [PATCH 14/35] Fix creating abstract machines on account sync Cura-9277 Co-authored-by: joeydelarago --- cura/Settings/AbstractMachine.py | 4 ++-- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/Settings/AbstractMachine.py b/cura/Settings/AbstractMachine.py index 0dd4dfb1c0..837cfad4bd 100644 --- a/cura/Settings/AbstractMachine.py +++ b/cura/Settings/AbstractMachine.py @@ -6,8 +6,8 @@ from cura.Settings.GlobalStack import GlobalStack class AbstractMachine(GlobalStack): """ Behaves as a type of machine, represents multiple machines of the same type """ - def __init__(self): - super(self) + def __init__(self, container_id: str): + super().__init__(container_id) self.setMetaDataEntry("type", "abstract_machine") def getMachinesOfType(self) -> List[GlobalStack]: diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index f5ede7c0d1..a73d08d8fa 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -405,7 +405,7 @@ class CloudOutputDeviceManager: self._setOutputDeviceMetadata(device, new_machine) - CuraStackBuilder.createAbstractMachine(new_machine) + CuraStackBuilder.createAbstractMachine(device.name, device.printerType) if activate: CuraApplication.getInstance().getMachineManager().setActiveMachine(new_machine.getId()) From 6f6c2df28a049607d90d0cea6a8f58f9f1fcc11c Mon Sep 17 00:00:00 2001 From: Joey de l'Arago Date: Fri, 19 Aug 2022 14:45:42 +0200 Subject: [PATCH 15/35] Update requirements-conan-package.txt --- .github/workflows/requirements-conan-package.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/requirements-conan-package.txt b/.github/workflows/requirements-conan-package.txt index 1af154c83c..cf9d4193ef 100644 --- a/.github/workflows/requirements-conan-package.txt +++ b/.github/workflows/requirements-conan-package.txt @@ -1,2 +1,2 @@ -conan!=1.51.0,!=1.51.1,!=1.51.2 +conan!=1.51.0,!=1.51.1,!=1.51.2,!=1.51.3 sip==6.5.1 From d7f119415f572c360dd3199d3acd842c8fcc6792 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Fri, 19 Aug 2022 16:35:00 +0200 Subject: [PATCH 16/35] Use pretty-printed string for the `AbstractMachine` name Cura-9277 Co-authored-by: joeydelarago --- cura/Settings/CuraStackBuilder.py | 36 ++++++++----------- .../src/Cloud/CloudOutputDeviceManager.py | 2 +- 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index bc02fd6cd1..0b700eae93 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -268,27 +268,25 @@ class CuraStackBuilder: return definition_changes_container @classmethod - def createAbstractMachine(cls, name, definition_id): - # cls.createMachine(definition_id, definition_id) - """Create a new instance of a machine. + def createAbstractMachine(cls, definition_id) -> Optional[AbstractMachine]: + """Create a new instance of an abstract machine. - :param name: The name of the new machine. - :param definition_id: The ID of the machine definition to use. - :param machine_extruder_count: The number of extruders in the machine. + :param definition_id: The ID of the machine definition to use. - :return: The new global stack or None if an error occurred. - """ + :return: The new Abstract Machine or None if an error occurred. + """ + abstract_machine_id = definition_id + "_abstract_machine" from cura.CuraApplication import CuraApplication application = CuraApplication.getInstance() registry = application.getContainerRegistry() container_tree = ContainerTree.getInstance() - if registry.findContainerStacks(type="abstract_machine", id=definition_id): + if registry.findContainerStacks(type="abstract_machine", id=abstract_machine_id): # This abstract machine already exists - return + return None - match registry.findDefinitionContainers(id=definition_id): + match registry.findDefinitionContainers(type="machine", id=definition_id): case []: # It should not be possible for the definition to be missing since an abstract machine will only # be created as a result of a machine with definition_id being created. @@ -296,26 +294,20 @@ class CuraStackBuilder: return None case [machine_definition, *_definitions]: machine_node = container_tree.machines[machine_definition.getId()] + name = machine_definition.getName() - generated_name = registry.createUniqueName("machine", "", name, machine_definition.getName()) - # Make sure the new name does not collide with any definition or (quality) profile - # createUniqueName() only looks at other stacks, but not at definitions or quality profiles - # Note that we don't go for uniqueName() immediately because that function matches with ignore_case set to true - if registry.findContainersMetadata(id=generated_name): - generated_name = registry.uniqueName(generated_name) - - stack = AbstractMachine(generated_name) + stack = AbstractMachine(abstract_machine_id) stack.setDefinition(machine_definition) cls.createUserContainer( - generated_name, + name, machine_definition, + stack, application.empty_variant_container, application.empty_material_container, machine_node.preferredGlobalQuality().container, ) - # FIXME: This should have a pretty name - stack.setName(generated_name) + stack.setName(name) registry.addContainer(stack) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index a73d08d8fa..94b2eec80b 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -405,7 +405,7 @@ class CloudOutputDeviceManager: self._setOutputDeviceMetadata(device, new_machine) - CuraStackBuilder.createAbstractMachine(device.name, device.printerType) + CuraStackBuilder.createAbstractMachine(device.printerType) if activate: CuraApplication.getInstance().getMachineManager().setActiveMachine(new_machine.getId()) From f22d446fa401d5a2e6e8650184826c4ccb2878df Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Fri, 19 Aug 2022 16:35:13 +0200 Subject: [PATCH 17/35] Implement `getMachines` function Cura-9277 Co-authored-by: joeydelarago --- cura/Settings/AbstractMachine.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/cura/Settings/AbstractMachine.py b/cura/Settings/AbstractMachine.py index 837cfad4bd..7bf8454a49 100644 --- a/cura/Settings/AbstractMachine.py +++ b/cura/Settings/AbstractMachine.py @@ -1,16 +1,21 @@ from typing import List +from UM.Settings.ContainerStack import ContainerStack from cura.Settings.GlobalStack import GlobalStack class AbstractMachine(GlobalStack): - """ Behaves as a type of machine, represents multiple machines of the same type """ + """ Represents a group of machines of the same type. This allows the user to select settings before selecting a printer. """ def __init__(self, container_id: str): super().__init__(container_id) self.setMetaDataEntry("type", "abstract_machine") - def getMachinesOfType(self) -> List[GlobalStack]: - pass - + def getMachines(self) -> List[ContainerStack]: + from cura.CuraApplication import CuraApplication + application = CuraApplication.getInstance() + registry = application.getContainerRegistry() + printer_type = self.definition.getId() + cloud_printer_type = 3 + return [machine for machine in registry.findContainerStacks(type="machine") if machine.definition.id == printer_type and cloud_printer_type in machine.configuredConnectionTypes] From 963110a9c636a2d80a7db93b5aa53f9255a8ef12 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Fri, 19 Aug 2022 16:41:02 +0200 Subject: [PATCH 18/35] Remove Fix me Cura-9277 Co-authored-by: joeydelarago --- cura/Settings/CuraContainerRegistry.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index f65697277e..70d03b5ddc 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -108,8 +108,7 @@ class CuraContainerRegistry(ContainerRegistry): :param container_type: :type{string} Type of the container (machine, quality, ...) :param container_name: :type{string} Name to check """ - # FIXME: this should check for abstract machine - container_class = ContainerStack if container_type == "machine" else InstanceContainer + container_class = ContainerStack if container_type in "machine" else InstanceContainer return self.findContainersMetadata(container_type = container_class, id = container_name, type = container_type, ignore_case = True) or \ self.findContainersMetadata(container_type = container_class, name = container_name, type = container_type) From 544ac33537a0d0f078bcf73ae4175e9c615faaac Mon Sep 17 00:00:00 2001 From: joeydelarago Date: Mon, 22 Aug 2022 10:33:47 +0200 Subject: [PATCH 19/35] Add resource type for abstract machine so they can be saved. CURA-9277 --- cura/CuraApplication.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index eeaead4f71..a5664ec524 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -145,6 +145,8 @@ class CuraApplication(QtApplication): DefinitionChangesContainer = Resources.UserType + 10 SettingVisibilityPreset = Resources.UserType + 11 IntentInstanceContainer = Resources.UserType + 12 + AbstractMachineStack = Resources.UserType + 13 + pyqtEnum(ResourceTypes) @@ -432,6 +434,7 @@ class CuraApplication(QtApplication): self._container_registry.addResourceType(self.ResourceTypes.MachineStack, "machine") self._container_registry.addResourceType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes") self._container_registry.addResourceType(self.ResourceTypes.IntentInstanceContainer, "intent") + self._container_registry.addResourceType(self.ResourceTypes.AbstractMachineStack, "abstract_machine") Resources.addType(self.ResourceTypes.QmlFiles, "qml") Resources.addType(self.ResourceTypes.Firmware, "firmware") From c4be0e298caaab54a0135ddfab336a8ffba10744 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Mon, 22 Aug 2022 11:57:18 +0200 Subject: [PATCH 20/35] Add mime type to `AbstractMachine` Cura-9277 Co-authored-by: joeydelarago --- cura/Settings/AbstractMachine.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/cura/Settings/AbstractMachine.py b/cura/Settings/AbstractMachine.py index 7bf8454a49..50321d9a9f 100644 --- a/cura/Settings/AbstractMachine.py +++ b/cura/Settings/AbstractMachine.py @@ -2,6 +2,8 @@ from typing import List from UM.Settings.ContainerStack import ContainerStack from cura.Settings.GlobalStack import GlobalStack +from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase +from UM.Settings.ContainerRegistry import ContainerRegistry class AbstractMachine(GlobalStack): @@ -19,3 +21,14 @@ class AbstractMachine(GlobalStack): printer_type = self.definition.getId() cloud_printer_type = 3 return [machine for machine in registry.findContainerStacks(type="machine") if machine.definition.id == printer_type and cloud_printer_type in machine.configuredConnectionTypes] + + +## private: +abstract_machine_mime = MimeType( + name = "application/x-cura-abstract-machine", + comment = "Cura Abstract Machine", + suffixes = ["global.cfg"] +) + +MimeTypeDatabase.addMimeType(abstract_machine_mime) +ContainerRegistry.addContainerTypeByName(AbstractMachine, "abstract_machine", abstract_machine_mime.name) From 61ce8dff7dba43fb771b7541d69b01a9dda843bb Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Mon, 22 Aug 2022 11:58:05 +0200 Subject: [PATCH 21/35] Add the abstract stack to the `Resources` Cura-9277 Co-authored-by: joeydelarago --- cura/CuraApplication.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index a5664ec524..f8812285bc 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -424,6 +424,7 @@ class CuraApplication(QtApplication): Resources.addStorageType(self.ResourceTypes.DefinitionChangesContainer, "definition_changes") Resources.addStorageType(self.ResourceTypes.SettingVisibilityPreset, "setting_visibility") Resources.addStorageType(self.ResourceTypes.IntentInstanceContainer, "intent") + Resources.addStorageType(self.ResourceTypes.AbstractMachineStack, "abstract_machine_instances") self._container_registry.addResourceType(self.ResourceTypes.QualityInstanceContainer, "quality") self._container_registry.addResourceType(self.ResourceTypes.QualityChangesInstanceContainer, "quality_changes") @@ -483,6 +484,7 @@ class CuraApplication(QtApplication): ("variant", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.VariantInstanceContainer, "application/x-uranium-instancecontainer"), ("setting_visibility", SettingVisibilityPresetsModel.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.SettingVisibilityPreset, "application/x-uranium-preferences"), ("machine", 2): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer"), + ("abstract_machine", 2): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer"), ("extruder", 2): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer") } ) From 32c30faf6acbc6db9c8fdda4a9dfd1cc87a67d5d Mon Sep 17 00:00:00 2001 From: "j.spijker@ultimaker.com" Date: Mon, 22 Aug 2022 11:58:37 +0200 Subject: [PATCH 22/35] Use the latest SIP Contributes to CURA-8788 --- .github/workflows/requirements-conan-package.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/requirements-conan-package.txt b/.github/workflows/requirements-conan-package.txt index cf9d4193ef..fcc1379cfa 100644 --- a/.github/workflows/requirements-conan-package.txt +++ b/.github/workflows/requirements-conan-package.txt @@ -1,2 +1,2 @@ conan!=1.51.0,!=1.51.1,!=1.51.2,!=1.51.3 -sip==6.5.1 +sip From d83673a972b6922c5d35a9d476f289b85369cf8c Mon Sep 17 00:00:00 2001 From: joeydelarago Date: Mon, 22 Aug 2022 14:25:17 +0200 Subject: [PATCH 23/35] Use ConnectionType enum Move import statement CURA-9277 --- cura/Settings/AbstractMachine.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/Settings/AbstractMachine.py b/cura/Settings/AbstractMachine.py index 50321d9a9f..477edc0a0e 100644 --- a/cura/Settings/AbstractMachine.py +++ b/cura/Settings/AbstractMachine.py @@ -1,6 +1,8 @@ from typing import List from UM.Settings.ContainerStack import ContainerStack +from cura.CuraApplication import CuraApplication +from cura.PrinterOutput.PrinterOutputDevice import ConnectionType from cura.Settings.GlobalStack import GlobalStack from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase from UM.Settings.ContainerRegistry import ContainerRegistry @@ -14,13 +16,11 @@ class AbstractMachine(GlobalStack): self.setMetaDataEntry("type", "abstract_machine") def getMachines(self) -> List[ContainerStack]: - from cura.CuraApplication import CuraApplication application = CuraApplication.getInstance() registry = application.getContainerRegistry() printer_type = self.definition.getId() - cloud_printer_type = 3 - return [machine for machine in registry.findContainerStacks(type="machine") if machine.definition.id == printer_type and cloud_printer_type in machine.configuredConnectionTypes] + return [machine for machine in registry.findContainerStacks(type="machine") if machine.definition.id == printer_type and ConnectionType.CloudConnection in machine.configuredConnectionTypes] ## private: From 77a179be76a1f1370f9a5487a968ad5946489bde Mon Sep 17 00:00:00 2001 From: Casper Lamboo Date: Mon, 22 Aug 2022 14:32:59 +0200 Subject: [PATCH 24/35] Code style CURA-9277 Co-authored-by: Jelle Spijker --- cura/Settings/CuraStackBuilder.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index 0b700eae93..98ad3075b7 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -218,7 +218,7 @@ class CuraStackBuilder: # Create user container user_container = cls.createUserChangesContainer(new_stack_id + "_user", definition.getId(), new_stack_id, - is_global_stack=True) + is_global_stack = True) stack.definitionChanges = cls.createDefinitionChangesContainer(stack, new_stack_id + "_settings") stack.variant = variant_container @@ -282,11 +282,11 @@ class CuraStackBuilder: registry = application.getContainerRegistry() container_tree = ContainerTree.getInstance() - if registry.findContainerStacks(type="abstract_machine", id=abstract_machine_id): + if registry.findContainerStacks(type = "abstract_machine", id = abstract_machine_id): # This abstract machine already exists return None - match registry.findDefinitionContainers(type="machine", id=definition_id): + match registry.findDefinitionContainers(type = "machine", id = definition_id): case []: # It should not be possible for the definition to be missing since an abstract machine will only # be created as a result of a machine with definition_id being created. From 5761b3f27b9098c8ffe138876b634d7d6f7ad1a8 Mon Sep 17 00:00:00 2001 From: Casper Lamboo Date: Mon, 22 Aug 2022 14:35:07 +0200 Subject: [PATCH 25/35] Typing CUR-9277 Co-authored-by: Jelle Spijker --- cura/Settings/AbstractMachine.py | 2 +- cura/Settings/CuraStackBuilder.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/cura/Settings/AbstractMachine.py b/cura/Settings/AbstractMachine.py index 477edc0a0e..d3cae76ccb 100644 --- a/cura/Settings/AbstractMachine.py +++ b/cura/Settings/AbstractMachine.py @@ -11,7 +11,7 @@ from UM.Settings.ContainerRegistry import ContainerRegistry class AbstractMachine(GlobalStack): """ Represents a group of machines of the same type. This allows the user to select settings before selecting a printer. """ - def __init__(self, container_id: str): + def __init__(self, container_id: str) -> None: super().__init__(container_id) self.setMetaDataEntry("type", "abstract_machine") diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index 98ad3075b7..6a9ae728b7 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -210,7 +210,7 @@ class CuraStackBuilder: stack: GlobalStack, variant_container: "InstanceContainer", material_container: "InstanceContainer", - quality_container: "InstanceContainer"): + quality_container: "InstanceContainer") -> None: from cura.CuraApplication import CuraApplication application = CuraApplication.getInstance() @@ -268,7 +268,7 @@ class CuraStackBuilder: return definition_changes_container @classmethod - def createAbstractMachine(cls, definition_id) -> Optional[AbstractMachine]: + def createAbstractMachine(cls, definition_id: str) -> Optional[AbstractMachine]: """Create a new instance of an abstract machine. :param definition_id: The ID of the machine definition to use. From 12f3581337b434f26e120ab08e0bccedbe253777 Mon Sep 17 00:00:00 2001 From: Casper Lamboo Date: Mon, 22 Aug 2022 14:44:45 +0200 Subject: [PATCH 26/35] Assign result of `createAbstractMachine` to a variable With prepended underscore to highlight the result of the function is not being used. CURA-9277 --- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index 94b2eec80b..c2d00e98e0 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -405,7 +405,7 @@ class CloudOutputDeviceManager: self._setOutputDeviceMetadata(device, new_machine) - CuraStackBuilder.createAbstractMachine(device.printerType) + _abstract_machine = CuraStackBuilder.createAbstractMachine(device.printerType) if activate: CuraApplication.getInstance().getMachineManager().setActiveMachine(new_machine.getId()) From 35502e45faaa003419340347e7daa7df862415b6 Mon Sep 17 00:00:00 2001 From: Casper Lamboo Date: Mon, 22 Aug 2022 14:48:04 +0200 Subject: [PATCH 27/35] Apply suggestions from code review CURA-9277 Co-authored-by: Jelle Spijker --- cura/CuraApplication.py | 2 +- cura/Settings/AbstractMachine.py | 6 +++--- cura/Settings/CuraContainerRegistry.py | 2 +- cura/Settings/CuraStackBuilder.py | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index f8812285bc..e696609666 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -484,7 +484,7 @@ class CuraApplication(QtApplication): ("variant", InstanceContainer.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.VariantInstanceContainer, "application/x-uranium-instancecontainer"), ("setting_visibility", SettingVisibilityPresetsModel.Version * 1000000 + self.SettingVersion): (self.ResourceTypes.SettingVisibilityPreset, "application/x-uranium-preferences"), ("machine", 2): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer"), - ("abstract_machine", 2): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer"), + ("abstract_machine", 1): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer"), ("extruder", 2): (Resources.DefinitionContainers, "application/x-uranium-definitioncontainer") } ) diff --git a/cura/Settings/AbstractMachine.py b/cura/Settings/AbstractMachine.py index d3cae76ccb..3a8dbd54ea 100644 --- a/cura/Settings/AbstractMachine.py +++ b/cura/Settings/AbstractMachine.py @@ -24,11 +24,11 @@ class AbstractMachine(GlobalStack): ## private: -abstract_machine_mime = MimeType( +_abstract_machine_mime = MimeType( name = "application/x-cura-abstract-machine", comment = "Cura Abstract Machine", suffixes = ["global.cfg"] ) -MimeTypeDatabase.addMimeType(abstract_machine_mime) -ContainerRegistry.addContainerTypeByName(AbstractMachine, "abstract_machine", abstract_machine_mime.name) +MimeTypeDatabase.addMimeType(_abstract_machine_mime) +ContainerRegistry.addContainerTypeByName(AbstractMachine, "abstract_machine", _abstract_machine_mime.name) diff --git a/cura/Settings/CuraContainerRegistry.py b/cura/Settings/CuraContainerRegistry.py index 70d03b5ddc..1a711ef919 100644 --- a/cura/Settings/CuraContainerRegistry.py +++ b/cura/Settings/CuraContainerRegistry.py @@ -108,7 +108,7 @@ class CuraContainerRegistry(ContainerRegistry): :param container_type: :type{string} Type of the container (machine, quality, ...) :param container_name: :type{string} Name to check """ - container_class = ContainerStack if container_type in "machine" else InstanceContainer + container_class = ContainerStack if "machine" in container_type else InstanceContainer return self.findContainersMetadata(container_type = container_class, id = container_name, type = container_type, ignore_case = True) or \ self.findContainersMetadata(container_type = container_class, name = container_name, type = container_type) diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index 6a9ae728b7..1c55026dcf 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -290,7 +290,7 @@ class CuraStackBuilder: case []: # It should not be possible for the definition to be missing since an abstract machine will only # be created as a result of a machine with definition_id being created. - Logger.error("w", "Definition {definition} was not found!", definition=definition_id) + Logger.error(f"Definition {definition_id} was not found!") return None case [machine_definition, *_definitions]: machine_node = container_tree.machines[machine_definition.getId()] From 54e9dbf82793da9e41525813822e4b8aebe73c52 Mon Sep 17 00:00:00 2001 From: jspijker Date: Mon, 22 Aug 2022 14:57:28 +0200 Subject: [PATCH 28/35] Show device name of failed machine creation in log CURA-9277 Detect and Load Specific printers and Cloud Printer Types --- .../UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py index c2d00e98e0..30bbf68f6c 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDeviceManager.py @@ -400,7 +400,7 @@ class CloudOutputDeviceManager: # 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, show_warning_message=False) if not new_machine: - Logger.log("e", "Failed creating a new machine") + Logger.error(f"Failed creating a new machine for {device.name}") return False self._setOutputDeviceMetadata(device, new_machine) From 5082e64f0c1d60e4820a3ba35fd3ca82c8be3051 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Mon, 22 Aug 2022 14:58:32 +0200 Subject: [PATCH 29/35] Move cura-import to top of the file Cura-9277 Co-authored-by: joeydelarago --- cura/Settings/CuraStackBuilder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index 1c55026dcf..b016db22d7 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -9,6 +9,7 @@ from UM.Settings.Interfaces import DefinitionContainerInterface from UM.Settings.InstanceContainer import InstanceContainer from cura.Machines.ContainerTree import ContainerTree +from cura.CuraApplication import CuraApplication from .AbstractMachine import AbstractMachine from .GlobalStack import GlobalStack from .ExtruderStack import ExtruderStack @@ -277,7 +278,6 @@ class CuraStackBuilder: """ abstract_machine_id = definition_id + "_abstract_machine" - from cura.CuraApplication import CuraApplication application = CuraApplication.getInstance() registry = application.getContainerRegistry() container_tree = ContainerTree.getInstance() From f6bf7050fb5d574ccfb94310bf58cf9beeab38c6 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Mon, 22 Aug 2022 15:01:51 +0200 Subject: [PATCH 30/35] Revert "Move cura-import to top of the file" This reverts commit 5082e64f0c1d60e4820a3ba35fd3ca82c8be3051. --- cura/Settings/CuraStackBuilder.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index b016db22d7..1c55026dcf 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -9,7 +9,6 @@ from UM.Settings.Interfaces import DefinitionContainerInterface from UM.Settings.InstanceContainer import InstanceContainer from cura.Machines.ContainerTree import ContainerTree -from cura.CuraApplication import CuraApplication from .AbstractMachine import AbstractMachine from .GlobalStack import GlobalStack from .ExtruderStack import ExtruderStack @@ -278,6 +277,7 @@ class CuraStackBuilder: """ abstract_machine_id = definition_id + "_abstract_machine" + from cura.CuraApplication import CuraApplication application = CuraApplication.getInstance() registry = application.getContainerRegistry() container_tree = ContainerTree.getInstance() From 5884aa3311578f5e9d8043cdfc747f07eadf314e Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Mon, 22 Aug 2022 15:03:48 +0200 Subject: [PATCH 31/35] Add comment about circular import Cura-9277 Co-authored-by: joeydelarago --- cura/Settings/CuraStackBuilder.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cura/Settings/CuraStackBuilder.py b/cura/Settings/CuraStackBuilder.py index 1c55026dcf..7eff275457 100644 --- a/cura/Settings/CuraStackBuilder.py +++ b/cura/Settings/CuraStackBuilder.py @@ -28,7 +28,7 @@ class CuraStackBuilder: :return: The new global stack or None if an error occurred. """ - from cura.CuraApplication import CuraApplication + from cura.CuraApplication import CuraApplication # inline import needed due to circular import application = CuraApplication.getInstance() registry = application.getContainerRegistry() container_tree = ContainerTree.getInstance() @@ -92,7 +92,7 @@ class CuraStackBuilder: :param extruder_position: The position of the current extruder. """ - from cura.CuraApplication import CuraApplication + from cura.CuraApplication import CuraApplication # inline import needed due to circular import application = CuraApplication.getInstance() registry = application.getContainerRegistry() From 3413caab6218d550bbc9f0ebc9d266394a0ca686 Mon Sep 17 00:00:00 2001 From: joeydelarago Date: Mon, 22 Aug 2022 16:29:08 +0200 Subject: [PATCH 32/35] Set latest.json location back to ultimaker website. CURA-9272 --- conanfile.py | 2 +- cura/ApplicationMetadata.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/conanfile.py b/conanfile.py index ca835a53fc..bcdaeda5d9 100644 --- a/conanfile.py +++ b/conanfile.py @@ -102,7 +102,7 @@ class CuraConan(ConanFile): @property def _cura_latest_url(self): - return "https://raw.githubusercontent.com/Ultimaker/Uranium/CURA-9272_semver_postfix/tests/latest.json" + return "https://software.ultimaker.com/latest.json" @property def requirements_txts(self): diff --git a/cura/ApplicationMetadata.py b/cura/ApplicationMetadata.py index 678f8b7e4a..4938d569e7 100644 --- a/cura/ApplicationMetadata.py +++ b/cura/ApplicationMetadata.py @@ -9,7 +9,7 @@ DEFAULT_CURA_DISPLAY_NAME = "Ultimaker Cura" DEFAULT_CURA_VERSION = "dev" DEFAULT_CURA_BUILD_TYPE = "" DEFAULT_CURA_DEBUG_MODE = False -DEFAULT_CURA_LATEST_URL = "https://raw.githubusercontent.com/Ultimaker/Uranium/CURA-9272_semver_postfix/tests/latest.json" +DEFAULT_CURA_LATEST_URL = "https://software.ultimaker.com/latest.json" # 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 From c80dd621696ace2889d7df51a88079bb96c8af66 Mon Sep 17 00:00:00 2001 From: joeydelarago Date: Mon, 22 Aug 2022 16:34:18 +0200 Subject: [PATCH 33/35] Fix circular import. CURA-9277 --- cura/Settings/AbstractMachine.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cura/Settings/AbstractMachine.py b/cura/Settings/AbstractMachine.py index 3a8dbd54ea..a89201a294 100644 --- a/cura/Settings/AbstractMachine.py +++ b/cura/Settings/AbstractMachine.py @@ -1,7 +1,6 @@ from typing import List from UM.Settings.ContainerStack import ContainerStack -from cura.CuraApplication import CuraApplication from cura.PrinterOutput.PrinterOutputDevice import ConnectionType from cura.Settings.GlobalStack import GlobalStack from UM.MimeTypeDatabase import MimeType, MimeTypeDatabase @@ -16,6 +15,8 @@ class AbstractMachine(GlobalStack): self.setMetaDataEntry("type", "abstract_machine") def getMachines(self) -> List[ContainerStack]: + from cura.CuraApplication import CuraApplication + application = CuraApplication.getInstance() registry = application.getContainerRegistry() From e073adfa9efbe922f1c1058039bbfc285fe8676d Mon Sep 17 00:00:00 2001 From: joeydelarago Date: Mon, 22 Aug 2022 17:02:53 +0200 Subject: [PATCH 34/35] Fix conditional in recipe versioning to use proper syntax --- .github/workflows/conan-recipe-version.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/conan-recipe-version.yml b/.github/workflows/conan-recipe-version.yml index 3ab3d59547..9b662e215b 100644 --- a/.github/workflows/conan-recipe-version.yml +++ b/.github/workflows/conan-recipe-version.yml @@ -135,7 +135,7 @@ jobs: user = "_" channel = "_" else: - if not latest_branch_version.prerelease.contains("."): + if not "." in latest_branch_version.prerelease: # The prerealese did not contain a version number, default it to 1 latest_branch_version.prerelease.append(".1") if event_name == "pull_request": From 21878058eb501647582668ccad5e3214d6f43edd Mon Sep 17 00:00:00 2001 From: joeydelarago Date: Mon, 22 Aug 2022 17:08:55 +0200 Subject: [PATCH 35/35] Fix prerelease string assignment --- .github/workflows/conan-recipe-version.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/conan-recipe-version.yml b/.github/workflows/conan-recipe-version.yml index 9b662e215b..ddadfe1781 100644 --- a/.github/workflows/conan-recipe-version.yml +++ b/.github/workflows/conan-recipe-version.yml @@ -135,9 +135,9 @@ jobs: user = "_" channel = "_" else: - if not "." in latest_branch_version.prerelease: + if latest_branch_version.prerelease and not "." in latest_branch_version.prerelease: # The prerealese did not contain a version number, default it to 1 - latest_branch_version.prerelease.append(".1") + latest_branch_version.prerelease += ".1" if event_name == "pull_request": actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{latest_branch_version.patch}-{latest_branch_version.prerelease.lower()}+{buildmetadata}pr_{issue_number}_{no_commits}" else: