Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 27 additions & 13 deletions agents/plans/README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,39 @@
# Feature plans

Long-lived design notes for features not yet (or not fully) implemented.
Long-lived design notes for features. Keep files after shipping as reference (`status: done`).

**Token rule:** Do **not** load files in this directory unless the user prompt is clearly about that feature. See [conventions/token-lean.md](../conventions/token-lean.md). Never bulk-load `plans/`.

## Status values

YAML `status` at the top of each plan:

| Status | Meaning |
| ---------- | ------------------------------------------------- |
| `planning` | Design only / not started |
| `partial` | Useful slice shipped; acceptance criteria open |
| `done` | Plan scope met; file kept as reference |
| `deferred` | Explicitly postponed (post-v1, blocked, or later) |

Update `status` when a matching PR merges or the work is shelved. Prefer `done` over synonyms (`implemented`, etc.).

## Discovery order (sketch-from-shape track)

```text
shp-origin-orientation --> cross-section-tool --> sketch-from-shape-section
(frame first) (prototype/learn) (deferred until findings)
(partial) (done) (partial)

sketch-mode-shape-faint (parallel UX: ghost/wire shapes while sketching)
sketch-mode-shape-faint (done; parallel UX)
```

| Plan | Load only when prompt is about |
| ---------------------------------------------------------------- | ---------------------------------------------------------------------- |
| [shp-origin-orientation.md](shp-origin-orientation.md) | shape origin, shape frame, shape axes / orientation annotation |
| [cross-section-tool.md](cross-section-tool.md) | cross-section tool, section cut preview, cutting-plane experiment |
| [sketch-from-shape-section.md](sketch-from-shape-section.md) | "sketch from shape", section → editable sketch (end-state; deferred) |
| [sketch-mode-shape-faint.md](sketch-mode-shape-faint.md) | faint/ghost/wireframe shapes in sketch mode, alpha blending solids |
| [shape-list-hierarchy-phase3.md](shape-list-hierarchy-phase3.md) | parent transform inheritance, Parts/planes, Boolean history (#214) |
| [wasm-multithreading.md](wasm-multithreading.md) | WASM/Emscripten pthreads, SharedArrayBuffer, parallel OCCT on web |
| [wasm-alt-drag-multiselect.md](wasm-alt-drag-multiselect.md) | WASM Alt+LMB drag rectangle multi-select broken (#220) |
| [configurable-hotkeys.md](configurable-hotkeys.md) | remappable shortcuts, keybindings, `gui.hotkeys`, free Dimension off D |
| Plan | Status | Load only when prompt is about |
| ---------------------------------------------------------------- | ---------- | ---------------------------------------------------------------------- |
| [shp-origin-orientation.md](shp-origin-orientation.md) | partial | shape origin, shape frame, shape axes / orientation annotation |
| [cross-section-tool.md](cross-section-tool.md) | done | cross-section tool, section cut preview, cutting-plane experiment |
| [sketch-from-shape-section.md](sketch-from-shape-section.md) | partial | "sketch from shape", section → editable sketch |
| [sketch-mode-shape-faint.md](sketch-mode-shape-faint.md) | done | faint/ghost/wireframe shapes in sketch mode, alpha blending solids |
| [shape-list-hierarchy-phase3.md](shape-list-hierarchy-phase3.md) | deferred | parent transform inheritance, Parts/planes, Boolean history (#214) |
| [assembly-inspection-mode.md](assembly-inspection-mode.md) | deferred | assembly idle/inspection mode, Part vs arrange context, Move semantics |
| [wasm-multithreading.md](wasm-multithreading.md) | planning | WASM/Emscripten pthreads, SharedArrayBuffer, parallel OCCT on web |
| [wasm-alt-drag-multiselect.md](wasm-alt-drag-multiselect.md) | planning | WASM Alt+LMB drag rectangle multi-select broken (#220) |
| [configurable-hotkeys.md](configurable-hotkeys.md) | done | remappable shortcuts, keybindings, `gui.hotkeys`, free Dimension off D |
138 changes: 138 additions & 0 deletions agents/plans/assembly-inspection-mode.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
---
status: deferred
topic: assembly-inspection-mode
depends_on: shape-list-hierarchy-phase3
blocks: null
github_issue: null
---

# Assembly inspection mode

**Load only when** the prompt is about assembly inspection / assembly idle mode, Part vs assembly context, or how Move/Duplicate relate to assemblies. Skip otherwise ([token-lean](../conventions/token-lean.md)). Index: [plans/README.md](README.md).

Post-v1 product design. Do **not** ship Assembly inspection until [phase 3 placement / Parts](shape-list-hierarchy-phase3.md) exist. This note explains *why* the mode fits CAD practice and *how* to introduce it without forking Move tools.

## Short answer

| Question | Answer |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| Does assembly inspection align with CAD workflows? | Yes — as a third idle context (sketch / part / assembly). |
| Should EzyCad add it now? | No — assemblies are not first-class yet (only Shape List groups + baked transforms). |
| What makes Move “assembly-like” instead of “edit a solid”? | Relative **placement** on Parts (children follow), not rewriting BREP. |
| Elegant fix for today’s awkwardness? | One Move/Rotate/Duplicate family; meaning from **selection kind**; Assembly inspection as arrange idle home. |

## Design-process framing

Two phases of work, two kinds of idle mode:

1. **Make geometry** — Sketch inspection + Inspection (`Mode::Normal`): draw profiles, see solids alongside (or faint), extrude, fillet, boolean.
2. **Arrange components** — Assembly inspection (future): duplicate / place / move Parts relative to each other; later mates and instances.

That split matches SolidWorks / Inventor / Fusion (sketch nested in part, part nested in assembly). EzyCad names the idle states “inspection” (= browse/select + launch tools + Esc parent), not metrology “Inspect.”

```mermaid
flowchart TB
assemblyIdle[Assembly_inspection]
partIdle[Inspection_Normal]
sketchIdle[Sketch_inspection]
sketchTools[Sketch_tools]
assemblyIdle -->|"edit part"| partIdle
partIdle -->|"edit sketch"| sketchIdle
sketchIdle --> sketchTools
sketchTools -->|"Esc"| sketchIdle
sketchIdle -->|"Esc"| partIdle
partIdle -->|"Esc"| assemblyIdle
```

## What exists today

| UI label | Mode | Role |
| ---------------------- | ------------------------------ | ----------------------------------------------------------------------------- |
| Inspection mode | `Mode::Normal` | Idle 3D solids: selection filter, materials, booleans, transforms |
| Sketch inspection mode | `Mode::Sketch_inspection_mode` | Idle 2D sketch: show sketch, ortho, faint solids; Esc parent for sketch tools |

Esc ladder (see [docs/usage.md](../../docs/usage.md)): sketch tool → sketch inspection → Normal.

**Not first-class yet:** Parts, instances, mates, inherited parent transforms. Shape List **groups** are organizational (STEP XCAF hierarchy on import). Move / Rotate / Scale / Align cylinders **bake** into leaf BREP — one-shot geometry edits, not assembly placement. Toolbar icons named `Assembly_*.png` are FreeCAD-style assets for those shape tools, not an assembly workbench.

Planned model: [shape-list-hierarchy-phase3.md](shape-list-hierarchy-phase3.md) (#214) — relative placement, typed nodes (Body, Group, Part, …), non-baking transforms.

## The awkward nuance (and why it feels wrong)

Today Move / Duplicate / Align run from **Inspection** and rewrite solid geometry. Mentally that is still “edit a shape,” even when the user is trying to “place a part.”

You are not wrong that assembly mode would help **when arranging**. The gap is that the **engine** does not yet distinguish place-part from edit-solid. Adding a third mode that still calls the bake path would only re-label the awkwardness.

## Elegant fix

Do **not** invent forever-parallel tools (“Shape Move” vs “Assembly Move”). Fix the document model first; modes then express intent.

### 1. One transform family; semantics by target

Phase 3: Move/Rotate/Scale update relative placement (`world = parentWorld * local`) instead of baking BREP.

| Selection | What Move / Rotate / Duplicate should do |
| ---------------- | ---------------------------------------------------------------------- |
| Body (in a Part) | Change that body’s local pose inside the part |
| Part / Group | Change placement; children follow |
| Later: instance | New instance shares definition; move changes only that instance’s pose |

Same hotkeys / toolbar. **Object kind decides meaning**, not a forked command.

### 2. Idle modes express intent, not different math

After placement exists:

- **Inspection (Part)** — default selection bodies/features; modeling tools; Move on a body = local pose.
- **Assembly inspection** — default selection Parts; Esc parent for arrange tools; Move on a Part = assembly placement; Align can grow into mate-create.
- **Sketch inspection** — unchanged (profiles + faint solids).

Users feel assembly mode when arranging; the engine still uses one placement pipeline.

### 3. Ordered migration

```mermaid
flowchart LR
today[Today_bake_BREP]
place[Phase3_placement]
asmIdle[Assembly_inspection]
mates[Mates_instances]
today --> place
place --> asmIdle
asmIdle --> mates
```

1. **Phase 3 placement** — transforms become placement; Part/Group move as rigid subtrees. Arranging is no longer “rewrite solid.”
2. **Add Assembly inspection** — idle + Part-focused selection; Esc parent for Move/Align/Duplicate when arranging. Tools stay shared.
3. **Evolve Align / Duplicate** — Align → optional persistent mate; Duplicate Part → instance (or copy), not only cloned BREP.
4. **Keep bake only for true geometry edits** — e.g. scale-as-feature if needed; not for ordinary place.

### 4. What not to do

- Ship Assembly inspection while Move still bakes BREP (cosmetic mode).
- Split Move into two permanent commands.
- Force every multi-body document into Assembly mode (single-part work stays in Inspection).

## Industry context (brief)

CAD products rarely brand the idle state “inspection”; they use document or edit context:

- **SolidWorks / Inventor** — assembly vs part document; Edit Part / Edit Assembly; sketch inside part.
- **Fusion** — component browser + Edit in Place; sketch sub-mode of the active component.
- **FreeCAD** — workbenches (PartDesign vs Assembly).

Shared idea: layered contexts with Esc / finish stepping outward. EzyCad’s “inspection” vocabulary can stay for consistency, or later rename all three to Sketch / Part / Assembly **context** (larger UX rename).

## Product stance (fixed for this plan)

1. Keep `Mode::Normal` as the 3D idle mode through hierarchy phase 1–2; keep bake Move/Duplicate there until placement lands.
2. Introduce `Assembly_inspection` (name TBD in code) only with phase 3+ Part + relative placement; mates/instances can follow.
3. Then: Inspection = make/edit geometry; Assembly inspection = arrange Parts; Sketch inspection stays under Part.
4. No v1 Assembly inspection mode.

## Related

- Implementation of placement / Parts: [shape-list-hierarchy-phase3.md](shape-list-hierarchy-phase3.md)
- Modes / Esc parent map: [src/doc/gui.md](../../src/doc/gui.md), [src/mode.h](../../src/mode.h)
- User Esc ladder / tool docs: [docs/usage.md](../../docs/usage.md)
- Shape List groups today: [src/doc/shape.md](../../src/doc/shape.md)
2 changes: 1 addition & 1 deletion agents/plans/configurable-hotkeys.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
status: implemented
status: done
topic: configurable-hotkeys
depends_on: null
blocks:
Expand Down
2 changes: 1 addition & 1 deletion agents/plans/cross-section-tool.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
status: implemented-v0
status: done
topic: cross-section-tool
depends_on: shp-origin-orientation
blocks:
Expand Down
2 changes: 1 addition & 1 deletion agents/plans/shape-list-hierarchy-phase3.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
status: planning
status: deferred
topic: shape-list-hierarchy-phase3
depends_on: null
blocks: null
Expand Down
2 changes: 1 addition & 1 deletion agents/plans/shp-origin-orientation.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
status: planning
status: partial
topic: shp-origin-orientation
depends_on: null
blocks:
Expand Down
4 changes: 2 additions & 2 deletions agents/plans/sketch-mode-shape-faint.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
status: implemented
status: done
topic: sketch-mode-shape-faint
helps:
- shp-origin-orientation
Expand All @@ -13,7 +13,7 @@ helps:

## Status

**Implemented** (prototype): Settings **Shapes in sketch mode** = Off / Ghost (default) / Wire; Ghost opacity; `Occt_view::sync_sketch_shape_faint_style` on mode change and new shapes.
**Done** (prototype): Settings **Shapes in sketch mode** = Off / Ghost (default) / Wire; Ghost opacity; `Occt_view::sync_sketch_shape_faint_style` on mode change and new shapes.

## Why

Expand Down
2 changes: 1 addition & 1 deletion agents/plans/wasm-alt-drag-multiselect.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
status: planned
status: planning
topic: wasm-alt-drag-multiselect
depends_on: []
blocks: []
Expand Down
2 changes: 1 addition & 1 deletion agents/plans/wasm-multithreading.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
status: planned
status: planning
topic: wasm-multithreading
depends_on: []
blocks: []
Expand Down
Loading