From 61ab800857157a568d96af610fd51a253be695b7 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Tue, 18 Feb 2025 10:09:11 +0100 Subject: [PATCH 1/5] Move 3DConnexion support to plugin CURA-12407 --- cura/CuraApplication.py | 12 +++---- {cura => plugins/3DConnexion}/NavlibClient.py | 31 ++++++------------- .../3DConnexion}/OverlayNode.py | 0 plugins/3DConnexion/__init__.py | 22 +++++++++++++ plugins/3DConnexion/plugin.json | 8 +++++ resources/bundled_packages/cura.json | 17 ++++++++++ 6 files changed, 62 insertions(+), 28 deletions(-) rename {cura => plugins/3DConnexion}/NavlibClient.py (94%) rename {cura/Scene => plugins/3DConnexion}/OverlayNode.py (100%) create mode 100644 plugins/3DConnexion/__init__.py create mode 100644 plugins/3DConnexion/plugin.json diff --git a/cura/CuraApplication.py b/cura/CuraApplication.py index 723cbcd2e5..b292191091 100755 --- a/cura/CuraApplication.py +++ b/cura/CuraApplication.py @@ -36,6 +36,7 @@ from UM.Operations.SetTransformOperation import SetTransformOperation from UM.OutputDevice.ProjectOutputDevice import ProjectOutputDevice from UM.Platform import Platform from UM.PluginError import PluginNotFoundError +from UM.PluginObject import PluginObject from UM.Preferences import Preferences from UM.Qt.Bindings.FileProviderModel import FileProviderModel from UM.Qt.QtApplication import QtApplication # The class we're inheriting from. @@ -130,8 +131,6 @@ from .Machines.Models.IntentSelectionModel import IntentSelectionModel from .PrintOrderManager import PrintOrderManager from .SingleInstance import SingleInstance -from .NavlibClient import NavlibClient - if TYPE_CHECKING: from UM.Settings.EmptyInstanceContainer import EmptyInstanceContainer @@ -220,6 +219,7 @@ class CuraApplication(QtApplication): self._machine_error_checker = None self._backend_plugins: List[BackendPlugin] = [] + self._view_manipulators: List[PluginObject] = [] self._machine_settings_manager = MachineSettingsManager(self, parent = self) self._material_management_model = None @@ -845,6 +845,7 @@ class CuraApplication(QtApplication): self._plugin_registry.addType("profile_reader", self._addProfileReader) self._plugin_registry.addType("profile_writer", self._addProfileWriter) self._plugin_registry.addType("backend_plugin", self._addBackendPlugin) + self._plugin_registry.addType("view_manipulator", self._addViewManipulator) if Platform.isLinux(): lib_suffixes = {"", "64", "32", "x32"} # A few common ones on different distributions. @@ -1039,10 +1040,6 @@ class CuraApplication(QtApplication): controller.setCameraTool("CameraTool") controller.setSelectionTool("SelectionTool") - self._navlib_client = NavlibClient(controller.getScene(), self.getRenderer()) - self._navlib_client.put_profile_hint("UltiMaker Cura") - self._navlib_client.enable_navigation(True) - # Hide the splash screen self.closeSplash() @@ -1951,6 +1948,9 @@ class CuraApplication(QtApplication): def getBackendPlugins(self) -> List["BackendPlugin"]: return self._backend_plugins + def _addViewManipulator(self, view_manipulator: "PluginObject"): + self._view_manipulators.append(view_manipulator) + @pyqtSlot("QSize") def setMinimumWindowSize(self, size): main_window = self.getMainWindow() diff --git a/cura/NavlibClient.py b/plugins/3DConnexion/NavlibClient.py similarity index 94% rename from cura/NavlibClient.py rename to plugins/3DConnexion/NavlibClient.py index db7711e773..9a3488f1ed 100644 --- a/cura/NavlibClient.py +++ b/plugins/3DConnexion/NavlibClient.py @@ -3,25 +3,18 @@ from UM.Math.Vector import Vector from UM.Math.AxisAlignedBox import AxisAlignedBox from cura.PickingPass import PickingPass from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator -from cura.Scene.OverlayNode import OverlayNode, SceneNode +from UM.Scene import SceneNode from UM.Resources import Resources +from UM.PluginObject import PluginObject from UM.Logger import Logger +from .OverlayNode import OverlayNode +import pynavlib.pynavlib_interface as pynav -try: - import pynavlib.pynavlib_interface as pynav - parent_class = pynav.NavlibNavigationModel -except BaseException as exception: - Logger.warning(f"Unable to load 3DConnexion library: {exception}") - pynav = None - parent_class = object - -class NavlibClient(parent_class): +class NavlibClient(pynav.NavlibNavigationModel, PluginObject): def __init__(self, scene, renderer) -> None: - if not pynav: - return - - super().__init__(False, pynav.NavlibOptions.RowMajorOrder) + pynav.NavlibNavigationModel.__init__(self, False, pynav.NavlibOptions.RowMajorOrder) + PluginObject.__init__(self) self._scene = scene self._renderer = renderer self._pointer_pick = None @@ -29,14 +22,8 @@ class NavlibClient(parent_class): self._hit_selection_only = False self._picking_pass = None self._pivot_node = OverlayNode(node=SceneNode(), image_path=Resources.getPath(Resources.Images, "cor.png"), size=2.5) - - def put_profile_hint(self, hint) -> None: - if pynav: - super().put_profile_hint(hint) - - def enable_navigation(self, enabled) -> None: - if pynav: - super().enable_navigation(enabled) + self.put_profile_hint("UltiMaker Cura") + self.enable_navigation(True) def pick(self, x, y, check_selection = False, radius = 0.): diff --git a/cura/Scene/OverlayNode.py b/plugins/3DConnexion/OverlayNode.py similarity index 100% rename from cura/Scene/OverlayNode.py rename to plugins/3DConnexion/OverlayNode.py diff --git a/plugins/3DConnexion/__init__.py b/plugins/3DConnexion/__init__.py new file mode 100644 index 0000000000..368580797e --- /dev/null +++ b/plugins/3DConnexion/__init__.py @@ -0,0 +1,22 @@ +# Copyright (c) 2025 Ultimaker B.V. +# Cura is released under the terms of the LGPLv3 or higher. + +from UM.Logger import Logger + +from typing import TYPE_CHECKING, Dict, Any + +if TYPE_CHECKING: + from UM.Application import Application + + +def getMetaData() -> Dict[str, Any]: + return {} + + +def register(app: "Application") -> Dict[str, Any]: + try: + from .NavlibClient import NavlibClient + return { "view_manipulator": NavlibClient(app.getController().getScene(), app.getRenderer()) } + except BaseException as exception: + Logger.warning(f"Unable to load 3DConnexion library: {exception}") + return { } diff --git a/plugins/3DConnexion/plugin.json b/plugins/3DConnexion/plugin.json new file mode 100644 index 0000000000..eadb70fc44 --- /dev/null +++ b/plugins/3DConnexion/plugin.json @@ -0,0 +1,8 @@ +{ + "name": "3DConnexion mouses", + "author": "3DConnexion", + "version": "1.0.0", + "description": "Allows working with 3D mouses inside Cura.", + "api": 8, + "i18n-catalog": "cura" +} diff --git a/resources/bundled_packages/cura.json b/resources/bundled_packages/cura.json index c89db0e151..e3e4f02c1f 100644 --- a/resources/bundled_packages/cura.json +++ b/resources/bundled_packages/cura.json @@ -1,4 +1,21 @@ { + "3DConnexion": { + "package_info": { + "package_id": "3DConnexion", + "package_type": "plugin", + "display_name": "3DConnexion mouses", + "description": "Allows working with 3D mouses inside Cura.", + "package_version": "1.0.0", + "sdk_version": "8.6.0", + "website": "https://3dconnexion.com", + "author": { + "author_id": "UltimakerPackages", + "display_name": "3DConnexion", + "email": "plugins@ultimaker.com", + "website": "https://3dconnexion.com" + } + } + }, "3MFReader": { "package_info": { "package_id": "3MFReader", From 5eec594f49d6dd2154a5f58ffa54a3102a27d0b4 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Wed, 19 Feb 2025 08:59:17 +0100 Subject: [PATCH 2/5] Add pynavlib explicitely to pyinstaller CURA-12407 --- conandata.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/conandata.yml b/conandata.yml index ba9b85c479..2904b87f6a 100644 --- a/conandata.yml +++ b/conandata.yml @@ -110,6 +110,7 @@ pyinstaller: - "win32cred" - "win32timezone" - "pkgutil" + - "pynavlib" hiddenimports_WINDOWS_ONLY: - "PyQt6.Qt" - "PyQt6.Qt6" From d0560b9a83767442886c29e1faac172b2ee44c9e Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Wed, 19 Feb 2025 15:54:16 +0100 Subject: [PATCH 3/5] Move pynavlib to collect_all instead of hiddenimports CURA-12407 --- conandata.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conandata.yml b/conandata.yml index 2904b87f6a..b098ce19cf 100644 --- a/conandata.yml +++ b/conandata.yml @@ -110,7 +110,6 @@ pyinstaller: - "win32cred" - "win32timezone" - "pkgutil" - - "pynavlib" hiddenimports_WINDOWS_ONLY: - "PyQt6.Qt" - "PyQt6.Qt6" @@ -126,6 +125,7 @@ pyinstaller: - "PyQt6.sip" - "stl" - "keyrings.alt" + - "pynavlib" collect_all_WINDOWS_ONLY: - "PyQt6.Qt" - "PyQt6.Qt6" From 8f7256a647d1d8cbd6f56a8bd09396a5ea353b43 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Thu, 20 Feb 2025 08:26:14 +0100 Subject: [PATCH 4/5] Fix wrong class import CURA-12407 --- plugins/3DConnexion/NavlibClient.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/3DConnexion/NavlibClient.py b/plugins/3DConnexion/NavlibClient.py index 9a3488f1ed..68bbcf5772 100644 --- a/plugins/3DConnexion/NavlibClient.py +++ b/plugins/3DConnexion/NavlibClient.py @@ -3,7 +3,7 @@ from UM.Math.Vector import Vector from UM.Math.AxisAlignedBox import AxisAlignedBox from cura.PickingPass import PickingPass from UM.Scene.Iterator.DepthFirstIterator import DepthFirstIterator -from UM.Scene import SceneNode +from UM.Scene.SceneNode import SceneNode from UM.Resources import Resources from UM.PluginObject import PluginObject from UM.Logger import Logger From 14367665dcddaed76a8d0af2b7cdefc9e26d3341 Mon Sep 17 00:00:00 2001 From: Erwan MATHIEU Date: Thu, 20 Feb 2025 08:40:12 +0100 Subject: [PATCH 5/5] Add note for platform availability CURA-12407 --- resources/bundled_packages/cura.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/bundled_packages/cura.json b/resources/bundled_packages/cura.json index e3e4f02c1f..1b32ee3484 100644 --- a/resources/bundled_packages/cura.json +++ b/resources/bundled_packages/cura.json @@ -4,7 +4,7 @@ "package_id": "3DConnexion", "package_type": "plugin", "display_name": "3DConnexion mouses", - "description": "Allows working with 3D mouses inside Cura.", + "description": "Allows working with 3D mouses inside Cura.\nOnly available on Windows and MacOS.", "package_version": "1.0.0", "sdk_version": "8.6.0", "website": "https://3dconnexion.com",