SpaceMouse (3Dconnexion) navigation for Foundry Mari.
Mari has no native SpaceMouse support. Space Calipers adds it — as a single Python script, no compiled code, no 3DxWare driver required. It talks to the device directly over raw HID and drives Mari's camera through the Python API.
Part of the Calipers tool family: Face Calipers, Asset Calipers, Space Calipers.
- 3D viewport — orbit / pan / dolly, in both perspective and orthographic projections (ortho zoom correctly drives the camera scale)
- Rotation styles — Turntable (horizon stays level — ideal for character work), Trackball (free), Fly (first-person)
- Orbit pivots — View target, Object center, World origin
- UV (2D) view — slide the cap to pan, tilt forward/back to zoom
- Node Graph — same pan/zoom scheme, active while your mouse cursor is over the graph; move the cursor away and the cap controls the viewport again
- Adaptive clipping — near/far planes follow the camera so close-ups don't slice geometry (Mari only auto-adjusts clips during its own navigation)
- Dockable settings palette — View > Palettes > SpaceMouse: per-panel sensitivity, per-axis inverts, deadzone, smoothing; everything persists between sessions
- Device buttons — left button restores a saved view, right button saves the current view
| Component | Version |
|---|---|
| Mari | 7.1 (Python 3.10) |
| OS | Windows 11 |
| Device | SpaceMouse Wireless Bluetooth Edition, via 3Dconnexion Universal Receiver |
Other SpaceMouse models should work — the HID backend matches any 3Dconnexion
multi-axis controller (vendor IDs 0x046D, 0x256F) and understands both the
split and the combined 12-byte report formats. If your model doesn't,
please open an issue with the output of the enumeration snippet from
Troubleshooting.
Mari bundles its own Python interpreter, so the package must match Mari's Python version, not your system's. Check it in Mari's Python Console:
import sys; print(sys.version) # e.g. 3.10.10 -> cp310Then, in a regular terminal (adjust 310 to your version):
mkdir C:\MariLibs
pip download hidapi --python-version 310 --implementation cp --platform win_amd64 --only-binary=:all: -d C:\MariLibs\wheels
tar -xf C:\MariLibs\wheels\hidapi-<version>-cp310-cp310-win_amd64.whl -C C:\MariLibs
A .whl is a zip archive — the tar command (built into Windows 10/11)
unpacks it so that hid.cp310-win_amd64.pyd sits directly in C:\MariLibs.
Using a different folder? Edit
EXTRA_SITE_DIRat the top of the script. Avoid paths insideDocumentsif OneDrive redirection is active — pip and Mari may disagree about whereDocumentsactually is.
Copy mari_spacemouse.py into:
%USERPROFILE%\Documents\Mari\Scripts\
(or any directory listed in your MARI_SCRIPT_PATH).
Edit > Preferences > GPU > uncheck "Pause Canvas Rendering" — otherwise the viewport only updates while the mouse cursor is over it, which defeats the purpose of a second navigation device.
Navigation starts automatically (toggleable in the palette). The settings palette lives in View > Palettes > SpaceMouse.
| Motion | 3D viewport | UV view | Node Graph |
|---|---|---|---|
| Slide left/right | Pan | Pan | Pan |
| Push/pull | Zoom (dolly) | Pan vertical | Pan vertical |
| Tilt forward/back | Orbit vertical | Zoom | Zoom |
| Twist | Orbit horizontal | — | — |
| Lift | Pan vertical | — | — |
| Left button | Restore saved view | ||
| Right button | Save current view |
Every axis can be inverted per panel; speeds are per panel too.
"SpaceMouse not found / No module named 'hid'" — the hidapi wheel is
missing, unpacked in the wrong place, or built for the wrong Python version.
Re-check step 1; the wheel tag (cp310) must match Mari's Python.
Device not found, but hidapi imports fine — check what Windows exposes. In Mari's Python Console:
import hid
for d in hid.enumerate():
if d['vendor_id'] in (0x046D, 0x256F):
print(hex(d['product_id']), d.get('usage_page'), d.get('usage'), d['product_string'])You want a line with usage_page 1, usage 8 (Multi-axis Controller). If the
list is empty: try the USB cable or the Universal Receiver instead of
Bluetooth, and/or kill the 3DxService process — the official driver can
hold the device.
Zoom appears dead — check which projection tab you're in. In the Ortho view, moving the camera doesn't change the image (that's how orthographic projection works); Space Calipers handles this by driving the camera scale, but only when it correctly detects the ortho camera. If it persists, open an issue with your Mari version.
Viewport freezes when the cursor leaves it — you skipped step 3 (Pause Canvas Rendering).
Camera creeps when the cap is released — wireless models can have zero drift; raise Deadzone to 0.05–0.08.
No 3DxWare SDK, no compiled extension. The script reads the device's HID
input reports directly via hidapi, filters them (deadzone + exponential
smoothing), and applies the motion to mari.canvases.current().camera()
via translation / lookAt / up / scale at ~60 Hz from a Qt timer.
Panel routing is cursor-aware: a QGraphicsView under the mouse cursor
(the Node Graph) takes priority; otherwise the active canvas receives the
input, with the UV camera type getting the 2D scheme.
MIT — see LICENSE.