Changelog¶
All notable changes to NavCube are documented here. This project follows Semantic Versioning.
v1.0.1¶
DPI and adaptive sizing fix.
Fixed¶
- NavCube size now stable across all display scale factors.
The previous implementation used
logicalDotsPerInch() / 96as a multiplier, causing Qt 6's automatic HiDPI scaling to double-scale the widget — at 150 % Windows zoom the cube appeared ~2.25× larger than intended. The new formula usesphysicalDotsPerInch()anddevicePixelRatio()to target a consistent physical size (≈ 26.5 mm) on every display at every OS scale factor: 100 %, 125 %, 150 %, 200 %, 4K, and Retina.
Added¶
NavCubeStyle.size_fraction— when > 0, sizes the cube as a percentage of the parent widget's shorter side with automatic parent-resize tracking via an event filter.NavCubeStyle.size_min/size_max— clamp bounds (in 96-dpi-equivalent pixels) used withsize_fraction.NavCubeOverlaynow installs a parent event filter whensize_fraction > 0, so the cube resizes synchronously before the host'sresizeEventhandler repositions it — no layout jitter.
v1.0.0¶
Initial release.
This is the first public version of NavCube — extracted from Osdag and polished into a standalone library.
What's included¶
NavCubeOverlay — a pure PySide6 widget that draws a FreeCAD-style NaviCube with QPainter:
- 6 main faces, 12 edge faces, 8 corner faces with FreeCAD-style chamfered geometry
- Orbit buttons (North/South/East/West), roll arrows (Left/Right), home button, and backside dot
- Smooth quaternion SLERP animations with antipodal handling — no NaN crashes on 180° flips
- Quintic ease-in-out animation curve for natural-feeling motion
- Per-face Lambertian shading with configurable light direction
- Back-face culling with a configurable visibility threshold
- DPI-aware rendering that recalculates automatically when moved between monitors
- Overlay mode (transparent floating window) and inline mode (standard QWidget)
- Light and dark theme support with automatic detection from QPalette
NavCubeStyle — full visual control through a Python dataclass:
- 60+ configurable fields covering geometry, animation, colors, fonts, labels, borders, and shadows
- Runtime style swapping via set_style() with a full rebuild and repaint
- Separate light-theme and dark-theme color palettes
- Customizable face labels — any language, any script
- Configurable font family, weight, and size constraints
- Optional XYZ axis gizmo with configurable colors
Coordinate system support:
- Z-up by default (OCC, FreeCAD, Blender)
- Y-up via _WORLD_ROT class attribute override (Three.js, Unity, Unreal)
- Clear sign convention: push_camera() takes the inward direction, viewOrientationRequested emits the outward direction
OCCNavCubeSync — OCC V3d_View connector:
- Adaptive poll rate: every tick during interaction, every 4 ticks at idle
- Atomic camera updates via Camera.SetEye() + Camera.SetUp() to eliminate animation flicker
- Fallback to SetProj/SetUp for older pythonocc builds
- Clean teardown with no dangling references
VTKNavCubeSync — VTK renderer connector: - Same architecture and API as the OCC connector
SLERP smoothing during live camera interaction: - Quaternion-based smoothing (alpha 0.65) absorbs momentary renderer instabilities - ~8 ms effective visual lag — imperceptible in use - Automatically turns off when interaction ends
Dependencies¶
- Python 3.10+
- PySide6
- NumPy
- Optional:
pythonocc-core(OCC connector) - Optional:
vtk(VTK connector)
License¶
LGPL-2.1