Merge pull request #20287 from Ultimaker/CURA-12407_3DConnexion-mouses-as-plugin

CURA-12407 Move 3DConnexion support to plugin
This commit is contained in:
Erwan MATHIEU 2025-02-20 10:00:30 +01:00 committed by GitHub
commit 8c4fe9c1ab
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 63 additions and 28 deletions

View File

@ -125,6 +125,7 @@ pyinstaller:
- "PyQt6.sip"
- "stl"
- "keyrings.alt"
- "pynavlib"
collect_all_WINDOWS_ONLY:
- "PyQt6.Qt"
- "PyQt6.Qt6"

View File

@ -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()

View File

@ -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.SceneNode 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.):

View File

@ -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 { }

View File

@ -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"
}

View File

@ -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.\nOnly available on Windows and MacOS.",
"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",