From bf3e319783512701e9b97394a849f0d909409be5 Mon Sep 17 00:00:00 2001 From: Trailcode Date: Sat, 1 Aug 2026 18:13:19 -0600 Subject: [PATCH] Update --- agents/plans/README.md | 40 ++++-- agents/plans/assembly-inspection-mode.md | 138 ++++++++++++++++++++ agents/plans/configurable-hotkeys.md | 2 +- agents/plans/cross-section-tool.md | 2 +- agents/plans/shape-list-hierarchy-phase3.md | 2 +- agents/plans/shp-origin-orientation.md | 2 +- agents/plans/sketch-mode-shape-faint.md | 4 +- agents/plans/wasm-alt-drag-multiselect.md | 2 +- agents/plans/wasm-multithreading.md | 2 +- 9 files changed, 173 insertions(+), 21 deletions(-) create mode 100644 agents/plans/assembly-inspection-mode.md diff --git a/agents/plans/README.md b/agents/plans/README.md index c3ce0501..4dcd0361 100644 --- a/agents/plans/README.md +++ b/agents/plans/README.md @@ -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 | diff --git a/agents/plans/assembly-inspection-mode.md b/agents/plans/assembly-inspection-mode.md new file mode 100644 index 00000000..3b4c6113 --- /dev/null +++ b/agents/plans/assembly-inspection-mode.md @@ -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) diff --git a/agents/plans/configurable-hotkeys.md b/agents/plans/configurable-hotkeys.md index de1057a1..3073651c 100644 --- a/agents/plans/configurable-hotkeys.md +++ b/agents/plans/configurable-hotkeys.md @@ -1,5 +1,5 @@ --- -status: implemented +status: done topic: configurable-hotkeys depends_on: null blocks: diff --git a/agents/plans/cross-section-tool.md b/agents/plans/cross-section-tool.md index 7be0d491..4eb892a3 100644 --- a/agents/plans/cross-section-tool.md +++ b/agents/plans/cross-section-tool.md @@ -1,5 +1,5 @@ --- -status: implemented-v0 +status: done topic: cross-section-tool depends_on: shp-origin-orientation blocks: diff --git a/agents/plans/shape-list-hierarchy-phase3.md b/agents/plans/shape-list-hierarchy-phase3.md index 9756aa77..4c8da764 100644 --- a/agents/plans/shape-list-hierarchy-phase3.md +++ b/agents/plans/shape-list-hierarchy-phase3.md @@ -1,5 +1,5 @@ --- -status: planning +status: deferred topic: shape-list-hierarchy-phase3 depends_on: null blocks: null diff --git a/agents/plans/shp-origin-orientation.md b/agents/plans/shp-origin-orientation.md index 5e42ec9b..d0346a6d 100644 --- a/agents/plans/shp-origin-orientation.md +++ b/agents/plans/shp-origin-orientation.md @@ -1,5 +1,5 @@ --- -status: planning +status: partial topic: shp-origin-orientation depends_on: null blocks: diff --git a/agents/plans/sketch-mode-shape-faint.md b/agents/plans/sketch-mode-shape-faint.md index c72b5dd0..97640890 100644 --- a/agents/plans/sketch-mode-shape-faint.md +++ b/agents/plans/sketch-mode-shape-faint.md @@ -1,5 +1,5 @@ --- -status: implemented +status: done topic: sketch-mode-shape-faint helps: - shp-origin-orientation @@ -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 diff --git a/agents/plans/wasm-alt-drag-multiselect.md b/agents/plans/wasm-alt-drag-multiselect.md index 4dffebe5..463fab43 100644 --- a/agents/plans/wasm-alt-drag-multiselect.md +++ b/agents/plans/wasm-alt-drag-multiselect.md @@ -1,5 +1,5 @@ --- -status: planned +status: planning topic: wasm-alt-drag-multiselect depends_on: [] blocks: [] diff --git a/agents/plans/wasm-multithreading.md b/agents/plans/wasm-multithreading.md index f88ca8c9..79c1891a 100644 --- a/agents/plans/wasm-multithreading.md +++ b/agents/plans/wasm-multithreading.md @@ -1,5 +1,5 @@ --- -status: planned +status: planning topic: wasm-multithreading depends_on: [] blocks: []