UsdLayerManager/openspec/changes/undo-redo-scene-editing/proposal.md

2.8 KiB

Why

The application currently applies all edits (transforms, attribute changes, prim creation/deletion, layer operations) directly to the live USD stage with no reversal mechanism, making it impossible to correct mistakes without closing and reopening the scene. Undo/redo is a foundational feature expected in any scene editor, and its absence is a critical usability gap.

What Changes

  • Introduce a CommandHistory class (command pattern) that records reversible ICommand objects.
  • Wrap all mutating operations — prim create, prim delete, add/replace reference, transform gizmo drag, property panel TRS edits, arbitrary attribute edits, and layer management operations — in concrete ICommand subclasses with Execute() / Undo() pairs.
  • Expose Ctrl+Z / Ctrl+Y (and Ctrl+Shift+Z) global hotkeys processed in the main loop.
  • Integrate gizmo drag commits: the TransformManipulator currently emits continuous per-frame deltas; it will instead emit a single command on drag-end so that one undo step reverses the entire drag.
  • Add Edit → Undo / Redo menu items with greyed-out state when the stack is empty.
  • Clear the history stack on stage close / new stage open (invalid USD references cannot be safely replayed).

Capabilities

New Capabilities

  • command-history: Core undo/redo stack — ICommand interface, CommandHistory manager, hotkey dispatch, and menu integration.
  • undoable-transform-edits: Commands wrapping UsdGeomXformCommonAPI writes from both the viewport gizmo and the Property panel.
  • undoable-scene-edits: Commands wrapping prim creation, prim deletion, add-reference, and replace-reference operations.
  • undoable-attribute-edits: Command wrapping arbitrary UsdAttribute::Set<T> calls from PropertyManager.
  • undoable-layer-ops: Commands wrapping LayerManager sublayer create, remove, reorder, and mute/unmute operations.

Modified Capabilities

(none — no existing spec-level requirements are being tightened or relaxed)

Impact

  • New file: src/core/CommandHistory.h/.cppICommand, CommandHistory.
  • New files: src/core/commands/ — one .h/.cpp pair per concrete command group.
  • Modified: src/ui/TransformManipulator.cpp — capture drag-start state, emit command on drag-end instead of applying incremental deltas.
  • Modified: src/ui/PropertyPanel.cpp — wrap TRS writes in commands.
  • Modified: src/ui/SceneHierarchyPanel.cpp — wrap create/delete/ref operations in commands.
  • Modified: src/core/PropertyManager.cpp — wrap SetPropertyValue in command.
  • Modified: src/ui/LayerPanel.cpp — wrap layer CRUD in commands.
  • Modified: src/ui/Application.cpp — add CommandHistory member, hotkey handling, Edit menu.
  • Modified: CMakeLists.txt — add new source files.
  • No new external dependencies.