Skip to content

Add a FreeCAD-style navigation cube with rotation arrows#591

Open
markomarkovic wants to merge 4 commits into
CadQuery:masterfrom
markomarkovic:navigation-cube
Open

Add a FreeCAD-style navigation cube with rotation arrows#591
markomarkovic wants to merge 4 commits into
CadQuery:masterfrom
markomarkovic:navigation-cube

Conversation

@markomarkovic

Copy link
Copy Markdown

Navigation cube

This PR adds an interactive navigation cube to the upper-right corner of the 3D viewport, similar to FreeCAD's, plus two curved arrow buttons that roll the view in 45° steps around the screen-normal axis. It addresses the common problem of losing orientation with the Turntable/Trackball controls by providing a persistent orientation reference with one-click reorientation.

Features

  • The cube is OCCT's native AIS_ViewCube, displayed as a transform-persistent object in the existing view — it follows every rotation source (both orbit methods, keyboard shortcuts, toolbar view actions) with no camera-sync code, keeps a constant screen size, and is unaffected by zoom
  • Clicking a face, edge or corner starts an eased camera animation to that orientation; zoom, center, distance and projection type are preserved (OCCT's default fit-on-click is undone by re-framing the animation's target camera)
  • Cube faces/edges/corners and the arrows highlight on hover; hover detection is confined to the cube's screen region, so the rest of the viewport keeps its existing no-hover behavior, and selection semantics are unchanged
  • The rotation arrows are screen-fixed 2D overlays (they don't rotate with the camera) that roll the camera as a pure animated rotation
  • New "Show navigation cube" preference (default on); the overlay objects are excluded from fit()
  • The cube's FRONT/BACK labels match the toolbar's Front/Back actions. Note this is the opposite of OCCT's default (which labels the −Y face FRONT, as FreeCAD does); since CQ-editor's front_view looks from +Y, consistency with the existing toolbar was chosen over OCCT's convention. As a consequence the default Iso view faces the side labeled BACK — happy to flip the convention instead if that's preferred.

Implementation notes

  • A few non-obvious OCCT behaviors are handled and covered by tests: HandleClick requires ViewAnimation().SetView() (segfault otherwise) and a LastActiveView; the finishing animation frame only invalidates the view (an explicit redraw is needed); clicks landing mid-animation must settle the running animation first, or OCCT's repeated-click detection (which snaps the camera up vector to its canonical value) compares against a partially rotated camera
  • 14 new tests in tests/test_navigation_cube.py (pytest-qt), covering display, reorientation with zoom/center/pan preservation, animation edge cases, hover, the preference, and fit() exclusion

Disclosure

The code in this PR was written by an AI assistant (Claude, by Anthropic) working under my direction: I specified the feature, made the design decisions, tested the result interactively, and reviewed the changes. Happy to adjust anything that doesn't fit the project's conventions.

Renders OCCT's AIS_ViewCube as a transform-persistent overlay in the
upper-right corner of the viewport: it always reflects the current
camera orientation, keeps a constant screen size and allows one-click
reorientation. Clicking a face, edge or corner starts an eased camera
animation that preserves zoom, center, distance and projection type.
Cube parts highlight on hover; hovering is confined to the cube's
corner region so the rest of the viewport keeps its no-hover behavior.
The cube can be toggled with the new 'Show navigation cube' preference
and is excluded from fit(). FRONT/BACK labels follow the toolbar's
Front/Back view actions.
Two curved arrow buttons above the navigation cube, similar to
FreeCAD's, roll the camera around the screen-normal axis in animated
45 degree steps (pure roll: projection, zoom, center and distance are
preserved). The arrows are screen-fixed 2D overlays that do not rotate
with the camera, fill with the highlight color on hover, share the
'Show navigation cube' preference and are excluded from fit().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant