From 24a0ba3974933ab15d55c0e5a262aa22b9c19856 Mon Sep 17 00:00:00 2001 From: jellespijker Date: Tue, 10 Oct 2023 05:20:19 +0200 Subject: [PATCH 001/133] Update PyQt6 dependencies to latest versions PyQt6 and PyQt6-sip along with their dependencies are updated to newer versions (6.5.2 and 13.5.2) in both requirements.txt and Uranium/requirements.txt. This is to ensure the application uses the latest and most secure versions of the libraries, potentially improving application performance and security. These updates also ensure compatibility with current and upcoming features and bug fixes. Contributes to CURA-11137 --- requirements.txt | 75 ++++++++++++++++++++++++------------------------ 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/requirements.txt b/requirements.txt index dfa974ef7d..48ee3abcdc 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,41 +1,42 @@ ### Direct requirements for Uranium and libCharon ### -PyQt6-sip==13.4.1 \ - --hash=sha256:0df998f2b6ceeacfd10de773441572e215be0c9cae566cc7dd36e231bf714a12 \ - --hash=sha256:224575e84805c4317bacd5d1b8e93e0ad5c48685dadbbe1e902d4ebe16f22828 \ - --hash=sha256:36ae29cdc223cacc1257d0f5075cf81474550c6d26b728f922487a2aa935f130 \ - --hash=sha256:3a674c591d4274d4ea8127205290e927a7dab0eb87a0038d4f4ea1d430782649 \ - --hash=sha256:3ef9392e4ae29d393b79237d85840cdc6b8831f36eed5d56c7d9b329b380cc8d \ - --hash=sha256:43935873d60f57719632840d517afee04ef8f30e92cfe0dadc7e6326691920fc \ - --hash=sha256:5731f22618435654352ef07684549a17be82b75254227fc80b4b5b0b59fc6656 \ - --hash=sha256:5bc4beb6fb1de4c9ba8beee7b1a4a813fa888c3b095206dafcd25d7e6e4ed2a7 \ - --hash=sha256:5c36ab984402e96792eebf4b031abfaa589aa20af3190a79c54502c16964d97e \ - --hash=sha256:a2a0461992c6657f343308b150c4d6b57e9e7a0e5c2f79538434e7fb869ea827 \ - --hash=sha256:a81490ee84d7a41a126b116081bd97d758f41bf706aee0a8cec24d6e4c660184 \ - --hash=sha256:e00e287ea05bbc293fc6e2198301962af9b7b622bd2daf4288f925a88ae35dc9 \ - --hash=sha256:e670a7b2fb7e32204ce67d274017bfff3e21139d217d60cebbfcb75b019c91ee \ - --hash=sha256:ee06f255787a0b4957f357f93b78d2a11ca3761916833e3afa83f1381d4d1a46 \ - --hash=sha256:fbee0d554e0e98f56dbf6d94b00a28cc32425938ad7ae98fd91f8822c5b24d45 \ - --hash=sha256:fcc6d78314783f4a193f02353f431b7ea4d357f47c3c7a7d0740e723f69c64dc -PyQt6==6.4.2 \ - --hash=sha256:18d1daf98d9236d55102cdadafd1056f5802f3c9288fcf7238569937b71a89f0 \ - --hash=sha256:25bd399b4a95dce65d5f937c1aa85d3c7e14a21745ae2a4ca14c0116cd104290 \ - --hash=sha256:740244f608fe15ee1d89695c43f31a14caeca41c4f02ac36c86dfba4a5d5813d \ - --hash=sha256:c128bc0f17833e324593e3db83e99470d451a197dd17ff0333927b946c935bd9 -PyQt6-Qt6==6.4.2 \ - --hash=sha256:9f07c3c100cb46cca4074965e7494d4df4f0fc016497d5303c1fe135822876e1 \ - --hash=sha256:a29b8c858babd523e80c8db5f8fd19792641588ec04eab49af18b7a4423eb99f \ - --hash=sha256:c0e91d0275d428496cacff717a9b719c52bfa52b21f124d638b79cc2217bc81e \ - --hash=sha256:d19c4e72615762cd6f0b043f23fa5f0b02656091427ce6de1efccd58e10e6a53 -PyQt6-NetworkAuth==6.4.0 \ - --hash=sha256:ab6178b3b2902ae9939a148555cfcee8c7803d6b0d5924cd1bd8f3407b8b9210 \ - --hash=sha256:c16ec80232d88024b60d04386a23cc93067e5644a65f47f26ffb13d84dcd4a6d \ - --hash=sha256:c302cd0d838c7229eda5e26e0b1b3d3ec4f8720f8d9379472bce5a89ff0735c2 \ - --hash=sha256:d948fc0cf43b64afbda2acb5bf2392f785a1e7a2950d79ea850c1a3f4ae12f1a -PyQt6-NetworkAuth-Qt6==6.4.2 \ - --hash=sha256:179094bcb4d4d056316c22d3d067cd94d4591da23f804461bfb025ccfa29b2b4 \ - --hash=sha256:1de6abbb5fa6585b97ae49d3f64b0dfad40bd56b1a31744d9775ff26247241c8 \ - --hash=sha256:79ec4b0fc9450bbedbff03541b93b10d1c7e761cd2cc16ce70d2b09dcdf8c720 \ - --hash=sha256:d96d557fe61edb9b68d189f270f0393d6579c8d308e6b0d41bc0699371d7cb4e +PyQt6-sip==13.5.2 \ + --hash=sha256:1bdb1f7b5b2f6ac31d517a6f3a13c38055640ac0014f67a2e5422d2083ce69ec \ + --hash=sha256:318d4d1c7ef60f69c68227cef78fc439accc9028ec6149200eea3d34c433d373 \ + --hash=sha256:4b5b0c4b557e0293eba008021342459a0f91c69a7a2eb5231276d495d1d2960a \ + --hash=sha256:5b499eff7150d9f31fe835a73cc41f076bba2fcde0f5b0325b1284797f17c0ac \ + --hash=sha256:5d0fd42da765198b51d7fe12c29721cbe3e14b77ca4f68aa43618149ee7dbeff \ + --hash=sha256:831f5d606fc5296a80303ab30892c3308954c5766039bf7a96267488bb2524a5 \ + --hash=sha256:87d758ba999baa16459f0a3c7f7ed47a5b45e8991ad691f17345bf3c493a4281 \ + --hash=sha256:91812f0094443b816a74a89954d60bb50060807f54d7c016a4de7bd29454091e \ + --hash=sha256:94afb031db89159aa330891eba2c937b0378b4b264570998848c7a78eddf7c94 \ + --hash=sha256:9ad5b8c4c92d62e00ebf254a4c9656668b130f2a1d2792034e0d82b2d6571509 \ + --hash=sha256:9c9dac067710015895f523f5a2a4d59cbef8624a152b6f9a426e5b848d8c6d29 \ + --hash=sha256:ace942b78378bff8ae2d6bafccc84465f1ff0cf30720b8321e0bd6c95c36ede6 \ + --hash=sha256:b54b0d8d21c5835af8f6d6d8a323a23106e67b7cd4c31e23c35bb4c321000de8 \ + --hash=sha256:c0b4e55c4d0dc44728da90eb1451dfff0d05260b4a3496ff0014494e6c1865a6 \ + --hash=sha256:dcf602c233ee7600e810927adcb9e518d61bc796a6b2013c17feedd24c4e5413 \ + --hash=sha256:ebf6264b6feda01ba37d3b60a4bb87493bdb87be70f7b2a5384a7acd4902d88d +PyQt6==6.5.2 \ + --hash=sha256:1487ee7350f9ffb66d60ab4176519252c2b371762cbe8f8340fd951f63801280 \ + --hash=sha256:5bad1437eb0c1ae801103b32ef04ef62ef1cce505b448525f60089ce36329b89 \ + --hash=sha256:70468cca4537756c714a57fa1baa5beabb9b38775f52f9611f49870705672c55 \ + --hash=sha256:ff1d12767b578f0f0e87cdb12198e7dcad9a176c40d1d1d799984181b0af93cb +PyQt6-Qt6==6.5.2 \ + --hash=sha256:4b37f6f93c0980469ccc570998d3e3de243028bae7389fb6330443ab215ce2f6 \ + --hash=sha256:5a3c7bb899678bf801136b31cd589ed4d0d54ab32be5fb76c2bdeb161a9662ad \ + --hash=sha256:8dad61b4666d91882d7e1c4d619c71e7429c13e19182f8b3bebf3ecf95107d4c \ + --hash=sha256:953f3c0e99e486081a6d438b32fbc240da97457226562eb68cf1b11c516386fd +PyQt6-NetworkAuth==6.5.0 \ + --hash=sha256:6dc9e44a978698b673926e34da486f946ccbbeeac02078517c4d1ee23d0546a4 \ + --hash=sha256:7170db3f99e13aef855d9d52a00a8baa2dea92d12f9b441fed9c6dec57f83e09 \ + --hash=sha256:a8c8cb00a615dde1efaf1d7926e8532df77d6d08798d33b6325fb8f2ff0f220d \ + --hash=sha256:ac56d362c9efcfc194e358cc2bba362535b0775dc2bd8257f964e0bcfe7d421a +PyQt6-NetworkAuth-Qt6==6.5.2 \ + --hash=sha256:0588b93ec5a6f2c492a42dc56967f06d33306169e716c5636448816a65956278 \ + --hash=sha256:29396a63b68e8fa26587c35e8befad0a84e3a05e03551d1329ffd527684edc68 \ + --hash=sha256:2ec8ca45764d2f122912ad6c754b5ffe65f143b5a52f99649cc7931b475e064b \ + --hash=sha256:76e0877ed86247784740a0eb928f3c77da7466f08d96d17306efda6060df2c44 + certifi==2023.5.7; \ --hash=sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716 cryptography==41.0.1 \ From 6301926885f170f79189b0cf6fdc2d3594d1ba2e Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 7 Nov 2023 18:08:08 +0530 Subject: [PATCH 002/133] Calculating time of travel for each line segment CURA-7647 --- cura/LayerPolygon.py | 6 ++++++ plugins/SimulationView/SimulationView.py | 5 +++++ plugins/SimulationView/SimulationViewMainComponent.qml | 6 +++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py index 103703e594..4eb21dd45f 100644 --- a/cura/LayerPolygon.py +++ b/cura/LayerPolygon.py @@ -1,5 +1,6 @@ # Copyright (c) 2019 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. +import math import numpy from typing import Optional, cast @@ -186,6 +187,11 @@ class LayerPolygon: def types(self): return self._types + @property + def lineLengths(self): + return [math.sqrt(sum((b - a) ** 2 for a, b in zip(self._data[i], self._data[i + 1]))) + for i in range(len(self._data) - 1)] + @property def data(self): return self._data diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 473948bc46..88fc44df98 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -400,6 +400,9 @@ class SimulationView(CuraView): def getMaxFeedrate(self) -> float: return self._max_feedrate + def getSimulationTime(self) -> list: + return [length / feedrate for length, feedrate in zip(self._visible_lengths, self._current_feedrates)] + def getMinThickness(self) -> float: if abs(self._min_thickness - sys.float_info.max) < 10: # Some lenience due to floating point rounding. return 0.0 # If it's still max-float, there are no measurements. Use 0 then. @@ -524,8 +527,10 @@ class SimulationView(CuraView): visible_indicies_with_extrusion = numpy.where(numpy.isin(polyline.types, visible_line_types_with_extrusion))[0] if visible_indices.size == 0: # No items to take maximum or minimum of. continue + self._visible_lengths = numpy.take(polyline.lineLengths, visible_indices) visible_feedrates = numpy.take(polyline.lineFeedrates, visible_indices) visible_feedrates_with_extrusion = numpy.take(polyline.lineFeedrates, visible_indicies_with_extrusion) + self._current_feedrates = visible_feedrates visible_linewidths = numpy.take(polyline.lineWidths, visible_indices) visible_linewidths_with_extrusion = numpy.take(polyline.lineWidths, visible_indicies_with_extrusion) visible_thicknesses = numpy.take(polyline.lineThicknesses, visible_indices) diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index a82d1e3db9..b2ef7b8356 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -136,9 +136,10 @@ Item Timer { id: simulationTimer - interval: 100 + interval: parseFloat(UM.SimulationView.getSimulationTime[pathNumber]).toFixed(2) //10 //dont change running: false repeat: true + property int pathNumber : 0 onTriggered: { var currentPath = UM.SimulationView.currentPath @@ -153,10 +154,12 @@ Item if (currentPath >= numPaths) { UM.SimulationView.setCurrentPath(0) + pathNumber =0 } else { UM.SimulationView.setCurrentPath(currentPath + 1) + pathNumber = 0 } } // If the simulation is already playing and we reach the end of a layer, then it automatically @@ -184,6 +187,7 @@ Item // The status must be set here instead of in the resumeSimulation function otherwise it won't work // correctly, because part of the logic is in this trigger function. isSimulationPlaying = true + pathNumber += 1 } } From efda0aaba4329948485021bbbc4d2e365a5b63c4 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 7 Nov 2023 18:42:41 +0530 Subject: [PATCH 003/133] updated for every layer CURA-7647 --- plugins/SimulationView/SimulationView.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 88fc44df98..2f09c8018b 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -78,6 +78,8 @@ class SimulationView(CuraView): self._minimum_path_num = 0 self.currentLayerNumChanged.connect(self._onCurrentLayerNumChanged) + self._current_feedrates = {} + self._visible_lengths ={} self._busy = False self._simulation_running = False @@ -401,7 +403,7 @@ class SimulationView(CuraView): return self._max_feedrate def getSimulationTime(self) -> list: - return [length / feedrate for length, feedrate in zip(self._visible_lengths, self._current_feedrates)] + return [length / feedrate for length, feedrate in zip(self._visible_lengths[self._current_layer_num], self._current_feedrates[self._current_layer_num])] def getMinThickness(self) -> float: if abs(self._min_thickness - sys.float_info.max) < 10: # Some lenience due to floating point rounding. @@ -527,10 +529,10 @@ class SimulationView(CuraView): visible_indicies_with_extrusion = numpy.where(numpy.isin(polyline.types, visible_line_types_with_extrusion))[0] if visible_indices.size == 0: # No items to take maximum or minimum of. continue - self._visible_lengths = numpy.take(polyline.lineLengths, visible_indices) + self._visible_lengths[layer_index] = numpy.take(polyline.lineLengths, visible_indices) visible_feedrates = numpy.take(polyline.lineFeedrates, visible_indices) visible_feedrates_with_extrusion = numpy.take(polyline.lineFeedrates, visible_indicies_with_extrusion) - self._current_feedrates = visible_feedrates + self._current_feedrates[layer_index] = visible_feedrates visible_linewidths = numpy.take(polyline.lineWidths, visible_indices) visible_linewidths_with_extrusion = numpy.take(polyline.lineWidths, visible_indicies_with_extrusion) visible_thicknesses = numpy.take(polyline.lineThicknesses, visible_indices) From 457cecba5943c09b1b3b5b2a573a18c0915e0bc0 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Wed, 8 Nov 2023 13:29:47 +0530 Subject: [PATCH 004/133] using numpy for array calculation CURA-7647 --- cura/LayerPolygon.py | 4 ++-- plugins/SimulationView/SimulationView.py | 2 +- plugins/SimulationView/SimulationViewMainComponent.qml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py index 4eb21dd45f..e5fd307dc9 100644 --- a/cura/LayerPolygon.py +++ b/cura/LayerPolygon.py @@ -189,8 +189,8 @@ class LayerPolygon: @property def lineLengths(self): - return [math.sqrt(sum((b - a) ** 2 for a, b in zip(self._data[i], self._data[i + 1]))) - for i in range(len(self._data) - 1)] + data_array = numpy.array(self._data) + return numpy.linalg.norm(data_array[1:] - data_array[:-1], axis=1) @property def data(self): diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 2f09c8018b..18d1f981c7 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -403,7 +403,7 @@ class SimulationView(CuraView): return self._max_feedrate def getSimulationTime(self) -> list: - return [length / feedrate for length, feedrate in zip(self._visible_lengths[self._current_layer_num], self._current_feedrates[self._current_layer_num])] + return self._visible_lengths[self._current_layer_num] / self._current_feedrates[self._current_layer_num] def getMinThickness(self) -> float: if abs(self._min_thickness - sys.float_info.max) < 10: # Some lenience due to floating point rounding. diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index b2ef7b8356..66acff656a 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -136,7 +136,7 @@ Item Timer { id: simulationTimer - interval: parseFloat(UM.SimulationView.getSimulationTime[pathNumber]).toFixed(2) //10 //dont change + interval: parseFloat(UM.SimulationView.getSimulationTime[pathNumber]).toFixed(2) running: false repeat: true property int pathNumber : 0 From 2dfe6d7e5df4251bd2deac449453bc3d09248ac5 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Sat, 11 Nov 2023 08:54:23 +0100 Subject: [PATCH 005/133] Set requirements and version with conandata This will allow workflow automations to easily create release branches and set the versions Contributes to CURA-10831 --- conandata.yml | 19 +++++++++++++++++++ conanfile.py | 26 +++++++------------------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/conandata.yml b/conandata.yml index c027bde567..a36e30983c 100644 --- a/conandata.yml +++ b/conandata.yml @@ -1,3 +1,22 @@ +version: "5.6.0-beta.1" +requirements: + - "uranium/(latest)@ultimaker/stable" + - "curaengine/(latest)@ultimaker/stable" + - "cura_binary_data/(latest)@ultimaker/stable" + - "fdm_materials/(latest)@ultimaker/stable" + - "curaengine_plugin_gradual_flow/0.1.0" + - "dulcificum/(latest)@ultimaker/stable" + - "pyarcus/5.3.0" + - "pysavitar/5.3.0" + - "pynest2d/5.3.0" + - "curaengine_grpc_definitions/0.1.0" + - "cpython/3.10.4" + - "boost/1.82.0" + - "fmt/9.0.0" + - "zlib/1.2.13" +requirements_internal: + - "fdm_materials/(latest)@internal/testing" + - "cura_private_data/(latest)@internal/testing" urls: default: cloud_api_root: "https://api.ultimaker.com" diff --git a/conanfile.py b/conanfile.py index 20ded4bc3c..ae0caaacdf 100644 --- a/conanfile.py +++ b/conanfile.py @@ -50,7 +50,7 @@ class CuraConan(ConanFile): def set_version(self): if not self.version: - self.version = "5.6.0-beta.1" + self.version = self.conan_data["version"] @property def _pycharm_targets(self): @@ -313,24 +313,12 @@ class CuraConan(ConanFile): raise ConanInvalidConfiguration("Only versions 5+ are support") def requirements(self): - self.requires("boost/1.82.0") - self.requires("fmt/9.0.0") - self.requires("curaengine_grpc_definitions/0.1.0") - self.requires("zlib/1.2.13") - self.requires("pyarcus/5.3.0") - self.requires("dulcificum/(latest)@ultimaker/stable") - self.requires("curaengine/(latest)@ultimaker/stable") - self.requires("pysavitar/5.3.0") - self.requires("pynest2d/5.3.0") - self.requires("curaengine_plugin_gradual_flow/0.1.0") - self.requires("uranium/(latest)@ultimaker/stable") - self.requires("cura_binary_data/(latest)@ultimaker/stable") - self.requires("cpython/3.10.4") - if self.options.internal: - self.requires("cura_private_data/(latest)@internal/testing") - self.requires("fdm_materials/(latest)@internal/testing") - else: - self.requires("fdm_materials/(latest)@ultimaker/stable") + for req in self.conan_data["requirements"]: + if self.options.internal and "fdm_materials" in req: + continue + self.requires(req) + for req in self.conan_data["requirements_internal"]: + self.requires(req) def build_requirements(self): if self.options.get_safe("enable_i18n", False): From 220054cbb52db2d245360f5ba38dcf5c92bf1b85 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Sat, 11 Nov 2023 08:59:53 +0100 Subject: [PATCH 006/133] Use cura-workflows to determine version Contributes to CURA-10831 --- .github/workflows/conan-package.yml | 2 +- .github/workflows/conan-recipe-version.yml | 217 --------------------- .github/workflows/unit-test.yml | 2 +- 3 files changed, 2 insertions(+), 219 deletions(-) delete mode 100644 .github/workflows/conan-recipe-version.yml diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index 4b5c0f914a..ad460f56b9 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -63,7 +63,7 @@ jobs: permissions: contents: read - uses: ultimaker/cura/.github/workflows/conan-recipe-version.yml@main + uses: ultimaker/cura-workflows/.github/workflows/conan-recipe-version.yml@CURA-10831 with: project_name: cura diff --git a/.github/workflows/conan-recipe-version.yml b/.github/workflows/conan-recipe-version.yml deleted file mode 100644 index 097b9f5dd6..0000000000 --- a/.github/workflows/conan-recipe-version.yml +++ /dev/null @@ -1,217 +0,0 @@ -name: Get Conan Recipe Version - -on: - workflow_call: - inputs: - project_name: - required: true - type: string - - user: - required: false - default: ultimaker - type: string - - additional_buildmetadata: - required: false - default: "" - type: string - - outputs: - recipe_id_full: - description: "The full Conan recipe id: /@/" - value: ${{ jobs.get-semver.outputs.recipe_id_full }} - - recipe_id_latest: - description: "The full Conan recipe aliased (latest) id: /(latest)@/" - value: ${{ jobs.get-semver.outputs.recipe_id_latest }} - - recipe_semver_full: - description: "The full semver ..-+" - value: ${{ jobs.get-semver.outputs.semver_full }} - - is_release_branch: - description: "is current branch a release branch?" - value: ${{ jobs.get-semver.outputs.release_branch }} - - user: - description: "The conan user" - value: ${{ jobs.get-semver.outputs.user }} - - channel: - description: "The conan channel" - value: ${{ jobs.get-semver.outputs.channel }} - - project_name: - description: "The conan projectname" - value: ${{ inputs.project_name }} - -jobs: - get-semver: - - runs-on: ubuntu-latest - - outputs: - recipe_id_full: ${{ steps.get-conan-broadcast-data.outputs.recipe_id_full }} - recipe_id_latest: ${{ steps.get-conan-broadcast-data.outputs.recipe_id_latest }} - semver_full: ${{ steps.get-conan-broadcast-data.outputs.semver_full }} - is_release_branch: ${{ steps.get-conan-broadcast-data.outputs.is_release_branch }} - user: ${{ steps.get-conan-broadcast-data.outputs.user }} - channel: ${{ steps.get-conan-broadcast-data.outputs.channel }} - - steps: - - name: Checkout repo - uses: actions/checkout@v3 - if: ${{ github.event.pull_request.head.repo.full_name == github.repository }} - with: - fetch-depth: 0 - ref: ${{ github.head_ref }} - - - name: Checkout repo PR - uses: actions/checkout@v3 - if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} - with: - fetch-depth: 0 - ref: ${{ github.base_ref }} - - - name: Setup Python and pip - uses: actions/setup-python@v4 - with: - python-version: "3.11.x" - cache: 'pip' - cache-dependency-path: .github/workflows/requirements-conan-package.txt - - - name: Install Python requirements and Create default Conan profile - run: | - pip install -r .github/workflows/requirements-conan-package.txt - pip install gitpython - - - id: get-conan-broadcast-data - name: Get Conan broadcast data - run: | - import subprocess - import os - from conan.tools.scm import Version - from conan.errors import ConanException - from git import Repo - - repo = Repo('.') - user = "${{ inputs.user }}".lower() - project_name = "${{ inputs.project_name }}" - event_name = "${{ github.event_name }}" - issue_number = "${{ github.ref }}".split('/')[2] - is_tag = "${{ github.ref_type }}" == "tag" - is_release_branch = False - ref_name = "${{ github.base_ref }}" if event_name == "pull_request" else "${{ github.ref_name }}" - buildmetadata = "" if "${{ inputs.additional_buildmetadata }}" == "" else "${{ inputs.additional_buildmetadata }}_" - - # FIXME: for when we push a tag (such as an release) - channel = "testing" - if is_tag: - branch_version = Version(ref_name) - is_release_branch = True - channel = "_" - user = "_" - actual_version = f"{branch_version}" - else: - try: - branch_version = Version(repo.active_branch.name) - except ConanException: - branch_version = Version('0.0.0') - if ref_name == f"{branch_version.major}.{branch_version.minor}": - channel = 'stable' - is_release_branch = True - elif ref_name in ("main", "master"): - channel = 'testing' - else: - channel = "_".join(repo.active_branch.name.replace("-", "_").split("_")[:2]).lower() - - if "pull_request" in event_name: - channel = f"pr_{issue_number}" - - # %% Get the actual version - latest_branch_version = Version("0.0.0") - latest_branch_tag = None - for tag in repo.active_branch.repo.tags: - if str(tag).startswith("firmware") or str(tag).startswith("master"): - continue # Quick-fix for the versioning scheme name of the embedded team in fdm_materials(_private) repo - try: - version = Version(tag) - except ConanException: - continue - if version > latest_branch_version and version < Version("6.0.0"): - # FIXME: stupid old Cura tags 13.04 etc. keep popping up, als the fdm_material tag for firmware are messing with this - latest_branch_version = version - latest_branch_tag = repo.tag(tag) - - if latest_branch_tag: - # %% Get the actual version - sha_commit = repo.commit().hexsha[:6] - latest_branch_version_prerelease = latest_branch_version.pre - if latest_branch_version.pre and not "." in str(latest_branch_version.pre): - # The prerealese did not contain a version number, default it to 1 - latest_branch_version_prerelease = f"{latest_branch_version.pre}.1" - if event_name == "pull_request": - actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{latest_branch_version.patch}-{str(latest_branch_version_prerelease).lower()}+{buildmetadata}pr_{issue_number}_{sha_commit}" - channel_metadata = f"{channel}_{sha_commit}" - else: - if channel in ("stable", "_", ""): - channel_metadata = f"{sha_commit}" - else: - channel_metadata = f"{channel}_{sha_commit}" - if is_release_branch: - if (latest_branch_version.pre == "" or latest_branch_version.pre is None) and branch_version > latest_branch_version: - actual_version = f"{branch_version.major}.{branch_version.minor}.0-beta.1+{buildmetadata}{channel_metadata}" - elif latest_branch_version.pre == "": - # An actual full release has been created, we are working on patch - bump_up_patch = int(str(latest_branch_version.patch)) + 1 - actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{bump_up_patch}-beta.1+{buildmetadata}{channel_metadata}" - elif latest_branch_version.pre is None: - actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{int(latest_branch_version.patch.value) + 1}-beta.1+{buildmetadata}{channel_metadata}" - else: - # An beta release has been created we are working toward a next beta or full release - bump_up_release_tag = int(str(latest_branch_version.pre).split('.')[1]) + 1 - actual_version = f"{latest_branch_version.major}.{latest_branch_version.minor}.{latest_branch_version.patch}-{str(latest_branch_version.pre).split('.')[0]}.{bump_up_release_tag}+{buildmetadata}{channel_metadata}" - else: - max_branches_version = Version("0.0.0") - for branch in repo.references: - try: - if "remotes/origin" in branch.abspath: - b_version = Version(branch.name.split("/")[-1]) - if b_version < Version("6.0.0") and b_version > max_branches_version: - max_branches_version = b_version - except: - pass - if max_branches_version > latest_branch_version: - actual_version = f"{max_branches_version.major}.{int(str(max_branches_version.minor)) + 1}.0-alpha+{buildmetadata}{channel}_{sha_commit}" - else: - actual_version = f"{latest_branch_version.major}.{int(str(latest_branch_version.minor)) + 1}.0-alpha+{buildmetadata}{channel_metadata}" - - # %% Set the environment output - output_env = os.environ["GITHUB_OUTPUT"] - content = "" - if os.path.exists(output_env): - with open(output_env, "r") as f: - content = f.read() - - with open(output_env, "w") as f: - f.write(content) - f.writelines(f"name={project_name}\n") - f.writelines(f"version={actual_version}\n") - f.writelines(f"channel={channel}\n") - f.writelines(f"recipe_id_full={project_name}/{actual_version}@{user}/{channel}\n") - f.writelines(f"recipe_id_latest={project_name}/latest@{user}/{channel}\n") - f.writelines(f"semver_full={actual_version}\n") - f.writelines(f"is_release_branch={str(is_release_branch).lower()}\n") - - summary_env = os.environ["GITHUB_STEP_SUMMARY"] - with open(summary_env, "w") as f: - f.writelines(f"# {project_name}\n") - f.writelines(f"name={project_name}\n") - f.writelines(f"version={actual_version}\n") - f.writelines(f"channel={channel}\n") - f.writelines(f"recipe_id_full={project_name}/{actual_version}@{user}/{channel}\n") - f.writelines(f"recipe_id_latest={project_name}/latest@{user}/{channel}\n") - f.writelines(f"semver_full={actual_version}\n") - f.writelines(f"is_release_branch={str(is_release_branch).lower()}\n") - shell: python diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 8321f42a23..2f8f593199 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -64,7 +64,7 @@ permissions: jobs: conan-recipe-version: - uses: ultimaker/cura/.github/workflows/conan-recipe-version.yml@main + uses: ultimaker/cura-workflows/.github/workflows/conan-recipe-version.yml@CURA-10831 with: project_name: cura From 33ecec6951c7cbb7449c4cd3d27a72e45cf618ba Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Sat, 11 Nov 2023 10:42:05 +0100 Subject: [PATCH 007/133] add release tagging info to conandata Contributes to CURA-10831 --- conandata.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/conandata.yml b/conandata.yml index a36e30983c..16d79c4ffa 100644 --- a/conandata.yml +++ b/conandata.yml @@ -1,4 +1,5 @@ version: "5.6.0-beta.1" +release: false requirements: - "uranium/(latest)@ultimaker/stable" - "curaengine/(latest)@ultimaker/stable" From 1fb1fe9faa93a3f65a634f894f7f981bcc9b6cbf Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Sat, 11 Nov 2023 11:59:56 +0100 Subject: [PATCH 008/133] don't set release from conandata.yml Contributes to CURA-10831 --- conandata.yml | 5 ----- conanfile.py | 4 ++++ 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/conandata.yml b/conandata.yml index 16d79c4ffa..470f6f32e4 100644 --- a/conandata.yml +++ b/conandata.yml @@ -1,5 +1,4 @@ version: "5.6.0-beta.1" -release: false requirements: - "uranium/(latest)@ultimaker/stable" - "curaengine/(latest)@ultimaker/stable" @@ -11,10 +10,6 @@ requirements: - "pysavitar/5.3.0" - "pynest2d/5.3.0" - "curaengine_grpc_definitions/0.1.0" - - "cpython/3.10.4" - - "boost/1.82.0" - - "fmt/9.0.0" - - "zlib/1.2.13" requirements_internal: - "fdm_materials/(latest)@internal/testing" - "cura_private_data/(latest)@internal/testing" diff --git a/conanfile.py b/conanfile.py index ae0caaacdf..9f22d10f23 100644 --- a/conanfile.py +++ b/conanfile.py @@ -319,6 +319,10 @@ class CuraConan(ConanFile): self.requires(req) for req in self.conan_data["requirements_internal"]: self.requires(req) + self.requires("cpython/3.10.4") + self.requires("boost/1.82.0") + self.requires("fmt/9.0.0") + self.requires("zlib/1.2.13") def build_requirements(self): if self.options.get_safe("enable_i18n", False): From 1216674728924877783b3a920fc2c80e7c353d85 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Sun, 12 Nov 2023 11:00:21 +0100 Subject: [PATCH 009/133] Modernize conanfile.py This commit updates the Uranium dependency in the Conan file and introduces an internationalization (i18n) option. It refactor the devtool checks to check for the "enable_i18n" option instead. Lastly, cleanups and adjustments are done in preparation for enabling i18n in the build process. Contributes to CURA-10831 --- conanfile.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/conanfile.py b/conanfile.py index 9f22d10f23..d80de96ea3 100644 --- a/conanfile.py +++ b/conanfile.py @@ -318,6 +318,8 @@ class CuraConan(ConanFile): continue self.requires(req) for req in self.conan_data["requirements_internal"]: + if not self.options.internal and "fdm_materials" in req: + continue self.requires(req) self.requires("cpython/3.10.4") self.requires("boost/1.82.0") @@ -495,6 +497,7 @@ echo "CURA_APP_NAME={{ cura_app_name }}" >> ${{ env_prefix }}GITHUB_ENV del self.info.options.cloud_api_version del self.info.options.display_name del self.info.options.cura_debug_mode + self.options.rm_safe("i18n") # TODO: Use the hash of requirements.txt and requirements-ultimaker.txt, Because changing these will actually result in a different # Cura. This is needed because the requirements.txt aren't managed by Conan and therefor not resolved in the package_id. This isn't From 39e505371ef6d1a6674773797b3b6b1c807c975d Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Sun, 12 Nov 2023 11:08:09 +0100 Subject: [PATCH 010/133] fix option naming should be `enable_i18n` Contributes to CURA-10831 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index d80de96ea3..872bbe6c47 100644 --- a/conanfile.py +++ b/conanfile.py @@ -497,7 +497,7 @@ echo "CURA_APP_NAME={{ cura_app_name }}" >> ${{ env_prefix }}GITHUB_ENV del self.info.options.cloud_api_version del self.info.options.display_name del self.info.options.cura_debug_mode - self.options.rm_safe("i18n") + self.options.rm_safe("enable_i18n") # TODO: Use the hash of requirements.txt and requirements-ultimaker.txt, Because changing these will actually result in a different # Cura. This is needed because the requirements.txt aren't managed by Conan and therefor not resolved in the package_id. This isn't From 96f6aac79bce225f6361739c9329dc943680c21c Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Thu, 16 Nov 2023 11:46:51 +0100 Subject: [PATCH 011/133] Create the Cura binaries Contributes to CURA-10831 --- .github/workflows/conan-package-create.yml | 153 --------------------- .github/workflows/conan-package.yml | 96 ++----------- 2 files changed, 14 insertions(+), 235 deletions(-) delete mode 100644 .github/workflows/conan-package-create.yml diff --git a/.github/workflows/conan-package-create.yml b/.github/workflows/conan-package-create.yml deleted file mode 100644 index 18e2600e1d..0000000000 --- a/.github/workflows/conan-package-create.yml +++ /dev/null @@ -1,153 +0,0 @@ -name: Create and Upload Conan package - -on: - workflow_call: - inputs: - project_name: - required: true - type: string - - recipe_id_full: - required: true - type: string - - build_id: - required: true - type: number - - build_info: - required: false - default: true - type: boolean - - recipe_id_latest: - required: false - type: string - - runs_on: - required: true - type: string - - python_version: - required: true - type: string - - conan_config_branch: - required: false - type: string - - conan_logging_level: - required: false - type: string - - conan_clean_local_cache: - required: false - type: boolean - default: false - - conan_upload_community: - required: false - default: true - type: boolean - -env: - CONAN_LOGIN_USERNAME: ${{ secrets.CONAN_USER }} - CONAN_PASSWORD: ${{ secrets.CONAN_PASS }} - CONAN_LOG_RUN_TO_OUTPUT: 1 - CONAN_LOGGING_LEVEL: ${{ inputs.conan_logging_level }} - CONAN_NON_INTERACTIVE: 1 - -jobs: - conan-package-create: - runs-on: ${{ inputs.runs_on }} - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup Python and pip - uses: actions/setup-python@v4 - with: - python-version: ${{ inputs.python_version }} - cache: 'pip' - cache-dependency-path: .github/workflows/requirements-conan-package.txt - - - name: Install Python requirements for runner - run: pip install -r https://raw.githubusercontent.com/Ultimaker/Cura/main/.github/workflows/requirements-conan-package.txt - # Note the runner requirements are always installed from the main branch in the Ultimaker/Cura repo - - - name: Use Conan download cache (Bash) - if: ${{ runner.os != 'Windows' }} - run: conan config set storage.download_cache="$HOME/.conan/conan_download_cache" - - - name: Use Conan download cache (Powershell) - if: ${{ runner.os == 'Windows' }} - run: conan config set storage.download_cache="C:\Users\runneradmin\.conan\conan_download_cache" - - - name: Cache Conan local repository packages (Bash) - uses: actions/cache@v3 - if: ${{ runner.os != 'Windows' }} - with: - path: | - $HOME/.conan/data - $HOME/.conan/conan_download_cache - key: conan-${{ inputs.runs_on }}-${{ runner.arch }}-create-cache - - - name: Cache Conan local repository packages (Powershell) - uses: actions/cache@v3 - if: ${{ runner.os == 'Windows' }} - with: - path: | - C:\Users\runneradmin\.conan\data - C:\.conan - C:\Users\runneradmin\.conan\conan_download_cache - key: conan-${{ inputs.runs_on }}-${{ runner.arch }}-create-cache - - - name: Install MacOS system requirements - if: ${{ runner.os == 'Macos' }} - run: brew install autoconf automake ninja - - # NOTE: Due to what are probably github issues, we have to remove the cache and reconfigure before the rest. - # This is maybe because grub caches the disk it uses last time, which is recreated each time. - - name: Install Linux system requirements - if: ${{ runner.os == 'Linux' }} - run: | - sudo rm /var/cache/debconf/config.dat - sudo dpkg --configure -a - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y - sudo apt update - sudo apt upgrade - sudo apt install build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config flex bison -y - - - name: Install GCC-13 on ubuntu - if: ${{ startsWith(inputs.runs_on, 'ubuntu') }} - run: | - sudo apt install g++-13 gcc-13 -y - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13 - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 13 - - - name: Create the default Conan profile - run: conan profile new default --detect - - - name: Get Conan configuration from branch - if: ${{ inputs.conan_config_branch != '' }} - run: conan config install https://github.com/Ultimaker/conan-config.git -a "-b ${{ inputs.conan_config_branch }}" - - - name: Get Conan configuration - run: | - conan config install https://github.com/Ultimaker/conan-config.git - conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}" - - - name: Add Cura private Artifactory remote - run: conan remote add cura-private https://ultimaker.jfrog.io/artifactory/api/conan/cura-private True - - - name: Create the Packages - run: conan install ${{ inputs.recipe_id_full }} --build=missing --update -c tools.build:skip_test=True - - - name: Upload the Package(s) - if: ${{ always() && inputs.conan_upload_community }} - run: conan upload ${{ inputs.recipe_id_full }} -r cura --all -c - - - name: Upload the Package(s) to the private Artifactory - if: ${{ always() && ! inputs.conan_upload_community }} - run: conan upload ${{ inputs.recipe_id_full }} -r cura-private --all -c diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index ad460f56b9..46831194b1 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -51,95 +51,27 @@ on: env: CONAN_LOGIN_USERNAME_CURA: ${{ secrets.CONAN_USER }} CONAN_PASSWORD_CURA: ${{ secrets.CONAN_PASS }} - CONAN_LOGIN_USERNAME_CURA_CE: ${{ secrets.CONAN_USER }} - CONAN_PASSWORD_CURA_CE: ${{ secrets.CONAN_PASS }} - CONAN_LOG_RUN_TO_OUTPUT: 1 - CONAN_LOGGING_LEVEL: ${{ inputs.conan_logging_level }} - CONAN_NON_INTERACTIVE: 1 -permissions: { } +# FIXME: point to `main` once merged jobs: conan-recipe-version: - permissions: - contents: read - uses: ultimaker/cura-workflows/.github/workflows/conan-recipe-version.yml@CURA-10831 with: project_name: cura - conan-package-create-linux: + conan-package-export: needs: [ conan-recipe-version ] - runs-on: 'ubuntu-latest' - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Cache Conan data - id: cache-conan - uses: actions/cache@v3 - with: - path: ~/.conan - key: ${{ runner.os }}-conan - - - name: Setup Python and pip - uses: actions/setup-python@v4 - with: - python-version: '3.11.x' - cache: 'pip' - cache-dependency-path: .github/workflows/requirements-conan-package.txt - - - name: Install Python requirements for runner - run: pip install -r .github/workflows/requirements-conan-package.txt - - # NOTE: Due to what are probably github issues, we have to remove the cache and reconfigure before the rest. - # This is maybe because grub caches the disk it uses last time, which is recreated each time. - - name: Install Linux system requirements - if: ${{ runner.os == 'Linux' }} - run: | - sudo rm /var/cache/debconf/config.dat - sudo dpkg --configure -a - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y - sudo apt update - sudo apt upgrade - sudo apt install efibootmgr build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config flex bison g++-12 gcc-12 -y - - - name: Install GCC-13 - run: | - sudo apt install g++-13 gcc-13 -y - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13 - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 13 - - - name: Create the default Conan profile - run: conan profile new default --detect --force - - - name: Get Conan configuration - run: | - conan config install https://github.com/Ultimaker/conan-config.git - conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}" - - - name: Create the Packages - run: conan create . ${{ needs.conan-recipe-version.outputs.recipe_id_full }} --build=missing --update -o ${{ needs.conan-recipe-version.outputs.project_name }}:devtools=True -o ${{ needs.conan-recipe-version.outputs.project_name }}:enable_i18n=True -c tools.build:skip_test=True - - - name: Create the latest alias - if: always() - run: conan alias ${{ needs.conan-recipe-version.outputs.recipe_id_latest }} ${{ needs.conan-recipe-version.outputs.recipe_id_full }} - - - name: Upload the Package(s) - if: always() - run: | - conan upload ${{ needs.conan-recipe-version.outputs.recipe_id_full }} -r cura --all -c - conan upload ${{ needs.conan-recipe-version.outputs.recipe_id_latest }} -r cura -c - - notify-create: - if: ${{ always() && (github.event_name == 'push' && (github.ref_name == 'main' || github.ref_name == 'master' || needs.conan-recipe-version.outputs.is_release_branch == 'true')) }} - needs: [ conan-recipe-version, conan-package-create-linux ] - - uses: ultimaker/cura/.github/workflows/notify.yml@main + uses: ultimaker/cura-workflows/.github/workflows/conan-recipe-export.yml@CURA-10831 with: - success: ${{ contains(join(needs.*.result, ','), 'success') }} - success_title: "New binaries created in ${{ github.repository }}" - success_body: "Created binaries for ${{ needs.conan-recipe-version.outputs.recipe_id_full }}" - failure_title: "Failed to create binaries in ${{ github.repository }}" - failure_body: "Failed to created binaries for ${{ needs.conan-recipe-version.outputs.recipe_id_full }}" + recipe_id_full: ${{ needs.conan-recipe-version.outputs.recipe_id_full }} + recipe_id_latest: ${{ needs.conan-recipe-version.outputs.recipe_id_latest }} + secrets: inherit + + conan-package-create-linux: + needs: [ conan-recipe-version, conan-package-export ] + + uses: ultimaker/cura-workflows/.github/workflows/conan-package-create-linux.yml@CURA-10831 + with: + recipe_id_full: ${{ needs.conan-recipe-version.outputs.recipe_id_full }} + conan_extra_args: '-c tools.build:skip_test=True -o ${{ needs.conan-recipe-version.outputs.project_name }}:enable_i18n=True' secrets: inherit From 78cafeca4bbcda7a2df8e5628e520f5e1c4f405e Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Thu, 16 Nov 2023 13:30:26 +0100 Subject: [PATCH 012/133] Only check internal requirements when building internal Contributes to CURA-10831 --- conanfile.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/conanfile.py b/conanfile.py index 872bbe6c47..17b42abc37 100644 --- a/conanfile.py +++ b/conanfile.py @@ -317,10 +317,11 @@ class CuraConan(ConanFile): if self.options.internal and "fdm_materials" in req: continue self.requires(req) - for req in self.conan_data["requirements_internal"]: - if not self.options.internal and "fdm_materials" in req: - continue - self.requires(req) + if self.options.internal: + for req in self.conan_data["requirements_internal"]: + if "fdm_materials" in req: + continue + self.requires(req) self.requires("cpython/3.10.4") self.requires("boost/1.82.0") self.requires("fmt/9.0.0") From 01998d2113fbac387b0163f71139cff0c416083c Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Thu, 16 Nov 2023 13:35:13 +0100 Subject: [PATCH 013/133] Simplify conan-package.yml workflow Removed redundant workflow dispatch inputs and comments in .github/workflows/conan-package.yml. These were unnecessary for the push-based workflow and have been simplified to streamline the process and make it more efficient. Contributes to CURA-10831 --- .github/workflows/conan-package.yml | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index 46831194b1..e06b7dd2d5 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -1,27 +1,6 @@ ---- name: conan-package -# Exports the recipe, sources and binaries for Mac, Windows and Linux and upload these to the server such that these can -# be used downstream. -# -# It should run on pushes against main or CURA-* branches, but it will only create the binaries for main and release branches - on: - workflow_dispatch: - inputs: - create_binaries_windows: - required: true - default: false - description: 'create binaries Windows' - create_binaries_linux: - required: true - default: false - description: 'create binaries Linux' - create_binaries_macos: - required: true - default: false - description: 'create binaries Macos' - push: paths: - 'plugins/**' From 3052c6be3b4ff728ea781e006ae3af22c2f42a1f Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 21 Nov 2023 13:21:25 +0100 Subject: [PATCH 014/133] Enable Sentry for the engine if the conan con sentry_url is set If you want to test this locally do a conan install with: ``` -c user.curaengine:sentry_url= ``` The URL is stored in the CuraEngine repository variables Contributes to CURA-11364 --- conanfile.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conanfile.py b/conanfile.py index 4b37bfdd52..4ec4ffc03f 100644 --- a/conanfile.py +++ b/conanfile.py @@ -306,6 +306,8 @@ class CuraConan(ConanFile): self.options["boost"].header_only = True if self.settings.os == "Linux": self.options["curaengine_grpc_definitions"].shared = True + if self.conf.get("user.curaengine:sentry_url", "", check_type = str) != "": + self.options["curaengine"].enable_sentry = True def validate(self): version = self.conf_info.get("user.cura:version", default = self.version, check_type = str) From 3bd2ea4296bfaf8ba190ce566b07e448674f57f6 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 21 Nov 2023 13:22:18 +0100 Subject: [PATCH 015/133] Pin dulcificum version Contributes to CURA-11364 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 4ec4ffc03f..6384469416 100644 --- a/conanfile.py +++ b/conanfile.py @@ -320,7 +320,7 @@ class CuraConan(ConanFile): self.requires("curaengine_grpc_definitions/0.1.0") self.requires("zlib/1.2.13") self.requires("pyarcus/5.3.0") - self.requires("dulcificum/(latest)@ultimaker/stable") + self.requires("dulcificum/0.1.0-beta.1") self.requires("curaengine/(latest)@ultimaker/testing") self.requires("pysavitar/5.3.0") self.requires("pynest2d/5.3.0") From f22d82c1e068a0bb7ae77aa228ef7dcf5bf00776 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 21 Nov 2023 13:27:26 +0100 Subject: [PATCH 016/133] Use CURA-11634 for CuraEngine Contributes to CURA-11364 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 6384469416..4fe68109e3 100644 --- a/conanfile.py +++ b/conanfile.py @@ -321,7 +321,7 @@ class CuraConan(ConanFile): self.requires("zlib/1.2.13") self.requires("pyarcus/5.3.0") self.requires("dulcificum/0.1.0-beta.1") - self.requires("curaengine/(latest)@ultimaker/testing") + self.requires("curaengine/(latest)@ultimaker/cura_11364") self.requires("pysavitar/5.3.0") self.requires("pynest2d/5.3.0") self.requires("curaengine_plugin_gradual_flow/0.1.0") From 60bf2fbc2c430a6711c746d0c433e3a50f381769 Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Tue, 21 Nov 2023 14:01:58 +0100 Subject: [PATCH 017/133] Add preference to disable sentry engine crash reporting CURA-11364 --- .../CuraEngineBackend/CuraEngineBackend.py | 20 +++++++++++++++---- resources/qml/Preferences/GeneralPage.qml | 19 ++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 1e965f5e8c..24f3dc1ae1 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -163,6 +163,7 @@ class CuraEngineBackend(QObject, Backend): self._is_disabled: bool = False application.getPreferences().addPreference("general/auto_slice", False) + application.getPreferences().addPreference("info/send_engine_crash", True) self._use_timer: bool = False @@ -173,6 +174,8 @@ class CuraEngineBackend(QObject, Backend): self._change_timer.setSingleShot(True) self._change_timer.setInterval(500) self.determineAutoSlicing() + + application.getPreferences().preferenceChanged.connect(self._onPreferencesChanged) self._slicing_error_message = Message( @@ -193,6 +196,9 @@ class CuraEngineBackend(QObject, Backend): application.initializationFinished.connect(self.initialize) + # Ensure that the initial value for send_engine_crash is handled correctly. + application.callLater(self._onPreferencesChanged, "info/send_engine_crash") + def startPlugins(self) -> None: """ Ensure that all backend plugins are started @@ -1088,11 +1094,17 @@ class CuraEngineBackend(QObject, Backend): self._change_timer.timeout.disconnect(self.slice) def _onPreferencesChanged(self, preference: str) -> None: - if preference != "general/auto_slice": + if preference != "general/auto_slice" and preference != "info/send_engine_crash": return - auto_slice = self.determineAutoSlicing() - if auto_slice: - self._change_timer.start() + if preference == "general/auto_slice": + auto_slice = self.determineAutoSlicing() + if auto_slice: + self._change_timer.start() + elif preference == "info/send_engine_crash": + if CuraApplication.getInstance().getPreferences().getValue("info/send_engine_crash"): + os.environ["use_sentry"] = str(1) + else: + os.environ["use_sentry"] = str(0) def tickle(self) -> None: """Tickle the backend so in case of auto slicing, it starts the timer.""" diff --git a/resources/qml/Preferences/GeneralPage.qml b/resources/qml/Preferences/GeneralPage.qml index 32bbcd5053..587084444c 100644 --- a/resources/qml/Preferences/GeneralPage.qml +++ b/resources/qml/Preferences/GeneralPage.qml @@ -120,6 +120,10 @@ UM.PreferencesPage UM.Preferences.resetPreference("info/send_slice_info") sendDataCheckbox.checked = boolCheck(UM.Preferences.getValue("info/send_slice_info")) + + UM.Preferences.resetPreference("info/send_engine_crash") + sendEngineCrashCheckbox.checked = boolCheck(UM.Preferences.getValue("info/send_engine_crash")) + UM.Preferences.resetPreference("info/automatic_update_check") checkUpdatesCheckbox.checked = boolCheck(UM.Preferences.getValue("info/automatic_update_check")) @@ -855,6 +859,21 @@ UM.PreferencesPage font: UM.Theme.getFont("medium_bold") text: catalog.i18nc("@label", "Privacy") } + UM.TooltipArea + { + width: childrenRect.width + height: visible ? childrenRect.height : 0 + text: catalog.i18nc("@info:tooltip", "Should slicing crashes be automatically reported to Ultimaker? Note, no models, IP addresses or other personally identifiable information is sent or stored.") + + UM.CheckBox + { + id: sendEngineCrashCheckbox + text: catalog.i18nc("@option:check","Send (anonymous) engine crash reports") + checked: boolCheck(UM.Preferences.getValue("info/send_engine_crash")) + onCheckedChanged: UM.Preferences.setValue("info/send_engine_crash", checked) + } + } + UM.TooltipArea { width: childrenRect.width From 9693ec2e0e47f68e64f9ffa805d09bfe792bbc2a Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 27 Nov 2023 08:10:34 +0100 Subject: [PATCH 018/133] Merge main and update versions Contribute to CURA-10831 --- conandata.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conandata.yml b/conandata.yml index 470f6f32e4..f12f129ec0 100644 --- a/conandata.yml +++ b/conandata.yml @@ -1,11 +1,11 @@ -version: "5.6.0-beta.1" +version: "5.7.0-alpha.0" requirements: - "uranium/(latest)@ultimaker/stable" - "curaengine/(latest)@ultimaker/stable" - "cura_binary_data/(latest)@ultimaker/stable" - "fdm_materials/(latest)@ultimaker/stable" - "curaengine_plugin_gradual_flow/0.1.0" - - "dulcificum/(latest)@ultimaker/stable" + - "dulcificum/0.1.0-beta.1" - "pyarcus/5.3.0" - "pysavitar/5.3.0" - "pynest2d/5.3.0" From e1110dd412c88d3d841a003bfe2fe9ce9ef5cf49 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 27 Nov 2023 16:23:13 +0100 Subject: [PATCH 019/133] Update workflow to be on par with other repo's Contribute to CURA-10831 --- .github/workflows/conan-package.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index e06b7dd2d5..24793fa4cc 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -11,21 +11,21 @@ on: - 'packaging/**' - '.github/workflows/conan-*.yml' - '.github/workflows/notify.yml' - - '.github/workflows/requirements-conan-package.txt' + - '.github/workflows/requirements-runner.txt' - 'requirements*.txt' - 'conanfile.py' - 'conandata.yml' - - 'GitVersion.yml' - '*.jinja' branches: - - main + - 'main' - 'CURA-*' - - '[1-9].[0-9]' - - '[1-9].[0-9][0-9]' + - 'PP-*' + - '[0-9].[0-9]' + - '[0-9].[0-9][0-9]' tags: - - '[1-9].[0-9].[0-9]*' - - '[1-9].[0-9].[0-9]' - - '[1-9].[0-9][0-9].[0-9]*' + - '[0-9].[0-9].[0-9]*' + - '[0-9].[0-9].[0-9]' + - '[0-9].[0-9][0-9].[0-9]*' env: CONAN_LOGIN_USERNAME_CURA: ${{ secrets.CONAN_USER }} From 1f9e0e2dee75bcbc12fbe1b54c61de10e5a5f65c Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Tue, 28 Nov 2023 15:15:39 +0100 Subject: [PATCH 020/133] Add url protocol support for msi, nsis, dmg and pkg installers CURA-11288 --- UltiMaker-Cura.spec.jinja | 4 +++ packaging/NSIS/Ultimaker-Cura.nsi.jinja | 15 +++++++++++ packaging/msi/UltiMaker-Cura.wxs.jinja | 36 +++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/UltiMaker-Cura.spec.jinja b/UltiMaker-Cura.spec.jinja index 3d540d3b8f..cd939cf736 100644 --- a/UltiMaker-Cura.spec.jinja +++ b/UltiMaker-Cura.spec.jinja @@ -266,6 +266,10 @@ app = UMBUNDLE( 'CFBundlePackageType': 'APPL', 'CFBundleVersionString': {{ version }}, 'CFBundleShortVersionString': {{ short_version }}, + 'CFBundleURLTypes': [{ + 'CFBundleURLName': '{{ display_name }}', + 'CFBundleURLSchemes': ['cura', 'slicer'], + }], 'CFBundleDocumentTypes': [{ 'CFBundleTypeRole': 'Viewer', 'CFBundleTypeExtensions': ['*'], diff --git a/packaging/NSIS/Ultimaker-Cura.nsi.jinja b/packaging/NSIS/Ultimaker-Cura.nsi.jinja index 9996b24773..228dba4fe4 100644 --- a/packaging/NSIS/Ultimaker-Cura.nsi.jinja +++ b/packaging/NSIS/Ultimaker-Cura.nsi.jinja @@ -192,3 +192,18 @@ DeleteRegKey ${REG_ROOT} "${UNINSTALL_PATH}" SectionEnd ###################################################################### + +Section UrlProtocol + WriteRegStr HKCR "cura" "" "URL:cura" + WriteRegStr HKCR "cura" "URL Protocol" "" + WriteRegStr HKCR "cura\DefaultIcon" "" "$INSTDIR\${MAIN_APP_EXE},1" + WriteRegStr HKCR "cura\shell" "" "open" + WriteRegStr HKCR "cura\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}" "%1"' + + WriteRegStr HKCR "slicer" "" "URL:slicer" + WriteRegStr HKCR "slicer" "URL Protocol" "" + WriteRegStr HKCR "slicer\DefaultIcon" "" "$INSTDIR\${MAIN_APP_EXE},1" + WriteRegStr HKCR "slicer\shell" "" "open" + WriteRegStr HKCR "slicer\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}" "%1"' + +SectionEnd \ No newline at end of file diff --git a/packaging/msi/UltiMaker-Cura.wxs.jinja b/packaging/msi/UltiMaker-Cura.wxs.jinja index a183a97d5f..5ce8cd0a08 100644 --- a/packaging/msi/UltiMaker-Cura.wxs.jinja +++ b/packaging/msi/UltiMaker-Cura.wxs.jinja @@ -33,6 +33,21 @@ /> + + + + + {% if "Enterprise" in app_name %} @@ -144,11 +159,32 @@ + + + + + + + + + + + + + + + + + + + + + From 593e959dd574784481add3c897061ae07763195c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 29 Nov 2023 10:42:12 +0100 Subject: [PATCH 021/133] Use cleaner notation for use_sentry env variable CURA-11364 Co-authored-by: Casper Lamboo --- plugins/CuraEngineBackend/CuraEngineBackend.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/plugins/CuraEngineBackend/CuraEngineBackend.py b/plugins/CuraEngineBackend/CuraEngineBackend.py index 24f3dc1ae1..818766d766 100755 --- a/plugins/CuraEngineBackend/CuraEngineBackend.py +++ b/plugins/CuraEngineBackend/CuraEngineBackend.py @@ -1101,10 +1101,7 @@ class CuraEngineBackend(QObject, Backend): if auto_slice: self._change_timer.start() elif preference == "info/send_engine_crash": - if CuraApplication.getInstance().getPreferences().getValue("info/send_engine_crash"): - os.environ["use_sentry"] = str(1) - else: - os.environ["use_sentry"] = str(0) + os.environ["use_sentry"] = "1" if CuraApplication.getInstance().getPreferences().getValue("info/send_engine_crash") else "0" def tickle(self) -> None: """Tickle the backend so in case of auto slicing, it starts the timer.""" From 7ed7cc260e25578c5746b44e2652ca7a16bff890 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Wed, 29 Nov 2023 15:22:30 +0100 Subject: [PATCH 022/133] Use testing conan packages Contributes to CURA-10831 --- conandata.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/conandata.yml b/conandata.yml index f12f129ec0..9a26235e2c 100644 --- a/conandata.yml +++ b/conandata.yml @@ -1,9 +1,9 @@ version: "5.7.0-alpha.0" requirements: - - "uranium/(latest)@ultimaker/stable" - - "curaengine/(latest)@ultimaker/stable" - - "cura_binary_data/(latest)@ultimaker/stable" - - "fdm_materials/(latest)@ultimaker/stable" + - "uranium/(latest)@ultimaker/testing" + - "curaengine/(latest)@ultimaker/testing" + - "cura_binary_data/(latest)@ultimaker/testing" + - "fdm_materials/(latest)@ultimaker/testing" - "curaengine_plugin_gradual_flow/0.1.0" - "dulcificum/0.1.0-beta.1" - "pyarcus/5.3.0" From 0d3a926259c6919e77dc7f39c9ff08f3fbb58ab9 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Wed, 29 Nov 2023 16:22:03 +0100 Subject: [PATCH 023/133] Update linux.yml --- .github/workflows/linux.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 1dee7a237f..d8cd580190 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -111,7 +111,7 @@ jobs: sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y sudo apt update sudo apt upgrade - sudo apt install build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config binutils coreutils desktop-file-utils fakeroot fuse libgdk-pixbuf2.0-dev patchelf squashfs-tools strace util-linux zsync -y + sudo apt install build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config binutils coreutils desktop-file-utils fakeroot fuse libgdk-pixbuf2.0-dev patchelf squashfs-tools strace util-linux zsync libxcb-cursor-dev -y # Get the AppImage tool wget --no-check-certificate --quiet https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O $GITHUB_WORKSPACE/appimagetool From d53b2d94abc0219995757c4c2e922226cefd0054 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Thu, 30 Nov 2023 11:51:35 +0100 Subject: [PATCH 024/133] Add directory for wix components CURA-11288 --- packaging/msi/UltiMaker-Cura.wxs.jinja | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/msi/UltiMaker-Cura.wxs.jinja b/packaging/msi/UltiMaker-Cura.wxs.jinja index 5ce8cd0a08..de441443f4 100644 --- a/packaging/msi/UltiMaker-Cura.wxs.jinja +++ b/packaging/msi/UltiMaker-Cura.wxs.jinja @@ -160,7 +160,7 @@ - + @@ -169,7 +169,7 @@ - + From ef5bc6d3d5965a02f603c72da1d20db6d2009723 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Thu, 30 Nov 2023 12:57:14 +0100 Subject: [PATCH 025/133] Use custom CPython 3.10.4 and OpenSSL 3.2.0 Due to changes made to the recipes up stream, and some tweaks to our own cpython recipe. We can now build cpython with the newest OpenSSL version Contribute to CURA-11080 --- conanfile.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 48cba847be..18ad185d6a 100644 --- a/conanfile.py +++ b/conanfile.py @@ -307,6 +307,7 @@ class CuraConan(ConanFile): self.options["pynest2d"].shared = True self.options["dulcificum"].shared = self.settings.os != "Windows" self.options["cpython"].shared = True + self.options["openssl"].shared = True self.options["boost"].header_only = True if self.settings.os == "Linux": self.options["curaengine_grpc_definitions"].shared = True @@ -329,7 +330,8 @@ class CuraConan(ConanFile): self.requires("curaengine_plugin_gradual_flow/0.1.0") self.requires("uranium/(latest)@ultimaker/testing") self.requires("cura_binary_data/(latest)@ultimaker/testing") - self.requires("cpython/3.10.4") + self.requires("cpython/3.10.4@ultimaker/stable") + self.requires("openssl/3.2.0") if self.options.internal: self.requires("cura_private_data/(latest)@internal/testing") self.requires("fdm_materials/(latest)@internal/testing") From 7573c3e994a7880136dcfdef920b99d42708f133 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Thu, 30 Nov 2023 12:58:47 +0100 Subject: [PATCH 026/133] Build OpenSSL 3 shared No longer a need to deploy a shared dep independently. Contribute to CURA-11080 --- .github/workflows/linux.yml | 15 +-------------- .github/workflows/macos.yml | 12 ------------ .github/workflows/windows.yml | 8 -------- 3 files changed, 1 insertion(+), 34 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index d8cd580190..8b6d892fa0 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -162,20 +162,7 @@ jobs: - name: Set Environment variables for Cura (bash) run: | . ./cura_inst/bin/activate_github_actions_env.sh - . ./cura_inst/bin/activate_github_actions_version_env.sh - - # FIXME: This is a workaround to ensure that we use and pack a shared library for OpenSSL 1.1.1l. We currently compile - # OpenSSL statically for CPython, but our Python Dependenies (such as PyQt6) require a shared library. - # Because Conan won't allow for building the same library with two different options (easily) we need to install it explicitly - # and do a manual copy to the VirtualEnv, such that Pyinstaller can find it. - - - name: Install OpenSSL shared - run: conan install openssl/1.1.1l@_/_ --build=missing --update -o openssl:shared=True -g deploy - - - name: Copy OpenSSL shared (Bash) - run: | - cp ./openssl/lib/*.so* ./cura_inst/bin/ || true - cp ./openssl/lib/*.dylib* ./cura_inst/bin/ || true + . ./cura_inst/bin/activate_github_actions_version_env.sh - name: Create the Cura dist run: pyinstaller ./cura_inst/UltiMaker-Cura.spec diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 2c7186a764..c7c34d9d51 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -177,18 +177,6 @@ jobs: env: TEMP_KEYCHAIN_PASSWORD: ${{ steps.macos-keychain-developer-cert.outputs.keychain-password }} - # FIXME: This is a workaround to ensure that we use and pack a shared library for OpenSSL 1.1.1l. We currently compile - # OpenSSL statically for CPython, but our Python Dependenies (such as PyQt6) require a shared library. - # Because Conan won't allow for building the same library with two different options (easily) we need to install it explicitly - # and do a manual copy to the VirtualEnv, such that Pyinstaller can find it. - - name: Install OpenSSL shared - run: conan install openssl/1.1.1l@_/_ --build=missing --update -o openssl:shared=True -g deploy - - - name: Copy OpenSSL shared (Bash) - run: | - cp ./openssl/lib/*.so* ./cura_inst/bin/ || true - cp ./openssl/lib/*.dylib* ./cura_inst/bin/ || true - - name: Create the Cura dist run: pyinstaller ./cura_inst/UltiMaker-Cura.spec diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 6944969313..dfffc4540b 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -140,14 +140,6 @@ jobs: .\cura_inst\Scripts\activate_github_actions_env.ps1 .\cura_inst\Scripts\activate_github_actions_version_env.ps1 -# - name: Install OpenSSL shared -# run: conan install openssl/1.1.1l@_/_ --build=missing --update -o openssl:shared=True -g deploy -# -# - name: Copy OpenSSL shared (Powershell) -# run: | -# cp openssl/bin/*.dll ./cura_inst/Scripts/ -# cp openssl/lib/*.lib ./cura_inst/Lib/ - - name: Create the Cura dist run: pyinstaller ./cura_inst/UltiMaker-Cura.spec From 1e190ebcb969057942ecb6e75c51dc8454f9a3b3 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Thu, 30 Nov 2023 13:16:25 +0100 Subject: [PATCH 027/133] Format file CURA-1364 --- conanfile.py | 208 ++++++++++++++++++++++++++++++--------------------- 1 file changed, 121 insertions(+), 87 deletions(-) diff --git a/conanfile.py b/conanfile.py index f7ebb4ef9c..6bae617e3a 100644 --- a/conanfile.py +++ b/conanfile.py @@ -30,7 +30,8 @@ class CuraConan(ConanFile): options = { "enterprise": ["True", "False", "true", "false"], # Workaround for GH Action passing boolean as lowercase string "staging": ["True", "False", "true", "false"], # Workaround for GH Action passing boolean as lowercase string - "devtools": [True, False], # FIXME: Split this up in testing and (development / build (pyinstaller) / system installer) tools + "devtools": [True, False], + # FIXME: Split this up in testing and (development / build (pyinstaller) / system installer) tools "cloud_api_version": "ANY", "display_name": "ANY", # TODO: should this be an option?? "cura_debug_mode": [True, False], # FIXME: Use profiles @@ -72,7 +73,7 @@ class CuraConan(ConanFile): self._cura_env.define("QML2_IMPORT_PATH", str(self._site_packages.joinpath("PyQt6", "Qt6", "qml"))) self._cura_env.define("QT_PLUGIN_PATH", str(self._site_packages.joinpath("PyQt6", "Qt6", "plugins"))) if not self.in_local_cache: - self._cura_env.define( "CURA_DATA_ROOT", str(self._share_dir.joinpath("cura"))) + self._cura_env.define("CURA_DATA_ROOT", str(self._share_dir.joinpath("cura"))) if self.settings.os == "Linux": self._cura_env.define("QT_QPA_FONTDIR", "/usr/share/fonts") @@ -163,7 +164,7 @@ class CuraConan(ConanFile): python_ins_cmd = f"python -c \"import pkg_resources; print(';'.join([(s.key+','+ s.version) for s in pkg_resources.working_set]))\"" from six import StringIO buffer = StringIO() - self.run(python_ins_cmd, run_environment= True, env = "conanrun", output=buffer) + self.run(python_ins_cmd, run_environment=True, env="conanrun", output=buffer) packages = str(buffer.getvalue()).split("-----------------\n") packages = packages[1].strip('\r\n').split(";") @@ -179,7 +180,7 @@ class CuraConan(ConanFile): # If you want a specific Cura version to show up on the splash screen add the user configuration `user.cura:version=VERSION` # the global.conf, profile, package_info (of dependency) or via the cmd line `-c user.cura:version=VERSION` - cura_version = Version(self.conf.get("user.cura:version", default = self.version, check_type = str)) + cura_version = Version(self.conf.get("user.cura:version", default=self.version, check_type=str)) pre_tag = f"-{cura_version.pre}" if cura_version.pre else "" build_tag = f"+{cura_version.build}" if cura_version.build else "" internal_tag = f"+internal" if self.options.internal else "" @@ -187,16 +188,16 @@ class CuraConan(ConanFile): with open(os.path.join(location, "CuraVersion.py"), "w") as f: f.write(cura_version_py.render( - cura_app_name = self.name, - cura_app_display_name = self._app_name, - cura_version = cura_version, - cura_build_type = "Enterprise" if self._enterprise else "", - cura_debug_mode = self.options.cura_debug_mode, - cura_cloud_api_root = self.conan_data["urls"][self._urls]["cloud_api_root"], - cura_cloud_api_version = self.options.cloud_api_version, - cura_cloud_account_api_root = self.conan_data["urls"][self._urls]["cloud_account_api_root"], - cura_marketplace_root = self.conan_data["urls"][self._urls]["marketplace_root"], - cura_digital_factory_url = self.conan_data["urls"][self._urls]["digital_factory_url"], + cura_app_name=self.name, + cura_app_display_name=self._app_name, + cura_version=cura_version, + cura_build_type="Enterprise" if self._enterprise else "", + cura_debug_mode=self.options.cura_debug_mode, + cura_cloud_api_root=self.conan_data["urls"][self._urls]["cloud_api_root"], + cura_cloud_api_version=self.options.cloud_api_version, + cura_cloud_account_api_root=self.conan_data["urls"][self._urls]["cloud_account_api_root"], + cura_marketplace_root=self.conan_data["urls"][self._urls]["marketplace_root"], + cura_digital_factory_url=self.conan_data["urls"][self._urls]["digital_factory_url"], cura_latest_url=self.conan_data["urls"][self._urls]["cura_latest_url"], conan_installs=self._conan_installs(), python_installs=self._python_installs(), @@ -261,37 +262,43 @@ class CuraConan(ConanFile): with open(os.path.join(self.recipe_folder, "UltiMaker-Cura.spec.jinja"), "r") as f: pyinstaller = Template(f.read()) - version = self.conf.get("user.cura:version", default = self.version, check_type = str) + version = self.conf.get("user.cura:version", default=self.version, check_type=str) cura_version = Version(version) with open(os.path.join(location, "UltiMaker-Cura.spec"), "w") as f: f.write(pyinstaller.render( - name = str(self.options.display_name).replace(" ", "-"), - display_name = self._app_name, - entrypoint = entrypoint_location, - datas = datas, - binaries = binaries, - venv_script_path = str(self._script_dir), - hiddenimports = pyinstaller_metadata["hiddenimports"], - collect_all = pyinstaller_metadata["collect_all"], - icon = icon_path, - entitlements_file = entitlements_file, - osx_bundle_identifier = "'nl.ultimaker.cura'" if self.settings.os == "Macos" else "None", - upx = str(self.settings.os == "Windows"), - strip = False, # This should be possible on Linux and MacOS but, it can also cause issues on some distributions. Safest is to disable it for now - target_arch = self._pyinstaller_spec_arch, - macos = self.settings.os == "Macos", - version = f"'{version}'", - short_version = f"'{cura_version.major}.{cura_version.minor}.{cura_version.patch}'", + name=str(self.options.display_name).replace(" ", "-"), + display_name=self._app_name, + entrypoint=entrypoint_location, + datas=datas, + binaries=binaries, + venv_script_path=str(self._script_dir), + hiddenimports=pyinstaller_metadata["hiddenimports"], + collect_all=pyinstaller_metadata["collect_all"], + icon=icon_path, + entitlements_file=entitlements_file, + osx_bundle_identifier="'nl.ultimaker.cura'" if self.settings.os == "Macos" else "None", + upx=str(self.settings.os == "Windows"), + strip=False, + # This should be possible on Linux and MacOS but, it can also cause issues on some distributions. Safest is to disable it for now + target_arch=self._pyinstaller_spec_arch, + macos=self.settings.os == "Macos", + version=f"'{version}'", + short_version=f"'{cura_version.major}.{cura_version.minor}.{cura_version.patch}'", )) def export_sources(self): - copy(self, "*", os.path.join(self.recipe_folder, "plugins"), os.path.join(self.export_sources_folder, "plugins")) - copy(self, "*", os.path.join(self.recipe_folder, "resources"), os.path.join(self.export_sources_folder, "resources"), excludes = "*.mo") + copy(self, "*", os.path.join(self.recipe_folder, "plugins"), + os.path.join(self.export_sources_folder, "plugins")) + copy(self, "*", os.path.join(self.recipe_folder, "resources"), + os.path.join(self.export_sources_folder, "resources"), excludes="*.mo") copy(self, "*", os.path.join(self.recipe_folder, "tests"), os.path.join(self.export_sources_folder, "tests")) - copy(self, "*", os.path.join(self.recipe_folder, "cura"), os.path.join(self.export_sources_folder, "cura"), excludes="CuraVersion.py") - copy(self, "*", os.path.join(self.recipe_folder, "packaging"), os.path.join(self.export_sources_folder, "packaging")) - copy(self, "*", os.path.join(self.recipe_folder, ".run_templates"), os.path.join(self.export_sources_folder, ".run_templates")) + copy(self, "*", os.path.join(self.recipe_folder, "cura"), os.path.join(self.export_sources_folder, "cura"), + excludes="CuraVersion.py") + copy(self, "*", os.path.join(self.recipe_folder, "packaging"), + os.path.join(self.export_sources_folder, "packaging")) + copy(self, "*", os.path.join(self.recipe_folder, ".run_templates"), + os.path.join(self.export_sources_folder, ".run_templates")) copy(self, "requirements.txt", self.recipe_folder, self.export_sources_folder) copy(self, "requirements-dev.txt", self.recipe_folder, self.export_sources_folder) copy(self, "requirements-ultimaker.txt", self.recipe_folder, self.export_sources_folder) @@ -310,11 +317,11 @@ class CuraConan(ConanFile): self.options["boost"].header_only = True if self.settings.os == "Linux": self.options["curaengine_grpc_definitions"].shared = True - if self.conf.get("user.curaengine:sentry_url", "", check_type = str) != "": + if self.conf.get("user.curaengine:sentry_url", "", check_type=str) != "": self.options["curaengine"].enable_sentry = True def validate(self): - version = self.conf.get("user.cura:version", default = self.version, check_type = str) + version = self.conf.get("user.cura:version", default=self.version, check_type=str) if version and Version(version) <= Version("4"): raise ConanInvalidConfiguration("Only versions 5+ are support") @@ -340,7 +347,7 @@ class CuraConan(ConanFile): def build_requirements(self): if self.options.get_safe("enable_i18n", False): - self.tool_requires("gettext/0.21", force_host_context = True) + self.tool_requires("gettext/0.21", force_host_context=True) def layout(self): self.folders.source = "." @@ -349,11 +356,12 @@ class CuraConan(ConanFile): self.cpp.package.libdirs = [os.path.join("site-packages", "cura")] self.cpp.package.bindirs = ["bin"] - self.cpp.package.resdirs = ["resources", "plugins", "packaging", "pip_requirements"] # pip_requirements should be the last item in the list + self.cpp.package.resdirs = ["resources", "plugins", "packaging", + "pip_requirements"] # pip_requirements should be the last item in the list def generate(self): copy(self, "cura_app.py", self.source_folder, str(self._script_dir)) - cura_run_envvars = self._cura_run_env.vars(self, scope = "run") + cura_run_envvars = self._cura_run_env.vars(self, scope="run") ext = ".ps1" if self.settings.os == "Windows" else ".sh" cura_run_envvars.save_script(os.path.join(self.folders.generators, f"cura_run_environment{ext}")) @@ -365,30 +373,32 @@ class CuraConan(ConanFile): if not self.in_local_cache: # Copy CuraEngine.exe to bindirs of Virtual Python Environment curaengine = self.dependencies["curaengine"].cpp_info - copy(self, "CuraEngine.exe", curaengine.bindirs[0], self.source_folder, keep_path = False) - copy(self, "CuraEngine", curaengine.bindirs[0], self.source_folder, keep_path = False) + copy(self, "CuraEngine.exe", curaengine.bindirs[0], self.source_folder, keep_path=False) + copy(self, "CuraEngine", curaengine.bindirs[0], self.source_folder, keep_path=False) # Copy the external plugins that we want to bundle with Cura - rmdir(self,str(self.source_path.joinpath("plugins", "CuraEngineGradualFlow"))) + rmdir(self, str(self.source_path.joinpath("plugins", "CuraEngineGradualFlow"))) curaengine_plugin_gradual_flow = self.dependencies["curaengine_plugin_gradual_flow"].cpp_info - copy(self, "*", curaengine_plugin_gradual_flow.resdirs[0], str(self.source_path.joinpath("plugins", "CuraEngineGradualFlow")), keep_path = True) - copy(self, "*", curaengine_plugin_gradual_flow.bindirs[0], self.source_folder, keep_path = False) - copy(self, "bundled_*.json", curaengine_plugin_gradual_flow.resdirs[1], str(self.source_path.joinpath("resources", "bundled_packages")), keep_path = False) + copy(self, "*", curaengine_plugin_gradual_flow.resdirs[0], + str(self.source_path.joinpath("plugins", "CuraEngineGradualFlow")), keep_path=True) + copy(self, "*", curaengine_plugin_gradual_flow.bindirs[0], self.source_folder, keep_path=False) + copy(self, "bundled_*.json", curaengine_plugin_gradual_flow.resdirs[1], + str(self.source_path.joinpath("resources", "bundled_packages")), keep_path=False) # Copy resources of cura_binary_data cura_binary_data = self.dependencies["cura_binary_data"].cpp_info - copy(self, "*", cura_binary_data.resdirs[0], str(self._share_dir.joinpath("cura")), keep_path = True) - copy(self, "*", cura_binary_data.resdirs[1], str(self._share_dir.joinpath("uranium")), keep_path = True) + copy(self, "*", cura_binary_data.resdirs[0], str(self._share_dir.joinpath("cura")), keep_path=True) + copy(self, "*", cura_binary_data.resdirs[1], str(self._share_dir.joinpath("uranium")), keep_path=True) if self.settings.os == "Windows": - copy(self, "*", cura_binary_data.resdirs[2], str(self._share_dir.joinpath("windows")), keep_path = True) + copy(self, "*", cura_binary_data.resdirs[2], str(self._share_dir.joinpath("windows")), keep_path=True) for dependency in self.dependencies.host.values(): for bindir in dependency.cpp_info.bindirs: - copy(self, "*.dll", bindir, str(self._site_packages), keep_path = False) + copy(self, "*.dll", bindir, str(self._site_packages), keep_path=False) for libdir in dependency.cpp_info.libdirs: - copy(self, "*.pyd", libdir, str(self._site_packages), keep_path = False) - copy(self, "*.pyi", libdir, str(self._site_packages), keep_path = False) - copy(self, "*.dylib", libdir, str(self._base_dir.joinpath("lib")), keep_path = False) + copy(self, "*.pyd", libdir, str(self._site_packages), keep_path=False) + copy(self, "*.pyi", libdir, str(self._site_packages), keep_path=False) + copy(self, "*.dylib", libdir, str(self._base_dir.joinpath("lib")), keep_path=False) # Copy materials (flat) rmdir(self, os.path.join(self.source_folder, "resources", "materials")) @@ -401,7 +411,8 @@ class CuraConan(ConanFile): copy(self, "*", cura_private_data.resdirs[0], str(self._share_dir.joinpath("cura"))) if self.options.devtools: - entitlements_file = "'{}'".format(os.path.join(self.source_folder, "packaging", "MacOS", "cura.entitlements")) + entitlements_file = "'{}'".format( + os.path.join(self.source_folder, "packaging", "MacOS", "cura.entitlements")) self._generate_pyinstaller_spec( location=self.generators_folder, entrypoint_location="'{}'".format( @@ -430,64 +441,87 @@ class CuraConan(ConanFile): mo_file = mo_file.parent.joinpath("LC_MESSAGES", mo_file.name) mkdir(self, str(unix_path(self, Path(mo_file).parent))) cpp_info = self.dependencies["gettext"].cpp_info - self.run(f"{cpp_info.bindirs[0]}/msgfmt {po_file} -o {mo_file} -f", env="conanbuild", ignore_errors=True) + self.run(f"{cpp_info.bindirs[0]}/msgfmt {po_file} -o {mo_file} -f", env="conanbuild", + ignore_errors=True) def deploy(self): - copy(self, "*", os.path.join(self.package_folder, self.cpp.package.resdirs[2]), os.path.join(self.install_folder, "packaging"), keep_path = True) + copy(self, "*", os.path.join(self.package_folder, self.cpp.package.resdirs[2]), + os.path.join(self.install_folder, "packaging"), keep_path=True) # Copy resources of Cura (keep folder structure) needed by pyinstaller to determine the module structure - copy(self, "*", os.path.join(self.package_folder, self.cpp_info.bindirs[0]), str(self._base_dir), keep_path = False) - copy(self, "*", os.path.join(self.package_folder, self.cpp_info.libdirs[0]), str(self._site_packages.joinpath("cura")), keep_path = True) - copy(self, "*", os.path.join(self.package_folder, self.cpp_info.resdirs[0]), str(self._share_dir.joinpath("cura", "resources")), keep_path = True) - copy(self, "*", os.path.join(self.package_folder, self.cpp_info.resdirs[1]), str(self._share_dir.joinpath("cura", "plugins")), keep_path = True) + copy(self, "*", os.path.join(self.package_folder, self.cpp_info.bindirs[0]), str(self._base_dir), + keep_path=False) + copy(self, "*", os.path.join(self.package_folder, self.cpp_info.libdirs[0]), + str(self._site_packages.joinpath("cura")), keep_path=True) + copy(self, "*", os.path.join(self.package_folder, self.cpp_info.resdirs[0]), + str(self._share_dir.joinpath("cura", "resources")), keep_path=True) + copy(self, "*", os.path.join(self.package_folder, self.cpp_info.resdirs[1]), + str(self._share_dir.joinpath("cura", "plugins")), keep_path=True) # Copy resources of Uranium (keep folder structure) uranium = self.dependencies["uranium"].cpp_info - copy(self, "*", uranium.resdirs[0], str(self._share_dir.joinpath("uranium", "resources")), keep_path = True) - copy(self, "*", uranium.resdirs[1], str(self._share_dir.joinpath("uranium", "plugins")), keep_path = True) - copy(self, "*", uranium.libdirs[0], str(self._site_packages.joinpath("UM")), keep_path = True) + copy(self, "*", uranium.resdirs[0], str(self._share_dir.joinpath("uranium", "resources")), keep_path=True) + copy(self, "*", uranium.resdirs[1], str(self._share_dir.joinpath("uranium", "plugins")), keep_path=True) + copy(self, "*", uranium.libdirs[0], str(self._site_packages.joinpath("UM")), keep_path=True) # Generate the GitHub Action version info Environment - version = self.conf.get("user.cura:version", default = self.version, check_type = str) + version = self.conf.get("user.cura:version", default=self.version, check_type=str) cura_version = Version(version) env_prefix = "Env:" if self.settings.os == "Windows" else "" - activate_github_actions_version_env = Template(r"""echo "CURA_VERSION_MAJOR={{ cura_version_major }}" >> ${{ env_prefix }}GITHUB_ENV + activate_github_actions_version_env = (Template(r"""echo "CURA_VERSION_MAJOR={{ cura_version_major }}" >> ${{ env_prefix }}GITHUB_ENV echo "CURA_VERSION_MINOR={{ cura_version_minor }}" >> ${{ env_prefix }}GITHUB_ENV echo "CURA_VERSION_PATCH={{ cura_version_patch }}" >> ${{ env_prefix }}GITHUB_ENV echo "CURA_VERSION_BUILD={{ cura_version_build }}" >> ${{ env_prefix }}GITHUB_ENV echo "CURA_VERSION_FULL={{ cura_version_full }}" >> ${{ env_prefix }}GITHUB_ENV -echo "CURA_APP_NAME={{ cura_app_name }}" >> ${{ env_prefix }}GITHUB_ENV - """).render(cura_version_major = cura_version.major, - cura_version_minor = cura_version.minor, - cura_version_patch = cura_version.patch, - cura_version_build = cura_version.build if cura_version.build != "" else "0", - cura_version_full = self.version, - cura_app_name = self._app_name, - env_prefix = env_prefix) +echo "CURA_APP_NAME={{ cura_app_name }}" >> ${{ env_prefix }}GITHUB_ENV""") + .render( + cura_version_major=cura_version.major, + cura_version_minor=cura_version.minor, + cura_version_patch=cura_version.patch, + cura_version_build=cura_version.build if cura_version.build != "" else "0", + cura_version_full=self.version, + cura_app_name=self._app_name, + env_prefix=env_prefix, + ) + ) ext = ".sh" if self.settings.os != "Windows" else ".ps1" - save(self, os.path.join(self._script_dir, f"activate_github_actions_version_env{ext}"), activate_github_actions_version_env) + save(self, os.path.join(self._script_dir, f"activate_github_actions_version_env{ext}"), + activate_github_actions_version_env) self._generate_cura_version(os.path.join(self._site_packages, "cura")) entitlements_file = "'{}'".format(Path(self.cpp_info.res_paths[2], "MacOS", "cura.entitlements")) - self._generate_pyinstaller_spec(location = self._base_dir, - entrypoint_location = "'{}'".format(os.path.join(self.package_folder, self.cpp_info.bindirs[0], self.conan_data["pyinstaller"]["runinfo"]["entrypoint"])).replace("\\", "\\\\"), - icon_path = "'{}'".format(os.path.join(self.package_folder, self.cpp_info.resdirs[2], self.conan_data["pyinstaller"]["icon"][str(self.settings.os)])).replace("\\", "\\\\"), - entitlements_file = entitlements_file if self.settings.os == "Macos" else "None") + self._generate_pyinstaller_spec(location=self._base_dir, + entrypoint_location="'{}'".format( + os.path.join(self.package_folder, self.cpp_info.bindirs[0], + self.conan_data["pyinstaller"]["runinfo"][ + "entrypoint"])).replace("\\", "\\\\"), + icon_path="'{}'".format( + os.path.join(self.package_folder, self.cpp_info.resdirs[2], + self.conan_data["pyinstaller"]["icon"][ + str(self.settings.os)])).replace("\\", "\\\\"), + entitlements_file=entitlements_file if self.settings.os == "Macos" else "None") def package(self): - copy(self, "cura_app.py", src = self.source_folder, dst = os.path.join(self.package_folder, self.cpp.package.bindirs[0])) - copy(self, "*", src = os.path.join(self.source_folder, "cura"), dst = os.path.join(self.package_folder, self.cpp.package.libdirs[0])) - copy(self, "*", src = os.path.join(self.source_folder, "resources"), dst = os.path.join(self.package_folder, self.cpp.package.resdirs[0])) + copy(self, "cura_app.py", src=self.source_folder, + dst=os.path.join(self.package_folder, self.cpp.package.bindirs[0])) + copy(self, "*", src=os.path.join(self.source_folder, "cura"), + dst=os.path.join(self.package_folder, self.cpp.package.libdirs[0])) + copy(self, "*", src=os.path.join(self.source_folder, "resources"), + dst=os.path.join(self.package_folder, self.cpp.package.resdirs[0])) copy(self, "*.mo", os.path.join(self.build_folder, "resources"), os.path.join(self.package_folder, "resources")) - copy(self, "*", src = os.path.join(self.source_folder, "plugins"), dst = os.path.join(self.package_folder, self.cpp.package.resdirs[1])) - copy(self, "requirement*.txt", src = self.source_folder, dst = os.path.join(self.package_folder, self.cpp.package.resdirs[-1])) - copy(self, "*", src = os.path.join(self.source_folder, "packaging"), dst = os.path.join(self.package_folder, self.cpp.package.resdirs[2])) + copy(self, "*", src=os.path.join(self.source_folder, "plugins"), + dst=os.path.join(self.package_folder, self.cpp.package.resdirs[1])) + copy(self, "requirement*.txt", src=self.source_folder, + dst=os.path.join(self.package_folder, self.cpp.package.resdirs[-1])) + copy(self, "*", src=os.path.join(self.source_folder, "packaging"), + dst=os.path.join(self.package_folder, self.cpp.package.resdirs[2])) # Remove the CuraEngineGradualFlow plugin from the package rmdir(self, os.path.join(self.package_folder, self.cpp.package.resdirs[1], "CuraEngineGradualFlow")) - rm(self, "bundled_*.json", os.path.join(self.package_folder, self.cpp.package.resdirs[0], "bundled_packages"), recursive = False) + rm(self, "bundled_*.json", os.path.join(self.package_folder, self.cpp.package.resdirs[0], "bundled_packages"), + recursive=False) # Remove the fdm_materials from the package rmdir(self, os.path.join(self.package_folder, self.cpp.package.resdirs[0], "materials")) From 2b5f8b3a7c4a77e7eb99fc974996efcd4b77ace0 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Thu, 30 Nov 2023 13:23:37 +0100 Subject: [PATCH 028/133] Remove deprecated `createAndRemoveOnUninstall` action from wix installer CURA-11288 --- packaging/msi/UltiMaker-Cura.wxs.jinja | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packaging/msi/UltiMaker-Cura.wxs.jinja b/packaging/msi/UltiMaker-Cura.wxs.jinja index de441443f4..07a2c7d8c9 100644 --- a/packaging/msi/UltiMaker-Cura.wxs.jinja +++ b/packaging/msi/UltiMaker-Cura.wxs.jinja @@ -161,7 +161,7 @@ - + @@ -170,7 +170,7 @@ - + From 87caa0307a80040a74d68a2060b9f34853e09115 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Thu, 30 Nov 2023 13:28:33 +0100 Subject: [PATCH 029/133] Display message on open file event CURA-11288 --- cura/CuraApplication.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index c6c44cf8f5..0ac7118776 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1154,6 +1154,15 @@ class CuraApplication(QtApplication): """Handle Qt events""" if event.type() == QEvent.Type.FileOpen: + + result_message = Message( + f"file: {str(event.file())}, url: {str(event.url())}", + lifetime=0, + title="OPENING FILE", + message_type=Message.MessageType.NEUTRAL, + ) + result_message.show() + if self._plugins_loaded: self._openFile(event.file()) else: From ad871c627ed5a4de7e93613f83e7439d8030818c Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Thu, 30 Nov 2023 13:42:48 +0100 Subject: [PATCH 030/133] Don't open file on open file event CURA-11288 --- cura/CuraApplication.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 0ac7118776..da1594c37b 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1163,10 +1163,10 @@ class CuraApplication(QtApplication): ) result_message.show() - if self._plugins_loaded: - self._openFile(event.file()) - else: - self._open_file_queue.append(event.file()) + # if self._plugins_loaded: + # self._openFile(event.file()) + # else: + # self._open_file_queue.append(event.file()) if int(event.type()) == 20: # 'QEvent.Type.Quit' enum isn't there, even though it should be according to docs. # Once we're at this point, everything should have been flushed already (past OnExitCallbackManager). From d93d66dd8adad41fb693b8c6e135caf44f92cd5f Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Thu, 30 Nov 2023 13:45:21 +0100 Subject: [PATCH 031/133] Use sentry cura engine version CURA-11364 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 6bae617e3a..3706604205 100644 --- a/conanfile.py +++ b/conanfile.py @@ -332,7 +332,7 @@ class CuraConan(ConanFile): self.requires("zlib/1.2.13") self.requires("pyarcus/5.3.0") self.requires("dulcificum/0.1.0-beta.1") - self.requires("curaengine/(latest)@ultimaker/testing") + self.requires("curaengine/latest@ultimaker/cura_11364") self.requires("pysavitar/5.3.0") self.requires("pynest2d/5.3.0") self.requires("curaengine_plugin_gradual_flow/0.1.0") From 66ad006bc528392bd7246a29cfec4896fb31105d Mon Sep 17 00:00:00 2001 From: Paul Kuiper <46715907+pkuiper-ultimaker@users.noreply.github.com> Date: Thu, 30 Nov 2023 14:15:00 +0100 Subject: [PATCH 032/133] Reduced line width of the middle raft layer from 1.2 to 0.4 Increase speed from 27.5mm/s to 90mm/s. --- resources/definitions/ultimaker_method_base.def.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/definitions/ultimaker_method_base.def.json b/resources/definitions/ultimaker_method_base.def.json index 8e9034c954..6ac68ef2de 100644 --- a/resources/definitions/ultimaker_method_base.def.json +++ b/resources/definitions/ultimaker_method_base.def.json @@ -357,7 +357,8 @@ "raft_base_thickness": { "value": 0.8 }, "raft_interface_extruder_nr": { "value": "raft_surface_extruder_nr" }, "raft_interface_layers": { "value": 2 }, - "raft_interface_line_width": { "value": 1.2 }, + "raft_interface_line_width": { "value": "line_width" }, + "raft_interface_speed": { "value": 90 }, "raft_interface_thickness": { "value": 0.3 }, "raft_margin": { "value": 3 }, "raft_surface_extruder_nr": { "value": "int(anyExtruderWithMaterial('material_is_support_material')) if support_enable and extruderValue(support_extruder_nr,'material_is_support_material') else raft_base_extruder_nr" }, From a442228f38d758870f7753870f03438e9fd6986b Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Thu, 30 Nov 2023 22:45:18 +0100 Subject: [PATCH 033/133] Open file on url scheme CURA-11289 --- cura/CuraApplication.py | 73 ++++++++++++++++++++++++++++++++--------- 1 file changed, 57 insertions(+), 16 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index da1594c37b..e7289a225f 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -8,9 +8,11 @@ import time import platform from pathlib import Path from typing import cast, TYPE_CHECKING, Optional, Callable, List, Any, Dict +import re +import requests import numpy -from PyQt6.QtCore import QObject, QTimer, QUrl, pyqtSignal, pyqtProperty, QEvent, pyqtEnum, QCoreApplication +from PyQt6.QtCore import QObject, QTimer, QUrl, QUrlQuery, pyqtSignal, pyqtProperty, QEvent, pyqtEnum, QCoreApplication from PyQt6.QtGui import QColor, QIcon from PyQt6.QtQml import qmlRegisterUncreatableType, qmlRegisterUncreatableMetaObject, qmlRegisterSingletonType, qmlRegisterType from PyQt6.QtWidgets import QMessageBox @@ -249,7 +251,7 @@ class CuraApplication(QtApplication): self._additional_components = {} # Components to add to certain areas in the interface self._open_file_queue = [] # A list of files to open (after the application has started) - + self._open_url_queue = [] # A list of urls to open (after the application has started) self._update_platform_activity_timer = None self._sidebar_custom_menu_items = [] # type: list # Keeps list of custom menu items for the side bar @@ -946,6 +948,8 @@ class CuraApplication(QtApplication): self.callLater(self._openFile, file_name) for file_name in self._open_file_queue: # Open all the files that were queued up while plug-ins were loading. self.callLater(self._openFile, file_name) + for url in self._open_url_queue: + self.callLater(self._openUrl, url) initializationFinished = pyqtSignal() showAddPrintersUncancellableDialog = pyqtSignal() # Used to show the add printers dialog with a greyed background @@ -1154,19 +1158,16 @@ class CuraApplication(QtApplication): """Handle Qt events""" if event.type() == QEvent.Type.FileOpen: - - result_message = Message( - f"file: {str(event.file())}, url: {str(event.url())}", - lifetime=0, - title="OPENING FILE", - message_type=Message.MessageType.NEUTRAL, - ) - result_message.show() - - # if self._plugins_loaded: - # self._openFile(event.file()) - # else: - # self._open_file_queue.append(event.file()) + if self._plugins_loaded: + if event.file(): + self._openFile(event.file()) + if event.url(): + self._openUrl(event.url()) + else: + if event.file(): + self._open_file_queue.append(event.file()) + if event.url(): + self._open_url_queue.append(event.url()) if int(event.type()) == 20: # 'QEvent.Type.Quit' enum isn't there, even though it should be according to docs. # Once we're at this point, everything should have been flushed already (past OnExitCallbackManager). @@ -1550,7 +1551,7 @@ class CuraApplication(QtApplication): if not nodes: return - objects_in_filename = {} # type: Dict[str, List[CuraSceneNode]] + objects_in_filename: Dict[str, List[CuraSceneNode]] = {} for node in nodes: mesh_data = node.getMeshData() if mesh_data: @@ -1791,6 +1792,46 @@ class CuraApplication(QtApplication): def _openFile(self, filename): self.readLocalFile(QUrl.fromLocalFile(filename)) + def _openUrl(self, url: QUrl) -> None: + supported_schemes = ["cura", "slicer"] + if url.scheme() not in supported_schemes: + # only handle cura:// and slicer:// urls schemes + return + + match url.host() + url.path(): + case "open": + query = QUrlQuery(url.query()) + model_url = QUrl(query.queryItemValue("file", options=QUrl.ComponentFormattingOption.FullyDecoded)) + response = requests.get(model_url.url()) + if response.status_code is not 200: + Logger.log("e", "Could not download file from {0}".format(model_url.url())) + return + + content_disposition = response.headers.get('Content-Disposition') + if content_disposition is None: + Logger.log("w", + "Could not find Content-Disposition header in response from {0}".format(model_url.url())) + # Use the last part of the url as the filename, and assume it is an STL file + filename = model_url.path().split("/")[-1] + ".stl" + else: + # content_disposition is in the following format + # ``` + # content_disposition attachment; "filename=[FILENAME]" + # ``` + # Use a regex to extract the filename + # content_disposition = response.headers.get('Content-Disposition') + content_disposition_match = re.match(r'attachment; filename="(?P.*)"', + content_disposition) + assert content_disposition_match is not None + filename = content_disposition_match.group("filename") + + tmp = tempfile.NamedTemporaryFile(suffix=filename, delete=False) + with open(tmp.name, "wb") as f: + f.write(response.content) + self.readLocalFile(QUrl.fromLocalFile(tmp.name), add_to_recent_files=False) + case path: + Logger.log("w", "Unsupported url scheme path: {0}".format(path)) + def _addProfileReader(self, profile_reader): # TODO: Add the profile reader to the list of plug-ins that can be used when importing profiles. pass From b629669f77ee7dc3345283170b8148d017f073f7 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Thu, 30 Nov 2023 14:00:28 +0100 Subject: [PATCH 034/133] Use sip<=6.7.12 6.8.0 seams to have bug which is botching up building pyArcus Contribute to CURA-11080 --- .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 9380d1cb98..215557e367 100644 --- a/.github/workflows/requirements-conan-package.txt +++ b/.github/workflows/requirements-conan-package.txt @@ -1,2 +1,2 @@ conan>=1.60.2,<2.0.0 -sip +sip<=6.7.12 From 10b69e801e7547bbf730345552ba61f337685aab Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Thu, 30 Nov 2023 23:38:27 +0100 Subject: [PATCH 035/133] Openssl shared on Linux static for the rest Contribute to CURA-11080 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 18ad185d6a..d52d62e5cc 100644 --- a/conanfile.py +++ b/conanfile.py @@ -307,10 +307,10 @@ class CuraConan(ConanFile): self.options["pynest2d"].shared = True self.options["dulcificum"].shared = self.settings.os != "Windows" self.options["cpython"].shared = True - self.options["openssl"].shared = True self.options["boost"].header_only = True if self.settings.os == "Linux": self.options["curaengine_grpc_definitions"].shared = True + self.options["openssl"].shared = True def validate(self): version = self.conf.get("user.cura:version", default = self.version, check_type = str) From 79c7db3e6f621ad444be94d98a2c27da6d2c9c04 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Fri, 1 Dec 2023 08:13:30 +0100 Subject: [PATCH 036/133] Use Uranium workign branch CURA-11137 Contributes to CURA-10831 and CURA-11137 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index d52d62e5cc..1244661849 100644 --- a/conanfile.py +++ b/conanfile.py @@ -328,7 +328,7 @@ class CuraConan(ConanFile): self.requires("pysavitar/5.3.0") self.requires("pynest2d/5.3.0") self.requires("curaengine_plugin_gradual_flow/0.1.0") - self.requires("uranium/(latest)@ultimaker/testing") + self.requires("uranium/(latest)@ultimaker/cura_11137") # FIXME: Use `testing` once the branch is merged self.requires("cura_binary_data/(latest)@ultimaker/testing") self.requires("cpython/3.10.4@ultimaker/stable") self.requires("openssl/3.2.0") From 31d48aabe7ca0b2eca3033b94f2eed7d9b3e20f5 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Fri, 1 Dec 2023 09:15:21 +0100 Subject: [PATCH 037/133] Use Qt6.6 and PyQt6.6 Contributes to CURA-11137 --- requirements.txt | 79 +++++++++++++++++++++++++----------------------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/requirements.txt b/requirements.txt index 48ee3abcdc..76339c884f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,41 +1,46 @@ ### Direct requirements for Uranium and libCharon ### -PyQt6-sip==13.5.2 \ - --hash=sha256:1bdb1f7b5b2f6ac31d517a6f3a13c38055640ac0014f67a2e5422d2083ce69ec \ - --hash=sha256:318d4d1c7ef60f69c68227cef78fc439accc9028ec6149200eea3d34c433d373 \ - --hash=sha256:4b5b0c4b557e0293eba008021342459a0f91c69a7a2eb5231276d495d1d2960a \ - --hash=sha256:5b499eff7150d9f31fe835a73cc41f076bba2fcde0f5b0325b1284797f17c0ac \ - --hash=sha256:5d0fd42da765198b51d7fe12c29721cbe3e14b77ca4f68aa43618149ee7dbeff \ - --hash=sha256:831f5d606fc5296a80303ab30892c3308954c5766039bf7a96267488bb2524a5 \ - --hash=sha256:87d758ba999baa16459f0a3c7f7ed47a5b45e8991ad691f17345bf3c493a4281 \ - --hash=sha256:91812f0094443b816a74a89954d60bb50060807f54d7c016a4de7bd29454091e \ - --hash=sha256:94afb031db89159aa330891eba2c937b0378b4b264570998848c7a78eddf7c94 \ - --hash=sha256:9ad5b8c4c92d62e00ebf254a4c9656668b130f2a1d2792034e0d82b2d6571509 \ - --hash=sha256:9c9dac067710015895f523f5a2a4d59cbef8624a152b6f9a426e5b848d8c6d29 \ - --hash=sha256:ace942b78378bff8ae2d6bafccc84465f1ff0cf30720b8321e0bd6c95c36ede6 \ - --hash=sha256:b54b0d8d21c5835af8f6d6d8a323a23106e67b7cd4c31e23c35bb4c321000de8 \ - --hash=sha256:c0b4e55c4d0dc44728da90eb1451dfff0d05260b4a3496ff0014494e6c1865a6 \ - --hash=sha256:dcf602c233ee7600e810927adcb9e518d61bc796a6b2013c17feedd24c4e5413 \ - --hash=sha256:ebf6264b6feda01ba37d3b60a4bb87493bdb87be70f7b2a5384a7acd4902d88d -PyQt6==6.5.2 \ - --hash=sha256:1487ee7350f9ffb66d60ab4176519252c2b371762cbe8f8340fd951f63801280 \ - --hash=sha256:5bad1437eb0c1ae801103b32ef04ef62ef1cce505b448525f60089ce36329b89 \ - --hash=sha256:70468cca4537756c714a57fa1baa5beabb9b38775f52f9611f49870705672c55 \ - --hash=sha256:ff1d12767b578f0f0e87cdb12198e7dcad9a176c40d1d1d799984181b0af93cb -PyQt6-Qt6==6.5.2 \ - --hash=sha256:4b37f6f93c0980469ccc570998d3e3de243028bae7389fb6330443ab215ce2f6 \ - --hash=sha256:5a3c7bb899678bf801136b31cd589ed4d0d54ab32be5fb76c2bdeb161a9662ad \ - --hash=sha256:8dad61b4666d91882d7e1c4d619c71e7429c13e19182f8b3bebf3ecf95107d4c \ - --hash=sha256:953f3c0e99e486081a6d438b32fbc240da97457226562eb68cf1b11c516386fd -PyQt6-NetworkAuth==6.5.0 \ - --hash=sha256:6dc9e44a978698b673926e34da486f946ccbbeeac02078517c4d1ee23d0546a4 \ - --hash=sha256:7170db3f99e13aef855d9d52a00a8baa2dea92d12f9b441fed9c6dec57f83e09 \ - --hash=sha256:a8c8cb00a615dde1efaf1d7926e8532df77d6d08798d33b6325fb8f2ff0f220d \ - --hash=sha256:ac56d362c9efcfc194e358cc2bba362535b0775dc2bd8257f964e0bcfe7d421a -PyQt6-NetworkAuth-Qt6==6.5.2 \ - --hash=sha256:0588b93ec5a6f2c492a42dc56967f06d33306169e716c5636448816a65956278 \ - --hash=sha256:29396a63b68e8fa26587c35e8befad0a84e3a05e03551d1329ffd527684edc68 \ - --hash=sha256:2ec8ca45764d2f122912ad6c754b5ffe65f143b5a52f99649cc7931b475e064b \ - --hash=sha256:76e0877ed86247784740a0eb928f3c77da7466f08d96d17306efda6060df2c44 +PyQt6-sip==13.6.0 \ + --hash=sha256:0dfd22cfedd87e96f9d51e0778ca2ba3dc0be83e424e9e0f98f6994d8d9c90f0 \ + --hash=sha256:13885361ca2cb2f5085d50359ba61b3fabd41b139fb58f37332acbe631ef2357 \ + --hash=sha256:24441032a29791e82beb7dfd76878339058def0e97fdb7c1cea517f3a0e6e96b \ + --hash=sha256:2486e1588071943d4f6657ba09096dc9fffd2322ad2c30041e78ea3f037b5778 \ + --hash=sha256:3075d8b325382750829e6cde6971c943352309d35768a4d4da0587459606d562 \ + --hash=sha256:33ea771fe777eb0d1a2c3ef35bcc3f7a286eb3ff09cd5b2fdd3d87d1f392d7e8 \ + --hash=sha256:39854dba35f8e5a4288da26ecb5f40b4c5ec1932efffb3f49d5ea435a7f37fb3 \ + --hash=sha256:3bf03e130fbfd75c9c06e687b86ba375410c7a9e835e4e03285889e61dd4b0c4 \ + --hash=sha256:43fb8551796030aae3d66d6e35e277494071ec6172cd182c9569ab7db268a2f5 \ + --hash=sha256:58f68a48400e0b3d1ccb18090090299bad26e3aed7ccb7057c65887b79b8aeea \ + --hash=sha256:5b9c6b6f9cfccb48cbb78a59603145a698fb4ffd176764d7083e5bf47631d8df \ + --hash=sha256:747f6ca44af81777a2c696bd501bc4815a53ec6fc94d4e25830e10bc1391f8ab \ + --hash=sha256:86a7b67c64436e32bffa9c28c9f21bf14a9faa54991520b12c3f6f435f24df7f \ + --hash=sha256:8c282062125eea5baf830c6998587d98c50be7c3a817a057fb95fef647184012 \ + --hash=sha256:8f9df9f7ccd8a9f0f1d36948c686f03ce1a1281543a3e636b7b7d5e086e1a436 \ + --hash=sha256:98bf954103b087162fa63b3a78f30b0b63da22fd6450b610ec1b851dbb798228 \ + --hash=sha256:9adf672f9114687533a74d5c2d4c03a9a929ad5ad9c3e88098a7da1a440ab916 \ + --hash=sha256:a6ce80bc24618d8a41be8ca51ad9f10e8bc4296dd90ab2809573df30a23ae0e5 \ + --hash=sha256:d6b5f699aaed0ac1fcd23e8fbca70d8a77965831b7c1ce474b81b1678817a49d \ + --hash=sha256:fa759b6339ff7e25f9afe2a6b651b775f0a36bcb3f5fa85e81a90d3b033c83f4 \ + --hash=sha256:fa7b10af7488efc5e53b41dd42c0f421bde6c2865a107af7ae259aff9d841da9 +PyQt6==6.6.0 \ + --hash=sha256:33655db05ac2de699320f035250c21434c77144a6a2943aca3f4c579dabc3f7b \ + --hash=sha256:3ef68830a9b32050c30f7962c56a5927802c9193b68eaf405faecb8ce9ae10a8 \ + --hash=sha256:d41512d66044c2df9c5f515a56a922170d68a37b3406ffddc8b4adc57181b576 \ + --hash=sha256:fc7185d65755f26d7a6842492ec5398c92544dc4eafbbcbef1b1922aca585c96 +PyQt6-Qt6==6.6.0 \ + --hash=sha256:1b079a33088d32ff47872cdb37fd15aa42101f0be46c3340244483849b781438 \ + --hash=sha256:8cb30d64a4d32465ea1686bc827cbe452225fb387c4873356b0fa7b9ae63534f \ + --hash=sha256:a151f34712cd645111e89cb30b02e5fb69c9dcc3603ab3c03a561e874bd7cbcf \ + --hash=sha256:e5483ae04bf107411c7469f1be9f9e2eb9840303e788b3ac524fe30af90d45f4 +PyQt6-NetworkAuth==6.6.0 \ + --hash=sha256:7b90b81792fe53105287c8cbb5e4b22bc44a482268ffb7d3e33f852807f86182 \ + --hash=sha256:c7e2335159aa795e2fe6fb069ccce6308672ab80f26c50fab57caf957371cbb5 \ + --hash=sha256:cdfc0bfaea16a9e09f075bdafefb996aa9fdec392052ba4fb3cbac233c1958fb \ + --hash=sha256:f60ff9a62f5129dc2a9d4c495fb47f9a03e4dfb666b50fb7d61f46e89bf7b6a2 +PyQt6-NetworkAuth-Qt6==6.6.0 \ + --hash=sha256:481d9093e1fb1ac6843d8beabcd359cc34b74b9a2cbb3e2b68d96bd3f178d4e0 \ + --hash=sha256:4cc48fd375730a0ba5fbed9d64abb2914f587377560a78a63aff893f9e276a45 \ + --hash=sha256:5006deabf55304d4a3e0b3c954f93e5835546b11e789d14653a2493d12d3a063 \ + --hash=sha256:bcd56bfc892fec961c51eba3c0bf32ba8317a762d9e254d3830569611ed569d6 certifi==2023.5.7; \ --hash=sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716 From cf6874c98481bd899a4a47c9af05af1570688a34 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Fri, 1 Dec 2023 10:53:30 +0100 Subject: [PATCH 038/133] Use the `HttpRequestManager` to avoid blocking the main thread CURA-11289 --- cura/CuraApplication.py | 65 ++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 27 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index e7289a225f..079a27b6ce 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -2,17 +2,18 @@ # Cura is released under the terms of the LGPLv3 or higher. import enum import os +import re import sys import tempfile import time import platform from pathlib import Path from typing import cast, TYPE_CHECKING, Optional, Callable, List, Any, Dict -import re import requests import numpy -from PyQt6.QtCore import QObject, QTimer, QUrl, QUrlQuery, pyqtSignal, pyqtProperty, QEvent, pyqtEnum, QCoreApplication +from PyQt6.QtCore import QObject, QTimer, QUrl, QUrlQuery, pyqtSignal, pyqtProperty, QEvent, pyqtEnum, QCoreApplication, \ + QByteArray from PyQt6.QtGui import QColor, QIcon from PyQt6.QtQml import qmlRegisterUncreatableType, qmlRegisterUncreatableMetaObject, qmlRegisterSingletonType, qmlRegisterType from PyQt6.QtWidgets import QMessageBox @@ -1802,33 +1803,43 @@ class CuraApplication(QtApplication): case "open": query = QUrlQuery(url.query()) model_url = QUrl(query.queryItemValue("file", options=QUrl.ComponentFormattingOption.FullyDecoded)) - response = requests.get(model_url.url()) - if response.status_code is not 200: - Logger.log("e", "Could not download file from {0}".format(model_url.url())) + + def on_finish(response): + content_disposition_header_key = QByteArray("content-disposition".encode()) + + if not response.hasRawHeader(content_disposition_header_key): + Logger.log("w", "Could not find Content-Disposition header in response from {0}".format( + model_url.url())) + # Use the last part of the url as the filename, and assume it is an STL file + filename = model_url.path().split("/")[-1] + ".stl" + else: + # content_disposition is in the format + # ``` + # content_disposition attachment; "filename=[FILENAME]" + # ``` + # Use a regex to extract the filename + content_disposition = str(response.rawHeader(content_disposition_header_key).data(), + encoding='utf-8') + content_disposition_match = re.match(r'attachment; filename="(?P.*)"', + content_disposition) + assert content_disposition_match is not None + filename = content_disposition_match.group("filename") + + tmp = tempfile.NamedTemporaryFile(suffix=filename, delete=False) + with open(tmp.name, "wb") as f: + f.write(response.readAll()) + + self.readLocalFile(QUrl.fromLocalFile(tmp.name), add_to_recent_files=False) + + def on_error(): + Logger.log("w", "Could not download file from {0}".format(model_url.url())) return - content_disposition = response.headers.get('Content-Disposition') - if content_disposition is None: - Logger.log("w", - "Could not find Content-Disposition header in response from {0}".format(model_url.url())) - # Use the last part of the url as the filename, and assume it is an STL file - filename = model_url.path().split("/")[-1] + ".stl" - else: - # content_disposition is in the following format - # ``` - # content_disposition attachment; "filename=[FILENAME]" - # ``` - # Use a regex to extract the filename - # content_disposition = response.headers.get('Content-Disposition') - content_disposition_match = re.match(r'attachment; filename="(?P.*)"', - content_disposition) - assert content_disposition_match is not None - filename = content_disposition_match.group("filename") - - tmp = tempfile.NamedTemporaryFile(suffix=filename, delete=False) - with open(tmp.name, "wb") as f: - f.write(response.content) - self.readLocalFile(QUrl.fromLocalFile(tmp.name), add_to_recent_files=False) + self.getHttpRequestManager().get( + model_url.url(), + callback=on_finish, + error_callback=on_error, + ) case path: Logger.log("w", "Unsupported url scheme path: {0}".format(path)) From b847cf626bed6827aeaa3064bed8fb26a1f59549 Mon Sep 17 00:00:00 2001 From: jellespijker Date: Fri, 1 Dec 2023 11:29:02 +0100 Subject: [PATCH 039/133] Use working CURA-10831 packages Contribute to CURA-10831 --- conandata.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/conandata.yml b/conandata.yml index 9a26235e2c..aa83523ad9 100644 --- a/conandata.yml +++ b/conandata.yml @@ -1,9 +1,9 @@ version: "5.7.0-alpha.0" requirements: - - "uranium/(latest)@ultimaker/testing" - - "curaengine/(latest)@ultimaker/testing" - - "cura_binary_data/(latest)@ultimaker/testing" - - "fdm_materials/(latest)@ultimaker/testing" + - "uranium/(latest)@ultimaker/cura_10831" + - "curaengine/(latest)@ultimaker/cura_10831" + - "cura_binary_data/(latest)@ultimaker/cura_10831" + - "fdm_materials/(latest)@ultimaker/cura_10831" - "curaengine_plugin_gradual_flow/0.1.0" - "dulcificum/0.1.0-beta.1" - "pyarcus/5.3.0" @@ -11,8 +11,8 @@ requirements: - "pynest2d/5.3.0" - "curaengine_grpc_definitions/0.1.0" requirements_internal: - - "fdm_materials/(latest)@internal/testing" - - "cura_private_data/(latest)@internal/testing" + - "fdm_materials/(latest)@internal/cura_10831" + - "cura_private_data/(latest)@internal/cura_10831" urls: default: cloud_api_root: "https://api.ultimaker.com" From 4b4b8b351462f7b788816c2ddbf2d75d38ee7de6 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Fri, 1 Dec 2023 13:03:40 +0100 Subject: [PATCH 040/133] Update nsi installer CURA-11288 --- packaging/NSIS/Ultimaker-Cura.nsi.jinja | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packaging/NSIS/Ultimaker-Cura.nsi.jinja b/packaging/NSIS/Ultimaker-Cura.nsi.jinja index 228dba4fe4..c562e5f654 100644 --- a/packaging/NSIS/Ultimaker-Cura.nsi.jinja +++ b/packaging/NSIS/Ultimaker-Cura.nsi.jinja @@ -197,13 +197,11 @@ Section UrlProtocol WriteRegStr HKCR "cura" "" "URL:cura" WriteRegStr HKCR "cura" "URL Protocol" "" WriteRegStr HKCR "cura\DefaultIcon" "" "$INSTDIR\${MAIN_APP_EXE},1" - WriteRegStr HKCR "cura\shell" "" "open" - WriteRegStr HKCR "cura\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}" "%1"' + WriteRegStr HKCR "cura\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}"' WriteRegStr HKCR "slicer" "" "URL:slicer" WriteRegStr HKCR "slicer" "URL Protocol" "" WriteRegStr HKCR "slicer\DefaultIcon" "" "$INSTDIR\${MAIN_APP_EXE},1" - WriteRegStr HKCR "slicer\shell" "" "open" - WriteRegStr HKCR "slicer\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}" "%1"' + WriteRegStr HKCR "slicer\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}"' SectionEnd \ No newline at end of file From 34aecf20fe4f8f5e1ff4e52e80969d2f4279cb15 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Fri, 1 Dec 2023 13:04:49 +0100 Subject: [PATCH 041/133] pin uranium CURA-11288 --- conanfile.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/conanfile.py b/conanfile.py index 48cba847be..2c756f20c8 100644 --- a/conanfile.py +++ b/conanfile.py @@ -327,7 +327,7 @@ class CuraConan(ConanFile): self.requires("pysavitar/5.3.0") self.requires("pynest2d/5.3.0") self.requires("curaengine_plugin_gradual_flow/0.1.0") - self.requires("uranium/(latest)@ultimaker/testing") + self.requires("uranium/latest@ultimaker/cura_11288") self.requires("cura_binary_data/(latest)@ultimaker/testing") self.requires("cpython/3.10.4") if self.options.internal: @@ -358,7 +358,7 @@ class CuraConan(ConanFile): vr = VirtualRunEnv(self) vr.generate() - self._generate_cura_version(os.path.join(self.source_folder, "cura")) + # self._generate_cura_version(os.path.join(self.source_folder, "cura")) if not self.in_local_cache: # Copy CuraEngine.exe to bindirs of Virtual Python Environment @@ -466,7 +466,7 @@ echo "CURA_APP_NAME={{ cura_app_name }}" >> ${{ env_prefix }}GITHUB_ENV ext = ".sh" if self.settings.os != "Windows" else ".ps1" save(self, os.path.join(self._script_dir, f"activate_github_actions_version_env{ext}"), activate_github_actions_version_env) - self._generate_cura_version(os.path.join(self._site_packages, "cura")) + # self._generate_cura_version(os.path.join(self._site_packages, "cura")) entitlements_file = "'{}'".format(Path(self.cpp_info.res_paths[2], "MacOS", "cura.entitlements")) self._generate_pyinstaller_spec(location = self._base_dir, From 19b75b96fb007973bb2fe3f3c0ef0e1e95567903 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Fri, 1 Dec 2023 16:13:19 +0100 Subject: [PATCH 042/133] unpin dulcificum CURA-11288 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 2c756f20c8..b58cbb4b7f 100644 --- a/conanfile.py +++ b/conanfile.py @@ -322,7 +322,7 @@ class CuraConan(ConanFile): self.requires("curaengine_grpc_definitions/0.1.0") self.requires("zlib/1.2.13") self.requires("pyarcus/5.3.0") - self.requires("dulcificum/0.1.0-beta.1") + self.requires("dulcificum/(latest)@ultimaker/testing") self.requires("curaengine/(latest)@ultimaker/testing") self.requires("pysavitar/5.3.0") self.requires("pynest2d/5.3.0") From 4d97e779ed3322bc99c53ab7d0f4b7ad152e5d58 Mon Sep 17 00:00:00 2001 From: jellespijker Date: Fri, 1 Dec 2023 16:18:44 +0100 Subject: [PATCH 043/133] Use process-pull-request workflow Contribute to CURA-10831 --- .github/workflows/process-pull-request.yml | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/.github/workflows/process-pull-request.yml b/.github/workflows/process-pull-request.yml index 7fe3aedc96..f34e26f13e 100644 --- a/.github/workflows/process-pull-request.yml +++ b/.github/workflows/process-pull-request.yml @@ -1,15 +1,11 @@ name: process-pull-request on: - pull_request_target: - types: [opened, reopened, edited, synchronize, review_requested, ready_for_review, assigned] + pull_request_target: + types: [ opened, reopened, edited, review_requested, ready_for_review, assigned ] +# FIXME: Use `main` instead of `CURA-10831` once merged jobs: - add_label: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions-ecosystem/action-add-labels@v1 - if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} - with: - labels: 'PR: Community Contribution :crown:' \ No newline at end of file + add_label: + uses: ultimaker/cura-workflows/.github/workflows/process-pull-request.yml@CURA-10831 + secrets: inherit \ No newline at end of file From bffbded591d85735ad0110517061e744b2765983 Mon Sep 17 00:00:00 2001 From: jellespijker Date: Fri, 1 Dec 2023 17:42:27 +0100 Subject: [PATCH 044/133] Override spdlog version --- conanfile.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 48cba847be..d40b668a6e 100644 --- a/conanfile.py +++ b/conanfile.py @@ -318,7 +318,8 @@ class CuraConan(ConanFile): def requirements(self): self.requires("boost/1.82.0") - self.requires("fmt/9.0.0") + self.requires("spdlog/1.12.0") + self.requires("fmt/10.1.1") self.requires("curaengine_grpc_definitions/0.1.0") self.requires("zlib/1.2.13") self.requires("pyarcus/5.3.0") From b19d5d47d35a8874c8f2aee14f2a2e311c02d742 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 4 Dec 2023 10:22:44 +0100 Subject: [PATCH 045/133] Use dulcificum 0.1.1-beta.0 Contributes to CURA-10831 --- .github/workflows/notify.yml | 54 ------------------------------------ conandata.yml | 2 +- 2 files changed, 1 insertion(+), 55 deletions(-) delete mode 100644 .github/workflows/notify.yml diff --git a/.github/workflows/notify.yml b/.github/workflows/notify.yml deleted file mode 100644 index 370b54c78b..0000000000 --- a/.github/workflows/notify.yml +++ /dev/null @@ -1,54 +0,0 @@ -name: Get Conan Recipe Version - -on: - workflow_call: - inputs: - success: - required: true - type: boolean - - success_title: - required: true - type: string - - success_body: - required: true - type: string - - failure_title: - required: true - type: string - - failure_body: - required: true - type: string - - -jobs: - slackNotification: - name: Slack Notification - - runs-on: ubuntu-latest - - steps: - - name: Slack notify on-success - if: ${{ inputs.success }} - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_USERNAME: ${{ github.repository }} - SLACK_COLOR: green - SLACK_ICON: https://github.com/Ultimaker/Cura/blob/main/icons/cura-128.png?raw=true - SLACK_TITLE: ${{ inputs.success_title }} - SLACK_MESSAGE: ${{ inputs.success_body }} - SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} - - - name: Slack notify on-failure - if: ${{ !inputs.success }} - uses: rtCamp/action-slack-notify@v2 - env: - SLACK_USERNAME: ${{ github.repository }} - SLACK_COLOR: red - SLACK_ICON: https://github.com/Ultimaker/Cura/blob/main/icons/cura-128.png?raw=true - SLACK_TITLE: ${{ inputs.failure_title }} - SLACK_MESSAGE: ${{ inputs.failure_body }} - SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }} diff --git a/conandata.yml b/conandata.yml index aa83523ad9..d0856481f1 100644 --- a/conandata.yml +++ b/conandata.yml @@ -5,7 +5,7 @@ requirements: - "cura_binary_data/(latest)@ultimaker/cura_10831" - "fdm_materials/(latest)@ultimaker/cura_10831" - "curaengine_plugin_gradual_flow/0.1.0" - - "dulcificum/0.1.0-beta.1" + - "dulcificum/latest@ultimaker/cura_10831" - "pyarcus/5.3.0" - "pysavitar/5.3.0" - "pynest2d/5.3.0" From ba9e122f6add419824e6fc03d55df40766d4e71d Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Mon, 4 Dec 2023 11:45:12 +0100 Subject: [PATCH 046/133] unpin dulcificum --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 53d1c9799d..03648f66d8 100644 --- a/conanfile.py +++ b/conanfile.py @@ -324,7 +324,7 @@ class CuraConan(ConanFile): self.requires("curaengine_grpc_definitions/0.1.0") self.requires("zlib/1.2.13") self.requires("pyarcus/5.3.0") - self.requires("dulcificum/0.1.0-beta.1") + self.requires("dulcificum/(latest)@ultimaker/testing") self.requires("curaengine/(latest)@ultimaker/testing") self.requires("pysavitar/5.3.0") self.requires("pynest2d/5.3.0") From 7f1158c36454184fe00be15e5e22df86cb2c2769 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 4 Dec 2023 13:43:30 +0100 Subject: [PATCH 047/133] Use cura-workflow OS installers Contribute to CURA-10831 --- .github/workflows/installers.yml | 92 ++++++----- .github/workflows/linux.yml | 257 ----------------------------- .github/workflows/macos.yml | 270 ------------------------------- .github/workflows/windows.yml | 264 ------------------------------ 4 files changed, 48 insertions(+), 835 deletions(-) delete mode 100644 .github/workflows/linux.yml delete mode 100644 .github/workflows/macos.yml delete mode 100644 .github/workflows/windows.yml diff --git a/.github/workflows/installers.yml b/.github/workflows/installers.yml index 38133ad1de..b3ea88969c 100644 --- a/.github/workflows/installers.yml +++ b/.github/workflows/installers.yml @@ -50,45 +50,46 @@ jobs: release_tag: ${{ steps.default.outputs.release_tag }} steps: - - name: Output default values - id: default - shell: python - run: | - import os - import datetime - - if "${{ github.event_name }}" != "schedule": - cura_conan_version = "${{ github.event.inputs.cura_conan_version }}" - else: - now = datetime.datetime.now() - cura_conan_version = "cura/latest@ultimaker/stable" if now.hour == int(os.environ['LATEST_RELEASE_SCHEDULE_HOUR']) else "cura/latest@ultimaker/testing" - - release_tag = f"nightly-{os.environ['LATEST_RELEASE']}" if "/stable" in cura_conan_version else "nightly" - - # Set cura_conan_version environment variable - output_env = os.environ["GITHUB_OUTPUT"] - content = "" - if os.path.exists(output_env): - with open(output_env, "r") as f: - content = f.read() - with open(output_env, "w") as f: - f.write(content) - f.writelines(f"cura_conan_version={cura_conan_version}\n") - f.writelines(f"release_tag={release_tag}\n") - - summary_env = os.environ["GITHUB_STEP_SUMMARY"] - content = "" - if os.path.exists(summary_env): - with open(summary_env, "r") as f: - content = f.read() - - with open(summary_env, "w") as f: - f.write(content) - f.writelines(f"# cura_conan_version = {cura_conan_version}\n") - f.writelines(f"# release_tag = {release_tag}\n") + - name: Output default values + id: default + shell: python + run: | + import os + import datetime + + if "${{ github.event_name }}" != "schedule": + cura_conan_version = "${{ github.event.inputs.cura_conan_version }}" + else: + now = datetime.datetime.now() + cura_conan_version = "cura/latest@ultimaker/stable" if now.hour == int(os.environ['LATEST_RELEASE_SCHEDULE_HOUR']) else "cura/latest@ultimaker/testing" + + release_tag = f"nightly-{os.environ['LATEST_RELEASE']}" if "/stable" in cura_conan_version else "nightly" + + # Set cura_conan_version environment variable + output_env = os.environ["GITHUB_OUTPUT"] + content = "" + if os.path.exists(output_env): + with open(output_env, "r") as f: + content = f.read() + with open(output_env, "w") as f: + f.write(content) + f.writelines(f"cura_conan_version={cura_conan_version}\n") + f.writelines(f"release_tag={release_tag}\n") + + summary_env = os.environ["GITHUB_STEP_SUMMARY"] + content = "" + if os.path.exists(summary_env): + with open(summary_env, "r") as f: + content = f.read() + + with open(summary_env, "w") as f: + f.write(content) + f.writelines(f"# cura_conan_version = {cura_conan_version}\n") + f.writelines(f"# release_tag = {release_tag}\n") + # FIXME: point to `main` once merged windows-installer: - uses: ./.github/workflows/windows.yml + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-windows.yml@CURA-10831 needs: [ default_values ] with: cura_conan_version: ${{ needs.default_values.outputs.cura_conan_version }} @@ -99,8 +100,9 @@ jobs: operating_system: windows-2022 secrets: inherit + # FIXME: point to `main` once merged linux-installer: - uses: ./.github/workflows/linux.yml + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-linux.yml@CURA-10831 needs: [ default_values ] with: cura_conan_version: ${{ needs.default_values.outputs.cura_conan_version }} @@ -111,8 +113,9 @@ jobs: operating_system: ubuntu-22.04 secrets: inherit + # FIXME: point to `main` once merged macos-installer: - uses: ./.github/workflows/macos.yml + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-macos.yml@CURA-10831 needs: [ default_values ] with: cura_conan_version: ${{ needs.default_values.outputs.cura_conan_version }} @@ -123,8 +126,9 @@ jobs: operating_system: self-hosted-X64 secrets: inherit + # FIXME: point to `main` once merged macos-arm-installer: - uses: ./.github/workflows/macos.yml + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-macos.yml@CURA-10831 needs: [ default_values ] with: cura_conan_version: ${{ needs.default_values.outputs.cura_conan_version }} @@ -142,9 +146,9 @@ jobs: needs: [ default_values, windows-installer, linux-installer, macos-installer, macos-arm-installer ] steps: - name: Checkout - uses: actions/checkout@v3 - - # It's not necessary to download all three, but it does make sure we have at least one if an OS is skipped. + uses: actions/checkout@v4 + with: + fetch-depth: 1 - name: Download the run info uses: actions/download-artifact@v2 @@ -193,7 +197,7 @@ jobs: with: name: ${{ steps.filename.outputs.LINUX }}-AppImage path: installers - + - name: Download linux installer jobs asc artifacts uses: actions/download-artifact@v2 with: diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml deleted file mode 100644 index 8b6d892fa0..0000000000 --- a/.github/workflows/linux.yml +++ /dev/null @@ -1,257 +0,0 @@ -name: Linux Installer -run-name: ${{ inputs.cura_conan_version }} for Linux-${{ inputs.architecture }} by @${{ github.actor }} - -on: - workflow_dispatch: - inputs: - cura_conan_version: - description: 'Cura Conan Version' - default: 'cura/latest@ultimaker/testing' - required: true - type: string - conan_args: - description: 'Conan args: eq.: --require-override' - default: '' - required: false - type: string - enterprise: - description: 'Build Cura as an Enterprise edition' - default: false - required: true - type: boolean - staging: - description: 'Use staging API' - default: false - required: true - type: boolean - architecture: - description: 'Architecture' - required: true - default: 'X64' - type: choice - options: - - X64 - operating_system: - description: 'OS' - required: true - default: 'ubuntu-22.04' - type: choice - options: - - ubuntu-22.04 - - workflow_call: - inputs: - cura_conan_version: - description: 'Cura Conan Version' - default: 'cura/latest@ultimaker/testing' - required: true - type: string - conan_args: - description: 'Conan args: eq.: --require-override' - default: '' - required: false - type: string - enterprise: - description: 'Build Cura as an Enterprise edition' - default: false - required: true - type: boolean - staging: - description: 'Use staging API' - default: false - required: true - type: boolean - architecture: - description: 'Architecture' - required: true - default: 'X64' - type: string - operating_system: - description: 'OS' - required: true - default: 'ubuntu-22.04' - type: string - -env: - CONAN_LOGIN_USERNAME_CURA: ${{ secrets.CONAN_USER }} - CONAN_PASSWORD_CURA: ${{ secrets.CONAN_PASS }} - GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} - CURA_CONAN_VERSION: ${{ inputs.cura_conan_version }} - ENTERPRISE: ${{ inputs.enterprise }} - STAGING: ${{ inputs.staging }} - -jobs: - cura-installer-create: - runs-on: ${{ inputs.operating_system }} - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup Python and pip - uses: actions/setup-python@v4 - with: - python-version: '3.10.x' - cache: 'pip' - cache-dependency-path: .github/workflows/requirements-conan-package.txt - - - name: Install Python requirements for runner - run: pip install -r .github/workflows/requirements-conan-package.txt - - - name: Cache Conan local repository packages (Bash) - uses: actions/cache@v3 - with: - path: | - $HOME/.conan/data - $HOME/.conan/conan_download_cache - key: conan-${{ runner.os }}-${{ runner.arch }}-installer-cache - - - name: Install Linux system requirements - run: | - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y - sudo apt update - sudo apt upgrade - sudo apt install build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config binutils coreutils desktop-file-utils fakeroot fuse libgdk-pixbuf2.0-dev patchelf squashfs-tools strace util-linux zsync libxcb-cursor-dev -y - - # Get the AppImage tool - wget --no-check-certificate --quiet https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage -O $GITHUB_WORKSPACE/appimagetool - chmod +x $GITHUB_WORKSPACE/appimagetool - echo "APPIMAGETOOL_LOCATION=$GITHUB_WORKSPACE/appimagetool" >> $GITHUB_ENV - - # Get the AppImage builder - wget --no-check-certificate --quiet -O $GITHUB_WORKSPACE/appimage-builder-x86_64.AppImage https://github.com/AppImageCrafters/appimage-builder/releases/download/v1.1.0/appimage-builder-1.1.0-x86_64.AppImage - chmod +x appimage-builder-x86_64.AppImage - echo "APPIMAGEBUILDER_LOCATION=$GITHUB_WORKSPACE/appimage-builder-x86_64.AppImage" >> $GITHUB_ENV - - # Make sure these tools can be found on the path - echo "$GITHUB_WORKSPACE" >> $GITHUB_PATH - - - name: Install GCC-13 - run: | - sudo apt install g++-13 gcc-13 -y - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13 - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 13 - - - name: Create the default Conan profile - run: conan profile new default --detect --force - - - name: Configure GPG Key Linux (Bash) - run: echo -n "$GPG_PRIVATE_KEY" | base64 --decode | gpg --import - - - name: Get Conan configuration - run: | - conan config install https://github.com/Ultimaker/conan-config.git - conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}" - - - name: Use Conan download cache (Bash) - run: conan config set storage.download_cache="$HOME/.conan/conan_download_cache" - - - name: Create the Packages (Bash) - run: conan install $CURA_CONAN_VERSION ${{ inputs.conan_args }} --build=missing --update -if cura_inst -g VirtualPythonEnv -o cura:enterprise=$ENTERPRISE -o cura:staging=$STAGING -c tools.build:skip_test=True - - - name: Remove internal packages before uploading - run: | - conan remove "*@internal/*" -f || true - conan remove "cura_private_data*" -f || true - - - name: Upload the Package(s) - if: always() - run: | - conan upload "*" -r cura --all -c - - - name: Set Environment variables for Cura (bash) - run: | - . ./cura_inst/bin/activate_github_actions_env.sh - . ./cura_inst/bin/activate_github_actions_version_env.sh - - - name: Create the Cura dist - run: pyinstaller ./cura_inst/UltiMaker-Cura.spec - - - name: Output the name file name and extension - id: filename - shell: python - run: | - import os - enterprise = "-Enterprise" if "${{ inputs.enterprise }}" == "true" else "" - installer_filename = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-linux-${{ inputs.architecture }}" - output_env = os.environ["GITHUB_OUTPUT"] - content = "" - if os.path.exists(output_env): - with open(output_env, "r") as f: - content = f.read() - with open(output_env, "w") as f: - f.write(content) - f.writelines(f"INSTALLER_FILENAME={installer_filename}\n") - - - name: Summarize the used dependencies - shell: python - run: | - import os - - from cura.CuraVersion import ConanInstalls, PythonInstalls - - summary_env = os.environ["GITHUB_STEP_SUMMARY"] - content = "" - if os.path.exists(summary_env): - with open(summary_env, "r") as f: - content = f.read() - - with open(summary_env, "w") as f: - f.write(content) - f.writelines("# ${{ steps.filename.outputs.INSTALLER_FILENAME }}\n") - f.writelines("## Conan packages:\n") - for dep_name, dep_info in ConanInstalls.items(): - f.writelines(f"`{dep_name} {dep_info['version']} {dep_info['revision']}`\n") - - f.writelines("## Python modules:\n") - for dep_name, dep_info in PythonInstalls.items(): - f.writelines(f"`{dep_name} {dep_info['version']}`\n") - - - name: Create the Linux AppImage (Bash) - run: | - python ../cura_inst/packaging/AppImage-builder/create_appimage.py ./UltiMaker-Cura $CURA_VERSION_FULL "${{ steps.filename.outputs.INSTALLER_FILENAME }}.AppImage" - chmod +x "${{ steps.filename.outputs.INSTALLER_FILENAME }}.AppImage" - working-directory: dist - - - name: Upload the AppImage - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.filename.outputs.INSTALLER_FILENAME }}-AppImage - path: | - dist/${{ steps.filename.outputs.INSTALLER_FILENAME }}.AppImage - retention-days: 5 - - - name: Upload the asc - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.filename.outputs.INSTALLER_FILENAME }}-asc - path: | - dist/${{ steps.filename.outputs.INSTALLER_FILENAME }}.AppImage.asc - retention-days: 5 - - - name: Write the run info - shell: python - run: | - import os - with open("run_info.sh", "w") as f: - f.writelines(f'echo "CURA_VERSION_FULL={os.environ["CURA_VERSION_FULL"]}" >> $GITHUB_ENV\n') - - name: Upload the run info - uses: actions/upload-artifact@v3 - with: - name: linux-run-info - path: | - run_info.sh - retention-days: 5 - - notify-export: - if: ${{ always() }} - needs: [ cura-installer-create ] - - uses: ultimaker/cura/.github/workflows/notify.yml@main - with: - success: ${{ contains(join(needs.*.result, ','), 'success') }} - success_title: "Create the Cura distributions" - success_body: "Installers for ${{ inputs.cura_conan_version }}" - failure_title: "Failed to create the Cura distributions" - failure_body: "Failed to create at least 1 installer for ${{ inputs.cura_conan_version }}" - secrets: inherit diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml deleted file mode 100644 index c7c34d9d51..0000000000 --- a/.github/workflows/macos.yml +++ /dev/null @@ -1,270 +0,0 @@ -name: Macos Installer -run-name: ${{ inputs.cura_conan_version }} for Macos-${{ inputs.architecture }} by @${{ github.actor }} - -on: - workflow_dispatch: - inputs: - cura_conan_version: - description: 'Cura Conan Version' - default: 'cura/latest@ultimaker/testing' - required: true - type: string - conan_args: - description: 'Conan args: eq.: --require-override' - default: '' - required: false - type: string - enterprise: - description: 'Build Cura as an Enterprise edition' - default: false - required: true - type: boolean - staging: - description: 'Use staging API' - default: false - required: true - type: boolean - architecture: - description: 'Architecture' - required: true - default: 'ARM64' - type: choice - options: - - X64 - - ARM64 - operating_system: - description: 'OS' - required: true - default: 'self-hosted-ARM64' - type: choice - options: - - self-hosted-X64 - - self-hosted-ARM64 - - macos-11 - - macos-12 - workflow_call: - inputs: - cura_conan_version: - description: 'Cura Conan Version' - default: 'cura/latest@ultimaker/testing' - required: true - type: string - conan_args: - description: 'Conan args: eq.: --require-override' - default: '' - required: false - type: string - enterprise: - description: 'Build Cura as an Enterprise edition' - default: false - required: true - type: boolean - staging: - description: 'Use staging API' - default: false - required: true - type: boolean - architecture: - description: 'Architecture' - required: true - default: 'ARM64' - type: string - operating_system: - description: 'OS' - required: true - default: 'self-hosted-ARM64' - type: string - -env: - CONAN_LOGIN_USERNAME_CURA: ${{ secrets.CONAN_USER }} - CONAN_PASSWORD_CURA: ${{ secrets.CONAN_PASS }} - CODESIGN_IDENTITY: ${{ secrets.CODESIGN_IDENTITY }} - MAC_NOTARIZE_USER: ${{ secrets.MAC_NOTARIZE_USER }} - MAC_NOTARIZE_PASS: ${{ secrets.MAC_NOTARIZE_PASS }} - MACOS_CERT_P12: ${{ secrets.MACOS_CERT_P12 }} - MACOS_CERT_INSTALLER_P12: ${{ secrets.MACOS_CERT_INSTALLER_P12 }} - MACOS_CERT_USER: ${{ secrets.MACOS_CERT_USER }} - MACOS_CERT_PASSPHRASE: ${{ secrets.MACOS_CERT_PASSPHRASE }} - CURA_CONAN_VERSION: ${{ inputs.cura_conan_version }} - ENTERPRISE: ${{ inputs.enterprise }} - STAGING: ${{ inputs.staging }} - -jobs: - cura-installer-create: - runs-on: ${{ inputs.operating_system }} - - outputs: - INSTALLER_FILENAME: ${{ steps.filename.outputs.INSTALLER_FILENAME }} - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup Python and pip - uses: actions/setup-python@v4 - with: - python-version: '3.11.x' - cache: 'pip' - cache-dependency-path: .github/workflows/requirements-conan-package.txt - - - name: Install Python requirements for runner - run: pip install -r .github/workflows/requirements-conan-package.txt - - - name: Cache Conan local repository packages (Bash) - uses: actions/cache@v3 - with: - path: | - $HOME/.conan/data - $HOME/.conan/conan_download_cache - key: conan-${{ runner.os }}-${{ runner.arch }}-installer-cache - - - name: Install MacOS system requirements - run: brew install cmake autoconf automake ninja create-dmg - - - name: Create the default Conan profile - run: conan profile new default --detect --force - - - name: Remove Macos keychain (Bash) - run: security delete-keychain signing_temp.keychain || true - - - name: Configure Macos keychain Developer Cert(Bash) - id: macos-keychain-developer-cert - uses: apple-actions/import-codesign-certs@v1 - with: - keychain-password: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }} - p12-file-base64: ${{ secrets.MACOS_CERT_P12 }} - p12-password: ${{ secrets.MACOS_CERT_PASSPHRASE }} - - - name: Configure Macos keychain Installer Cert (Bash) - id: macos-keychain-installer-cert - uses: apple-actions/import-codesign-certs@v1 - with: - keychain-password: ${{ secrets.MACOS_KEYCHAIN_PASSWORD }} - create-keychain: false # keychain is created in previous use of action. - p12-file-base64: ${{ secrets.MACOS_CERT_INSTALLER_P12 }} - p12-password: ${{ secrets.MACOS_CERT_PASSPHRASE }} - - - name: Remove private Artifactory - run: conan remote remove cura-private-conan-dev || true - - - name: Get Conan configuration - run: | - conan config install https://github.com/Ultimaker/conan-config.git - conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}" - - - name: Use Conan download cache (Bash) - run: conan config set storage.download_cache="$HOME/.conan/conan_download_cache" - - - name: Create the Packages (Bash) - run: conan install $CURA_CONAN_VERSION ${{ inputs.conan_args }} --build=missing --update -if cura_inst -g VirtualPythonEnv -o cura:enterprise=$ENTERPRISE -o cura:staging=$STAGING -c tools.build:skip_test=True - - - name: Remove internal packages before uploading - run: | - conan remove "*@internal/*" -f || true - conan remove "cura_private_data*" -f || true - - - name: Upload the Package(s) - run: | - conan upload "*" -r cura --all -c - - - name: Set Environment variables for Cura (bash) - run: | - . ./cura_inst/bin/activate_github_actions_env.sh - . ./cura_inst/bin/activate_github_actions_version_env.sh - - - name: Unlock Macos keychain (Bash) - run: security unlock -p $TEMP_KEYCHAIN_PASSWORD signing_temp.keychain - env: - TEMP_KEYCHAIN_PASSWORD: ${{ steps.macos-keychain-developer-cert.outputs.keychain-password }} - - - name: Create the Cura dist - run: pyinstaller ./cura_inst/UltiMaker-Cura.spec - - - name: Output the name file name and extension - id: filename - shell: python - run: | - import os - enterprise = "-Enterprise" if "${{ inputs.enterprise }}" == "true" else "" - installer_filename = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-macos-${{ inputs.architecture }}" - output_env = os.environ["GITHUB_OUTPUT"] - content = "" - if os.path.exists(output_env): - with open(output_env, "r") as f: - content = f.read() - with open(output_env, "w") as f: - f.write(content) - f.writelines(f"INSTALLER_FILENAME={installer_filename}\n") - - - name: Summarize the used dependencies - shell: python - run: | - import os - - from cura.CuraVersion import ConanInstalls, PythonInstalls - - summary_env = os.environ["GITHUB_STEP_SUMMARY"] - content = "" - if os.path.exists(summary_env): - with open(summary_env, "r") as f: - content = f.read() - - with open(summary_env, "w") as f: - f.write(content) - f.writelines("# ${{ steps.filename.outputs.INSTALLER_FILENAME }}\n") - f.writelines("## Conan packages:\n") - for dep_name, dep_info in ConanInstalls.items(): - f.writelines(f"`{dep_name} {dep_info['version']} {dep_info['revision']}`\n") - - f.writelines("## Python modules:\n") - for dep_name, dep_info in PythonInstalls.items(): - f.writelines(f"`{dep_name} {dep_info['version']}`\n") - - - name: Create the Macos dmg (Bash) - run: python ../cura_inst/packaging/MacOS/build_macos.py --source_path ../cura_inst --dist_path . --cura_conan_version $CURA_CONAN_VERSION --filename "${{ steps.filename.outputs.INSTALLER_FILENAME }}" --build_dmg --build_pkg --app_name "$CURA_APP_NAME" - working-directory: dist - - - name: Upload the dmg - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.filename.outputs.INSTALLER_FILENAME }}-dmg - path: | - dist/${{ steps.filename.outputs.INSTALLER_FILENAME }}.dmg - retention-days: 5 - - - name: Upload the pkg - uses: actions/upload-artifact@v3 - with: - name: ${{ steps.filename.outputs.INSTALLER_FILENAME }}-pkg - path: | - dist/${{ steps.filename.outputs.INSTALLER_FILENAME }}.pkg - retention-days: 5 - - - name: Write the run info - shell: python - run: | - import os - with open("run_info.sh", "w") as f: - f.writelines(f'echo "CURA_VERSION_FULL={os.environ["CURA_VERSION_FULL"]}" >> $GITHUB_ENV\n') - - - name: Upload the run info - uses: actions/upload-artifact@v3 - with: - name: macos-run-info - path: | - run_info.sh - retention-days: 5 - - - notify-export: - if: ${{ always() }} - needs: [ cura-installer-create ] - - uses: ultimaker/cura/.github/workflows/notify.yml@main - with: - success: ${{ contains(join(needs.*.result, ','), 'success') }} - success_title: "Create the Cura distributions" - success_body: "Installers for ${{ inputs.cura_conan_version }}" - failure_title: "Failed to create the Cura distributions" - failure_body: "Failed to create at least 1 installer for ${{ inputs.cura_conan_version }}" - secrets: inherit diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml deleted file mode 100644 index dfffc4540b..0000000000 --- a/.github/workflows/windows.yml +++ /dev/null @@ -1,264 +0,0 @@ -name: Windows Installer -run-name: ${{ inputs.cura_conan_version }} for Windows-${{ inputs.architecture }} by @${{ github.actor }} - -on: - workflow_dispatch: - inputs: - cura_conan_version: - description: 'Cura Conan Version' - default: 'cura/latest@ultimaker/testing' - required: true - type: string - conan_args: - description: 'Conan args: eq.: --require-override' - default: '' - required: false - type: string - enterprise: - description: 'Build Cura as an Enterprise edition' - default: false - required: true - type: boolean - staging: - description: 'Use staging API' - default: false - required: true - type: boolean - architecture: - description: 'Architecture' - required: true - default: 'X64' - type: choice - options: - - X64 - operating_system: - description: 'OS' - required: true - default: 'windows-2022' - type: choice - options: - - windows-2022 - workflow_call: - inputs: - cura_conan_version: - description: 'Cura Conan Version' - default: 'cura/latest@ultimaker/testing' - required: true - type: string - conan_args: - description: 'Conan args: eq.: --require-override' - default: '' - required: false - type: string - enterprise: - description: 'Build Cura as an Enterprise edition' - default: false - required: true - type: boolean - staging: - description: 'Use staging API' - default: false - required: true - type: boolean - architecture: - description: 'Architecture' - required: true - default: 'X64' - type: string - operating_system: - description: 'OS' - required: true - default: 'windows-2022' - type: string - -env: - CONAN_LOGIN_USERNAME_CURA: ${{ secrets.CONAN_USER }} - CONAN_PASSWORD_CURA: ${{ secrets.CONAN_PASS }} - WIN_CERT_INSTALLER_CER: ${{ secrets.WIN_CERT_INSTALLER_CER }} - WIN_CERT_INSTALLER_CER_PASS: ${{ secrets.WIN_CERT_INSTALLER_CER_PASS }} - CURA_CONAN_VERSION: ${{ inputs.cura_conan_version }} - ENTERPRISE: ${{ inputs.enterprise }} - STAGING: ${{ inputs.staging }} - -jobs: - cura-installer-create: - runs-on: ${{ inputs.operating_system }} - - outputs: - INSTALLER_FILENAME: ${{ steps.filename.outputs.INSTALLER_FILENAME }} - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup Python and pip - uses: actions/setup-python@v4 - with: - python-version: '3.10.x' - cache: 'pip' - cache-dependency-path: .github/workflows/requirements-conan-package.txt - - - name: Install Python requirements for runner - run: pip install -r .github/workflows/requirements-conan-package.txt - - - name: Cache Conan local repository packages (Powershell) - uses: actions/cache@v3 - with: - path: | - C:\Users\runneradmin\.conan\data - C:\.conan - C:\Users\runneradmin\.conan\conan_download_cache - key: conan-${{ runner.os }}-${{ runner.arch }}-installer-cache - - - name: Create the default Conan profile - run: conan profile new default --detect --force - - - name: Get Conan configuration - run: | - conan config install https://github.com/Ultimaker/conan-config.git - conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}" - - - name: Use Conan download cache (Powershell) - run: conan config set storage.download_cache="C:\Users\runneradmin\.conan\conan_download_cache" - - - name: Create the Packages (Powershell) - run: conan install $Env:CURA_CONAN_VERSION ${{ inputs.conan_args }} --build=missing --update -if cura_inst -g VirtualPythonEnv -o cura:enterprise=$Env:ENTERPRISE -o cura:staging=$Env:STAGING -c tools.build:skip_test=True - - - name: Remove internal packages before uploading - run: | - conan remove "*@internal/*" -f || true - conan remove "cura_private_data*" -f || true - - - name: Upload the Package(s) - if: always() - run: | - conan upload "*" -r cura --all -c - - - name: Set Environment variables for Cura (Powershell) - run: | - echo "${Env:WIX}\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - .\cura_inst\Scripts\activate_github_actions_env.ps1 - .\cura_inst\Scripts\activate_github_actions_version_env.ps1 - - - name: Create the Cura dist - run: pyinstaller ./cura_inst/UltiMaker-Cura.spec - - - name: Output the name file name and extension - id: filename - shell: python - run: | - import os - enterprise = "-Enterprise" if "${{ inputs.enterprise }}" == "true" else "" - installer_filename = f"UltiMaker-Cura-{os.getenv('CURA_VERSION_FULL')}{enterprise}-win64-${{ inputs.architecture }}" - output_env = os.environ["GITHUB_OUTPUT"] - content = "" - if os.path.exists(output_env): - with open(output_env, "r") as f: - content = f.read() - with open(output_env, "w") as f: - f.write(content) - f.writelines(f"INSTALLER_FILENAME={installer_filename}\n") - - - name: Summarize the used dependencies - shell: python - run: | - import os - - from cura.CuraVersion import ConanInstalls, PythonInstalls - - summary_env = os.environ["GITHUB_STEP_SUMMARY"] - content = "" - if os.path.exists(summary_env): - with open(summary_env, "r") as f: - content = f.read() - - with open(summary_env, "w") as f: - f.write(content) - f.writelines("# ${{ steps.filename.outputs.INSTALLER_FILENAME }}\n") - f.writelines("## Conan packages:\n") - for dep_name, dep_info in ConanInstalls.items(): - f.writelines(f"`{dep_name} {dep_info['version']} {dep_info['revision']}`\n") - - f.writelines("## Python modules:\n") - for dep_name, dep_info in PythonInstalls.items(): - f.writelines(f"`{dep_name} {dep_info['version']}`\n") - - - name: Create PFX certificate from BASE64_PFX_CONTENT secret - id: create-pfx - env: - PFX_CONTENT: ${{ secrets.WIN_CERT_INSTALLER_CER }} - run: | - $pfxPath = Join-Path -Path $env:RUNNER_TEMP -ChildPath "cert.pfx"; - $encodedBytes = [System.Convert]::FromBase64String($env:PFX_CONTENT); - Set-Content $pfxPath -Value $encodedBytes -AsByteStream; - echo "PFX_PATH=$pfxPath" >> $env:GITHUB_OUTPUT; - - - name: Create the Windows msi installer (Powershell) - run: | - python ..\cura_inst\packaging\msi\create_windows_msi.py ..\cura_inst .\UltiMaker-Cura "${{steps.filename.outputs.INSTALLER_FILENAME }}.msi" "$Env:CURA_APP_NAME" - working-directory: dist - - - name: Sign the Windows msi installer (Powershell) - env: - PFX_PATH: ${{ steps.create-pfx.outputs.PFX_PATH }} - run: | - & "C:/Program Files (x86)/Windows Kits/10/bin/10.0.17763.0/x86/signtool.exe" sign /f $Env:PFX_PATH /p "$Env:WIN_CERT_INSTALLER_CER_PASS" /fd SHA256 /t http://timestamp.digicert.com "${{steps.filename.outputs.INSTALLER_FILENAME }}.msi" - working-directory: dist - - - name: Create the Windows exe installer (Powershell) - run: | - python ..\cura_inst\packaging\NSIS\create_windows_installer.py ../cura_inst . "${{steps.filename.outputs.INSTALLER_FILENAME }}.exe" - working-directory: dist - - - name: Sign the Windows exe installer (Powershell) - env: - PFX_PATH: ${{ steps.create-pfx.outputs.PFX_PATH }} - run: | - & "C:/Program Files (x86)/Windows Kits/10/bin/10.0.17763.0/x86/signtool.exe" sign /f $Env:PFX_PATH /p "$Env:WIN_CERT_INSTALLER_CER_PASS" /fd SHA256 /t http://timestamp.digicert.com "${{steps.filename.outputs.INSTALLER_FILENAME }}.exe" - working-directory: dist - - - name: Upload the msi - uses: actions/upload-artifact@v3 - with: - name: ${{steps.filename.outputs.INSTALLER_FILENAME }}-msi - path: | - dist/${{steps.filename.outputs.INSTALLER_FILENAME }}.msi - retention-days: 5 - - - name: Upload the exe - uses: actions/upload-artifact@v3 - with: - name: ${{steps.filename.outputs.INSTALLER_FILENAME }}-exe - path: | - dist/${{steps.filename.outputs.INSTALLER_FILENAME }}.exe - retention-days: 5 - - # NOTE: The extension is .sh, since this isn't going to build-environment, so not on the Win build image. - - name: Write the run info - shell: python - run: | - import os - with open("run_info.sh", "w") as f: - f.writelines(f'echo "CURA_VERSION_FULL={os.environ["CURA_VERSION_FULL"]}" >> $GITHUB_ENV\n') - - # NOTE: The extension is .sh, since this isn't going to build-environment, so not on the Win build image. - - name: Upload the run info - uses: actions/upload-artifact@v3 - with: - name: windows-run-info - path: | - run_info.sh - retention-days: 5 - - notify-export: - if: ${{ always() }} - needs: [ cura-installer-create ] - - uses: ultimaker/cura/.github/workflows/notify.yml@main - with: - success: ${{ contains(join(needs.*.result, ','), 'success') }} - success_title: "Create the Cura distributions" - success_body: "Installers for ${{ inputs.cura_conan_version }}" - failure_title: "Failed to create the Cura distributions" - failure_body: "Failed to create at least 1 installer for ${{ inputs.cura_conan_version }}" - secrets: inherit From 89be765841bf453d6ee02ef8490a29dd02995072 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Mon, 4 Dec 2023 13:48:05 +0100 Subject: [PATCH 048/133] Revert "unpin dulcificum" This reverts commit ba9e122f6add419824e6fc03d55df40766d4e71d. --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 03648f66d8..53d1c9799d 100644 --- a/conanfile.py +++ b/conanfile.py @@ -324,7 +324,7 @@ class CuraConan(ConanFile): self.requires("curaengine_grpc_definitions/0.1.0") self.requires("zlib/1.2.13") self.requires("pyarcus/5.3.0") - self.requires("dulcificum/(latest)@ultimaker/testing") + self.requires("dulcificum/0.1.0-beta.1") self.requires("curaengine/(latest)@ultimaker/testing") self.requires("pysavitar/5.3.0") self.requires("pynest2d/5.3.0") From 58c174ff6884b2054f3f19faa1602dfd48c35694 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Mon, 4 Dec 2023 13:49:02 +0100 Subject: [PATCH 049/133] pin dulcificum to `0.1.0-beta.2` --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 53d1c9799d..4a5201edb7 100644 --- a/conanfile.py +++ b/conanfile.py @@ -324,7 +324,7 @@ class CuraConan(ConanFile): self.requires("curaengine_grpc_definitions/0.1.0") self.requires("zlib/1.2.13") self.requires("pyarcus/5.3.0") - self.requires("dulcificum/0.1.0-beta.1") + self.requires("dulcificum/0.1.0-beta.2") self.requires("curaengine/(latest)@ultimaker/testing") self.requires("pysavitar/5.3.0") self.requires("pynest2d/5.3.0") From 2d3ef87a472bf60252f3a214a0ed862badf99f31 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 4 Dec 2023 13:54:08 +0100 Subject: [PATCH 050/133] Use the latest `stable` dulcificum build Contribute to CURA-10831 --- conandata.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conandata.yml b/conandata.yml index d0856481f1..52f15cb3f3 100644 --- a/conandata.yml +++ b/conandata.yml @@ -5,7 +5,7 @@ requirements: - "cura_binary_data/(latest)@ultimaker/cura_10831" - "fdm_materials/(latest)@ultimaker/cura_10831" - "curaengine_plugin_gradual_flow/0.1.0" - - "dulcificum/latest@ultimaker/cura_10831" + - "dulcificum/latest@ultimaker/stable" - "pyarcus/5.3.0" - "pysavitar/5.3.0" - "pynest2d/5.3.0" From 7a4d26452adc81f74f7fc2d6c6700d4c69a1a466 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 4 Dec 2023 14:00:42 +0100 Subject: [PATCH 051/133] Fix testing against literal instead of value Contribute to CURA-10831 --- cura/PrinterOutput/Models/MaterialOutputModel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/PrinterOutput/Models/MaterialOutputModel.py b/cura/PrinterOutput/Models/MaterialOutputModel.py index 6920cead1b..dedcc2136b 100644 --- a/cura/PrinterOutput/Models/MaterialOutputModel.py +++ b/cura/PrinterOutput/Models/MaterialOutputModel.py @@ -43,7 +43,7 @@ class MaterialOutputModel(QObject): } - if guid is None and brand is not "empty" and type in _MATERIAL_MAP: + if guid is None and brand != "empty" and type in _MATERIAL_MAP: name = _MATERIAL_MAP[type]["name"] guid = _MATERIAL_MAP[type]["guid"] return name, guid From e904123b8095376d31138b0c095909773a4e7d43 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 4 Dec 2023 14:41:46 +0100 Subject: [PATCH 052/133] Use Uranium CURA-11137 Contribute to CURA-11137 --- .github/workflows/conan-recipe-export.yml | 110 ---------------------- conandata.yml | 2 +- 2 files changed, 1 insertion(+), 111 deletions(-) delete mode 100644 .github/workflows/conan-recipe-export.yml diff --git a/.github/workflows/conan-recipe-export.yml b/.github/workflows/conan-recipe-export.yml deleted file mode 100644 index 69c4e4d34a..0000000000 --- a/.github/workflows/conan-recipe-export.yml +++ /dev/null @@ -1,110 +0,0 @@ -name: Export Conan Recipe to server - -on: - workflow_call: - inputs: - recipe_id_full: - required: true - type: string - - recipe_id_latest: - required: false - type: string - - runs_on: - required: true - type: string - - python_version: - required: true - type: string - - conan_config_branch: - required: false - type: string - - conan_logging_level: - required: false - type: string - - conan_export_binaries: - required: false - type: boolean - - conan_upload_community: - required: false - default: true - type: boolean - -env: - CONAN_LOGIN_USERNAME: ${{ secrets.CONAN_USER }} - CONAN_PASSWORD: ${{ secrets.CONAN_PASS }} - CONAN_LOG_RUN_TO_OUTPUT: 1 - CONAN_LOGGING_LEVEL: ${{ inputs.conan_logging_level }} - CONAN_NON_INTERACTIVE: 1 - -jobs: - package-export: - runs-on: ${{ inputs.runs_on }} - - steps: - - name: Checkout project - uses: actions/checkout@v3 - - - name: Setup Python and pip - uses: actions/setup-python@v4 - with: - python-version: ${{ inputs.python_version }} - cache: 'pip' - cache-dependency-path: .github/workflows/requirements-conan-package.txt - - - name: Install Python requirements and Create default Conan profile - run: | - pip install -r https://raw.githubusercontent.com/Ultimaker/Cura/main/.github/workflows/requirements-conan-package.txt - conan profile new default --detect - # Note the runner requirements are always installed from the main branch in the Ultimaker/Cura repo - - - name: Cache Conan local repository packages - uses: actions/cache@v3 - with: - path: $HOME/.conan/data - key: ${{ runner.os }}-conan-export-cache - - - name: Get Conan configuration from branch - if: ${{ inputs.conan_config_branch != '' }} - run: conan config install https://github.com/Ultimaker/conan-config.git -a "-b ${{ inputs.conan_config_branch }}" - - - name: Get Conan configuration - run: | - conan config install https://github.com/Ultimaker/conan-config.git - conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}" - - - name: Add Cura private Artifactory remote - run: conan remote add cura-private-conan-dev https://cura.jfrog.io/artifactory/api/conan/cura-private-conan-dev True - - - name: Set GH service account for remote cura-conan-dev - run: conan user -p ${{ secrets.CONAN_GH_RUNNER_PASS }} -r cura-private-conan-dev "${{ secrets.CONAN_GH_RUNNER_USER }}" - - - name: Export the Package (binaries) - if: ${{ inputs.conan_export_binaries }} - run: conan create . ${{ inputs.recipe_id_full }} --build=missing --update -c tools.build:skip_test=True - - - name: Export the Package - if: ${{ !inputs.conan_export_binaries }} - run: conan export . ${{ inputs.recipe_id_full }} - - - name: Create the latest alias - if: always() - run: conan alias ${{ inputs.recipe_id_latest }} ${{ inputs.recipe_id_full }} - - - name: Upload the Package(s) - if: ${{ always() && inputs.conan_upload_community }} - run: | - conan upload ${{ inputs.recipe_id_full }} -r cura --all -c - conan upload ${{ inputs.recipe_id_latest }} -r cura -c - - - name: Upload the Package(s) to the private Artifactory - if: ${{ always() && ! inputs.conan_upload_community }} - run: | - conan upload ${{ inputs.recipe_id_full }} -r cura-private-conan-dev --all -c - conan upload ${{ inputs.recipe_id_latest }} -r cura-private-conan-dev -c diff --git a/conandata.yml b/conandata.yml index 52f15cb3f3..347602a02e 100644 --- a/conandata.yml +++ b/conandata.yml @@ -1,6 +1,6 @@ version: "5.7.0-alpha.0" requirements: - - "uranium/(latest)@ultimaker/cura_10831" + - "uranium/(latest)@ultimaker/cura_11137" - "curaengine/(latest)@ultimaker/cura_10831" - "cura_binary_data/(latest)@ultimaker/cura_10831" - "fdm_materials/(latest)@ultimaker/cura_10831" From 20ab319ec07c501a017b6cf6e6d73350d029f638 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 4 Dec 2023 16:31:50 +0100 Subject: [PATCH 053/133] Use default values from cura-workflows Contributes to CURA-10831 --- .github/workflows/installers.yml | 50 ++++---------------------------- 1 file changed, 6 insertions(+), 44 deletions(-) diff --git a/.github/workflows/installers.yml b/.github/workflows/installers.yml index b3ea88969c..aa1f5a49f0 100644 --- a/.github/workflows/installers.yml +++ b/.github/workflows/installers.yml @@ -39,53 +39,15 @@ env: CONAN_ARGS: ${{ inputs.conan_args || '' }} ENTERPRISE: ${{ inputs.enterprise || false }} STAGING: ${{ inputs.staging || false }} - LATEST_RELEASE: '5.6' - LATEST_RELEASE_SCHEDULE_HOUR: 4 jobs: default_values: - runs-on: ubuntu-latest - outputs: - cura_conan_version: ${{ steps.default.outputs.cura_conan_version }} - release_tag: ${{ steps.default.outputs.release_tag }} - - steps: - - name: Output default values - id: default - shell: python - run: | - import os - import datetime - - if "${{ github.event_name }}" != "schedule": - cura_conan_version = "${{ github.event.inputs.cura_conan_version }}" - else: - now = datetime.datetime.now() - cura_conan_version = "cura/latest@ultimaker/stable" if now.hour == int(os.environ['LATEST_RELEASE_SCHEDULE_HOUR']) else "cura/latest@ultimaker/testing" - - release_tag = f"nightly-{os.environ['LATEST_RELEASE']}" if "/stable" in cura_conan_version else "nightly" - - # Set cura_conan_version environment variable - output_env = os.environ["GITHUB_OUTPUT"] - content = "" - if os.path.exists(output_env): - with open(output_env, "r") as f: - content = f.read() - with open(output_env, "w") as f: - f.write(content) - f.writelines(f"cura_conan_version={cura_conan_version}\n") - f.writelines(f"release_tag={release_tag}\n") - - summary_env = os.environ["GITHUB_STEP_SUMMARY"] - content = "" - if os.path.exists(summary_env): - with open(summary_env, "r") as f: - content = f.read() - - with open(summary_env, "w") as f: - f.write(content) - f.writelines(f"# cura_conan_version = {cura_conan_version}\n") - f.writelines(f"# release_tag = {release_tag}\n") + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-default-value.yml@CURA-10831 + with: + cura_conan_version: ${{ inputs.cura_conan_version }} + latest_release: '5.6' + latest_release_schedule_hour: 4 + latest_release_tag: 'nightly' # FIXME: point to `main` once merged windows-installer: From ce0cdd0b91f8df5a28e9bdf0bebd13c8f850bdb2 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Mon, 4 Dec 2023 17:07:43 +0100 Subject: [PATCH 054/133] =?UTF-8?q?Model=20translations=20while=20changing?= =?UTF-8?q?=20build=20plates=20while=20importing=20models,=20coordinate=20?= =?UTF-8?q?translations=20shouldn=E2=80=99t=20matter=20and=20the=20object?= =?UTF-8?q?=20should=20be=20organized=20on=20the=20plate=20where=20it=20fi?= =?UTF-8?q?nds=20space.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CURA-11166 --- cura/CuraApplication.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index c6c44cf8f5..7e2f0fb1ca 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -179,6 +179,7 @@ class CuraApplication(QtApplication): self._use_single_instance = False self._single_instance = None + self._project_mode = None self._cura_formula_functions = None # type: Optional[CuraFormulaFunctions] @@ -1845,7 +1846,7 @@ class CuraApplication(QtApplication): Logger.log("i", "Attempting to read file %s", file.toString()) if not file.isValid(): return - + self._project_mode = project_mode scene = self.getController().getScene() for node in DepthFirstIterator(scene.getRoot()): @@ -1855,16 +1856,16 @@ class CuraApplication(QtApplication): is_project_file = self.checkIsValidProjectFile(file) - if project_mode is None: - project_mode = self.getPreferences().getValue("cura/choice_on_open_project") + if self._project_mode is None: + self._project_mode = self.getPreferences().getValue("cura/choice_on_open_project") - if is_project_file and project_mode == "open_as_project": + if is_project_file and self._project_mode == "open_as_project": # open as project immediately without presenting a dialog workspace_handler = self.getWorkspaceFileHandler() workspace_handler.readLocalFile(file, add_to_recent_files_hint = add_to_recent_files) return - if is_project_file and project_mode == "always_ask": + if is_project_file and self._project_mode == "always_ask": # present a dialog asking to open as project or import models self.callLater(self.openProjectFile.emit, file, add_to_recent_files) return @@ -1999,8 +2000,11 @@ class CuraApplication(QtApplication): center_y = 0 node.translate(Vector(0, center_y, 0)) - nodes_to_arrange.append(node) + # If file extention is 3mf and models are to be loaded from a cura project, + # models are to be arranged in buildplate. + elif self._project_mode == "open_as_model": + nodes_to_arrange.append(node) # This node is deep copied from some other node which already has a BuildPlateDecorator, but the deepcopy # of BuildPlateDecorator produces one that's associated with build plate -1. So, here we need to check if From 040f85c9560951f35994109d62b89c597604bc23 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 4 Dec 2023 17:36:32 +0100 Subject: [PATCH 055/133] Remove redundant export workflow Contributes to CURA-10831 --- .github/workflows/conan-recipe-export.yml | 110 ---------------------- 1 file changed, 110 deletions(-) delete mode 100644 .github/workflows/conan-recipe-export.yml diff --git a/.github/workflows/conan-recipe-export.yml b/.github/workflows/conan-recipe-export.yml deleted file mode 100644 index 69c4e4d34a..0000000000 --- a/.github/workflows/conan-recipe-export.yml +++ /dev/null @@ -1,110 +0,0 @@ -name: Export Conan Recipe to server - -on: - workflow_call: - inputs: - recipe_id_full: - required: true - type: string - - recipe_id_latest: - required: false - type: string - - runs_on: - required: true - type: string - - python_version: - required: true - type: string - - conan_config_branch: - required: false - type: string - - conan_logging_level: - required: false - type: string - - conan_export_binaries: - required: false - type: boolean - - conan_upload_community: - required: false - default: true - type: boolean - -env: - CONAN_LOGIN_USERNAME: ${{ secrets.CONAN_USER }} - CONAN_PASSWORD: ${{ secrets.CONAN_PASS }} - CONAN_LOG_RUN_TO_OUTPUT: 1 - CONAN_LOGGING_LEVEL: ${{ inputs.conan_logging_level }} - CONAN_NON_INTERACTIVE: 1 - -jobs: - package-export: - runs-on: ${{ inputs.runs_on }} - - steps: - - name: Checkout project - uses: actions/checkout@v3 - - - name: Setup Python and pip - uses: actions/setup-python@v4 - with: - python-version: ${{ inputs.python_version }} - cache: 'pip' - cache-dependency-path: .github/workflows/requirements-conan-package.txt - - - name: Install Python requirements and Create default Conan profile - run: | - pip install -r https://raw.githubusercontent.com/Ultimaker/Cura/main/.github/workflows/requirements-conan-package.txt - conan profile new default --detect - # Note the runner requirements are always installed from the main branch in the Ultimaker/Cura repo - - - name: Cache Conan local repository packages - uses: actions/cache@v3 - with: - path: $HOME/.conan/data - key: ${{ runner.os }}-conan-export-cache - - - name: Get Conan configuration from branch - if: ${{ inputs.conan_config_branch != '' }} - run: conan config install https://github.com/Ultimaker/conan-config.git -a "-b ${{ inputs.conan_config_branch }}" - - - name: Get Conan configuration - run: | - conan config install https://github.com/Ultimaker/conan-config.git - conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}" - - - name: Add Cura private Artifactory remote - run: conan remote add cura-private-conan-dev https://cura.jfrog.io/artifactory/api/conan/cura-private-conan-dev True - - - name: Set GH service account for remote cura-conan-dev - run: conan user -p ${{ secrets.CONAN_GH_RUNNER_PASS }} -r cura-private-conan-dev "${{ secrets.CONAN_GH_RUNNER_USER }}" - - - name: Export the Package (binaries) - if: ${{ inputs.conan_export_binaries }} - run: conan create . ${{ inputs.recipe_id_full }} --build=missing --update -c tools.build:skip_test=True - - - name: Export the Package - if: ${{ !inputs.conan_export_binaries }} - run: conan export . ${{ inputs.recipe_id_full }} - - - name: Create the latest alias - if: always() - run: conan alias ${{ inputs.recipe_id_latest }} ${{ inputs.recipe_id_full }} - - - name: Upload the Package(s) - if: ${{ always() && inputs.conan_upload_community }} - run: | - conan upload ${{ inputs.recipe_id_full }} -r cura --all -c - conan upload ${{ inputs.recipe_id_latest }} -r cura -c - - - name: Upload the Package(s) to the private Artifactory - if: ${{ always() && ! inputs.conan_upload_community }} - run: | - conan upload ${{ inputs.recipe_id_full }} -r cura-private-conan-dev --all -c - conan upload ${{ inputs.recipe_id_latest }} -r cura-private-conan-dev -c From 9ad993f8ca0a67ae17f59f2d8ea33eccd4eea9c5 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 4 Dec 2023 18:06:20 +0100 Subject: [PATCH 056/133] Reinstate OS specific installer workflows For those that wants to build a OS specific installer Contributes to CURA-10831 --- .github/workflows/linux.yml | 58 +++++++++++++++++++++ .github/workflows/macos.yml | 62 +++++++++++++++++++++++ .github/workflows/requirements-runner.txt | 0 .github/workflows/windows.yml | 58 +++++++++++++++++++++ 4 files changed, 178 insertions(+) create mode 100644 .github/workflows/linux.yml create mode 100644 .github/workflows/macos.yml create mode 100644 .github/workflows/requirements-runner.txt create mode 100644 .github/workflows/windows.yml diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml new file mode 100644 index 0000000000..5e63b13c14 --- /dev/null +++ b/.github/workflows/linux.yml @@ -0,0 +1,58 @@ +name: Linux installers +run-name: ${{ inputs.cura_conan_version }} by @${{ github.actor }} + +on: + workflow_dispatch: + inputs: + cura_conan_version: + description: 'Cura Conan Version' + default: 'cura/latest@ultimaker/testing' + required: true + type: string + conan_args: + description: 'Conan args: eq.: --require-override' + default: '' + required: false + type: string + enterprise: + description: 'Build Cura as an Enterprise edition' + default: false + required: true + type: boolean + staging: + description: 'Use staging API' + default: false + required: true + type: boolean + architecture: + description: 'Architecture' + required: true + default: 'X64' + type: choice + options: + - X64 + operating_system: + description: 'OS' + required: true + default: 'ubuntu-22.04' + type: choice + options: + - ubuntu-22.04 + +env: + CONAN_ARGS: ${{ inputs.conan_args || '' }} + ENTERPRISE: ${{ inputs.enterprise || false }} + STAGING: ${{ inputs.staging || false }} + +jobs: + # FIXME: point to `main` once merged + windows-installer: + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-linux.yml@CURA-10831 + with: + cura_conan_version: ${{ inputs.cura_conan_version }} + conan_args: ${{ inputs.conan_args }} + enterprise: ${{ inputs.enterprise == 'true' }} + staging: ${{ inputs.staging == 'true' }} + architecture: ${{ inputs.architecture }} + operating_system: ${{ inputs.operating_system }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml new file mode 100644 index 0000000000..42b719f1ca --- /dev/null +++ b/.github/workflows/macos.yml @@ -0,0 +1,62 @@ +name: MacOS installers +run-name: ${{ inputs.cura_conan_version }} by @${{ github.actor }} + +on: + workflow_dispatch: + inputs: + cura_conan_version: + description: 'Cura Conan Version' + default: 'cura/latest@ultimaker/testing' + required: true + type: string + conan_args: + description: 'Conan args: eq.: --require-override' + default: '' + required: false + type: string + enterprise: + description: 'Build Cura as an Enterprise edition' + default: false + required: true + type: boolean + staging: + description: 'Use staging API' + default: false + required: true + type: boolean + architecture: + description: 'Architecture' + required: true + default: 'ARM64' + type: choice + options: + - X64 + - ARM64 + operating_system: + description: 'OS' + required: true + default: 'self-hosted-ARM64' + type: choice + options: + - self-hosted-X64 + - self-hosted-ARM64 + - macos-11 + - macos-12 + +env: + CONAN_ARGS: ${{ inputs.conan_args || '' }} + ENTERPRISE: ${{ inputs.enterprise || false }} + STAGING: ${{ inputs.staging || false }} + +jobs: + # FIXME: point to `main` once merged + windows-installer: + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-macos.yml@CURA-10831 + with: + cura_conan_version: ${{ inputs.cura_conan_version }} + conan_args: ${{ inputs.conan_args }} + enterprise: ${{ inputs.enterprise == 'true' }} + staging: ${{ inputs.staging == 'true' }} + architecture: ${{ inputs.architecture }} + operating_system: ${{ inputs.operating_system }} + secrets: inherit \ No newline at end of file diff --git a/.github/workflows/requirements-runner.txt b/.github/workflows/requirements-runner.txt new file mode 100644 index 0000000000..e69de29bb2 diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml new file mode 100644 index 0000000000..c60aeee51e --- /dev/null +++ b/.github/workflows/windows.yml @@ -0,0 +1,58 @@ +name: Windows installers +run-name: ${{ inputs.cura_conan_version }} by @${{ github.actor }} + +on: + workflow_dispatch: + inputs: + cura_conan_version: + description: 'Cura Conan Version' + default: 'cura/latest@ultimaker/testing' + required: true + type: string + conan_args: + description: 'Conan args: eq.: --require-override' + default: '' + required: false + type: string + enterprise: + description: 'Build Cura as an Enterprise edition' + default: false + required: true + type: boolean + staging: + description: 'Use staging API' + default: false + required: true + type: boolean + architecture: + description: 'Architecture' + required: true + default: 'X64' + type: choice + options: + - X64 + operating_system: + description: 'OS' + required: true + default: 'windows-2022' + type: choice + options: + - windows-2022 + +env: + CONAN_ARGS: ${{ inputs.conan_args || '' }} + ENTERPRISE: ${{ inputs.enterprise || false }} + STAGING: ${{ inputs.staging || false }} + +jobs: + # FIXME: point to `main` once merged + windows-installer: + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-windows.yml@CURA-10831 + with: + cura_conan_version: ${{ inputs.cura_conan_version }} + conan_args: ${{ inputs.conan_args }} + enterprise: ${{ inputs.enterprise == 'true' }} + staging: ${{ inputs.staging == 'true' }} + architecture: ${{ inputs.architecture }} + operating_system: ${{ inputs.operating_system }} + secrets: inherit \ No newline at end of file From b678951759ff3c804e5b0bbef6450d1c52574ce3 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 4 Dec 2023 18:15:50 +0100 Subject: [PATCH 057/133] Applied work-around for GH true/false instead of True/False Contributes to CURA-10831 --- conanfile.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/conanfile.py b/conanfile.py index de66f1d409..92d0e326d9 100644 --- a/conanfile.py +++ b/conanfile.py @@ -34,7 +34,7 @@ class CuraConan(ConanFile): "cloud_api_version": "ANY", "display_name": "ANY", # TODO: should this be an option?? "cura_debug_mode": [True, False], # FIXME: Use profiles - "internal": [True, False], + "internal": ["True", "False", "true", "false"], # Workaround for GH Action passing boolean as lowercase string "enable_i18n": [True, False], } default_options = { @@ -44,7 +44,7 @@ class CuraConan(ConanFile): "cloud_api_version": "1", "display_name": "UltiMaker Cura", "cura_debug_mode": False, # Not yet implemented - "internal": False, + "internal": "False", "enable_i18n": False, } @@ -84,6 +84,10 @@ class CuraConan(ConanFile): def _enterprise(self): return self.options.enterprise in ["True", 'true'] + @property + def _internal(self): + return self.options.enterprise in ["True", 'true'] + @property def _app_name(self): if self._enterprise: @@ -182,7 +186,7 @@ class CuraConan(ConanFile): cura_version = Version(self.conf.get("user.cura:version", default = self.version, check_type = str)) pre_tag = f"-{cura_version.pre}" if cura_version.pre else "" build_tag = f"+{cura_version.build}" if cura_version.build else "" - internal_tag = f"+internal" if self.options.internal else "" + internal_tag = f"+internal" if self._internal else "" cura_version = f"{cura_version.major}.{cura_version.minor}.{cura_version.patch}{pre_tag}{build_tag}{internal_tag}" with open(os.path.join(location, "CuraVersion.py"), "w") as f: @@ -206,7 +210,7 @@ class CuraConan(ConanFile): pyinstaller_metadata = self.conan_data["pyinstaller"] datas = [] for data in pyinstaller_metadata["datas"].values(): - if not self.options.internal and data.get("internal", False): + if not self._internal and data.get("internal", False): continue if "package" in data: # get the paths from conan package @@ -319,10 +323,10 @@ class CuraConan(ConanFile): def requirements(self): for req in self.conan_data["requirements"]: - if self.options.internal and "fdm_materials" in req: + if self._internal and "fdm_materials" in req: continue self.requires(req) - if self.options.internal: + if self._internal: for req in self.conan_data["requirements_internal"]: if "fdm_materials" in req: continue @@ -392,7 +396,7 @@ class CuraConan(ConanFile): copy(self, "*", fdm_materials.resdirs[0], self.source_folder) # Copy internal resources - if self.options.internal: + if self._internal: cura_private_data = self.dependencies["cura_private_data"].cpp_info copy(self, "*", cura_private_data.resdirs[0], str(self._share_dir.joinpath("cura"))) From 260a73e14ceea38f4dd15fe4741240a4e25183fd Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 4 Dec 2023 19:51:11 +0100 Subject: [PATCH 058/133] Use older name for OS specific installer workflows Contributes to CURA-10831 --- .github/workflows/linux.yml | 2 +- .github/workflows/macos.yml | 2 +- .github/workflows/windows.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 5e63b13c14..535d087700 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -1,4 +1,4 @@ -name: Linux installers +name: Linux Installer run-name: ${{ inputs.cura_conan_version }} by @${{ github.actor }} on: diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 42b719f1ca..02f45385e7 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -1,4 +1,4 @@ -name: MacOS installers +name: MacOS Installer run-name: ${{ inputs.cura_conan_version }} by @${{ github.actor }} on: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index c60aeee51e..ef7e986ec3 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -1,4 +1,4 @@ -name: Windows installers +name: Windows Installer run-name: ${{ inputs.cura_conan_version }} by @${{ github.actor }} on: From ad96082a1611bae8528ff4bceee41640d5236888 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 5 Dec 2023 05:03:59 +0100 Subject: [PATCH 059/133] Port unit-test to cura-workflows Contributes to CURA-10831 --- .github/workflows/unit-test.yml | 139 ++++---------------------------- 1 file changed, 16 insertions(+), 123 deletions(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 2f8f593199..ca585d54b6 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -1,4 +1,3 @@ ---- name: unit-test on: @@ -9,23 +8,18 @@ on: - 'cura/**' - 'icons/**' - 'tests/**' - - 'packaging/**' - - '.github/workflows/conan-*.yml' - '.github/workflows/unit-test.yml' - - '.github/workflows/notify.yml' - - '.github/workflows/requirements-conan-package.txt' + - '.github/workflows/requirements-runner.txt' - 'requirements*.txt' - 'conanfile.py' - 'conandata.yml' - - 'GitVersion.yml' - '*.jinja' branches: - main - 'CURA-*' - - '[1-9]+.[0-9]+' - tags: - - '[0-9]+.[0-9]+.[0-9]+' - - '[0-9]+.[0-9]+-beta' + - 'PP-*' + - '[0-9]+.[0-9]+' + pull_request: paths: - 'plugins/**' @@ -33,35 +27,23 @@ on: - 'cura/**' - 'icons/**' - 'tests/**' - - 'packaging/**' - - '.github/workflows/conan-*.yml' - '.github/workflows/unit-test.yml' - - '.github/workflows/notify.yml' - - '.github/workflows/requirements-conan-package.txt' + - '.github/workflows/requirements-runner.txt' - 'requirements*.txt' - 'conanfile.py' - 'conandata.yml' - - 'GitVersion.yml' - '*.jinja' branches: - main - - '[1-9]+.[0-9]+' - tags: - - '[0-9]+.[0-9]+.[0-9]+' - - '[0-9]+.[0-9]+-beta' - -env: - CONAN_LOGIN_USERNAME_CURA: ${{ secrets.CONAN_USER }} - CONAN_PASSWORD_CURA: ${{ secrets.CONAN_PASS }} - CONAN_LOGIN_USERNAME_CURA_CE: ${{ secrets.CONAN_USER }} - CONAN_PASSWORD_CURA_CE: ${{ secrets.CONAN_PASS }} - CONAN_LOG_RUN_TO_OUTPUT: 1 - CONAN_LOGGING_LEVEL: info - CONAN_NON_INTERACTIVE: 1 + - '[0-9]+.[0-9]+' permissions: contents: read +env: + CONAN_LOGIN_USERNAME: ${{ secrets.CONAN_USER }} + CONAN_PASSWORD: ${{ secrets.CONAN_PASS }} + jobs: conan-recipe-version: uses: ultimaker/cura-workflows/.github/workflows/conan-recipe-version.yml@CURA-10831 @@ -69,98 +51,9 @@ jobs: project_name: cura testing: - runs-on: ubuntu-22.04 - needs: [ conan-recipe-version ] - - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - fetch-depth: 2 - - - name: Setup Python and pip - uses: actions/setup-python@v4 - with: - python-version: '3.11.x' - architecture: 'x64' - cache: 'pip' - cache-dependency-path: .github/workflows/requirements-conan-package.txt - - - name: Install Python requirements and Create default Conan profile - run: pip install -r requirements-conan-package.txt - working-directory: .github/workflows/ - - - name: Use Conan download cache (Bash) - if: ${{ runner.os != 'Windows' }} - run: conan config set storage.download_cache="$HOME/.conan/conan_download_cache" - - - name: Cache Conan local repository packages (Bash) - uses: actions/cache@v3 - if: ${{ runner.os != 'Windows' }} - with: - path: | - $HOME/.conan/data - $HOME/.conan/conan_download_cache - key: conan-${{ runner.os }}-${{ runner.arch }}-unit-cache - - # NOTE: Due to what are probably github issues, we have to remove the cache and reconfigure before the rest. - # This is maybe because grub caches the disk it uses last time, which is recreated each time. - - name: Install Linux system requirements - if: ${{ runner.os == 'Linux' }} - run: | - sudo rm /var/cache/debconf/config.dat - sudo dpkg --configure -a - sudo add-apt-repository ppa:ubuntu-toolchain-r/test -y - sudo apt update - sudo apt upgrade - sudo apt install build-essential checkinstall libegl-dev zlib1g-dev libssl-dev ninja-build autoconf libx11-dev libx11-xcb-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev libxcomposite-dev libxcursor-dev libxdamage-dev libxdmcp-dev libxext-dev libxfixes-dev libxi-dev libxinerama-dev libxkbfile-dev libxmu-dev libxmuu-dev libxpm-dev libxrandr-dev libxrender-dev libxres-dev libxss-dev libxt-dev libxtst-dev libxv-dev libxvmc-dev libxxf86vm-dev xtrans-dev libxcb-render0-dev libxcb-render-util0-dev libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev xkb-data libxcb-dri3-dev uuid-dev libxcb-util-dev libxkbcommon-x11-dev pkg-config -y - - - name: Install GCC-13 - run: | - sudo apt install g++-13 gcc-13 -y - sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 13 - sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 13 - - - name: Get Conan configuration - run: | - conan config install https://github.com/Ultimaker/conan-config.git - conan config install https://github.com/Ultimaker/conan-config.git -a "-b runner/${{ runner.os }}/${{ runner.arch }}" - - - name: Get Conan profile - run: conan profile new default --detect --force - - - name: Install dependencies - run: conan install . ${{ needs.conan-recipe-version.outputs.recipe_id_full }} --build=missing --update -o cura:devtools=True -g VirtualPythonEnv -if venv - - - name: Upload the Dependency package(s) - run: conan upload "*" -r cura --all -c - - - name: Set Environment variables for Cura (bash) - if: ${{ runner.os != 'Windows' }} - run: | - . ./venv/bin/activate_github_actions_env.sh - - - name: Run Unit Test - id: run-test - run: | - pytest --junitxml=junit_cura.xml - working-directory: tests - - - name: Save PR metadata - if: always() - run: | - echo ${{ github.event.number }} > pr-id.txt - echo ${{ github.event.pull_request.head.repo.full_name }} > pr-head-repo.txt - echo ${{ github.event.pull_request.head.ref }} > pr-head-ref.txt - working-directory: tests - - - name: Upload Test Results - if: always() - uses: actions/upload-artifact@v3 - with: - name: test-result - path: | - tests/**/*.xml - tests/pr-id.txt - tests/pr-head-repo.txt - tests/pr-head-ref.txt + uses: ultimaker/cura-workflows/.github/workflows/unit-test.yml@CURA-10831 + with: + recipe_id_full: ${{ needs.conan-recipe-version.outputs.recipe_id_full }} + conan_extra_args: '-o cura:devtools=True -c tools.build:skip_test=False' + unit_test_cmd: 'pytest --junitxml=junit_cura.xml' + unit_test_dir: 'tests' \ No newline at end of file From a69e4f1678c8832831b4adc8fb986c7f0ccf1f1c Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 5 Dec 2023 05:05:12 +0100 Subject: [PATCH 060/133] set needs for testing job Contributes to CURA-10831 --- .github/workflows/unit-test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index ca585d54b6..3083c8f11b 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -52,6 +52,7 @@ jobs: testing: uses: ultimaker/cura-workflows/.github/workflows/unit-test.yml@CURA-10831 + needs: [ conan-recipe-version ] with: recipe_id_full: ${{ needs.conan-recipe-version.outputs.recipe_id_full }} conan_extra_args: '-o cura:devtools=True -c tools.build:skip_test=False' From 6140d5ad145fb29a39f1ed0f7bb3f5e6468d1256 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 5 Dec 2023 05:06:40 +0100 Subject: [PATCH 061/133] only run on main/release and PR's Contributes to CURA-10831 --- .github/workflows/unit-test.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 3083c8f11b..d7e8543abe 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -16,8 +16,6 @@ on: - '*.jinja' branches: - main - - 'CURA-*' - - 'PP-*' - '[0-9]+.[0-9]+' pull_request: From a2eb1dc085aa4f92e8487bc2cf9da3e2bfd0f55c Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 5 Dec 2023 05:30:57 +0100 Subject: [PATCH 062/133] Activate all activate_github_action envs Contributes to CURA-10831 --- .github/workflows/unit-test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index d7e8543abe..484490f5ed 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -55,4 +55,5 @@ jobs: recipe_id_full: ${{ needs.conan-recipe-version.outputs.recipe_id_full }} conan_extra_args: '-o cura:devtools=True -c tools.build:skip_test=False' unit_test_cmd: 'pytest --junitxml=junit_cura.xml' - unit_test_dir: 'tests' \ No newline at end of file + unit_test_dir: 'tests' + conan_generator_dir: './venv/bin' \ No newline at end of file From 3dcf208d73f257b2875bc519ebb8d6dcdd715599 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 5 Dec 2023 05:31:51 +0100 Subject: [PATCH 063/133] Revert "only run on main/release and PR's" This reverts commit 6140d5ad145fb29a39f1ed0f7bb3f5e6468d1256. --- .github/workflows/unit-test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 484490f5ed..2312340a11 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -16,6 +16,8 @@ on: - '*.jinja' branches: - main + - 'CURA-*' + - 'PP-*' - '[0-9]+.[0-9]+' pull_request: From e688a3a9df0f5b48a1373042bcd82c502e7a8869 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 5 Dec 2023 05:51:48 +0100 Subject: [PATCH 064/133] use relative location of pytest Somehow pytest can't be found on the PATH Contributes to CURA-10831 --- .github/workflows/unit-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 2312340a11..d8716c9dac 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -56,6 +56,6 @@ jobs: with: recipe_id_full: ${{ needs.conan-recipe-version.outputs.recipe_id_full }} conan_extra_args: '-o cura:devtools=True -c tools.build:skip_test=False' - unit_test_cmd: 'pytest --junitxml=junit_cura.xml' + unit_test_cmd: '../venv/bin/pytest --junitxml=junit_cura.xml' unit_test_dir: 'tests' conan_generator_dir: './venv/bin' \ No newline at end of file From 86493b9c4d19a157907cb4bd08c63f039c184875 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 5 Dec 2023 06:05:21 +0100 Subject: [PATCH 065/133] Use VirtualPythonEnv generator Contributes to CURA-10831 --- .github/workflows/unit-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index d8716c9dac..714cf9d6af 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -55,7 +55,7 @@ jobs: needs: [ conan-recipe-version ] with: recipe_id_full: ${{ needs.conan-recipe-version.outputs.recipe_id_full }} - conan_extra_args: '-o cura:devtools=True -c tools.build:skip_test=False' - unit_test_cmd: '../venv/bin/pytest --junitxml=junit_cura.xml' + conan_extra_args: '-g VirtualPythonEnv -o cura:devtools=True -c tools.build:skip_test=False' + unit_test_cmd: 'pytest --junitxml=junit_cura.xml' unit_test_dir: 'tests' conan_generator_dir: './venv/bin' \ No newline at end of file From f5354c058f90ff7079876dd2693680c727ced7c9 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 5 Dec 2023 07:08:36 +0100 Subject: [PATCH 066/133] Add FIXME reminders Contributes to CURA-10831 --- .github/workflows/unit-test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 714cf9d6af..6369e7e395 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -45,12 +45,14 @@ env: CONAN_PASSWORD: ${{ secrets.CONAN_PASS }} jobs: + # FIXME: Change to `main` instead of `CURA-10831` once merged conan-recipe-version: uses: ultimaker/cura-workflows/.github/workflows/conan-recipe-version.yml@CURA-10831 with: project_name: cura testing: + # FIXME: Change to `main` instead of `CURA-10831` once merged uses: ultimaker/cura-workflows/.github/workflows/unit-test.yml@CURA-10831 needs: [ conan-recipe-version ] with: From 1334b65bdfca7bb23e7c95c446f9ad3746fb0e7c Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 5 Dec 2023 07:17:21 +0100 Subject: [PATCH 067/133] Post the unit test result on PR's Contributes to CURA-10831 --- .github/workflows/unit-test-post.yml | 85 +++------------------------- 1 file changed, 8 insertions(+), 77 deletions(-) diff --git a/.github/workflows/unit-test-post.yml b/.github/workflows/unit-test-post.yml index 36c1d5acfd..119ca30f33 100644 --- a/.github/workflows/unit-test-post.yml +++ b/.github/workflows/unit-test-post.yml @@ -1,82 +1,13 @@ name: unit-test-post on: - workflow_run: - workflows: [ "unit-test" ] - types: [ completed ] + workflow_run: + workflows: [ "unit-test" ] + types: [ completed ] jobs: - publish-test-results: - if: ${{ github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' }} - runs-on: ubuntu-latest - - steps: - - name: Download analysis results - uses: actions/github-script@v3.1.0 - with: - script: | - let artifacts = await github.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: ${{github.event.workflow_run.id }}, - }); - let matchArtifact = artifacts.data.artifacts.filter((artifact) => { - return artifact.name == "test-result" - })[0]; - let download = await github.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: matchArtifact.id, - archive_format: "zip", - }); - let fs = require("fs"); - fs.writeFileSync("${{github.workspace}}/test-result.zip", Buffer.from(download.data)); - - - name: Set environment variables - run: | - mkdir pr_env - unzip test-result.zip -d pr_env - echo "pr_id=$(cat pr_env/pr-id.txt)" >> $GITHUB_ENV - echo "pr_head_repo=$(cat pr_env/pr-head-repo.txt)" >> $GITHUB_ENV - echo "pr_head_ref=$(cat pr_env/pr-head-ref.txt)" >> $GITHUB_ENV - - - uses: actions/checkout@v3 - with: - repository: ${{ env.pr_head_repo }} - ref: ${{ env.pr_head_ref }} - persist-credentials: false - - - name: Redownload analysis results - uses: actions/github-script@v3.1.0 - with: - script: | - let artifacts = await github.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: ${{github.event.workflow_run.id }}, - }); - let matchArtifact = artifacts.data.artifacts.filter((artifact) => { - return artifact.name == "test-result" - })[0]; - let download = await github.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: matchArtifact.id, - archive_format: "zip", - }); - let fs = require("fs"); - fs.writeFileSync("${{github.workspace}}/test-result.zip", Buffer.from(download.data)); - - - name: Extract analysis results - run: | - mkdir -p tests - unzip test-result.zip -d tests - - - name: Publish Unit Test Results - id: test-results - uses: EnricoMi/publish-unit-test-result-action@v1 - with: - files: "tests/**/*.xml" - - - name: Conclusion - run: echo "Conclusion is ${{ steps.test-results.outputs.json && fromJSON( steps.test-results.outputs.json ).conclusion }}" + publish-test-results: + uses: ultimaker/cura-workflows/.github/workflows/unit-test-post.yml@CURA-10831 + with: + event: ${{ github.event.workflow_run.event }} + conclusion: ${{ github.event.workflow_run.conclusion }} From b8d41abdeea2d69187ed85eb455f0e384a167d04 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 5 Dec 2023 07:18:57 +0100 Subject: [PATCH 068/133] Add FIXME reminder Contributes to CURA-10831 --- .github/workflows/unit-test-post.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/unit-test-post.yml b/.github/workflows/unit-test-post.yml index 119ca30f33..b4ca2ee699 100644 --- a/.github/workflows/unit-test-post.yml +++ b/.github/workflows/unit-test-post.yml @@ -6,6 +6,7 @@ on: types: [ completed ] jobs: + # FIXME: Use `main` instead of `CURA-10831` once merged publish-test-results: uses: ultimaker/cura-workflows/.github/workflows/unit-test-post.yml@CURA-10831 with: From 8aa6d2c5b6a2fe645a400fd495394ce475ac7d3f Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 5 Dec 2023 07:44:04 +0100 Subject: [PATCH 069/133] Update conan_data with actual version Contributes to CURA-10831 --- conanfile.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index 92d0e326d9..f1d73352aa 100644 --- a/conanfile.py +++ b/conanfile.py @@ -4,7 +4,7 @@ from pathlib import Path from jinja2 import Template from conan import ConanFile -from conan.tools.files import copy, rmdir, save, mkdir, rm +from conan.tools.files import copy, rmdir, save, mkdir, rm, update_conandata from conan.tools.microsoft import unix_path from conan.tools.env import VirtualRunEnv, Environment, VirtualBuildEnv from conan.tools.scm import Version @@ -289,6 +289,9 @@ class CuraConan(ConanFile): short_version = f"'{cura_version.major}.{cura_version.minor}.{cura_version.patch}'", )) + def export(self): + update_conandata(self, {"version": self.version}) + def export_sources(self): copy(self, "*", os.path.join(self.recipe_folder, "plugins"), os.path.join(self.export_sources_folder, "plugins")) copy(self, "*", os.path.join(self.recipe_folder, "resources"), os.path.join(self.export_sources_folder, "resources"), excludes = "*.mo") From 704f1280043423489832e9ee5280be8ab750208b Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 5 Dec 2023 10:15:51 +0100 Subject: [PATCH 070/133] Use CURA-10831 working packages for deps Contributes to CURA-10831 --- conandata.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/conandata.yml b/conandata.yml index 52f15cb3f3..0eec369c96 100644 --- a/conandata.yml +++ b/conandata.yml @@ -4,12 +4,12 @@ requirements: - "curaengine/(latest)@ultimaker/cura_10831" - "cura_binary_data/(latest)@ultimaker/cura_10831" - "fdm_materials/(latest)@ultimaker/cura_10831" - - "curaengine_plugin_gradual_flow/0.1.0" - - "dulcificum/latest@ultimaker/stable" + - "curaengine_plugin_gradual_flow/(latest)@ultimaker/cura_10831" + - "dulcificum/(latest)@ultimaker/cura_10831" - "pyarcus/5.3.0" - "pysavitar/5.3.0" - "pynest2d/5.3.0" - - "curaengine_grpc_definitions/0.1.0" + - "curaengine_grpc_definitions/(latest)@ultimaker/cura_10831" requirements_internal: - "fdm_materials/(latest)@internal/cura_10831" - "cura_private_data/(latest)@internal/cura_10831" From 68818a525d966e0260571e2a9cae0ae5d36d6afe Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Tue, 5 Dec 2023 13:53:30 +0100 Subject: [PATCH 071/133] Use absolute transform coordinates instead of relative CURA-11279 --- cura/Arranging/GridArrange.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/cura/Arranging/GridArrange.py b/cura/Arranging/GridArrange.py index f3c5f3a1a9..be6b36cc5a 100644 --- a/cura/Arranging/GridArrange.py +++ b/cura/Arranging/GridArrange.py @@ -242,13 +242,9 @@ class GridArrange(Arranger): center_grid_y = coord_grid_y + (0.5 * self._grid_height) bounding_box = node.getBoundingBox() - center_node_x = (bounding_box.left + bounding_box.right) * 0.5 - center_node_y = (bounding_box.back + bounding_box.front) * 0.5 + center_node_z = bounding_box.height / 2 - delta_x = center_grid_x - center_node_x - delta_y = center_grid_y - center_node_y - - return TranslateOperation(node, Vector(delta_x, 0, delta_y)) + return TranslateOperation(node, Vector(center_grid_x, center_node_z, center_grid_y), True) def _getGridCornerPoints( self, From 9a108dc7205cda8983faafe6576c055f0b613e66 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Tue, 5 Dec 2023 14:41:15 +0100 Subject: [PATCH 072/133] Set explicit parameter name Co-authored-by: Casper Lamboo --- cura/Arranging/GridArrange.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Arranging/GridArrange.py b/cura/Arranging/GridArrange.py index be6b36cc5a..c30b5c897f 100644 --- a/cura/Arranging/GridArrange.py +++ b/cura/Arranging/GridArrange.py @@ -244,7 +244,7 @@ class GridArrange(Arranger): bounding_box = node.getBoundingBox() center_node_z = bounding_box.height / 2 - return TranslateOperation(node, Vector(center_grid_x, center_node_z, center_grid_y), True) + return TranslateOperation(node, Vector(center_grid_x, center_node_z, center_grid_y), set_position = True) def _getGridCornerPoints( self, From a9c3c2b4b432d7224d97fa356e8d042f4848aeba Mon Sep 17 00:00:00 2001 From: Paul Kuiper <46715907+pkuiper-ultimaker@users.noreply.github.com> Date: Tue, 5 Dec 2023 15:25:52 +0100 Subject: [PATCH 073/133] Increased raft base layer speed from 5mm/s to 10mm/s and increased raft middle layer linewidth from 0.4 to 0.7mm to increase productivity. PP-408 --- resources/definitions/ultimaker_method_base.def.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/definitions/ultimaker_method_base.def.json b/resources/definitions/ultimaker_method_base.def.json index 6ac68ef2de..ea00c726c2 100644 --- a/resources/definitions/ultimaker_method_base.def.json +++ b/resources/definitions/ultimaker_method_base.def.json @@ -353,11 +353,11 @@ "print_sequence": { "enabled": false }, "raft_base_line_spacing": { "value": "2*raft_base_line_width" }, "raft_base_line_width": { "value": 1.4 }, - "raft_base_speed": { "value": 5 }, + "raft_base_speed": { "value": 10 }, "raft_base_thickness": { "value": 0.8 }, "raft_interface_extruder_nr": { "value": "raft_surface_extruder_nr" }, "raft_interface_layers": { "value": 2 }, - "raft_interface_line_width": { "value": "line_width" }, + "raft_interface_line_width": { "value": 0.7 }, "raft_interface_speed": { "value": 90 }, "raft_interface_thickness": { "value": 0.3 }, "raft_margin": { "value": 3 }, From b46f6e8e09582f49216e4f0af295a413b78c9e7e Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Tue, 5 Dec 2023 18:24:44 +0100 Subject: [PATCH 074/133] Add support for CLI file opening with 'cura' and 'slicer' schemes CURA-11288 --- cura/CuraApplication.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 079a27b6ce..a71b6d9915 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -276,6 +276,8 @@ class CuraApplication(QtApplication): self._conan_installs = ApplicationMetadata.CONAN_INSTALLS self._python_installs = ApplicationMetadata.PYTHON_INSTALLS + self._supported_url_schemes: List[str] = ["cura", "slicer"] + @pyqtProperty(str, constant=True) def ultimakerCloudApiRootUrl(self) -> str: return UltimakerCloudConstants.CuraCloudAPIRoot @@ -328,7 +330,11 @@ class CuraApplication(QtApplication): assert not "This crash is triggered by the trigger_early_crash command line argument." for filename in self._cli_args.file: - self._files_to_open.append(os.path.abspath(filename)) + url = QUrl(filename) + if url.scheme() in self._supported_url_schemes: + self._open_url_queue.append(url) + else: + self._files_to_open.append(os.path.abspath(filename)) def initialize(self) -> None: self.__addExpectedResourceDirsAndSearchPaths() # Must be added before init of super @@ -1794,8 +1800,7 @@ class CuraApplication(QtApplication): self.readLocalFile(QUrl.fromLocalFile(filename)) def _openUrl(self, url: QUrl) -> None: - supported_schemes = ["cura", "slicer"] - if url.scheme() not in supported_schemes: + if url.scheme() not in self._supported_url_schemes: # only handle cura:// and slicer:// urls schemes return From a7a4e4bd2911ae9a7a9095cb9d676b009233149a Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Wed, 6 Dec 2023 06:06:08 +0100 Subject: [PATCH 075/133] Revert "Update nsi installer" This reverts commit 4b4b8b351462f7b788816c2ddbf2d75d38ee7de6. --- packaging/NSIS/Ultimaker-Cura.nsi.jinja | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packaging/NSIS/Ultimaker-Cura.nsi.jinja b/packaging/NSIS/Ultimaker-Cura.nsi.jinja index c562e5f654..228dba4fe4 100644 --- a/packaging/NSIS/Ultimaker-Cura.nsi.jinja +++ b/packaging/NSIS/Ultimaker-Cura.nsi.jinja @@ -197,11 +197,13 @@ Section UrlProtocol WriteRegStr HKCR "cura" "" "URL:cura" WriteRegStr HKCR "cura" "URL Protocol" "" WriteRegStr HKCR "cura\DefaultIcon" "" "$INSTDIR\${MAIN_APP_EXE},1" - WriteRegStr HKCR "cura\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}"' + WriteRegStr HKCR "cura\shell" "" "open" + WriteRegStr HKCR "cura\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}" "%1"' WriteRegStr HKCR "slicer" "" "URL:slicer" WriteRegStr HKCR "slicer" "URL Protocol" "" WriteRegStr HKCR "slicer\DefaultIcon" "" "$INSTDIR\${MAIN_APP_EXE},1" - WriteRegStr HKCR "slicer\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}"' + WriteRegStr HKCR "slicer\shell" "" "open" + WriteRegStr HKCR "slicer\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}" "%1"' SectionEnd \ No newline at end of file From 351183f407360b89565084b0bdef72ff7e852570 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Wed, 6 Dec 2023 06:13:39 +0100 Subject: [PATCH 076/133] Temporarily pin spdlog CURA-11288 --- conanfile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/conanfile.py b/conanfile.py index b58cbb4b7f..081db4d933 100644 --- a/conanfile.py +++ b/conanfile.py @@ -335,6 +335,7 @@ class CuraConan(ConanFile): self.requires("fdm_materials/(latest)@internal/testing") else: self.requires("fdm_materials/(latest)@ultimaker/testing") + self.requires("spdlog/1.12.0@_/_") def build_requirements(self): if self.options.get_safe("enable_i18n", False): From c4939701e1f3ee37314f8e71a27eb4196ab3f3e1 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Wed, 6 Dec 2023 06:37:36 +0100 Subject: [PATCH 077/133] Re-enable genrate cura version CURA-11288 --- conanfile.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/conanfile.py b/conanfile.py index 081db4d933..ec5be608d6 100644 --- a/conanfile.py +++ b/conanfile.py @@ -359,7 +359,7 @@ class CuraConan(ConanFile): vr = VirtualRunEnv(self) vr.generate() - # self._generate_cura_version(os.path.join(self.source_folder, "cura")) + self._generate_cura_version(os.path.join(self.source_folder, "cura")) if not self.in_local_cache: # Copy CuraEngine.exe to bindirs of Virtual Python Environment @@ -467,7 +467,7 @@ echo "CURA_APP_NAME={{ cura_app_name }}" >> ${{ env_prefix }}GITHUB_ENV ext = ".sh" if self.settings.os != "Windows" else ".ps1" save(self, os.path.join(self._script_dir, f"activate_github_actions_version_env{ext}"), activate_github_actions_version_env) - # self._generate_cura_version(os.path.join(self._site_packages, "cura")) + self._generate_cura_version(os.path.join(self._site_packages, "cura")) entitlements_file = "'{}'".format(Path(self.cpp_info.res_paths[2], "MacOS", "cura.entitlements")) self._generate_pyinstaller_spec(location = self._base_dir, From 153e2e7bd073f4d7e367560345993525f7a5aebc Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Wed, 6 Dec 2023 07:14:36 +0100 Subject: [PATCH 078/133] Fix warning/Boyscouting CURA-11288 --- cura/PrinterOutput/Models/MaterialOutputModel.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/cura/PrinterOutput/Models/MaterialOutputModel.py b/cura/PrinterOutput/Models/MaterialOutputModel.py index 6920cead1b..d60c34ed10 100644 --- a/cura/PrinterOutput/Models/MaterialOutputModel.py +++ b/cura/PrinterOutput/Models/MaterialOutputModel.py @@ -42,8 +42,7 @@ class MaterialOutputModel(QObject): "tpu" :{"name" :"tpu_175" ,"guid": "19baa6a9-94ff-478b-b4a1-8157b74358d2"} } - - if guid is None and brand is not "empty" and type in _MATERIAL_MAP: + if guid is None and brand != "empty" and type in _MATERIAL_MAP: name = _MATERIAL_MAP[type]["name"] guid = _MATERIAL_MAP[type]["guid"] return name, guid From d6a73a5976067078c7e7e63e2d6a12b89573d566 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Wed, 6 Dec 2023 07:57:45 +0100 Subject: [PATCH 079/133] Fix opening files on windows `_open_url_queue` is expecting a list of strings, not a `QUrl` instance CURA-11288 --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index a71b6d9915..82313eece8 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -332,7 +332,7 @@ class CuraApplication(QtApplication): for filename in self._cli_args.file: url = QUrl(filename) if url.scheme() in self._supported_url_schemes: - self._open_url_queue.append(url) + self._open_url_queue.append(filename) else: self._files_to_open.append(os.path.abspath(filename)) From 568fc4ca766afa3ee14f1620d925b90363196b09 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Wed, 6 Dec 2023 08:49:37 +0100 Subject: [PATCH 080/133] Revert "Fix opening files on windows" This reverts commit d6a73a5976067078c7e7e63e2d6a12b89573d566. --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 82313eece8..a71b6d9915 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -332,7 +332,7 @@ class CuraApplication(QtApplication): for filename in self._cli_args.file: url = QUrl(filename) if url.scheme() in self._supported_url_schemes: - self._open_url_queue.append(filename) + self._open_url_queue.append(url) else: self._files_to_open.append(os.path.abspath(filename)) From 0353037b31cfd715bc01193ca676f871d2373515 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Wed, 6 Dec 2023 11:36:54 +0100 Subject: [PATCH 081/133] Use `getWorldPosition` for `TranslateOperation` CURA-11279 --- cura/Arranging/GridArrange.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/cura/Arranging/GridArrange.py b/cura/Arranging/GridArrange.py index c30b5c897f..13778e9de9 100644 --- a/cura/Arranging/GridArrange.py +++ b/cura/Arranging/GridArrange.py @@ -241,10 +241,8 @@ class GridArrange(Arranger): center_grid_x = coord_grid_x + (0.5 * self._grid_width) center_grid_y = coord_grid_y + (0.5 * self._grid_height) - bounding_box = node.getBoundingBox() - center_node_z = bounding_box.height / 2 - - return TranslateOperation(node, Vector(center_grid_x, center_node_z, center_grid_y), set_position = True) + return TranslateOperation(node, Vector(center_grid_x, node.getWorldPosition().y, center_grid_y), + set_position=True) def _getGridCornerPoints( self, From 920809f064d39f2426312428a02c7db0b3c4410d Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Wed, 6 Dec 2023 11:40:34 +0100 Subject: [PATCH 082/133] Use absolute transformation to set location for arrange Using relative positioning proved to create issues; when spamming of arrange instructions it was possible to end up in the following time line 1: arrange action a is started 2: arrange action b is started 3: arrange action a finished computation, and applies transformations on the models 4: arrange action b finishes computation and applies relative transformations on top of the previous transformations By using absolute positioning this issue is resolved CURA-11279 --- cura/Arranging/Nest2DArrange.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/cura/Arranging/Nest2DArrange.py b/cura/Arranging/Nest2DArrange.py index 968522d5a3..a67d04aa8c 100644 --- a/cura/Arranging/Nest2DArrange.py +++ b/cura/Arranging/Nest2DArrange.py @@ -14,7 +14,7 @@ from UM.Math.Quaternion import Quaternion from UM.Math.Vector import Vector from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation from UM.Operations.GroupedOperation import GroupedOperation -from UM.Operations.RotateOperation import RotateOperation +from UM.Operations.SetTransformOperation import SetTransformOperation from UM.Operations.TranslateOperation import TranslateOperation from cura.Arranging.Arranger import Arranger @@ -140,13 +140,17 @@ class Nest2DArrange(Arranger): grouped_operation.addOperation(AddSceneNodeOperation(node, scene_root)) if node_item.binId() == 0: - # We found a spot for it rotation_matrix = Matrix() rotation_matrix.setByRotationAxis(node_item.rotation(), Vector(0, -1, 0)) - grouped_operation.addOperation(RotateOperation(node, Quaternion.fromMatrix(rotation_matrix))) + + orientation = node.getWorldOrientation() * Quaternion.fromMatrix(rotation_matrix) + translation = node.getWorldPosition().preMultiply(rotation_matrix) + Vector( + node_item.translation().x() / self._factor, + 0, + node_item.translation().y() / self._factor + ) grouped_operation.addOperation( - TranslateOperation(node, Vector(node_item.translation().x() / self._factor, 0, - node_item.translation().y() / self._factor))) + SetTransformOperation(node, orientation=orientation, translation=translation)) else: # We didn't find a spot grouped_operation.addOperation( From 237d1a899baa03da667b72a7cc5be395b65e2dc5 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Wed, 6 Dec 2023 12:10:34 +0100 Subject: [PATCH 083/133] Revert "Use absolute transformation to set location for arrange" This reverts commit 920809f064d39f2426312428a02c7db0b3c4410d. --- cura/Arranging/Nest2DArrange.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/cura/Arranging/Nest2DArrange.py b/cura/Arranging/Nest2DArrange.py index a67d04aa8c..968522d5a3 100644 --- a/cura/Arranging/Nest2DArrange.py +++ b/cura/Arranging/Nest2DArrange.py @@ -14,7 +14,7 @@ from UM.Math.Quaternion import Quaternion from UM.Math.Vector import Vector from UM.Operations.AddSceneNodeOperation import AddSceneNodeOperation from UM.Operations.GroupedOperation import GroupedOperation -from UM.Operations.SetTransformOperation import SetTransformOperation +from UM.Operations.RotateOperation import RotateOperation from UM.Operations.TranslateOperation import TranslateOperation from cura.Arranging.Arranger import Arranger @@ -140,17 +140,13 @@ class Nest2DArrange(Arranger): grouped_operation.addOperation(AddSceneNodeOperation(node, scene_root)) if node_item.binId() == 0: + # We found a spot for it rotation_matrix = Matrix() rotation_matrix.setByRotationAxis(node_item.rotation(), Vector(0, -1, 0)) - - orientation = node.getWorldOrientation() * Quaternion.fromMatrix(rotation_matrix) - translation = node.getWorldPosition().preMultiply(rotation_matrix) + Vector( - node_item.translation().x() / self._factor, - 0, - node_item.translation().y() / self._factor - ) + grouped_operation.addOperation(RotateOperation(node, Quaternion.fromMatrix(rotation_matrix))) grouped_operation.addOperation( - SetTransformOperation(node, orientation=orientation, translation=translation)) + TranslateOperation(node, Vector(node_item.translation().x() / self._factor, 0, + node_item.translation().y() / self._factor))) else: # We didn't find a spot grouped_operation.addOperation( From 30e4c61620fc31703cf0b4227f419beea882db30 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Wed, 6 Dec 2023 12:39:10 +0100 Subject: [PATCH 084/133] review comments fix CURA-11166 --- cura/CuraApplication.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 7e2f0fb1ca..28dfd5e1c9 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -179,7 +179,7 @@ class CuraApplication(QtApplication): self._use_single_instance = False self._single_instance = None - self._project_mode = None + self._open_project_mode: Optional[str] = None self._cura_formula_functions = None # type: Optional[CuraFormulaFunctions] @@ -1846,7 +1846,7 @@ class CuraApplication(QtApplication): Logger.log("i", "Attempting to read file %s", file.toString()) if not file.isValid(): return - self._project_mode = project_mode + self._open_project_mode = project_mode scene = self.getController().getScene() for node in DepthFirstIterator(scene.getRoot()): @@ -1856,16 +1856,16 @@ class CuraApplication(QtApplication): is_project_file = self.checkIsValidProjectFile(file) - if self._project_mode is None: - self._project_mode = self.getPreferences().getValue("cura/choice_on_open_project") + if self._open_project_mode is None: + self._open_project_mode = self.getPreferences().getValue("cura/choice_on_open_project") - if is_project_file and self._project_mode == "open_as_project": + if is_project_file and self._open_project_mode == "open_as_project": # open as project immediately without presenting a dialog workspace_handler = self.getWorkspaceFileHandler() workspace_handler.readLocalFile(file, add_to_recent_files_hint = add_to_recent_files) return - if is_project_file and self._project_mode == "always_ask": + if is_project_file and self._open_project_mode == "always_ask": # present a dialog asking to open as project or import models self.callLater(self.openProjectFile.emit, file, add_to_recent_files) return @@ -2001,9 +2001,9 @@ class CuraApplication(QtApplication): node.translate(Vector(0, center_y, 0)) nodes_to_arrange.append(node) - # If file extention is 3mf and models are to be loaded from a cura project, - # models are to be arranged in buildplate. - elif self._project_mode == "open_as_model": + # If the file is a project,and models are to be loaded from a that project, + # models inside file should be arranged in buildplate. + elif self._open_project_mode == "open_as_model": nodes_to_arrange.append(node) # This node is deep copied from some other node which already has a BuildPlateDecorator, but the deepcopy From 84d56367f4f357caec408e14e4d396d96aa13aef Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Wed, 6 Dec 2023 13:33:57 +0100 Subject: [PATCH 085/133] Also listen to the "/" appended string for url schemes Windows adds a slash for some reason CURA-11288 --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index a71b6d9915..1f60130787 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1805,7 +1805,7 @@ class CuraApplication(QtApplication): return match url.host() + url.path(): - case "open": + case "open" | "open/": query = QUrlQuery(url.query()) model_url = QUrl(query.queryItemValue("file", options=QUrl.ComponentFormattingOption.FullyDecoded)) From 7574b56ebad4371efcbeb5bd42d0bbe864e317ec Mon Sep 17 00:00:00 2001 From: Casper Lamboo Date: Thu, 7 Dec 2023 10:32:01 +0100 Subject: [PATCH 086/133] Update conanfile.py --- conanfile.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/conanfile.py b/conanfile.py index 1ee2094490..678943759c 100644 --- a/conanfile.py +++ b/conanfile.py @@ -326,13 +326,12 @@ class CuraConan(ConanFile): self.requires("curaengine_grpc_definitions/0.1.0") self.requires("zlib/1.2.13") self.requires("pyarcus/5.3.0") - self.requires("dulcificum/(latest)@ultimaker/testing") self.requires("dulcificum/(latest)@ultimaker/stable") self.requires("curaengine/(latest)@ultimaker/testing") self.requires("pysavitar/5.3.0") self.requires("pynest2d/5.3.0") self.requires("curaengine_plugin_gradual_flow/0.1.0") - self.requires("uranium/latest@ultimaker/testing") + self.requires("uranium/(latest)@ultimaker/testing") self.requires("cura_binary_data/(latest)@ultimaker/testing") self.requires("cpython/3.10.4@ultimaker/stable") self.requires("openssl/3.2.0") @@ -341,7 +340,6 @@ class CuraConan(ConanFile): self.requires("fdm_materials/(latest)@internal/testing") else: self.requires("fdm_materials/(latest)@ultimaker/testing") - self.requires("spdlog/1.12.0@_/_") def build_requirements(self): if self.options.get_safe("enable_i18n", False): From f94198c1080fa15023020c7164ec7a3679aa0cbd Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Thu, 7 Dec 2023 14:41:44 +0100 Subject: [PATCH 087/133] Fix behaviour of internal property The attribute 'enterprise' in conanfile.py was incorrectly named and has been renamed to 'internal'. This revision ensures that options are accessed correctly to avoid potential issues in usage. Contributes to CURA-10831 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index f15766a57b..8ade8e771c 100644 --- a/conanfile.py +++ b/conanfile.py @@ -86,7 +86,7 @@ class CuraConan(ConanFile): @property def _internal(self): - return self.options.enterprise in ["True", 'true'] + return self.options.internal in ["True", 'true'] @property def _app_name(self): From 9bb065a294761831977104487ab0f1859888a101 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Fri, 8 Dec 2023 07:40:30 +0100 Subject: [PATCH 088/133] make sure fdm_materials is installed for internals Contributes to CURA-10831 --- conanfile.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/conanfile.py b/conanfile.py index 8ade8e771c..e9d06452f3 100644 --- a/conanfile.py +++ b/conanfile.py @@ -333,8 +333,6 @@ class CuraConan(ConanFile): self.requires(req) if self._internal: for req in self.conan_data["requirements_internal"]: - if "fdm_materials" in req: - continue self.requires(req) self.requires("cpython/3.10.4@ultimaker/stable") self.requires("openssl/3.2.0") From e6812a31d8e7c57a52482dbb47ca8e3ff5217194 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Fri, 8 Dec 2023 07:42:06 +0100 Subject: [PATCH 089/133] No need to create a conan-package Contributes to CURA-10831 --- .github/workflows/conan-package.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index 24793fa4cc..12567fde84 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -45,12 +45,3 @@ jobs: recipe_id_full: ${{ needs.conan-recipe-version.outputs.recipe_id_full }} recipe_id_latest: ${{ needs.conan-recipe-version.outputs.recipe_id_latest }} secrets: inherit - - conan-package-create-linux: - needs: [ conan-recipe-version, conan-package-export ] - - uses: ultimaker/cura-workflows/.github/workflows/conan-package-create-linux.yml@CURA-10831 - with: - recipe_id_full: ${{ needs.conan-recipe-version.outputs.recipe_id_full }} - conan_extra_args: '-c tools.build:skip_test=True -o ${{ needs.conan-recipe-version.outputs.project_name }}:enable_i18n=True' - secrets: inherit From f8239aa1fa288a6b465cbf5ae15531167ef5bbdf Mon Sep 17 00:00:00 2001 From: Remco Burema Date: Fri, 8 Dec 2023 10:29:59 +0100 Subject: [PATCH 090/133] Add 'Enterprise' if applicable to About-dialog. done as a 15 min fix --- resources/qml/Dialogs/AboutDialog.qml | 10 ++++++++++ .../themes/cura-light/images/enterprise.png | Bin 0 -> 2492 bytes 2 files changed, 10 insertions(+) create mode 100644 resources/themes/cura-light/images/enterprise.png diff --git a/resources/qml/Dialogs/AboutDialog.qml b/resources/qml/Dialogs/AboutDialog.qml index 8ea0c01888..947b46269a 100644 --- a/resources/qml/Dialogs/AboutDialog.qml +++ b/resources/qml/Dialogs/AboutDialog.qml @@ -45,6 +45,16 @@ UM.Dialog anchors.centerIn: parent } + Image + { + id: enterpriseLogo + visible: CuraApplication.isEnterprise + source: UM.Theme.getImage("enterprise") + fillMode: Image.PreserveAspectFit + + anchors.bottom: parent.bottom + } + UM.Label { id: version diff --git a/resources/themes/cura-light/images/enterprise.png b/resources/themes/cura-light/images/enterprise.png new file mode 100644 index 0000000000000000000000000000000000000000..6d92d80adbea617b9ac665d3b02e446fc4533f6a GIT binary patch literal 2492 zcmV;t2}AaYP)EX>4Tx04R}tkv&MmKpe$iQ>9fZ4t5Z6$WWau6curlDi*;)X)CnqU~=gfG-*gu zTpR`0f`cE6RRe3JS*_Mt`=0!Tp@O!O;X2JxB(Q`eQV=1djtZ)<5T#Wk#YCF+;~xGI$DbmXOs)zT zITlcZ3d!+<|H1EW&EnLgn-q!zy)U-?F$M&7fmXw|zmILZbprUGfh(=!uQh?$PtqG5 zEph}5ZUYzB9ZlW?E_Z<8CtWfmNAlAYibdf4jJ_!k4BZ0#Yi@7teVjf3S?X%}1~@nb z#!HmF?(yzmcW?imY4`U7S&wp^fW!DD00006VoOIv00aOC04y*FAmji5010qNS#tmY z3ljhU3ljkVnw%H_000McNliru=L`r53J5$jA432D02y>eSad^gZEa<4bO1wgWnpw> zWFU8GbZ8()Nlj2!fese{00)#wL_t(|+U;3QZyVPYJ#S{LAtj2Gl!)`_8OgHTBn8}} zNn1!p+C^%#HiBlAEV6N1B>e|gP^60%XwXd;au?YY1?seM7fpe*-2}0+hzqv`BsYMS zwl<(7N=S+l-%z$F>VupSIecAEnh$D*L&|a%?VOE-$NTQP?}O)_dkI8{5FtW@2oWMg zh!7z{ga{G-UqFIBU^n>~#61p+3-+LBH4px!-xw&^w(}brtOFZ>o*OCn`kdd;Kpg~e!QUNooj$Wa=YuT`Fdb7792N*fZ~%lpHR{B6dtC!sfk-$kP9RDguz=d`Jvx2H^quoBrb22ECv=IURw>c1JyG|yUn;0= zH$lL`=@Z)OA=}*j3y}KGf`Gu-eV{q5L&Hk-%pQlat`=bW>JCAsT4 zqkRL)#L#uNRQ#$l+6Y;v|7E5dRri=)s@-b0(@V8m*j%~My8L?=m9gP#LrE#SSocbm6V{Q4GvoI@j87^&NV0z==Ul{K}4Db#sPl!&h40_9Yel>T9T1|L7ZUX)lXf z`DvgbIM*xo_A1yvOwFbmW>&-OZQC`6IyWnI-c1Vdth-RMQx97;{~5X-GrEqgod((M ztQO>l6|43>*uS${m_K$mtGcM!>nmTr?4*Ki&%W6T`*zT0-O#s_0+v<3)X)w5Qvl&d zOAU40(AR4306;1!f#s^d2&FGiG)?Ps6u|C-)q{_vn~*x$Sf#+@ZVJu-A)brY*Y|eq z3tlT?*dxu9r>r>VKt^L!qe$H2o)6Rq%fB19j+=Wj8LlsXp|Zd3Q;L zocOgpU~In?xDMyuimYD!3D9>10F=zoEGwC>VXyo=)#!VjzR0ndIK_(9t00_%ll`is z{ub3zbKO4x*WOY|5vip31JCPRF`EFc2W{NAZ_K2UiCF-^SJayTrn`Co4XLNsn@UPZ zC8d`W! z1m8~$R&zaoiqZf;CkL-EX8c@HAj*x)1IU$CRnBZoNXa)T~d+>&S96ll(Eut=>TFk-r=WR%NtrfOF3E z{K`}G)cB$!eqAEeZ0>sBM`OLW6yPc=bbYTzsodXXUrDk5-KahfMSd3mFfsBG0LKR> z{=!D;jRADstWg?EbZx(~H3JBv%2?vn{f9UjI>(iZVOe)jH(ozb@_uQevekgGU7dj- zomVpb-)%8{UH6wlLa5fFr_}cV^s_v>2zkh^Tw+6++jeuyYS?}Z!@5P4*fbslY{3{m zS`}b=6sWr@V4vn!kP67ErS=W-|R-TO~Fx#Wu<`J@2XeucKuZpruI8Ajc1AhC}RKdR%Y0!TwR z*iyiivJ>5SWdeG-G1y-oOp{VhfQtpmc5b+U_^b&k5F2-4QX9f@e z!QyCg0uW9o2Csz8H7YHkno3GwMPq?x0%%i|crW*F>m&elQe9-aaZ5?dQ;H%_utMcB z)lyDueTf%cd;gY4drUrFU?p=GmiapNHe1z0-_VOnx+O&Ql3AmVJ-PoogIj|LUuJ7N zt^4A<+4_}1B$S5Vmv1AemwtPD3h<+?_P)M11#DVafJ5uKDLT7($v*`Y!c)Lf zA+QnDzJK=Ne@*~EV2?ky`eZkIWQCIRn?W{v%)bRR1@TCH!u|aj8}(PZnlF09p@4^t zQu%S4O@;@q9kEr?#$v*u)Me}#P9rDtSef0qBL(*OiLA6Ljp|jsWY!LgQe#2S?(}0000 Date: Fri, 8 Dec 2023 10:52:00 +0100 Subject: [PATCH 091/133] Fix a bug in which Cura sets fanspeed in the 0..255 range instead of the 0..1 range for Method machines. CURA-11441 --- resources/definitions/ultimaker_method_base.def.json | 1 + 1 file changed, 1 insertion(+) diff --git a/resources/definitions/ultimaker_method_base.def.json b/resources/definitions/ultimaker_method_base.def.json index 8e9034c954..d45f54f8b9 100644 --- a/resources/definitions/ultimaker_method_base.def.json +++ b/resources/definitions/ultimaker_method_base.def.json @@ -329,6 +329,7 @@ "machine_name": { "default_value": "UltiMaker Method" }, "machine_nozzle_cool_down_speed": { "value": 0.8 }, "machine_nozzle_heat_up_speed": { "value": 3.5 }, + "machine_scale_fan_speed_zero_to_one": { "value": true }, "machine_start_gcode": { "default_value": "" }, "material_bed_temperature": { "enabled": "machine_heated_bed" }, "material_bed_temperature_layer_0": { "enabled": "machine_heated_bed" }, From bf2c8b5a08e0fbf442edfa70ae4f11f04d3c32f2 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Fri, 8 Dec 2023 11:41:16 +0100 Subject: [PATCH 092/133] Simulation time fed to the timer controlling speed simulation time is made 10x faster than the actual time, for better visualisation CURA-7647 --- plugins/SimulationView/SimulationView.py | 10 ++++++---- .../SimulationViewMainComponent.qml | 6 +----- plugins/SimulationView/SimulationViewProxy.py | 15 +++++++++++++++ 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 18d1f981c7..6874b27625 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -79,7 +79,7 @@ class SimulationView(CuraView): self.currentLayerNumChanged.connect(self._onCurrentLayerNumChanged) self._current_feedrates = {} - self._visible_lengths ={} + self._lengths_of_polyline ={} self._busy = False self._simulation_running = False @@ -403,7 +403,9 @@ class SimulationView(CuraView): return self._max_feedrate def getSimulationTime(self) -> list: - return self._visible_lengths[self._current_layer_num] / self._current_feedrates[self._current_layer_num] + if len(self._lengths_of_polyline) > 0 and len(self._lengths_of_polyline) == len(self._current_feedrates): + return self._lengths_of_polyline[self._current_layer_num] / self._current_feedrates[self._current_layer_num] + return numpy.zeros(0) def getMinThickness(self) -> float: if abs(self._min_thickness - sys.float_info.max) < 10: # Some lenience due to floating point rounding. @@ -529,10 +531,10 @@ class SimulationView(CuraView): visible_indicies_with_extrusion = numpy.where(numpy.isin(polyline.types, visible_line_types_with_extrusion))[0] if visible_indices.size == 0: # No items to take maximum or minimum of. continue - self._visible_lengths[layer_index] = numpy.take(polyline.lineLengths, visible_indices) + self._lengths_of_polyline[layer_index] = polyline.lineLengths visible_feedrates = numpy.take(polyline.lineFeedrates, visible_indices) visible_feedrates_with_extrusion = numpy.take(polyline.lineFeedrates, visible_indicies_with_extrusion) - self._current_feedrates[layer_index] = visible_feedrates + self._current_feedrates[layer_index] = polyline.lineFeedrates visible_linewidths = numpy.take(polyline.lineWidths, visible_indices) visible_linewidths_with_extrusion = numpy.take(polyline.lineWidths, visible_indicies_with_extrusion) visible_thicknesses = numpy.take(polyline.lineThicknesses, visible_indices) diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 66acff656a..216095c15c 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -136,10 +136,9 @@ Item Timer { id: simulationTimer - interval: parseFloat(UM.SimulationView.getSimulationTime[pathNumber]).toFixed(2) + interval: UM.SimulationView.simulationTime running: false repeat: true - property int pathNumber : 0 onTriggered: { var currentPath = UM.SimulationView.currentPath @@ -154,12 +153,10 @@ Item if (currentPath >= numPaths) { UM.SimulationView.setCurrentPath(0) - pathNumber =0 } else { UM.SimulationView.setCurrentPath(currentPath + 1) - pathNumber = 0 } } // If the simulation is already playing and we reach the end of a layer, then it automatically @@ -187,7 +184,6 @@ Item // The status must be set here instead of in the resumeSimulation function otherwise it won't work // correctly, because part of the logic is in this trigger function. isSimulationPlaying = true - pathNumber += 1 } } diff --git a/plugins/SimulationView/SimulationViewProxy.py b/plugins/SimulationView/SimulationViewProxy.py index 669f7fdbcc..e80005fc36 100644 --- a/plugins/SimulationView/SimulationViewProxy.py +++ b/plugins/SimulationView/SimulationViewProxy.py @@ -2,9 +2,11 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import TYPE_CHECKING +import numpy from PyQt6.QtCore import QObject, pyqtSignal, pyqtProperty from UM.FlameProfiler import pyqtSlot from UM.Application import Application +from UM.Logger import Logger if TYPE_CHECKING: from .SimulationView import SimulationView @@ -54,6 +56,19 @@ class SimulationViewProxy(QObject): def currentPath(self): return self._simulation_view.getCurrentPath() + @pyqtProperty(int, notify=currentPathChanged) + def simulationTime(self): + # This if is activated when there is a layer change + if numpy.all(self._simulation_view.getSimulationTime()==0) or len(self._simulation_view.getSimulationTime()) <= self._simulation_view.getCurrentPath(): + return 100 + # Extracts the currents paths simulation time (in seconds) from the dict of simulation time of the current layer. + # We multiply the time with 100 to make it to ms from s.(Should be 1000 in real time). This scaling makes the simulation time 10x faster than the real time. + simulationTimeOfpath =self._simulation_view.getSimulationTime()[0][self._simulation_view.getCurrentPath()] * 100 + # Since the timer cannot process time less than 1 ms, we put a lower limit here + if simulationTimeOfpath < 1: + return 1 + return int(simulationTimeOfpath) + @pyqtProperty(int, notify=currentPathChanged) def minimumPath(self): return self._simulation_view.getMinimumPath() From 7711c15ddedcce78e735d0a016f36e0134d3814d Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Fri, 8 Dec 2023 11:43:38 +0100 Subject: [PATCH 093/133] removed unnecessary import CURA-7647 --- plugins/SimulationView/SimulationViewProxy.py | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/SimulationView/SimulationViewProxy.py b/plugins/SimulationView/SimulationViewProxy.py index e80005fc36..8f83e9b403 100644 --- a/plugins/SimulationView/SimulationViewProxy.py +++ b/plugins/SimulationView/SimulationViewProxy.py @@ -6,7 +6,6 @@ import numpy from PyQt6.QtCore import QObject, pyqtSignal, pyqtProperty from UM.FlameProfiler import pyqtSlot from UM.Application import Application -from UM.Logger import Logger if TYPE_CHECKING: from .SimulationView import SimulationView From f2f2f742bdfa10cd151566423cd9f405284216c1 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Fri, 8 Dec 2023 14:36:29 +0100 Subject: [PATCH 094/133] Apply suggestions from code review Co-authored-by: Casper Lamboo --- .github/workflows/conan-package.yml | 5 ++--- .github/workflows/installers.yml | 14 +++++--------- .github/workflows/linux.yml | 3 +-- .github/workflows/macos.yml | 3 +-- .github/workflows/process-pull-request.yml | 3 +-- .github/workflows/unit-test-post.yml | 3 +-- .github/workflows/unit-test.yml | 6 ++---- .github/workflows/windows.yml | 3 +-- conandata.yml | 18 +++++++++--------- 9 files changed, 23 insertions(+), 35 deletions(-) diff --git a/.github/workflows/conan-package.yml b/.github/workflows/conan-package.yml index 12567fde84..7ca2b0c467 100644 --- a/.github/workflows/conan-package.yml +++ b/.github/workflows/conan-package.yml @@ -31,16 +31,15 @@ env: CONAN_LOGIN_USERNAME_CURA: ${{ secrets.CONAN_USER }} CONAN_PASSWORD_CURA: ${{ secrets.CONAN_PASS }} -# FIXME: point to `main` once merged jobs: conan-recipe-version: - uses: ultimaker/cura-workflows/.github/workflows/conan-recipe-version.yml@CURA-10831 + uses: ultimaker/cura-workflows/.github/workflows/conan-recipe-version.yml@main with: project_name: cura conan-package-export: needs: [ conan-recipe-version ] - uses: ultimaker/cura-workflows/.github/workflows/conan-recipe-export.yml@CURA-10831 + uses: ultimaker/cura-workflows/.github/workflows/conan-recipe-export.yml@main with: recipe_id_full: ${{ needs.conan-recipe-version.outputs.recipe_id_full }} recipe_id_latest: ${{ needs.conan-recipe-version.outputs.recipe_id_latest }} diff --git a/.github/workflows/installers.yml b/.github/workflows/installers.yml index aa1f5a49f0..6e531ba833 100644 --- a/.github/workflows/installers.yml +++ b/.github/workflows/installers.yml @@ -42,16 +42,15 @@ env: jobs: default_values: - uses: ultimaker/cura-workflows/.github/workflows/cura-installer-default-value.yml@CURA-10831 + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-default-value.yml@main with: cura_conan_version: ${{ inputs.cura_conan_version }} latest_release: '5.6' latest_release_schedule_hour: 4 latest_release_tag: 'nightly' - # FIXME: point to `main` once merged windows-installer: - uses: ultimaker/cura-workflows/.github/workflows/cura-installer-windows.yml@CURA-10831 + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-windows.yml@main needs: [ default_values ] with: cura_conan_version: ${{ needs.default_values.outputs.cura_conan_version }} @@ -62,9 +61,8 @@ jobs: operating_system: windows-2022 secrets: inherit - # FIXME: point to `main` once merged linux-installer: - uses: ultimaker/cura-workflows/.github/workflows/cura-installer-linux.yml@CURA-10831 + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-linux.yml@main needs: [ default_values ] with: cura_conan_version: ${{ needs.default_values.outputs.cura_conan_version }} @@ -75,9 +73,8 @@ jobs: operating_system: ubuntu-22.04 secrets: inherit - # FIXME: point to `main` once merged macos-installer: - uses: ultimaker/cura-workflows/.github/workflows/cura-installer-macos.yml@CURA-10831 + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-macos.yml@main needs: [ default_values ] with: cura_conan_version: ${{ needs.default_values.outputs.cura_conan_version }} @@ -88,9 +85,8 @@ jobs: operating_system: self-hosted-X64 secrets: inherit - # FIXME: point to `main` once merged macos-arm-installer: - uses: ultimaker/cura-workflows/.github/workflows/cura-installer-macos.yml@CURA-10831 + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-macos.yml@main needs: [ default_values ] with: cura_conan_version: ${{ needs.default_values.outputs.cura_conan_version }} diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 535d087700..2ad8f90bfe 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -45,9 +45,8 @@ env: STAGING: ${{ inputs.staging || false }} jobs: - # FIXME: point to `main` once merged windows-installer: - uses: ultimaker/cura-workflows/.github/workflows/cura-installer-linux.yml@CURA-10831 + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-linux.yml@main with: cura_conan_version: ${{ inputs.cura_conan_version }} conan_args: ${{ inputs.conan_args }} diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 02f45385e7..d080fcc710 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -49,9 +49,8 @@ env: STAGING: ${{ inputs.staging || false }} jobs: - # FIXME: point to `main` once merged windows-installer: - uses: ultimaker/cura-workflows/.github/workflows/cura-installer-macos.yml@CURA-10831 + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-macos.yml@main with: cura_conan_version: ${{ inputs.cura_conan_version }} conan_args: ${{ inputs.conan_args }} diff --git a/.github/workflows/process-pull-request.yml b/.github/workflows/process-pull-request.yml index f34e26f13e..45b3f8c915 100644 --- a/.github/workflows/process-pull-request.yml +++ b/.github/workflows/process-pull-request.yml @@ -4,8 +4,7 @@ on: pull_request_target: types: [ opened, reopened, edited, review_requested, ready_for_review, assigned ] -# FIXME: Use `main` instead of `CURA-10831` once merged jobs: add_label: - uses: ultimaker/cura-workflows/.github/workflows/process-pull-request.yml@CURA-10831 + uses: ultimaker/cura-workflows/.github/workflows/process-pull-request.yml@main secrets: inherit \ No newline at end of file diff --git a/.github/workflows/unit-test-post.yml b/.github/workflows/unit-test-post.yml index b4ca2ee699..eaf69692a7 100644 --- a/.github/workflows/unit-test-post.yml +++ b/.github/workflows/unit-test-post.yml @@ -6,9 +6,8 @@ on: types: [ completed ] jobs: - # FIXME: Use `main` instead of `CURA-10831` once merged publish-test-results: - uses: ultimaker/cura-workflows/.github/workflows/unit-test-post.yml@CURA-10831 + uses: ultimaker/cura-workflows/.github/workflows/unit-test-post.yml@main with: event: ${{ github.event.workflow_run.event }} conclusion: ${{ github.event.workflow_run.conclusion }} diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index 6369e7e395..7c6910b39f 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -45,15 +45,13 @@ env: CONAN_PASSWORD: ${{ secrets.CONAN_PASS }} jobs: - # FIXME: Change to `main` instead of `CURA-10831` once merged conan-recipe-version: - uses: ultimaker/cura-workflows/.github/workflows/conan-recipe-version.yml@CURA-10831 + uses: ultimaker/cura-workflows/.github/workflows/conan-recipe-version.yml@main with: project_name: cura testing: - # FIXME: Change to `main` instead of `CURA-10831` once merged - uses: ultimaker/cura-workflows/.github/workflows/unit-test.yml@CURA-10831 + uses: ultimaker/cura-workflows/.github/workflows/unit-test.yml@main needs: [ conan-recipe-version ] with: recipe_id_full: ${{ needs.conan-recipe-version.outputs.recipe_id_full }} diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index ef7e986ec3..0007936969 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -45,9 +45,8 @@ env: STAGING: ${{ inputs.staging || false }} jobs: - # FIXME: point to `main` once merged windows-installer: - uses: ultimaker/cura-workflows/.github/workflows/cura-installer-windows.yml@CURA-10831 + uses: ultimaker/cura-workflows/.github/workflows/cura-installer-windows.yml@main with: cura_conan_version: ${{ inputs.cura_conan_version }} conan_args: ${{ inputs.conan_args }} diff --git a/conandata.yml b/conandata.yml index 0eec369c96..a28954bb3f 100644 --- a/conandata.yml +++ b/conandata.yml @@ -1,18 +1,18 @@ version: "5.7.0-alpha.0" requirements: - - "uranium/(latest)@ultimaker/cura_10831" - - "curaengine/(latest)@ultimaker/cura_10831" - - "cura_binary_data/(latest)@ultimaker/cura_10831" - - "fdm_materials/(latest)@ultimaker/cura_10831" - - "curaengine_plugin_gradual_flow/(latest)@ultimaker/cura_10831" - - "dulcificum/(latest)@ultimaker/cura_10831" + - "uranium/(latest)@ultimaker/latest" + - "curaengine/(latest)@ultimaker/latest" + - "cura_binary_data/(latest)@ultimaker/latest" + - "fdm_materials/(latest)@ultimaker/latest" + - "curaengine_plugin_gradual_flow/(latest)@ultimaker/stable" + - "dulcificum/(latest)@ultimaker/latest" - "pyarcus/5.3.0" - "pysavitar/5.3.0" - "pynest2d/5.3.0" - - "curaengine_grpc_definitions/(latest)@ultimaker/cura_10831" + - "curaengine_grpc_definitions/(latest)@ultimaker/latest" requirements_internal: - - "fdm_materials/(latest)@internal/cura_10831" - - "cura_private_data/(latest)@internal/cura_10831" + - "fdm_materials/(latest)@internal/latest" + - "cura_private_data/(latest)@internal/latest" urls: default: cloud_api_root: "https://api.ultimaker.com" From d9b75cedef53cc581c61a78d11f862e8540ed234 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Fri, 8 Dec 2023 15:07:41 +0100 Subject: [PATCH 095/133] point to testing Contributes to CURA-10831 --- conandata.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/conandata.yml b/conandata.yml index a28954bb3f..c4dd1ce6de 100644 --- a/conandata.yml +++ b/conandata.yml @@ -1,18 +1,18 @@ version: "5.7.0-alpha.0" requirements: - - "uranium/(latest)@ultimaker/latest" - - "curaengine/(latest)@ultimaker/latest" - - "cura_binary_data/(latest)@ultimaker/latest" - - "fdm_materials/(latest)@ultimaker/latest" + - "uranium/(latest)@ultimaker/testing" + - "curaengine/(latest)@ultimaker/testing" + - "cura_binary_data/(latest)@ultimaker/testing" + - "fdm_materials/(latest)@ultimaker/testing" - "curaengine_plugin_gradual_flow/(latest)@ultimaker/stable" - - "dulcificum/(latest)@ultimaker/latest" + - "dulcificum/(latest)@ultimaker/testing" - "pyarcus/5.3.0" - "pysavitar/5.3.0" - "pynest2d/5.3.0" - - "curaengine_grpc_definitions/(latest)@ultimaker/latest" + - "curaengine_grpc_definitions/(latest)@ultimaker/testing" requirements_internal: - - "fdm_materials/(latest)@internal/latest" - - "cura_private_data/(latest)@internal/latest" + - "fdm_materials/(latest)@internal/testing" + - "cura_private_data/(latest)@internal/testing" urls: default: cloud_api_root: "https://api.ultimaker.com" From 3da4fb2d263012612becba3b32289ef12141abb6 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 11 Dec 2023 09:13:36 +0100 Subject: [PATCH 096/133] Install pdb files Contribute to CURA-11443 --- conanfile.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conanfile.py b/conanfile.py index e9d06452f3..a3ca8f1c89 100644 --- a/conanfile.py +++ b/conanfile.py @@ -242,7 +242,7 @@ class CuraConan(ConanFile): self.output.warning(f"Source path for binary {binary['binary']} does not exist") continue - for bin in Path(src_path).glob(binary["binary"] + "*[.exe|.dll|.so|.dylib|.so.]*"): + for bin in Path(src_path).glob(binary["binary"] + "*[.exe|.dll|.so|.dylib|.so.|.pdb]*"): binaries.append((str(bin), binary["dst"])) for bin in Path(src_path).glob(binary["binary"]): binaries.append((str(bin), binary["dst"])) From ab480a29ce42d1d8481a5108f169a191b0707d52 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Mon, 11 Dec 2023 09:16:59 +0100 Subject: [PATCH 097/133] Use CuraEngine CURA-11443 Contribute to CURA-11443 --- conandata.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conandata.yml b/conandata.yml index c4dd1ce6de..7f542add2a 100644 --- a/conandata.yml +++ b/conandata.yml @@ -1,7 +1,7 @@ version: "5.7.0-alpha.0" requirements: - "uranium/(latest)@ultimaker/testing" - - "curaengine/(latest)@ultimaker/testing" + - "curaengine/(latest)@ultimaker/cura_11443" - "cura_binary_data/(latest)@ultimaker/testing" - "fdm_materials/(latest)@ultimaker/testing" - "curaengine_plugin_gradual_flow/(latest)@ultimaker/stable" From a19c667106fce8ab4e6f7c7f50bd16c709d2aa51 Mon Sep 17 00:00:00 2001 From: Saumya Jain <70144862+saumyaj3@users.noreply.github.com> Date: Mon, 11 Dec 2023 14:29:33 +0100 Subject: [PATCH 098/133] Update plugins/SimulationView/SimulationViewProxy.py simplified code Co-authored-by: Casper Lamboo --- plugins/SimulationView/SimulationViewProxy.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/SimulationView/SimulationViewProxy.py b/plugins/SimulationView/SimulationViewProxy.py index 8f83e9b403..e3d5ca13a7 100644 --- a/plugins/SimulationView/SimulationViewProxy.py +++ b/plugins/SimulationView/SimulationViewProxy.py @@ -64,9 +64,7 @@ class SimulationViewProxy(QObject): # We multiply the time with 100 to make it to ms from s.(Should be 1000 in real time). This scaling makes the simulation time 10x faster than the real time. simulationTimeOfpath =self._simulation_view.getSimulationTime()[0][self._simulation_view.getCurrentPath()] * 100 # Since the timer cannot process time less than 1 ms, we put a lower limit here - if simulationTimeOfpath < 1: - return 1 - return int(simulationTimeOfpath) + return int(max(1, simulationTimeOfpath)) @pyqtProperty(int, notify=currentPathChanged) def minimumPath(self): From ba0fb97d6373bd51c143a4ad7169885bf354c236 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 12 Dec 2023 10:01:59 +0100 Subject: [PATCH 099/133] Include threshold settings Contributes to CURA-11391 --- resources/definitions/fdmprinter.def.json | 82 +++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index b640fb5746..85785981d6 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -8305,6 +8305,88 @@ } } }, + "ppr": + { + "label": "Print Process Reporting", + "type": "category", + "icon": "DocumentFilled", + "description": "Reporting events that go out of set thresholds", + "enabled": false, + "children": + { + "ppr_enable": + { + "label": "Enable Print Process Reporting", + "description": "Enable print process reporting for setting threshold values for possible fault detection.", + "type": "bool", + "enabled": false, + "default_value": false, + "value": false, + "settable_per_mesh": false, + "settable_per_extruder": false + }, + "flow_warn_limit": + { + "label": "Flow Warning Detection Limit", + "description": "Limit on the flow warning for detection.", + "default_value": "15.0", + "enabled": "ppr_enable", + "unit": "%", + "type": "float", + "settable_per_extruder": true + }, + "flow_anomaly_limit": + { + "label": "Flow Anomaly Detection Limit", + "description": "Limit on flow anomaly for detection.", + "default_value": "25.0", + "enabled": "ppr_enable", + "unit": "%", + "type": "float", + "settable_per_extruder": true + }, + "print_temp_warn_limit": + { + "label": "Print temperature Warning Detection Limit", + "description": "Limit on Print temperature warning for detection.", + "unit": "\u00b0C", + "type": "float", + "default_value": "3.0", + "enabled": "ppr_enable", + "settable_per_extruder": true + }, + "print_temp_anomaly_limit": + { + "label": "Print temperature Anomaly Detection Limit", + "description": "Limit on Print Temperature anomaly for detection.", + "unit": "\u00b0C", + "type": "float", + "default_value": "7.0", + "enabled": "ppr_enable", + "settable_per_extruder": true + }, + "bv_temp_warn_limit": + { + "label": "Build Volume temperature Warning Detection Limit", + "description": "Limit on Build Volume Temperature warning for detection.", + "unit": "\u00b0C", + "type": "float", + "default_value": "7.5", + "enabled": "ppr_enable", + "settable_per_extruder": false + }, + "bv_temp_anomaly_limit": + { + "label": "Build Volume temperature Anomaly Detection Limit", + "description": "Limit on Build Volume temperature Anomaly for detection.", + "unit": "\u00b0C", + "type": "float", + "default_value": "10.0", + "enabled": "ppr_enable", + "settable_per_extruder": false + } + } + }, "command_line_settings": { "label": "Command Line Settings", From cc4627886b85f2e1ef94f3190350e812d591a303 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 12 Dec 2023 13:01:37 +0100 Subject: [PATCH 100/133] Name shortned for Cura settings CURA-11392 --- resources/definitions/fdmprinter.def.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/resources/definitions/fdmprinter.def.json b/resources/definitions/fdmprinter.def.json index 85785981d6..62143cf8f8 100644 --- a/resources/definitions/fdmprinter.def.json +++ b/resources/definitions/fdmprinter.def.json @@ -8327,7 +8327,7 @@ }, "flow_warn_limit": { - "label": "Flow Warning Detection Limit", + "label": "Flow Warning", "description": "Limit on the flow warning for detection.", "default_value": "15.0", "enabled": "ppr_enable", @@ -8337,7 +8337,7 @@ }, "flow_anomaly_limit": { - "label": "Flow Anomaly Detection Limit", + "label": "Flow Limit", "description": "Limit on flow anomaly for detection.", "default_value": "25.0", "enabled": "ppr_enable", @@ -8347,7 +8347,7 @@ }, "print_temp_warn_limit": { - "label": "Print temperature Warning Detection Limit", + "label": "Print temperature Warning", "description": "Limit on Print temperature warning for detection.", "unit": "\u00b0C", "type": "float", @@ -8357,7 +8357,7 @@ }, "print_temp_anomaly_limit": { - "label": "Print temperature Anomaly Detection Limit", + "label": "Print temperature Limit", "description": "Limit on Print Temperature anomaly for detection.", "unit": "\u00b0C", "type": "float", @@ -8367,7 +8367,7 @@ }, "bv_temp_warn_limit": { - "label": "Build Volume temperature Warning Detection Limit", + "label": "Build Volume temperature Warning", "description": "Limit on Build Volume Temperature warning for detection.", "unit": "\u00b0C", "type": "float", @@ -8377,7 +8377,7 @@ }, "bv_temp_anomaly_limit": { - "label": "Build Volume temperature Anomaly Detection Limit", + "label": "Build Volume temperature Limit", "description": "Limit on Build Volume temperature Anomaly for detection.", "unit": "\u00b0C", "type": "float", From 189a22aa4fc9a5414424760ccab87a0418cf99d7 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 12 Dec 2023 14:56:06 +0100 Subject: [PATCH 101/133] refactoring of code for easier access and avoid hanging issues CURA-7647 --- plugins/SimulationView/SimulationView.py | 13 +++++++++---- plugins/SimulationView/SimulationViewProxy.py | 7 ++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 6874b27625..186036a581 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -402,10 +402,13 @@ class SimulationView(CuraView): def getMaxFeedrate(self) -> float: return self._max_feedrate - def getSimulationTime(self) -> list: - if len(self._lengths_of_polyline) > 0 and len(self._lengths_of_polyline) == len(self._current_feedrates): - return self._lengths_of_polyline[self._current_layer_num] / self._current_feedrates[self._current_layer_num] - return numpy.zeros(0) + def getSimulationTime(self, currentIndex) -> list: + try: + return self._lengths_of_polyline[self._current_layer_num][currentIndex] / self._current_feedrates[self._current_layer_num][currentIndex] + except: + # In case of change in layers, currentIndex comes one more than the items in the lengths_of_polyline + # We give 1 second time for layer change + return 1 def getMinThickness(self) -> float: if abs(self._min_thickness - sys.float_info.max) < 10: # Some lenience due to floating point rounding. @@ -535,6 +538,8 @@ class SimulationView(CuraView): visible_feedrates = numpy.take(polyline.lineFeedrates, visible_indices) visible_feedrates_with_extrusion = numpy.take(polyline.lineFeedrates, visible_indicies_with_extrusion) self._current_feedrates[layer_index] = polyline.lineFeedrates + # if len(polyline.lineLengths) > 0 and len(polyline.lineLengths) == len(polyline.lineFeedrates): + # self._simulation_time[layer_index] = polyline.lineLengths / polyline.lineFeedrates visible_linewidths = numpy.take(polyline.lineWidths, visible_indices) visible_linewidths_with_extrusion = numpy.take(polyline.lineWidths, visible_indicies_with_extrusion) visible_thicknesses = numpy.take(polyline.lineThicknesses, visible_indices) diff --git a/plugins/SimulationView/SimulationViewProxy.py b/plugins/SimulationView/SimulationViewProxy.py index e3d5ca13a7..61366fccbb 100644 --- a/plugins/SimulationView/SimulationViewProxy.py +++ b/plugins/SimulationView/SimulationViewProxy.py @@ -57,12 +57,9 @@ class SimulationViewProxy(QObject): @pyqtProperty(int, notify=currentPathChanged) def simulationTime(self): - # This if is activated when there is a layer change - if numpy.all(self._simulation_view.getSimulationTime()==0) or len(self._simulation_view.getSimulationTime()) <= self._simulation_view.getCurrentPath(): - return 100 - # Extracts the currents paths simulation time (in seconds) from the dict of simulation time of the current layer. + # Extracts the currents paths simulation time (in seconds) for the current path from the dict of simulation time of the current layer. # We multiply the time with 100 to make it to ms from s.(Should be 1000 in real time). This scaling makes the simulation time 10x faster than the real time. - simulationTimeOfpath =self._simulation_view.getSimulationTime()[0][self._simulation_view.getCurrentPath()] * 100 + simulationTimeOfpath = self._simulation_view.getSimulationTime(self._simulation_view.getCurrentPath()) * 100 # Since the timer cannot process time less than 1 ms, we put a lower limit here return int(max(1, simulationTimeOfpath)) From 3c0b9a65db5e204cecc0dcdb43d8dd59d3b1d4f0 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 12 Dec 2023 14:59:41 +0100 Subject: [PATCH 102/133] removing commented code CURA-7647 --- plugins/SimulationView/SimulationView.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 186036a581..cbf5e571fc 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -538,8 +538,6 @@ class SimulationView(CuraView): visible_feedrates = numpy.take(polyline.lineFeedrates, visible_indices) visible_feedrates_with_extrusion = numpy.take(polyline.lineFeedrates, visible_indicies_with_extrusion) self._current_feedrates[layer_index] = polyline.lineFeedrates - # if len(polyline.lineLengths) > 0 and len(polyline.lineLengths) == len(polyline.lineFeedrates): - # self._simulation_time[layer_index] = polyline.lineLengths / polyline.lineFeedrates visible_linewidths = numpy.take(polyline.lineWidths, visible_indices) visible_linewidths_with_extrusion = numpy.take(polyline.lineWidths, visible_indicies_with_extrusion) visible_thicknesses = numpy.take(polyline.lineThicknesses, visible_indices) From a9aba2df748977554a454ce3e7d7b1667d152e8d Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 12 Dec 2023 16:06:22 +0100 Subject: [PATCH 103/133] maintenence. CURA-7647 --- plugins/SimulationView/SimulationView.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index cbf5e571fc..a659a6de97 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -402,13 +402,14 @@ class SimulationView(CuraView): def getMaxFeedrate(self) -> float: return self._max_feedrate - def getSimulationTime(self, currentIndex) -> list: + def getSimulationTime(self, currentIndex) -> float: try: - return self._lengths_of_polyline[self._current_layer_num][currentIndex] / self._current_feedrates[self._current_layer_num][currentIndex] + return (self._lengths_of_polyline[self._current_layer_num][currentIndex] / self._current_feedrates[self._current_layer_num][currentIndex])[0] + except: # In case of change in layers, currentIndex comes one more than the items in the lengths_of_polyline # We give 1 second time for layer change - return 1 + return 1.0 def getMinThickness(self) -> float: if abs(self._min_thickness - sys.float_info.max) < 10: # Some lenience due to floating point rounding. From 84565b7daa03613087b2544b78fc944e249eae3d Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 12 Dec 2023 16:53:34 +0100 Subject: [PATCH 104/133] removal of magic number CURA-7647 --- plugins/SimulationView/SimulationViewProxy.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/plugins/SimulationView/SimulationViewProxy.py b/plugins/SimulationView/SimulationViewProxy.py index 61366fccbb..576281874c 100644 --- a/plugins/SimulationView/SimulationViewProxy.py +++ b/plugins/SimulationView/SimulationViewProxy.py @@ -12,6 +12,11 @@ if TYPE_CHECKING: class SimulationViewProxy(QObject): + + S_TO_MS = 1000 + SPEED_OF_SIMULATION = 10 + FACTOR = S_TO_MS/SPEED_OF_SIMULATION + def __init__(self, simulation_view: "SimulationView", parent=None) -> None: super().__init__(parent) self._simulation_view = simulation_view @@ -59,7 +64,7 @@ class SimulationViewProxy(QObject): def simulationTime(self): # Extracts the currents paths simulation time (in seconds) for the current path from the dict of simulation time of the current layer. # We multiply the time with 100 to make it to ms from s.(Should be 1000 in real time). This scaling makes the simulation time 10x faster than the real time. - simulationTimeOfpath = self._simulation_view.getSimulationTime(self._simulation_view.getCurrentPath()) * 100 + simulationTimeOfpath = self._simulation_view.getSimulationTime(self._simulation_view.getCurrentPath()) * SimulationViewProxy.FACTOR # Since the timer cannot process time less than 1 ms, we put a lower limit here return int(max(1, simulationTimeOfpath)) From 3472ec26a10c330cd6aea040ef70e0d6db94434d Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Tue, 12 Dec 2023 17:19:28 +0100 Subject: [PATCH 105/133] Fix snapshot for makerbot CURA-11442 --- cura/Snapshot.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/Snapshot.py b/cura/Snapshot.py index 40c74c9693..f94b3ff42e 100644 --- a/cura/Snapshot.py +++ b/cura/Snapshot.py @@ -49,7 +49,7 @@ class Snapshot: """ if node is None: - root = Application.getInstance().getController().getScene().getRoot() + node = Application.getInstance().getController().getScene().getRoot() # the direction the camera is looking at to create the isometric view iso_view_dir = Vector(-1, -1, -1).normalized() From 5125c7d33a6dd1f36374d084d8100e22c9c3f99c Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Wed, 13 Dec 2023 17:00:02 +0100 Subject: [PATCH 106/133] Don't package system managed openssl This should fall back on the Conan package ssl version which is in the root of the AppDir Contributes to CURA-11080 --- packaging/AppImage-builder/AppImageBuilder.yml.jinja | 1 + 1 file changed, 1 insertion(+) diff --git a/packaging/AppImage-builder/AppImageBuilder.yml.jinja b/packaging/AppImage-builder/AppImageBuilder.yml.jinja index 446c0dacc0..9090a5f209 100644 --- a/packaging/AppImage-builder/AppImageBuilder.yml.jinja +++ b/packaging/AppImage-builder/AppImageBuilder.yml.jinja @@ -38,6 +38,7 @@ AppDir: - usr/share/doc/*/changelog.* - usr/share/doc/*/NEWS.* - usr/share/doc/*/TODO.* + - usr/lib/x86_64-linux-gnu/libssl.so* runtime: env: APPDIR_LIBRARY_PATH: "$APPDIR:$APPDIR/runtime/compat/:$APPDIR/usr/lib/x86_64-linux-gnu:$APPDIR/lib/x86_64-linux-gnu:$APPDIR/usr/lib:$APPDIR/usr/lib/x86_64-linux-gnu/gdk-pixbuf-2.0/2.10.0/loaders" From aebd5f32c5bb82a39d9d2f7a6ab070761e8e7e28 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Fri, 15 Dec 2023 10:08:16 +0100 Subject: [PATCH 107/133] Update Sentry to `1.39.1` Contributes to CURA-11464 --- requirements.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/requirements.txt b/requirements.txt index 76339c884f..916886e369 100644 --- a/requirements.txt +++ b/requirements.txt @@ -171,9 +171,9 @@ scipy==1.9.1 \ trimesh==3.9.36 \ --hash=sha256:f01e8edab14d1999700c980c21a1546f37417216ad915a53be649d263130181e \ --hash=sha256:8ac8bea693b3ee119f11b022fc9b9481c9f1af06cb38bc859bf5d16bbbe49b23 -sentry-sdk==0.13.5 \ - --hash=sha256:05285942901d38c7ce2498aba50d8e87b361fc603281a5902dda98f3f8c5e145 \ - --hash=sha256:c6b919623e488134a728f16326c6f0bcdab7e3f59e7f4c472a90eea4d6d8fe82 +sentry-sdk==1.39.1 \ + --hash=sha256:320a55cdf9da9097a0bead239c35b7e61f53660ef9878861824fd6d9b2eaf3b5 \ + --hash=sha256:81b5b9ffdd1a374e9eb0c053b5d2012155db9cbe76393a8585677b753bd5fdc1 mypy==0.931 \ --hash=sha256:0038b21890867793581e4cb0d810829f5fd4441aa75796b53033af3aa30430ce \ --hash=sha256:1171f2e0859cfff2d366da2c7092b06130f232c636a3f7301e3feb8b41f6377d \ @@ -209,9 +209,9 @@ idna==2.8 \ attrs==21.2.0 \ --hash=sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1 \ --hash=sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb -requests==2.22.0 \ - --hash=sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4 \ - --hash=sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31 +requests==2.31.0 \ + --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 \ + --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f # twisted Twisted==21.2.0 \ --hash=sha256:77544a8945cf69b98d2946689bbe0c75de7d145cdf11f391dd487eae8fc95a12 \ @@ -372,9 +372,9 @@ cffi==1.15.0 \ --hash=sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc \ --hash=sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997 \ --hash=sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796 -urllib3==1.25.9 \ - --hash=sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527 \ - --hash=sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115 +urllib3==2.1.0 \ + --hash=sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54 \ + --hash=sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3 mypy-extensions==0.4.3 \ --hash=sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d \ --hash=sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8 From 139c46fc9dbbb19f7128783369abd0f68e0b36ef Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Fri, 15 Dec 2023 10:23:42 +0100 Subject: [PATCH 108/133] Use generic job name --- .github/workflows/linux.yml | 2 +- .github/workflows/macos.yml | 2 +- .github/workflows/windows.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/linux.yml b/.github/workflows/linux.yml index 2ad8f90bfe..f88b77a022 100644 --- a/.github/workflows/linux.yml +++ b/.github/workflows/linux.yml @@ -45,7 +45,7 @@ env: STAGING: ${{ inputs.staging || false }} jobs: - windows-installer: + installer: uses: ultimaker/cura-workflows/.github/workflows/cura-installer-linux.yml@main with: cura_conan_version: ${{ inputs.cura_conan_version }} diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index d080fcc710..e909b9f839 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -49,7 +49,7 @@ env: STAGING: ${{ inputs.staging || false }} jobs: - windows-installer: + installer: uses: ultimaker/cura-workflows/.github/workflows/cura-installer-macos.yml@main with: cura_conan_version: ${{ inputs.cura_conan_version }} diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 0007936969..151935c3f3 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -45,7 +45,7 @@ env: STAGING: ${{ inputs.staging || false }} jobs: - windows-installer: + installer: uses: ultimaker/cura-workflows/.github/workflows/cura-installer-windows.yml@main with: cura_conan_version: ${{ inputs.cura_conan_version }} From 64cb060bd1c2ec23d498c81ea50a55957dfad3e6 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Fri, 15 Dec 2023 10:38:33 +0100 Subject: [PATCH 109/133] Revert "Update Sentry to `1.39.1`" This reverts commit aebd5f32c5bb82a39d9d2f7a6ab070761e8e7e28. --- requirements.txt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/requirements.txt b/requirements.txt index 916886e369..76339c884f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -171,9 +171,9 @@ scipy==1.9.1 \ trimesh==3.9.36 \ --hash=sha256:f01e8edab14d1999700c980c21a1546f37417216ad915a53be649d263130181e \ --hash=sha256:8ac8bea693b3ee119f11b022fc9b9481c9f1af06cb38bc859bf5d16bbbe49b23 -sentry-sdk==1.39.1 \ - --hash=sha256:320a55cdf9da9097a0bead239c35b7e61f53660ef9878861824fd6d9b2eaf3b5 \ - --hash=sha256:81b5b9ffdd1a374e9eb0c053b5d2012155db9cbe76393a8585677b753bd5fdc1 +sentry-sdk==0.13.5 \ + --hash=sha256:05285942901d38c7ce2498aba50d8e87b361fc603281a5902dda98f3f8c5e145 \ + --hash=sha256:c6b919623e488134a728f16326c6f0bcdab7e3f59e7f4c472a90eea4d6d8fe82 mypy==0.931 \ --hash=sha256:0038b21890867793581e4cb0d810829f5fd4441aa75796b53033af3aa30430ce \ --hash=sha256:1171f2e0859cfff2d366da2c7092b06130f232c636a3f7301e3feb8b41f6377d \ @@ -209,9 +209,9 @@ idna==2.8 \ attrs==21.2.0 \ --hash=sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1 \ --hash=sha256:ef6aaac3ca6cd92904cdd0d83f629a15f18053ec84e6432106f7a4d04ae4f5fb -requests==2.31.0 \ - --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 \ - --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f +requests==2.22.0 \ + --hash=sha256:11e007a8a2aa0323f5a921e9e6a2d7e4e67d9877e85773fba9ba6419025cbeb4 \ + --hash=sha256:9cf5292fcd0f598c671cfc1e0d7d1a7f13bb8085e9a590f48c010551dc6c4b31 # twisted Twisted==21.2.0 \ --hash=sha256:77544a8945cf69b98d2946689bbe0c75de7d145cdf11f391dd487eae8fc95a12 \ @@ -372,9 +372,9 @@ cffi==1.15.0 \ --hash=sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc \ --hash=sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997 \ --hash=sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796 -urllib3==2.1.0 \ - --hash=sha256:df7aa8afb0148fa78488e7899b2c59b5f4ffcfa82e6c54ccb9dd37c1d7b52d54 \ - --hash=sha256:55901e917a5896a349ff771be919f8bd99aff50b79fe58fec595eb37bbc56bb3 +urllib3==1.25.9 \ + --hash=sha256:3018294ebefce6572a474f0604c2021e33b3fd8006ecd11d62107a5d2a963527 \ + --hash=sha256:88206b0eb87e6d677d424843ac5209e3fb9d0190d0ee169599165ec25e9d9115 mypy-extensions==0.4.3 \ --hash=sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d \ --hash=sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8 From a071795f9e5415f575cd7e8e86e3347faf8e6a1a Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Fri, 15 Dec 2023 12:43:54 +0100 Subject: [PATCH 110/133] Fix monitor page CURA-11426 --- plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py index aed38a3949..9a11bb886c 100644 --- a/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py +++ b/plugins/UM3NetworkPrinting/src/Cloud/CloudOutputDevice.py @@ -331,7 +331,7 @@ class CloudOutputDevice(UltimakerNetworkedPrinterOutputDevice): return False [printer, *_] = self._printers - return printer.pinterType in ("ultimaker_methodx", "ultimaker_methodxl") + return printer.name in ("ultimaker_methodx", "ultimaker_methodxl") @pyqtProperty(bool, notify=_cloudClusterPrintersChanged) def supportsPrintJobActions(self) -> bool: From a6218c3f5432a6d08d0ff852f67892119b317a7d Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Fri, 15 Dec 2023 18:08:46 +0100 Subject: [PATCH 111/133] Use cura sentry id and version Contribute to CURA-11482 --- conandata.yml | 2 +- plugins/CuraEngineBackend/Cura.proto | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/conandata.yml b/conandata.yml index a0a5a204ca..dcf883c630 100644 --- a/conandata.yml +++ b/conandata.yml @@ -1,7 +1,7 @@ version: "5.7.0-alpha.0" requirements: - "uranium/(latest)@ultimaker/testing" - - "curaengine/(latest)@ultimaker/testing" + - "curaengine/(latest)@ultimaker/cura_11482" - "cura_binary_data/(latest)@ultimaker/testing" - "fdm_materials/(latest)@ultimaker/testing" - "curaengine_plugin_gradual_flow/(latest)@ultimaker/stable" diff --git a/plugins/CuraEngineBackend/Cura.proto b/plugins/CuraEngineBackend/Cura.proto index 54c322fa0a..9593b83528 100644 --- a/plugins/CuraEngineBackend/Cura.proto +++ b/plugins/CuraEngineBackend/Cura.proto @@ -33,6 +33,8 @@ message Slice repeated Extruder extruders = 3; // The settings sent to each extruder object repeated SettingExtruder limit_to_extruder = 4; // From which stack the setting would inherit if not defined per object repeated EnginePlugin engine_plugins = 5; + string sentry_id = 6; // The anonymized Sentry user id that requested the slice + string cura_version = 7; // The version of Cura that requested the slice } message Extruder From 5744371f380e8c7baa47c2ab05bea9157c5d7e58 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Sun, 17 Dec 2023 17:44:30 +0100 Subject: [PATCH 112/133] Add anonymous user tracking to slice message User tracking has been added to the 'slice_message' method in the 'StartSliceJob.py' file. A unique, anonymous UUID is generated for each user, stripping away identifiable data with a bitmask operation. The user's Cura version is also included in the message. This facilitates more robust analysis of crash reports and user behaviors. Contributes to CURA-11482 --- plugins/CuraEngineBackend/StartSliceJob.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/plugins/CuraEngineBackend/StartSliceJob.py b/plugins/CuraEngineBackend/StartSliceJob.py index a12e9e655d..fe7137150b 100644 --- a/plugins/CuraEngineBackend/StartSliceJob.py +++ b/plugins/CuraEngineBackend/StartSliceJob.py @@ -1,5 +1,7 @@ # Copyright (c) 2023 UltiMaker # Cura is released under the terms of the LGPLv3 or higher. +import uuid + import os import numpy @@ -30,6 +32,7 @@ from cura.CuraApplication import CuraApplication from cura.Scene.CuraSceneNode import CuraSceneNode from cura.OneAtATimeIterator import OneAtATimeIterator from cura.Settings.ExtruderManager import ExtruderManager +from cura.CuraVersion import CuraVersion NON_PRINTING_MESH_SETTINGS = ["anti_overhang_mesh", "infill_mesh", "cutting_mesh"] @@ -332,6 +335,11 @@ class StartSliceJob(Job): self._buildGlobalSettingsMessage(stack) self._buildGlobalInheritsStackMessage(stack) + user_id = uuid.getnode() # On all of Cura's supported platforms, this returns the MAC address which is pseudonymical information (!= anonymous). + user_id %= 2 ** 16 # So to make it anonymous, apply a bitmask selecting only the last 16 bits. This prevents it from being traceable to a specific user but still gives somewhat of an idea of whether it's just the same user hitting the same crash over and over again, or if it's widespread. + self._slice_message.sentry_id = "{user_id}" + self._slice_message.cura_version = CuraVersion + # Build messages for extruder stacks for extruder_stack in global_stack.extruderList: self._buildExtruderMessage(extruder_stack) From 82a3308d26a94ed834b5247dc2bfe945f68dee06 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Mon, 18 Dec 2023 17:03:52 +0100 Subject: [PATCH 113/133] for merging to main CURA-11482 --- conandata.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conandata.yml b/conandata.yml index dcf883c630..a0a5a204ca 100644 --- a/conandata.yml +++ b/conandata.yml @@ -1,7 +1,7 @@ version: "5.7.0-alpha.0" requirements: - "uranium/(latest)@ultimaker/testing" - - "curaengine/(latest)@ultimaker/cura_11482" + - "curaengine/(latest)@ultimaker/testing" - "cura_binary_data/(latest)@ultimaker/testing" - "fdm_materials/(latest)@ultimaker/testing" - "curaengine_plugin_gradual_flow/(latest)@ultimaker/stable" From cfec5e0cc112181d4db4af13ed6a0f8ec3047669 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 19 Dec 2023 10:12:56 +0100 Subject: [PATCH 114/133] Proof of concept for simulation Co-authored-by: Casper Lamboo CURA-7647 --- cura/LayerPolygon.py | 6 +- plugins/SimulationView/SimulationPass.py | 32 +++-- plugins/SimulationView/SimulationView.py | 124 +++++++++++++----- .../SimulationViewMainComponent.qml | 47 +------ plugins/SimulationView/SimulationViewProxy.py | 23 +--- 5 files changed, 128 insertions(+), 104 deletions(-) diff --git a/cura/LayerPolygon.py b/cura/LayerPolygon.py index e5fd307dc9..e772a8b78e 100644 --- a/cura/LayerPolygon.py +++ b/cura/LayerPolygon.py @@ -67,7 +67,7 @@ class LayerPolygon: # Buffering the colors shouldn't be necessary as it is not # re-used and can save a lot of memory usage. self._color_map = LayerPolygon.getColorMap() - self._colors = self._color_map[self._types] # type: numpy.ndarray + self._colors: numpy.ndarray = self._color_map[self._types] # When type is used as index returns true if type == LayerPolygon.InfillType # or type == LayerPolygon.SkinType @@ -75,8 +75,8 @@ class LayerPolygon: # Should be generated in better way, not hardcoded. self._is_infill_or_skin_type_map = numpy.array([0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0], dtype=bool) - self._build_cache_line_mesh_mask = None # type: Optional[numpy.ndarray] - self._build_cache_needed_points = None # type: Optional[numpy.ndarray] + self._build_cache_line_mesh_mask: Optional[numpy.ndarray] = None + self._build_cache_needed_points: Optional[numpy.ndarray] = None def buildCache(self) -> None: # For the line mesh we do not draw Infill or Jumps. Therefore those lines are filtered out. diff --git a/plugins/SimulationView/SimulationPass.py b/plugins/SimulationView/SimulationPass.py index 1294b37db4..3294f4b1e6 100644 --- a/plugins/SimulationView/SimulationPass.py +++ b/plugins/SimulationView/SimulationPass.py @@ -35,7 +35,7 @@ class SimulationPass(RenderPass): self._nozzle_shader = None self._disabled_shader = None self._old_current_layer = 0 - self._old_current_path = 0 + self._old_current_path: float = 0.0 self._switching_layers = True # Tracking whether the user is moving across layers (True) or across paths (False). If false, lower layers render as shadowy. self._gl = OpenGL.getInstance().getBindingsObject() self._scene = Application.getInstance().getController().getScene() @@ -139,7 +139,7 @@ class SimulationPass(RenderPass): continue # Render all layers below a certain number as line mesh instead of vertices. - if self._layer_view._current_layer_num > -1 and ((not self._layer_view._only_show_top_layers) or (not self._layer_view.getCompatibilityMode())): + if self._layer_view.getCurrentLayer() > -1 and ((not self._layer_view._only_show_top_layers) or (not self._layer_view.getCompatibilityMode())): start = 0 end = 0 element_counts = layer_data.getElementCounts() @@ -147,7 +147,7 @@ class SimulationPass(RenderPass): # In the current layer, we show just the indicated paths if layer == self._layer_view._current_layer_num: # We look for the position of the head, searching the point of the current path - index = self._layer_view._current_path_num + index = int(self._layer_view.getCurrentPath()) offset = 0 for polygon in layer_data.getLayer(layer).polygons: # The size indicates all values in the two-dimension array, and the second dimension is @@ -157,23 +157,33 @@ class SimulationPass(RenderPass): offset = 1 # This is to avoid the first point when there is more than one polygon, since has the same value as the last point in the previous polygon continue # The head position is calculated and translated - head_position = Vector(polygon.data[index+offset][0], polygon.data[index+offset][1], polygon.data[index+offset][2]) + node.getWorldPosition() + ratio = self._layer_view.getCurrentPath() - index + pos_a = Vector(polygon.data[index + offset][0], polygon.data[index + offset][1], + polygon.data[index + offset][2]) + if ratio > 0.0001: + pos_b = Vector(polygon.data[index + offset + 1][0], + polygon.data[index + offset + 1][1], + polygon.data[index + offset + 1][2]) + vec = pos_a * (1.0 - ratio) + pos_b * ratio + head_position = vec + node.getWorldPosition() + else: + head_position = pos_a + node.getWorldPosition() break break - if self._layer_view._minimum_layer_num > layer: + if self._layer_view.getMinimumLayer() > layer: start += element_counts[layer] end += element_counts[layer] # Calculate the range of paths in the last layer current_layer_start = end - current_layer_end = end + self._layer_view._current_path_num * 2 # Because each point is used twice + current_layer_end = end + int( self._layer_view.getCurrentPath()) * 2 # Because each point is used twice # This uses glDrawRangeElements internally to only draw a certain range of lines. # All the layers but the current selected layer are rendered first - if self._old_current_path != self._layer_view._current_path_num: + if self._old_current_path != self._layer_view.getCurrentPath(): self._current_shader = self._layer_shadow_shader self._switching_layers = False - if not self._layer_view.isSimulationRunning() and self._old_current_layer != self._layer_view._current_layer_num: + if not self._layer_view.isSimulationRunning() and self._old_current_layer != self._layer_view.getCurrentLayer(): self._current_shader = self._layer_shader self._switching_layers = True @@ -193,8 +203,8 @@ class SimulationPass(RenderPass): current_layer_batch.addItem(node.getWorldTransformation(), layer_data) current_layer_batch.render(self._scene.getActiveCamera()) - self._old_current_layer = self._layer_view._current_layer_num - self._old_current_path = self._layer_view._current_path_num + self._old_current_layer = self._layer_view.getCurrentLayer() + self._old_current_path = self._layer_view.getCurrentPath() # Create a new batch that is not range-limited batch = RenderBatch(self._layer_shader, type = RenderBatch.RenderType.Solid) @@ -230,4 +240,4 @@ class SimulationPass(RenderPass): if changed_object.callDecoration("getLayerData"): # Any layer data has changed. self._switching_layers = True self._old_current_layer = 0 - self._old_current_path = 0 + self._old_current_path = 0.0 diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index a659a6de97..64ec0dfc1b 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -40,7 +40,7 @@ from .SimulationViewProxy import SimulationViewProxy import numpy import os.path -from typing import Optional, TYPE_CHECKING, List, cast +from typing import Optional, TYPE_CHECKING, List, Tuple, cast if TYPE_CHECKING: from UM.Scene.SceneNode import SceneNode @@ -74,21 +74,20 @@ class SimulationView(CuraView): self._old_max_layers = 0 self._max_paths = 0 - self._current_path_num = 0 + self._current_path_num: float = 0.0 + self._current_time = 0.0 self._minimum_path_num = 0 self.currentLayerNumChanged.connect(self._onCurrentLayerNumChanged) - self._current_feedrates = {} - self._lengths_of_polyline ={} self._busy = False self._simulation_running = False - self._ghost_shader = None # type: Optional["ShaderProgram"] - self._layer_pass = None # type: Optional[SimulationPass] - self._composite_pass = None # type: Optional[CompositePass] - self._old_layer_bindings = None # type: Optional[List[str]] - self._simulationview_composite_shader = None # type: Optional["ShaderProgram"] - self._old_composite_shader = None # type: Optional["ShaderProgram"] + self._ghost_shader: Optional["ShaderProgram"] = None + self._layer_pass: Optional[SimulationPass] = None + self._composite_pass: Optional[CompositePass] = None + self._old_layer_bindings: Optional[List[str]] = None + self._simulationview_composite_shader: Optional["ShaderProgram"] = None + self._old_composite_shader: Optional["ShaderProgram"] = None self._max_feedrate = sys.float_info.min self._min_feedrate = sys.float_info.max @@ -99,13 +98,13 @@ class SimulationView(CuraView): self._min_flow_rate = sys.float_info.max self._max_flow_rate = sys.float_info.min - self._global_container_stack = None # type: Optional[ContainerStack] + self._global_container_stack: Optional[ContainerStack] = None self._proxy = None self._resetSettings() self._legend_items = None self._show_travel_moves = False - self._nozzle_node = None # type: Optional[NozzleNode] + self._nozzle_node: Optional[NozzleNode] = None Application.getInstance().getPreferences().addPreference("view/top_layer_count", 5) Application.getInstance().getPreferences().addPreference("view/only_show_top_layers", False) @@ -127,13 +126,12 @@ class SimulationView(CuraView): self._only_show_top_layers = bool(Application.getInstance().getPreferences().getValue("view/only_show_top_layers")) self._compatibility_mode = self._evaluateCompatibilityMode() - self._slice_first_warning_message = Message(catalog.i18nc("@info:status", - "Nothing is shown because you need to slice first."), - title = catalog.i18nc("@info:title", "No layers to show"), - option_text = catalog.i18nc("@info:option_text", - "Do not show this message again"), - option_state = False, - message_type = Message.MessageType.WARNING) + self._slice_first_warning_message = Message(catalog.i18nc("@info:status", "Nothing is shown because you need to slice first."), + title=catalog.i18nc("@info:title", "No layers to show"), + option_text=catalog.i18nc("@info:option_text", + "Do not show this message again"), + option_state=False, + message_type=Message.MessageType.WARNING) self._slice_first_warning_message.optionToggled.connect(self._onDontAskMeAgain) CuraApplication.getInstance().getPreferences().addPreference(self._no_layers_warning_preference, True) @@ -189,9 +187,82 @@ class SimulationView(CuraView): def getMaxLayers(self) -> int: return self._max_layers - def getCurrentPath(self) -> int: + def getCurrentPath(self) -> float: return self._current_path_num + def setTime(self, time: float) -> None: + self._current_time = time + + left_i = 0 + right_i = self._max_paths - 1 + + total_duration, cumulative_line_duration = self.cumulativeLineDuration() + + # make an educated guess about where to start + i = int(right_i * max(0.0, min(1.0, self._current_time / total_duration))) + + # binary search for the correct path + while left_i < right_i: + if cumulative_line_duration[i] <= self._current_time: + left_i = i + 1 + else: + right_i = i + i = int((left_i + right_i) / 2) + + left_value = cumulative_line_duration[i - 1] if i > 0 else 0.0 + right_value = cumulative_line_duration[i] + + assert (left_value <= self._current_time <= right_value) + + fractional_value = (self._current_time - left_value) / (right_value - left_value) + + self.setPath(i + fractional_value) + + def advanceTime(self, time_increase: float) -> bool: + """ + Advance the time by the given amount. + + :param time_increase: The amount of time to advance (in seconds). + :return: True if the time was advanced, False if the end of the simulation was reached. + """ + total_duration, cumulative_line_duration = self.cumulativeLineDuration() + + # time ratio + time_increase = time_increase + + if self._current_time + time_increase > total_duration: + # If we have reached the end of the simulation, go to the next layer. + if self.getCurrentLayer() == self.getMaxLayers(): + # If we are already at the last layer, go to the first layer. + self.setTime(total_duration) + return False + + # advance to the next layer, and reset the time + self.setLayer(self.getCurrentLayer() + 1) + self.setTime(0.0) + else: + self.setTime(self._current_time + time_increase) + return True + + def cumulativeLineDuration(self) -> Tuple[float, List[float]]: + # TODO: cache the total duration and cumulative line duration at each layer change event + cumulative_line_duration = [] + total_duration = 0.0 + for polyline in self.getLayerData().polygons: + for line_duration in list((polyline.lineLengths / polyline.lineFeedrates)[0]): + total_duration += line_duration + cumulative_line_duration.append(total_duration) + return total_duration, cumulative_line_duration + + def getLayerData(self) -> Optional["LayerData"]: + scene = self.getController().getScene() + for node in DepthFirstIterator(scene.getRoot()): # type: ignore + layer_data = node.callDecoration("getLayerData") + if not layer_data: + continue + return layer_data.getLayer(self.getCurrentLayer()) + return None + def getMinimumPath(self) -> int: return self._minimum_path_num @@ -279,7 +350,7 @@ class SimulationView(CuraView): self._startUpdateTopLayers() self.currentLayerNumChanged.emit() - def setPath(self, value: int) -> None: + def setPath(self, value: float) -> None: """ Set the upper end of the range of visible paths on the current layer. @@ -402,15 +473,6 @@ class SimulationView(CuraView): def getMaxFeedrate(self) -> float: return self._max_feedrate - def getSimulationTime(self, currentIndex) -> float: - try: - return (self._lengths_of_polyline[self._current_layer_num][currentIndex] / self._current_feedrates[self._current_layer_num][currentIndex])[0] - - except: - # In case of change in layers, currentIndex comes one more than the items in the lengths_of_polyline - # We give 1 second time for layer change - return 1.0 - def getMinThickness(self) -> float: if abs(self._min_thickness - sys.float_info.max) < 10: # Some lenience due to floating point rounding. return 0.0 # If it's still max-float, there are no measurements. Use 0 then. @@ -535,10 +597,8 @@ class SimulationView(CuraView): visible_indicies_with_extrusion = numpy.where(numpy.isin(polyline.types, visible_line_types_with_extrusion))[0] if visible_indices.size == 0: # No items to take maximum or minimum of. continue - self._lengths_of_polyline[layer_index] = polyline.lineLengths visible_feedrates = numpy.take(polyline.lineFeedrates, visible_indices) visible_feedrates_with_extrusion = numpy.take(polyline.lineFeedrates, visible_indicies_with_extrusion) - self._current_feedrates[layer_index] = polyline.lineFeedrates visible_linewidths = numpy.take(polyline.lineWidths, visible_indices) visible_linewidths_with_extrusion = numpy.take(polyline.lineWidths, visible_indicies_with_extrusion) visible_thicknesses = numpy.take(polyline.lineThicknesses, visible_indices) diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 216095c15c..23cbf8c611 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -136,54 +136,19 @@ Item Timer { id: simulationTimer - interval: UM.SimulationView.simulationTime + interval: 1000 / 60 running: false repeat: true onTriggered: { - var currentPath = UM.SimulationView.currentPath - var numPaths = UM.SimulationView.numPaths - var currentLayer = UM.SimulationView.currentLayer - var numLayers = UM.SimulationView.numLayers - - // When the user plays the simulation, if the path slider is at the end of this layer, we start - // the simulation at the beginning of the current layer. - if (!isSimulationPlaying) - { - if (currentPath >= numPaths) - { - UM.SimulationView.setCurrentPath(0) - } - else - { - UM.SimulationView.setCurrentPath(currentPath + 1) - } - } - // If the simulation is already playing and we reach the end of a layer, then it automatically - // starts at the beginning of the next layer. - else - { - if (currentPath >= numPaths) - { - // At the end of the model, the simulation stops - if (currentLayer >= numLayers) - { - playButton.pauseSimulation() - } - else - { - UM.SimulationView.setCurrentLayer(currentLayer + 1) - UM.SimulationView.setCurrentPath(0) - } - } - else - { - UM.SimulationView.setCurrentPath(currentPath + 1) - } + // divide by 1000 to accont for ms to s conversion + const advance_time = simulationTimer.interval / 1000.0; + if (!UM.SimulationView.advanceTime(advance_time)) { + playButton.pauseSimulation(); } // The status must be set here instead of in the resumeSimulation function otherwise it won't work // correctly, because part of the logic is in this trigger function. - isSimulationPlaying = true + isSimulationPlaying = true; } } diff --git a/plugins/SimulationView/SimulationViewProxy.py b/plugins/SimulationView/SimulationViewProxy.py index 576281874c..bf449a99d1 100644 --- a/plugins/SimulationView/SimulationViewProxy.py +++ b/plugins/SimulationView/SimulationViewProxy.py @@ -2,7 +2,6 @@ # Cura is released under the terms of the LGPLv3 or higher. from typing import TYPE_CHECKING -import numpy from PyQt6.QtCore import QObject, pyqtSignal, pyqtProperty from UM.FlameProfiler import pyqtSlot from UM.Application import Application @@ -12,11 +11,6 @@ if TYPE_CHECKING: class SimulationViewProxy(QObject): - - S_TO_MS = 1000 - SPEED_OF_SIMULATION = 10 - FACTOR = S_TO_MS/SPEED_OF_SIMULATION - def __init__(self, simulation_view: "SimulationView", parent=None) -> None: super().__init__(parent) self._simulation_view = simulation_view @@ -56,17 +50,13 @@ class SimulationViewProxy(QObject): def numPaths(self): return self._simulation_view.getMaxPaths() - @pyqtProperty(int, notify=currentPathChanged) + @pyqtProperty(float, notify=currentPathChanged) def currentPath(self): return self._simulation_view.getCurrentPath() - @pyqtProperty(int, notify=currentPathChanged) - def simulationTime(self): - # Extracts the currents paths simulation time (in seconds) for the current path from the dict of simulation time of the current layer. - # We multiply the time with 100 to make it to ms from s.(Should be 1000 in real time). This scaling makes the simulation time 10x faster than the real time. - simulationTimeOfpath = self._simulation_view.getSimulationTime(self._simulation_view.getCurrentPath()) * SimulationViewProxy.FACTOR - # Since the timer cannot process time less than 1 ms, we put a lower limit here - return int(max(1, simulationTimeOfpath)) + @pyqtSlot(float, result=bool) + def advanceTime(self, duration: float) -> bool: + return self._simulation_view.advanceTime(duration) @pyqtProperty(int, notify=currentPathChanged) def minimumPath(self): @@ -92,8 +82,8 @@ class SimulationViewProxy(QObject): def setMinimumLayer(self, layer_num): self._simulation_view.setMinimumLayer(layer_num) - @pyqtSlot(int) - def setCurrentPath(self, path_num): + @pyqtSlot(float) + def setCurrentPath(self, path_num: float): self._simulation_view.setPath(path_num) @pyqtSlot(int) @@ -229,4 +219,3 @@ class SimulationViewProxy(QObject): self._simulation_view.activityChanged.disconnect(self._onActivityChanged) self._simulation_view.globalStackChanged.disconnect(self._onGlobalStackChanged) self._simulation_view.preferencesChanged.disconnect(self._onPreferencesChanged) - From ddfd7d6a06842b2350b259ad9c22d8fd8fadcf06 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 19 Dec 2023 10:50:56 +0100 Subject: [PATCH 115/133] Use of APP_ASSOCIATE in url_scheme CURA-11288 --- packaging/NSIS/Ultimaker-Cura.nsi.jinja | 67 +++++++++++++++++++------ 1 file changed, 51 insertions(+), 16 deletions(-) diff --git a/packaging/NSIS/Ultimaker-Cura.nsi.jinja b/packaging/NSIS/Ultimaker-Cura.nsi.jinja index 228dba4fe4..3bef698805 100644 --- a/packaging/NSIS/Ultimaker-Cura.nsi.jinja +++ b/packaging/NSIS/Ultimaker-Cura.nsi.jinja @@ -144,6 +144,49 @@ SectionEnd ###################################################################### +Section UrlProtocol + +!macro APP_ASSOCIATE extension progid description commandname command + WriteRegStr HKCR "${extension}" "" "${description}" + WriteRegStr HKCR "${extension}" "URL Protocol" "" + WriteRegStr HKCR "${extension}\DefaultIcon" "" "${commandname},1" + WriteRegStr HKCR "${extension}\shell" "" "open" + WriteRegStr HKCR "${extension}\shell\open\command" "" '"${command}" "%1"' + !insertmacro APP_ASSOCIATE_SHORTCUT "${extension}" "${progid}" "${description}" "${command}" +!macroend + +WriteRegStr HKCR "cura" "" "URL:cura" +WriteRegStr HKCR "cura" "URL Protocol" "" +WriteRegStr HKCR "cura\DefaultIcon" "" "$INSTDIR\${MAIN_APP_EXE},1" +WriteRegStr HKCR "cura\shell" "" "open" +WriteRegStr HKCR "cura\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}" "%1"' + +WriteRegStr HKCR "slicer" "" "URL:slicer" +WriteRegStr HKCR "slicer" "URL Protocol" "" +WriteRegStr HKCR "slicer\DefaultIcon" "" "$INSTDIR\${MAIN_APP_EXE},1" +WriteRegStr HKCR "slicer\shell" "" "open" +WriteRegStr HKCR "slicer\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}" "%1"' + +; Set the uninstall section flag for this section +SetSectionFlags ${SECTION_UNINSTALL} + +; Define file associations for 'cura' protocol +StrCpy $0 "cura" +StrCpy $1 "URL:cura" +StrCpy $2 "CURA Protocol" +StrCpy $3 "$INSTDIR\${MAIN_APP_EXE},1" +Call APP_ASSOCIATE + +; Define file associations for 'slicer' protocol +StrCpy $0 "slicer" +StrCpy $1 "URL:slicer" +StrCpy $2 "SLICER Protocol" +StrCpy $3 "$INSTDIR\${MAIN_APP_EXE},1" +Call APP_ASSOCIATE + +SectionEnd +###################################################################### + Section Uninstall ${INSTALL_TYPE}{% for files in mapped_out_paths.values() %}{% for file in files %} Delete "{{ file[1] }}"{% endfor %}{% endfor %}{% for rem_dir in rmdir_paths %} @@ -187,23 +230,15 @@ RmDir "$SMPROGRAMS\{{ app_name }}" !insertmacro APP_UNASSOCIATE "stl" "Cura.model" !insertmacro APP_UNASSOCIATE "3mf" "Cura.project" +; Unassociate file associations for 'cura' protocol +StrCpy $0 "cura" +Call APP_UNASSOCIATE + +; Unassociate file associations for 'slicer' protocol +StrCpy $0 "slicer" +Call APP_UNASSOCIATE + DeleteRegKey ${REG_ROOT} "${REG_APP_PATH}" DeleteRegKey ${REG_ROOT} "${UNINSTALL_PATH}" SectionEnd -###################################################################### - -Section UrlProtocol - WriteRegStr HKCR "cura" "" "URL:cura" - WriteRegStr HKCR "cura" "URL Protocol" "" - WriteRegStr HKCR "cura\DefaultIcon" "" "$INSTDIR\${MAIN_APP_EXE},1" - WriteRegStr HKCR "cura\shell" "" "open" - WriteRegStr HKCR "cura\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}" "%1"' - - WriteRegStr HKCR "slicer" "" "URL:slicer" - WriteRegStr HKCR "slicer" "URL Protocol" "" - WriteRegStr HKCR "slicer\DefaultIcon" "" "$INSTDIR\${MAIN_APP_EXE},1" - WriteRegStr HKCR "slicer\shell" "" "open" - WriteRegStr HKCR "slicer\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}" "%1"' - -SectionEnd \ No newline at end of file From 5769fcba50134c7975437452a4a17f68927a6446 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 19 Dec 2023 13:26:19 +0100 Subject: [PATCH 116/133] Deleting the register key for url scheme CURA-11288 --- packaging/NSIS/Ultimaker-Cura.nsi.jinja | 32 ++----------------------- 1 file changed, 2 insertions(+), 30 deletions(-) diff --git a/packaging/NSIS/Ultimaker-Cura.nsi.jinja b/packaging/NSIS/Ultimaker-Cura.nsi.jinja index 3bef698805..0a2ce0f517 100644 --- a/packaging/NSIS/Ultimaker-Cura.nsi.jinja +++ b/packaging/NSIS/Ultimaker-Cura.nsi.jinja @@ -146,15 +146,6 @@ SectionEnd Section UrlProtocol -!macro APP_ASSOCIATE extension progid description commandname command - WriteRegStr HKCR "${extension}" "" "${description}" - WriteRegStr HKCR "${extension}" "URL Protocol" "" - WriteRegStr HKCR "${extension}\DefaultIcon" "" "${commandname},1" - WriteRegStr HKCR "${extension}\shell" "" "open" - WriteRegStr HKCR "${extension}\shell\open\command" "" '"${command}" "%1"' - !insertmacro APP_ASSOCIATE_SHORTCUT "${extension}" "${progid}" "${description}" "${command}" -!macroend - WriteRegStr HKCR "cura" "" "URL:cura" WriteRegStr HKCR "cura" "URL Protocol" "" WriteRegStr HKCR "cura\DefaultIcon" "" "$INSTDIR\${MAIN_APP_EXE},1" @@ -167,23 +158,6 @@ WriteRegStr HKCR "slicer\DefaultIcon" "" "$INSTDIR\${MAIN_APP_EXE},1" WriteRegStr HKCR "slicer\shell" "" "open" WriteRegStr HKCR "slicer\shell\open\command" "" '"$INSTDIR\${MAIN_APP_EXE}" "%1"' -; Set the uninstall section flag for this section -SetSectionFlags ${SECTION_UNINSTALL} - -; Define file associations for 'cura' protocol -StrCpy $0 "cura" -StrCpy $1 "URL:cura" -StrCpy $2 "CURA Protocol" -StrCpy $3 "$INSTDIR\${MAIN_APP_EXE},1" -Call APP_ASSOCIATE - -; Define file associations for 'slicer' protocol -StrCpy $0 "slicer" -StrCpy $1 "URL:slicer" -StrCpy $2 "SLICER Protocol" -StrCpy $3 "$INSTDIR\${MAIN_APP_EXE},1" -Call APP_ASSOCIATE - SectionEnd ###################################################################### @@ -231,12 +205,10 @@ RmDir "$SMPROGRAMS\{{ app_name }}" !insertmacro APP_UNASSOCIATE "3mf" "Cura.project" ; Unassociate file associations for 'cura' protocol -StrCpy $0 "cura" -Call APP_UNASSOCIATE +DeleteRegKey HKCR "cura" ; Unassociate file associations for 'slicer' protocol -StrCpy $0 "slicer" -Call APP_UNASSOCIATE +DeleteRegKey HKCR "slicer" DeleteRegKey ${REG_ROOT} "${REG_APP_PATH}" DeleteRegKey ${REG_ROOT} "${UNINSTALL_PATH}" From 69f8227b412e2eefa8e53b4c2e28fca6f803490c Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 19 Dec 2023 14:33:21 +0100 Subject: [PATCH 117/133] Path correction for cura application for msi CURA-11288 --- packaging/msi/UltiMaker-Cura.wxs.jinja | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packaging/msi/UltiMaker-Cura.wxs.jinja b/packaging/msi/UltiMaker-Cura.wxs.jinja index 07a2c7d8c9..e9cb01a041 100644 --- a/packaging/msi/UltiMaker-Cura.wxs.jinja +++ b/packaging/msi/UltiMaker-Cura.wxs.jinja @@ -164,8 +164,8 @@ - - + + @@ -173,8 +173,8 @@ - - + + From cb01026aad29777fdd2aa3eb05a6fbd9fe1f43ac Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Tue, 19 Dec 2023 15:27:53 +0100 Subject: [PATCH 118/133] Path correction for cura application for msi CURA-11288 --- packaging/msi/UltiMaker-Cura.wxs.jinja | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packaging/msi/UltiMaker-Cura.wxs.jinja b/packaging/msi/UltiMaker-Cura.wxs.jinja index e9cb01a041..c6ec5dbd63 100644 --- a/packaging/msi/UltiMaker-Cura.wxs.jinja +++ b/packaging/msi/UltiMaker-Cura.wxs.jinja @@ -164,8 +164,8 @@ - - + + @@ -173,8 +173,8 @@ - - + + From f663c57a927ca7a637bd382cd7b0ab9bc19c76aa Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Wed, 20 Dec 2023 08:50:37 +0100 Subject: [PATCH 119/133] Remove msi installer code Should be done for CURA-11435 CURA-11288 --- packaging/msi/UltiMaker-Cura.wxs.jinja | 36 -------------------------- 1 file changed, 36 deletions(-) diff --git a/packaging/msi/UltiMaker-Cura.wxs.jinja b/packaging/msi/UltiMaker-Cura.wxs.jinja index c6ec5dbd63..a183a97d5f 100644 --- a/packaging/msi/UltiMaker-Cura.wxs.jinja +++ b/packaging/msi/UltiMaker-Cura.wxs.jinja @@ -33,21 +33,6 @@ /> - - - - - {% if "Enterprise" in app_name %} @@ -159,32 +144,11 @@ - - - - - - - - - - - - - - - - - - - - - From f8f497b5781da97567077bff81bd75123b5bc3f4 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Wed, 20 Dec 2023 10:05:01 +0100 Subject: [PATCH 120/133] url registry entry for msi CURA-11435 --- packaging/msi/UltiMaker-Cura.wxs.jinja | 36 ++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/packaging/msi/UltiMaker-Cura.wxs.jinja b/packaging/msi/UltiMaker-Cura.wxs.jinja index a183a97d5f..c6ec5dbd63 100644 --- a/packaging/msi/UltiMaker-Cura.wxs.jinja +++ b/packaging/msi/UltiMaker-Cura.wxs.jinja @@ -33,6 +33,21 @@ /> + + + + + {% if "Enterprise" in app_name %} @@ -144,11 +159,32 @@ + + + + + + + + + + + + + + + + + + + + + From 76f86081c63c48652949d11d5c6aea62c5a4fd8b Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Wed, 20 Dec 2023 10:50:57 +0100 Subject: [PATCH 121/133] fixing the register entry CURA-11435 --- packaging/msi/UltiMaker-Cura.wxs.jinja | 41 ++++++++++++++++++++------ 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/packaging/msi/UltiMaker-Cura.wxs.jinja b/packaging/msi/UltiMaker-Cura.wxs.jinja index c6ec5dbd63..3dcb9ef2ee 100644 --- a/packaging/msi/UltiMaker-Cura.wxs.jinja +++ b/packaging/msi/UltiMaker-Cura.wxs.jinja @@ -160,24 +160,47 @@ - + + + + + + + + + + + + + + + + + + + + + 127.0.0.1 + + + + - - + + - + - - - - + + + + - From e08d183b6c424d9ecc5c5e4668e7e379edf0cabf Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Wed, 20 Dec 2023 10:56:25 +0100 Subject: [PATCH 122/133] undo commit 76f8608 CURA-11435 --- packaging/msi/UltiMaker-Cura.wxs.jinja | 37 +++++--------------------- 1 file changed, 7 insertions(+), 30 deletions(-) diff --git a/packaging/msi/UltiMaker-Cura.wxs.jinja b/packaging/msi/UltiMaker-Cura.wxs.jinja index 3dcb9ef2ee..21f017c813 100644 --- a/packaging/msi/UltiMaker-Cura.wxs.jinja +++ b/packaging/msi/UltiMaker-Cura.wxs.jinja @@ -160,31 +160,7 @@ - - - - - - - - - - - - - - - - - - - - - 127.0.0.1 - - - - + @@ -193,14 +169,15 @@ - + - - - - + + + + + From 41efdbabe0faf7bd70fe2d759db19be3e6033414 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Wed, 20 Dec 2023 18:16:04 +0100 Subject: [PATCH 123/133] Path change possible by user - simulation speed increased - no buffering in between layers - fps made 30 CURA-7647 --- plugins/SimulationView/SimulationView.py | 43 +++++++++++-------- .../SimulationViewMainComponent.qml | 3 +- 2 files changed, 27 insertions(+), 19 deletions(-) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 64ec0dfc1b..2663993f55 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -1,6 +1,6 @@ # Copyright (c) 2021 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. - +import math import sys from PyQt6.QtCore import Qt @@ -58,6 +58,7 @@ class SimulationView(CuraView): LAYER_VIEW_TYPE_LINE_TYPE = 1 LAYER_VIEW_TYPE_FEEDRATE = 2 LAYER_VIEW_TYPE_THICKNESS = 3 + SIMULATION_FACTOR = 5 _no_layers_warning_preference = "view/no_layers_warning" @@ -97,6 +98,7 @@ class SimulationView(CuraView): self._min_line_width = sys.float_info.max self._min_flow_rate = sys.float_info.max self._max_flow_rate = sys.float_info.min + self._cumulative_line_duration ={} self._global_container_stack: Optional[ContainerStack] = None self._proxy = None @@ -196,21 +198,21 @@ class SimulationView(CuraView): left_i = 0 right_i = self._max_paths - 1 - total_duration, cumulative_line_duration = self.cumulativeLineDuration() + total_duration = self.cumulativeLineDuration() # make an educated guess about where to start i = int(right_i * max(0.0, min(1.0, self._current_time / total_duration))) # binary search for the correct path while left_i < right_i: - if cumulative_line_duration[i] <= self._current_time: + if self._cumulative_line_duration[self.getCurrentLayer()][i] <= self._current_time: left_i = i + 1 else: right_i = i i = int((left_i + right_i) / 2) - left_value = cumulative_line_duration[i - 1] if i > 0 else 0.0 - right_value = cumulative_line_duration[i] + left_value = self._cumulative_line_duration[self.getCurrentLayer()][i - 1] if i > 0 else 0.0 + right_value = self._cumulative_line_duration[self.getCurrentLayer()][i] assert (left_value <= self._current_time <= right_value) @@ -225,10 +227,7 @@ class SimulationView(CuraView): :param time_increase: The amount of time to advance (in seconds). :return: True if the time was advanced, False if the end of the simulation was reached. """ - total_duration, cumulative_line_duration = self.cumulativeLineDuration() - - # time ratio - time_increase = time_increase + total_duration = self.cumulativeLineDuration() if self._current_time + time_increase > total_duration: # If we have reached the end of the simulation, go to the next layer. @@ -244,15 +243,20 @@ class SimulationView(CuraView): self.setTime(self._current_time + time_increase) return True - def cumulativeLineDuration(self) -> Tuple[float, List[float]]: - # TODO: cache the total duration and cumulative line duration at each layer change event - cumulative_line_duration = [] - total_duration = 0.0 - for polyline in self.getLayerData().polygons: - for line_duration in list((polyline.lineLengths / polyline.lineFeedrates)[0]): - total_duration += line_duration - cumulative_line_duration.append(total_duration) - return total_duration, cumulative_line_duration + def cumulativeLineDuration(self) -> float: + # Make sure _cumulative_line_duration is initialized properly + if self.getCurrentLayer() not in self._cumulative_line_duration: + self._cumulative_line_duration[self.getCurrentLayer()] = [] + total_duration = 0.0 + for polyline in self.getLayerData().polygons: + for line_duration in list((polyline.lineLengths / polyline.lineFeedrates)[0]): + total_duration += line_duration / SimulationView.SIMULATION_FACTOR + self._cumulative_line_duration[self.getCurrentLayer()].append(total_duration) + + # Calculate the total duration using numpy.sum + total_duration = (self._cumulative_line_duration[self.getCurrentLayer()][-1]) + + return total_duration def getLayerData(self) -> Optional["LayerData"]: scene = self.getController().getScene() @@ -360,6 +364,9 @@ class SimulationView(CuraView): if self._current_path_num != value: self._current_path_num = min(max(value, 0), self._max_paths) self._minimum_path_num = min(self._minimum_path_num, self._current_path_num) + # update _current time when the path is changed by user + if self.getCurrentLayer() in self._cumulative_line_duration and self._current_path_num < self._max_paths and round(self._current_path_num)== self._current_path_num: + self._current_time = self._cumulative_line_duration[self.getCurrentLayer()][int(self._current_path_num)] self._startUpdateTopLayers() self.currentPathNumChanged.emit() diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 23cbf8c611..0432cfc08d 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -127,6 +127,7 @@ Item function resumeSimulation() { UM.SimulationView.setSimulationRunning(true) + UM.SimulationView.setCurrentPath(UM.SimulationView.currentPath) simulationTimer.start() layerSlider.manuallyChanged = false pathSlider.manuallyChanged = false @@ -136,7 +137,7 @@ Item Timer { id: simulationTimer - interval: 1000 / 60 + interval: 1000 / 30 running: false repeat: true onTriggered: From e2e94b7f6b9252ad64641793ef9a4d283cff5bcb Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Thu, 21 Dec 2023 10:32:49 +0100 Subject: [PATCH 124/133] fps made 15 for lower GPU load - reinitialisation of cummulative_time for new model CURA-7647 --- plugins/SimulationView/SimulationView.py | 5 +++-- plugins/SimulationView/SimulationViewMainComponent.qml | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 2663993f55..bce7062a36 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -98,7 +98,7 @@ class SimulationView(CuraView): self._min_line_width = sys.float_info.max self._min_flow_rate = sys.float_info.max self._max_flow_rate = sys.float_info.min - self._cumulative_line_duration ={} + self._cumulative_line_duration = {} self._global_container_stack: Optional[ContainerStack] = None self._proxy = None @@ -253,7 +253,7 @@ class SimulationView(CuraView): total_duration += line_duration / SimulationView.SIMULATION_FACTOR self._cumulative_line_duration[self.getCurrentLayer()].append(total_duration) - # Calculate the total duration using numpy.sum + # total duration for a layer to simulate is the last element of the list total_duration = (self._cumulative_line_duration[self.getCurrentLayer()][-1]) return total_duration @@ -572,6 +572,7 @@ class SimulationView(CuraView): self._max_thickness = sys.float_info.min self._min_flow_rate = sys.float_info.max self._max_flow_rate = sys.float_info.min + self._cumulative_line_duration = {} # The colour scheme is only influenced by the visible lines, so filter the lines by if they should be visible. visible_line_types = [] diff --git a/plugins/SimulationView/SimulationViewMainComponent.qml b/plugins/SimulationView/SimulationViewMainComponent.qml index 0432cfc08d..d9e7a95bc1 100644 --- a/plugins/SimulationView/SimulationViewMainComponent.qml +++ b/plugins/SimulationView/SimulationViewMainComponent.qml @@ -137,12 +137,12 @@ Item Timer { id: simulationTimer - interval: 1000 / 30 + interval: 1000 / 15 running: false repeat: true onTriggered: { - // divide by 1000 to accont for ms to s conversion + // divide by 1000 to account for ms to s conversion const advance_time = simulationTimer.interval / 1000.0; if (!UM.SimulationView.advanceTime(advance_time)) { playButton.pauseSimulation(); From 3f8908f53a8207d2d75cab89618d22436df31ccd Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Thu, 21 Dec 2023 10:42:52 +0100 Subject: [PATCH 125/133] cleanup CURA-7647 --- plugins/SimulationView/SimulationView.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index bce7062a36..070a5c0345 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -1,6 +1,5 @@ # Copyright (c) 2021 Ultimaker B.V. # Cura is released under the terms of the LGPLv3 or higher. -import math import sys from PyQt6.QtCore import Qt @@ -40,7 +39,7 @@ from .SimulationViewProxy import SimulationViewProxy import numpy import os.path -from typing import Optional, TYPE_CHECKING, List, Tuple, cast +from typing import Optional, TYPE_CHECKING, List, cast if TYPE_CHECKING: from UM.Scene.SceneNode import SceneNode From 0de4f612b399cfe8b7a6c8059e9579489bcd739c Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Thu, 21 Dec 2023 14:13:16 +0100 Subject: [PATCH 126/133] fixing review comments. Cache only for the current layer CURA-7647 --- plugins/SimulationView/SimulationView.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 070a5c0345..1043c7659a 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -197,21 +197,22 @@ class SimulationView(CuraView): left_i = 0 right_i = self._max_paths - 1 - total_duration = self.cumulativeLineDuration() + cumulative_line_duration = self.cumulativeLineDuration() + total_duration = cumulative_line_duration[-1] # make an educated guess about where to start i = int(right_i * max(0.0, min(1.0, self._current_time / total_duration))) # binary search for the correct path while left_i < right_i: - if self._cumulative_line_duration[self.getCurrentLayer()][i] <= self._current_time: + if cumulative_line_duration[i] <= self._current_time: left_i = i + 1 else: right_i = i i = int((left_i + right_i) / 2) - left_value = self._cumulative_line_duration[self.getCurrentLayer()][i - 1] if i > 0 else 0.0 - right_value = self._cumulative_line_duration[self.getCurrentLayer()][i] + left_value = cumulative_line_duration[i - 1] if i > 0 else 0.0 + right_value = cumulative_line_duration[i] assert (left_value <= self._current_time <= right_value) @@ -226,7 +227,7 @@ class SimulationView(CuraView): :param time_increase: The amount of time to advance (in seconds). :return: True if the time was advanced, False if the end of the simulation was reached. """ - total_duration = self.cumulativeLineDuration() + total_duration = self.cumulativeLineDuration()[-1] if self._current_time + time_increase > total_duration: # If we have reached the end of the simulation, go to the next layer. @@ -242,9 +243,11 @@ class SimulationView(CuraView): self.setTime(self._current_time + time_increase) return True - def cumulativeLineDuration(self) -> float: + def cumulativeLineDuration(self) -> list: # Make sure _cumulative_line_duration is initialized properly if self.getCurrentLayer() not in self._cumulative_line_duration: + #clear cache + self._cumulative_line_duration = {} self._cumulative_line_duration[self.getCurrentLayer()] = [] total_duration = 0.0 for polyline in self.getLayerData().polygons: @@ -252,10 +255,7 @@ class SimulationView(CuraView): total_duration += line_duration / SimulationView.SIMULATION_FACTOR self._cumulative_line_duration[self.getCurrentLayer()].append(total_duration) - # total duration for a layer to simulate is the last element of the list - total_duration = (self._cumulative_line_duration[self.getCurrentLayer()][-1]) - - return total_duration + return self._cumulative_line_duration[self.getCurrentLayer()] def getLayerData(self) -> Optional["LayerData"]: scene = self.getController().getScene() @@ -364,8 +364,8 @@ class SimulationView(CuraView): self._current_path_num = min(max(value, 0), self._max_paths) self._minimum_path_num = min(self._minimum_path_num, self._current_path_num) # update _current time when the path is changed by user - if self.getCurrentLayer() in self._cumulative_line_duration and self._current_path_num < self._max_paths and round(self._current_path_num)== self._current_path_num: - self._current_time = self._cumulative_line_duration[self.getCurrentLayer()][int(self._current_path_num)] + if self._current_path_num < self._max_paths and round(self._current_path_num)== self._current_path_num: + self._current_time = self.cumulativeLineDuration()[int(self._current_path_num)] self._startUpdateTopLayers() self.currentPathNumChanged.emit() From 152cb27232310a35b3e71a70b438253a95c760f5 Mon Sep 17 00:00:00 2001 From: Saumya Jain <70144862+saumyaj3@users.noreply.github.com> Date: Thu, 21 Dec 2023 14:30:43 +0100 Subject: [PATCH 127/133] Update plugins/SimulationView/SimulationView.py review fix Co-authored-by: Casper Lamboo --- plugins/SimulationView/SimulationView.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 1043c7659a..04fc383fbb 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -243,7 +243,7 @@ class SimulationView(CuraView): self.setTime(self._current_time + time_increase) return True - def cumulativeLineDuration(self) -> list: + def cumulativeLineDuration(self) -> List[float]: # Make sure _cumulative_line_duration is initialized properly if self.getCurrentLayer() not in self._cumulative_line_duration: #clear cache From 608c2344c5d8b44e318d14a1284eb6204b194154 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Thu, 21 Dec 2023 16:25:12 +0100 Subject: [PATCH 128/133] on_error takes multiple args CURA-11289 --- cura/CuraApplication.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 52f38d4685..fd4b0c858c 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1837,7 +1837,7 @@ class CuraApplication(QtApplication): self.readLocalFile(QUrl.fromLocalFile(tmp.name), add_to_recent_files=False) - def on_error(): + def on_error(*args, **kwargs): Logger.log("w", "Could not download file from {0}".format(model_url.url())) return From a309c9efdb5e3520de880fec40a89835d87f14dd Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Thu, 21 Dec 2023 17:26:11 +0100 Subject: [PATCH 129/133] Error is displayed on Cura screen CURA-11289 --- cura/CuraApplication.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index fd4b0c858c..1ef2f63a9e 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -1839,6 +1839,9 @@ class CuraApplication(QtApplication): def on_error(*args, **kwargs): Logger.log("w", "Could not download file from {0}".format(model_url.url())) + Message("Could not download file: " + str(model_url.url()), + title= "Loading Model failed", + message_type=Message.MessageType.ERROR).show() return self.getHttpRequestManager().get( From 411b40d78c39923723ad31709d04f5558c7d1728 Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Fri, 22 Dec 2023 10:37:51 +0100 Subject: [PATCH 130/133] Simulation speed made 3X case where no polygon in layer is also addressed CURA-11289 --- plugins/SimulationView/SimulationView.py | 57 ++++++++++++------------ 1 file changed, 29 insertions(+), 28 deletions(-) diff --git a/plugins/SimulationView/SimulationView.py b/plugins/SimulationView/SimulationView.py index 04fc383fbb..337879475b 100644 --- a/plugins/SimulationView/SimulationView.py +++ b/plugins/SimulationView/SimulationView.py @@ -57,7 +57,7 @@ class SimulationView(CuraView): LAYER_VIEW_TYPE_LINE_TYPE = 1 LAYER_VIEW_TYPE_FEEDRATE = 2 LAYER_VIEW_TYPE_THICKNESS = 3 - SIMULATION_FACTOR = 5 + SIMULATION_FACTOR = 3 _no_layers_warning_preference = "view/no_layers_warning" @@ -192,33 +192,30 @@ class SimulationView(CuraView): return self._current_path_num def setTime(self, time: float) -> None: - self._current_time = time - - left_i = 0 - right_i = self._max_paths - 1 - cumulative_line_duration = self.cumulativeLineDuration() - total_duration = cumulative_line_duration[-1] + if len(cumulative_line_duration) > 0: + self._current_time = time + left_i = 0 + right_i = self._max_paths - 1 + total_duration = cumulative_line_duration[-1] + # make an educated guess about where to start + i = int(right_i * max(0.0, min(1.0, self._current_time / total_duration))) + # binary search for the correct path + while left_i < right_i: + if cumulative_line_duration[i] <= self._current_time: + left_i = i + 1 + else: + right_i = i + i = int((left_i + right_i) / 2) - # make an educated guess about where to start - i = int(right_i * max(0.0, min(1.0, self._current_time / total_duration))) + left_value = cumulative_line_duration[i - 1] if i > 0 else 0.0 + right_value = cumulative_line_duration[i] - # binary search for the correct path - while left_i < right_i: - if cumulative_line_duration[i] <= self._current_time: - left_i = i + 1 - else: - right_i = i - i = int((left_i + right_i) / 2) + assert (left_value <= self._current_time <= right_value) - left_value = cumulative_line_duration[i - 1] if i > 0 else 0.0 - right_value = cumulative_line_duration[i] + fractional_value = (self._current_time - left_value) / (right_value - left_value) - assert (left_value <= self._current_time <= right_value) - - fractional_value = (self._current_time - left_value) / (right_value - left_value) - - self.setPath(i + fractional_value) + self.setPath(i + fractional_value) def advanceTime(self, time_increase: float) -> bool: """ @@ -227,7 +224,9 @@ class SimulationView(CuraView): :param time_increase: The amount of time to advance (in seconds). :return: True if the time was advanced, False if the end of the simulation was reached. """ - total_duration = self.cumulativeLineDuration()[-1] + total_duration = 0.0 + if len(self.cumulativeLineDuration()) > 0: + total_duration = self.cumulativeLineDuration()[-1] if self._current_time + time_increase > total_duration: # If we have reached the end of the simulation, go to the next layer. @@ -250,10 +249,12 @@ class SimulationView(CuraView): self._cumulative_line_duration = {} self._cumulative_line_duration[self.getCurrentLayer()] = [] total_duration = 0.0 - for polyline in self.getLayerData().polygons: - for line_duration in list((polyline.lineLengths / polyline.lineFeedrates)[0]): - total_duration += line_duration / SimulationView.SIMULATION_FACTOR - self._cumulative_line_duration[self.getCurrentLayer()].append(total_duration) + polylines = self.getLayerData() + if polylines is not None: + for polyline in polylines.polygons: + for line_duration in list((polyline.lineLengths / polyline.lineFeedrates)[0]): + total_duration += line_duration / SimulationView.SIMULATION_FACTOR + self._cumulative_line_duration[self.getCurrentLayer()].append(total_duration) return self._cumulative_line_duration[self.getCurrentLayer()] From 224f6132286e0e2aec6386545cfb6921f58afcab Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Fri, 22 Dec 2023 11:36:51 +0100 Subject: [PATCH 131/133] Property of machinemanager redefined CURA-11459 --- resources/qml/PrinterSelector/MachineSelector.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/resources/qml/PrinterSelector/MachineSelector.qml b/resources/qml/PrinterSelector/MachineSelector.qml index b8b27049f6..1bad1d70bc 100644 --- a/resources/qml/PrinterSelector/MachineSelector.qml +++ b/resources/qml/PrinterSelector/MachineSelector.qml @@ -11,7 +11,7 @@ Cura.ExpandablePopup { id: machineSelector - property Cura.MachineManager machineManager + property var machineManager: Cura.MachineManager property bool isNetworkPrinter: machineManager.activeMachineHasNetworkConnection property bool isConnectedCloudPrinter: machineManager.activeMachineHasCloudConnection property bool isCloudRegistered: machineManager.activeMachineHasCloudRegistration @@ -107,6 +107,7 @@ Cura.ExpandablePopup { return UM.Theme.getIcon("Printer", "medium") } + else { return "" From 7fab301866b63d90ffb72603fdd3aa30a505cdec Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Fri, 22 Dec 2023 18:02:23 +0100 Subject: [PATCH 132/133] Guard against index out of bound CURA-7647 --- plugins/SimulationView/SimulationPass.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/plugins/SimulationView/SimulationPass.py b/plugins/SimulationView/SimulationPass.py index 3294f4b1e6..e97a0cd32c 100644 --- a/plugins/SimulationView/SimulationPass.py +++ b/plugins/SimulationView/SimulationPass.py @@ -160,14 +160,14 @@ class SimulationPass(RenderPass): ratio = self._layer_view.getCurrentPath() - index pos_a = Vector(polygon.data[index + offset][0], polygon.data[index + offset][1], polygon.data[index + offset][2]) - if ratio > 0.0001: + if ratio <= 0.0001 or index + offset == len(polygon.data): + head_position = pos_a + node.getWorldPosition() + else: pos_b = Vector(polygon.data[index + offset + 1][0], polygon.data[index + offset + 1][1], polygon.data[index + offset + 1][2]) vec = pos_a * (1.0 - ratio) + pos_b * ratio head_position = vec + node.getWorldPosition() - else: - head_position = pos_a + node.getWorldPosition() break break if self._layer_view.getMinimumLayer() > layer: From 632c10db51908445c41a3cd12bd2532c0df0211e Mon Sep 17 00:00:00 2001 From: "saumya.jain" Date: Wed, 27 Dec 2023 10:12:40 +0100 Subject: [PATCH 133/133] Guard against index for edge case CURA-7647 --- plugins/SimulationView/SimulationPass.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/SimulationView/SimulationPass.py b/plugins/SimulationView/SimulationPass.py index e97a0cd32c..dd94d678ae 100644 --- a/plugins/SimulationView/SimulationPass.py +++ b/plugins/SimulationView/SimulationPass.py @@ -160,7 +160,7 @@ class SimulationPass(RenderPass): ratio = self._layer_view.getCurrentPath() - index pos_a = Vector(polygon.data[index + offset][0], polygon.data[index + offset][1], polygon.data[index + offset][2]) - if ratio <= 0.0001 or index + offset == len(polygon.data): + if ratio <= 0.0001 or index + offset < len(polygon.data): head_position = pos_a + node.getWorldPosition() else: pos_b = Vector(polygon.data[index + offset + 1][0],