From 3052c6be3b4ff728ea781e006ae3af22c2f42a1f Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Tue, 21 Nov 2023 13:21:25 +0100 Subject: [PATCH 01/20] 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 02/20] 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 03/20] 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 04/20] 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 593e959dd574784481add3c897061ae07763195c Mon Sep 17 00:00:00 2001 From: Jaime van Kessel Date: Wed, 29 Nov 2023 10:42:12 +0100 Subject: [PATCH 05/20] 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 ef5bc6d3d5965a02f603c72da1d20db6d2009723 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Thu, 30 Nov 2023 12:57:14 +0100 Subject: [PATCH 06/20] 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 07/20] 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 08/20] 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 d93d66dd8adad41fb693b8c6e135caf44f92cd5f Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Thu, 30 Nov 2023 13:45:21 +0100 Subject: [PATCH 09/20] 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 b629669f77ee7dc3345283170b8148d017f073f7 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Thu, 30 Nov 2023 14:00:28 +0100 Subject: [PATCH 10/20] 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 11/20] 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 bffbded591d85735ad0110517061e744b2765983 Mon Sep 17 00:00:00 2001 From: jellespijker Date: Fri, 1 Dec 2023 17:42:27 +0100 Subject: [PATCH 12/20] 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 ba9e122f6add419824e6fc03d55df40766d4e71d Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Mon, 4 Dec 2023 11:45:12 +0100 Subject: [PATCH 13/20] 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 89be765841bf453d6ee02ef8490a29dd02995072 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Mon, 4 Dec 2023 13:48:05 +0100 Subject: [PATCH 14/20] 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 15/20] 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 68818a525d966e0260571e2a9cae0ae5d36d6afe Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Tue, 5 Dec 2023 13:53:30 +0100 Subject: [PATCH 16/20] 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 17/20] 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 0353037b31cfd715bc01193ca676f871d2373515 Mon Sep 17 00:00:00 2001 From: "c.lamboo" Date: Wed, 6 Dec 2023 11:36:54 +0100 Subject: [PATCH 18/20] 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 19/20] 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 20/20] 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(