BS-JD-103 - Brush element edit modes #12

Closed
opened 2026-06-06 01:46:32 -04:00 by Rbanh · 9 comments
Owner

Summary

Add vertex, edge, face, and clip edit modes for selected brushes.

Why

Useful blockout requires editing existing brush geometry without recreating whole shapes.

Implementation notes

  • Add edit mode state for brush element selection.
  • Implement vertex/edge/face transform operations.
  • Add clip plane tool for splitting or trimming convex brushes.
  • Keep generated mesh/collider rebuilds debounced and dirty-region aware where possible.

Acceptance criteria

  • Brush vertices, edges, and faces can be selected and transformed.
  • Clip mode previews result before commit.
  • Invalid edits are rejected with clear status text.
  • Edits are undoable as grouped operations.

Tests/docs

Geometry edit tests, invalid edit tests, and undo invariants. Update brush editing docs.

## Summary Add vertex, edge, face, and clip edit modes for selected brushes. ## Why Useful blockout requires editing existing brush geometry without recreating whole shapes. ## Implementation notes - Add edit mode state for brush element selection. - Implement vertex/edge/face transform operations. - Add clip plane tool for splitting or trimming convex brushes. - Keep generated mesh/collider rebuilds debounced and dirty-region aware where possible. ## Acceptance criteria - [ ] Brush vertices, edges, and faces can be selected and transformed. - [ ] Clip mode previews result before commit. - [ ] Invalid edits are rejected with clear status text. - [ ] Edits are undoable as grouped operations. ## Tests/docs Geometry edit tests, invalid edit tests, and undo invariants. Update brush editing docs.
Rbanh added this to the M1 - Brush-based blockout milestone 2026-06-06 01:46:32 -04:00
Rbanh added the
roadmap:jackdaw
type:feature
priority:P0
area:brushes
labels 2026-06-06 01:46:32 -04:00
Author
Owner

Starting implementation for BS-JD-103 - Brush element edit modes.

Plan for the next slice:

  • Add BrushEditMode resource and hotkeys for Object / Vertex / Edge / Face / Clip.
  • Only activate element modes when a brush actor is selected.
  • Add viewport element overlays for selected brushes: vertex handles, edge lines, face centers/normals, clip preview plane.
  • Add custom viewport picking for brush elements, storing selected vertex/edge/face IDs separately from actor selection.
  • Keep object selection/gizmos stable while in object mode; suppress ordinary object picking while element picking owns the click.
  • Update docs and tests around selection state/mode transitions.

I will keep this ticket open until element dragging/edit commits are implemented and verified.

Starting implementation for `BS-JD-103 - Brush element edit modes`. Plan for the next slice: - Add `BrushEditMode` resource and hotkeys for Object / Vertex / Edge / Face / Clip. - Only activate element modes when a brush actor is selected. - Add viewport element overlays for selected brushes: vertex handles, edge lines, face centers/normals, clip preview plane. - Add custom viewport picking for brush elements, storing selected vertex/edge/face IDs separately from actor selection. - Keep object selection/gizmos stable while in object mode; suppress ordinary object picking while element picking owns the click. - Update docs and tests around selection state/mode transitions. I will keep this ticket open until element dragging/edit commits are implemented and verified.
Author
Owner

Progress checkpoint committed as 0bfc062 Add brush element edit modes.

Implemented so far:

  • Added BrushEditMode resource: Object, Vertex, Edge, Face, Clip.
  • Added BrushElementSelection for brush element selection independent of actor selection.
  • Hotkeys with a selected brush: 1 vertex, 2 edge, 3 face, 4 clip; Esc returns to Object mode.
  • Added viewport overlays for vertices, edges, face centers/normals, and clip-oriented edge/face views.
  • Added custom brush element picking from viewport raycasts with Shift multi-select.
  • Ordinary object selection now yields while a brush element mode is active.
  • Added Brush: <mode> viewport badge.
  • Updated README and docs/editor/brushes.md.

Verification:

  • cargo fmt --check
  • cargo test -p editor brush_edit
  • cargo check --workspace --all-targets
  • cargo check --workspace --all-targets --all-features

Remaining before closing this ticket:

  • Drag/edit selected vertices, edges, and faces with convexity validation.
  • Commit edits as undoable history operations.
  • Clip mode should apply a split or explicit preview/commit behavior.
