Cura/plugins/3DConnexion/__init__.py
google-labs-jules[bot] 4698089f2a Add SpaceMouse support for Linux via libspnav
This change introduces support for 3Dconnexion SpaceMouse devices on Linux
within the 3DConnexion plugin.

Key changes:
-   Added `LinuxSpacenavClient.py`, which uses `ctypes` to interface with the
    system-provided `libspnav.so.0` library. This client handles opening a
    connection to the `spacenavd` daemon and polling for motion and button
    events.
-   Modified `NavlibClient.py` to include platform detection. On Linux, it
    now uses `LinuxSpacenavClient` for device input. On Windows and macOS,
    it continues to use the existing `pynavlib`.
-   Updated the plugin initialization in `plugins/3DConnexion/__init__.py`
    to gracefully handle cases where `libspnav.so.0` might be missing or
    `spacenavd` is not accessible on Linux, disabling the plugin in such
    scenarios.
-   The core camera manipulation logic in `NavlibClient.py` has been adapted
    to accept transformation matrices from either `pynavlib` or the new
    Linux client, aiming for consistent behavior.
-   Placeholder adaptations for some `pynavlib`-specific methods have been
    added for the Linux path, returning `None` or basic Python types where
    `pynav.*` types were previously used.

This implementation relies on you having `spacenavd` (version 0.6 or newer recommended)
installed and running, along with `libspnav0` (or equivalent).

Testing for this feature is currently manual, involving checking device
response for camera manipulation (pan, zoom, rotate) within Cura on a
Linux environment with a configured SpaceMouse.

Output:
2025-05-23 14:25:32 +00:00

41 lines
1.5 KiB
Python

# Copyright (c) 2025 UltiMaker
# 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 {
"tool": {
"visible": False
}
}
def register(app: "Application") -> Dict[str, Any]:
try:
from .NavlibClient import NavlibClient
client = NavlibClient(app.getController().getScene(), app.getRenderer())
# Check for Linux-specific initialization failure
if hasattr(client, "_platform_system") and client._platform_system == "Linux":
if not hasattr(client, "_linux_spacenav_client") or \
client._linux_spacenav_client is None or \
not client._linux_spacenav_client.available:
Logger.warning("Failed to initialize LinuxSpacenavClient. 3Dconnexion plugin will be disabled on Linux.")
return {} # Disable plugin on Linux due to internal init failure
# If pynavlib failed on non-Linux, it would likely raise an import error or similar,
# caught by the BaseException below.
# If on Linux and the above check passed, or on other platforms and NavlibClient init was successful.
return {"tool": client}
except BaseException as exception:
Logger.warning(f"Unable to load or initialize 3Dconnexion client: {exception}")
return {}