Progress checkpoint committed as `0bfc062 Add brush element edit modes`. Implemented so far: - Added `BrushEditMode` resource: Object, Vertex, Edge, Face, Clip. - Added `BrushElementSelection` for brush element selection independent of actor selection. - Hotkeys with a selected brush: `1` vertex, `2` edge, `3` face, `4` clip; `Esc` returns to Object mode. - Added viewport overlays for vertices, edges, face centers/normals, and clip-oriented edge/face views. - Added custom brush element picking from viewport raycasts with Shift multi-select. - Ordinary object selection now yields while a brush element mode is active. - Added `Brush: <mode>` viewport badge. - Updated README and `docs/editor/brushes.md`. Verification: - `cargo fmt --check` - `cargo test -p editor brush_edit` - `cargo check --workspace --all-targets` - `cargo check --workspace --all-targets --all-features` Remaining before closing this ticket: - Drag/edit selected vertices, edges, and faces with convexity validation. - Commit edits as undoable history operations. - Clip mode should apply a split or explicit preview/commit behavior.
Author
Owner

Second progress checkpoint committed as 93ab6c2 Add brush element drag edits.

Added:

  • Vertex/edge/face element drags on the viewport floor plane.
  • Drag preview mutates the selected brush live.
  • Matching duplicated corner vertices are moved across all faces so cube/prism brushes remain welded.
  • Face planes are recomputed after edits.
  • Releasing LMB commits a single undoable SetBrush command.
  • Added tests for face hit-test winding and welded vertex movement.
  • Updated docs to distinguish supported vertex/edge/face drag edits from pending clip split behavior.

Verification:

  • cargo fmt --check
  • cargo test -p editor brush_edit
  • cargo check --workspace --all-targets
  • cargo check --workspace --all-targets --all-features

Remaining before closing #12:

  • Clip mode needs an explicit split/commit behavior. I may implement a minimal clip-plane preview here, but actual split/CSG application likely belongs with #13 (BS-JD-104 - Brush CSG operations).
Second progress checkpoint committed as `93ab6c2 Add brush element drag edits`. Added: - Vertex/edge/face element drags on the viewport floor plane. - Drag preview mutates the selected brush live. - Matching duplicated corner vertices are moved across all faces so cube/prism brushes remain welded. - Face planes are recomputed after edits. - Releasing LMB commits a single undoable `SetBrush` command. - Added tests for face hit-test winding and welded vertex movement. - Updated docs to distinguish supported vertex/edge/face drag edits from pending clip split behavior. Verification: - `cargo fmt --check` - `cargo test -p editor brush_edit` - `cargo check --workspace --all-targets` - `cargo check --workspace --all-targets --all-features` Remaining before closing #12: - Clip mode needs an explicit split/commit behavior. I may implement a minimal clip-plane preview here, but actual split/CSG application likely belongs with #13 (`BS-JD-104 - Brush CSG operations`).
Author
Owner

Checkpoint pushed: d9e52d7 Reject invalid brush element edits.

Implemented:

  • Vertex/edge/face drag edits now validate the resulting BrushDesc on LMB release before committing history.
  • Invalid drag results are rejected, the brush component is restored to the pre-drag value, and operator/status text reports the first validation error.
  • Valid drag results still commit as one undoable SetBrush operation.
  • Added a regression test for a collapsed face drag producing invalid brush geometry.
  • Updated brush editing docs.

Verification:

  • cargo fmt --check
  • cargo test -p editor brush_edit
  • cargo check -p editor --all-targets
  • cargo check --workspace --all-targets
  • cargo check --workspace --all-targets --all-features

Remaining follow-up for the full ticket: clip mode still needs actual preview + commit behavior.

Checkpoint pushed: `d9e52d7 Reject invalid brush element edits`. Implemented: - Vertex/edge/face drag edits now validate the resulting `BrushDesc` on LMB release before committing history. - Invalid drag results are rejected, the brush component is restored to the pre-drag value, and operator/status text reports the first validation error. - Valid drag results still commit as one undoable `SetBrush` operation. - Added a regression test for a collapsed face drag producing invalid brush geometry. - Updated brush editing docs. Verification: - `cargo fmt --check` - `cargo test -p editor brush_edit` - `cargo check -p editor --all-targets` - `cargo check --workspace --all-targets` - `cargo check --workspace --all-targets --all-features` Remaining follow-up for the full ticket: clip mode still needs actual preview + commit behavior.
Author
Owner

Completion checkpoint pushed: f09d35e Add brush clip preview.

Implemented:

  • Clip mode now previews a bounds-based half-brush trim when exactly one face is selected.
  • The selected face chooses the dominant normal axis and side to keep; a magenta wireframe shows the pending clipped bounds.
  • Enter commits the clip through existing transform/brush history paths; Esc keeps the existing Object-mode cancel behavior.
  • Added a regression test for +X face clip preview producing a valid half-width brush and shifted transform.
  • Updated brush docs.

Full #12 coverage now includes:

  • Vertex/edge/face selection and transforms.
  • Invalid element drags rejected with status and reverted before history commit.
  • Undoable valid brush edits.
  • Bounds-based Clip mode preview + Enter commit.

Verification:

  • cargo fmt --check
  • cargo test -p editor brush_edit
  • cargo check -p editor --all-targets
  • cargo check --workspace --all-targets
  • cargo check --workspace --all-targets --all-features

Known limitation: Clip is the documented bounds-based MVP, not arbitrary plane clipping or split-into-two output.

Completion checkpoint pushed: `f09d35e Add brush clip preview`. Implemented: - Clip mode now previews a bounds-based half-brush trim when exactly one face is selected. - The selected face chooses the dominant normal axis and side to keep; a magenta wireframe shows the pending clipped bounds. - Enter commits the clip through existing transform/brush history paths; Esc keeps the existing Object-mode cancel behavior. - Added a regression test for +X face clip preview producing a valid half-width brush and shifted transform. - Updated brush docs. Full #12 coverage now includes: - Vertex/edge/face selection and transforms. - Invalid element drags rejected with status and reverted before history commit. - Undoable valid brush edits. - Bounds-based Clip mode preview + Enter commit. Verification: - `cargo fmt --check` - `cargo test -p editor brush_edit` - `cargo check -p editor --all-targets` - `cargo check --workspace --all-targets` - `cargo check --workspace --all-targets --all-features` Known limitation: Clip is the documented bounds-based MVP, not arbitrary plane clipping or split-into-two output.
Rbanh closed this issue 2026-06-06 06:49:09 -04:00
Author
Owner

QA checklist hardening committed locally as 1b9fbeb (Group brush clip history edits). Not pushed.

Fix:

  • Clip commit now uses one grouped SetBrushTransform history command instead of separate transform and brush history entries.
  • Undo/redo for a clip edit should now step the whole clip operation together.
  • Added regression coverage for the grouped clip command label.

Verification:

  • cargo fmt --check
  • cargo test -p editor brush_edit
  • cargo check -p editor --all-targets
  • cargo check --workspace --all-targets
  • cargo check --workspace --all-targets --all-features
QA checklist hardening committed locally as `1b9fbeb` (`Group brush clip history edits`). Not pushed. Fix: - Clip commit now uses one grouped `SetBrushTransform` history command instead of separate transform and brush history entries. - Undo/redo for a clip edit should now step the whole clip operation together. - Added regression coverage for the grouped clip command label. Verification: - `cargo fmt --check` - `cargo test -p editor brush_edit` - `cargo check -p editor --all-targets` - `cargo check --workspace --all-targets` - `cargo check --workspace --all-targets --all-features`
Rbanh reopened this issue 2026-06-06 14:38:01 -04:00
Author
Owner

Reopened after editor QA found brush element editing was not usable enough for acceptance: element modes did not clearly distinguish themselves, the actor transform gizmo stayed active, and press/drag behavior could move or snap geometry unpredictably.

Local QA-ready fix is implemented but not pushed:

  • Actor GizmoTargets are removed while Vertex/Edge/Face/Clip brush element modes are active, so the actor gizmo no longer moves the whole brush during element editing.
  • Brush element mode now shows a stronger viewport banner with active mode, selected element count, key hints, and Actor gizmo off state.
  • Element movement now requires pressing on an already-selected element. First click selects; a subsequent press/drag on that selected vertex/edge/face moves it. This avoids selection clicks starting an unintended floor-plane drag.
  • README and brush editor docs were updated for the interaction model.

Verification passed locally:

  • cargo fmt --check
  • cargo test -p editor brush_edit
  • cargo check -p editor --all-targets
  • cargo check --workspace --all-targets
  • cargo check --workspace --all-targets --all-features

Awaiting user QA before commit/push/signoff.

Reopened after editor QA found brush element editing was not usable enough for acceptance: element modes did not clearly distinguish themselves, the actor transform gizmo stayed active, and press/drag behavior could move or snap geometry unpredictably. Local QA-ready fix is implemented but not pushed: - Actor `GizmoTarget`s are removed while Vertex/Edge/Face/Clip brush element modes are active, so the actor gizmo no longer moves the whole brush during element editing. - Brush element mode now shows a stronger viewport banner with active mode, selected element count, key hints, and `Actor gizmo off` state. - Element movement now requires pressing on an already-selected element. First click selects; a subsequent press/drag on that selected vertex/edge/face moves it. This avoids selection clicks starting an unintended floor-plane drag. - README and brush editor docs were updated for the interaction model. Verification passed locally: - `cargo fmt --check` - `cargo test -p editor brush_edit` - `cargo check -p editor --all-targets` - `cargo check --workspace --all-targets` - `cargo check --workspace --all-targets --all-features` Awaiting user QA before commit/push/signoff.
Author
Owner

Updated the local QA-ready fix after review: brush element editing now uses a real transform gizmo for the selected element set instead of viewport floor-plane click/drag.

Current local behavior:

  • Vertex/Edge/Face modes spawn an editor-only brush element gizmo at the selected element pivot.
  • W, E, and R drive translate, rotate, and scale through the normal transform gizmo.
  • The normal actor gizmo remains suppressed in element modes, but the element gizmo target is preserved.
  • Gizmo deltas are applied to matching welded brush vertices, face planes are recomputed, and the edit is committed as one SetBrush history operation when the gizmo releases.
  • The history transform capture ignores the transient brush element gizmo so it does not create bogus actor transform history.
  • The old horizontal floor-plane drag path has been removed.
  • README and brush docs now describe the gizmo-based element workflow.

Verification passed locally:

  • cargo fmt
  • cargo test -p editor brush_edit
  • cargo check -p editor --all-targets
  • cargo check --workspace --all-targets
  • cargo check --workspace --all-targets --all-features

Awaiting user QA before commit/push/signoff.

Updated the local QA-ready fix after review: brush element editing now uses a real transform gizmo for the selected element set instead of viewport floor-plane click/drag. Current local behavior: - Vertex/Edge/Face modes spawn an editor-only brush element gizmo at the selected element pivot. - `W`, `E`, and `R` drive translate, rotate, and scale through the normal transform gizmo. - The normal actor gizmo remains suppressed in element modes, but the element gizmo target is preserved. - Gizmo deltas are applied to matching welded brush vertices, face planes are recomputed, and the edit is committed as one `SetBrush` history operation when the gizmo releases. - The history transform capture ignores the transient brush element gizmo so it does not create bogus actor transform history. - The old horizontal floor-plane drag path has been removed. - README and brush docs now describe the gizmo-based element workflow. Verification passed locally: - `cargo fmt` - `cargo test -p editor brush_edit` - `cargo check -p editor --all-targets` - `cargo check --workspace --all-targets` - `cargo check --workspace --all-targets --all-features` Awaiting user QA before commit/push/signoff.
Author
Owner

Current Bevy 0.19 tree re-verification for BS-JD-103:

Implemented behavior present locally:

  • Vertex/Edge/Face/Clip modes are wired through BrushEditMode and BrushElementSelection.
  • Selected brush elements use the standard transform gizmo via BrushElementGizmo.
  • Actor gizmo capture ignores transient brush element gizmos.
  • Valid element edits commit as grouped brush history operations; invalid edits restore the previous brush and report status.
  • Clip mode has a bounds-based preview and grouped Enter commit.

Verification run on 2026-06-24:

  • cargo test -p editor brush_edit -> 5 passed
  • cargo check -p editor --all-targets -> passed

Closing the implementation ticket. The broader interactive acceptance pass remains tracked by #37.

Current Bevy 0.19 tree re-verification for BS-JD-103: Implemented behavior present locally: - Vertex/Edge/Face/Clip modes are wired through `BrushEditMode` and `BrushElementSelection`. - Selected brush elements use the standard transform gizmo via `BrushElementGizmo`. - Actor gizmo capture ignores transient brush element gizmos. - Valid element edits commit as grouped brush history operations; invalid edits restore the previous brush and report status. - Clip mode has a bounds-based preview and grouped Enter commit. Verification run on 2026-06-24: - `cargo test -p editor brush_edit` -> 5 passed - `cargo check -p editor --all-targets` -> passed Closing the implementation ticket. The broader interactive acceptance pass remains tracked by #37.
Rbanh closed this issue 2026-06-24 12:36:41 -04:00
Sign in to join this conversation.
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: Falling-Metal-Interactive/Blacksite#12
No description provided.