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
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- WASM (OCCT 7.9.3): stop forcing a near-white AIS `SetColor` after every material apply. That OCCT 8 GLES workaround had been running on all Emscripten builds and made steel, gold, and other presets look identical (glass still showed transparency).
- WASM: clear AIS `OwnColor` when applying a Shape List material so presets are not stuck on a forced color. Prefer the **OCCT 7.9.3** wasm kit — OCCT 8.x GLES still has known shading regressions (`docs/building-occt.md`).

### Cross-section

- Added a temporary **Shape cross-section** preview tool for selected solids. Entering the tool with solids already selected updates the preview immediately; changing the selection while in the tool also updates it. Options choose a shared local **XY**, **XZ**, or **YZ** plane (first-selected axes, selection-bbox center), **Invert normal** (flips the annotation arrow and positive-offset direction while keeping the plane in place), **Hide back side** (on by default; display-only AIS clip opposite the yellow arrow), a bounding-box **Offset** slider (Ctrl+click to type; auto-updates preview) in project units, and **Clip** (half-space cut: keeps the positive-normal side, deletes the originals, adds clipped replacements; undoable). A translucent yellow plane and normal arrow annotate the cut. Solids the plane misses are skipped; the preview clears only if nothing in the selection is cut.
- Desktop preview sections multiple selected solids in parallel (worker pool); WASM remains single-threaded for the per-solid pool. Bounding-box culling skips solids that cannot meet the plane. Offset/plane dragging updates the yellow plane immediately and runs section wires asynchronously (cancel + latest-pending) so the Options slider stays responsive.
- Shapes now carry a bbox-centered local frame that follows baked move/rotate/scale transforms and persists in project JSON and shape undo records.

### Shape List

- **Shape List** is a hierarchical outliner: organizational **groups**, expand/collapse, drag-and-drop reparent, **Group** / **New group** / **Ungroup**, cascade delete, and Ctrl+click multi-select. Click a group (including empty) to set the **current group**; new primitives/extrudes/revolves are added there. Drop on empty space below the list to move a node to the document root. Group visibility hides the subtree. **Hide all** no longer clears per-shape visibility flags. Boolean results inherit a shared parent when inputs share one. STEP import preserves XCAF assembly groups (unless **Union shapes**).
Expand Down
2 changes: 2 additions & 0 deletions agents/conventions/occt-wasm-dual-version.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
| WASM (Emscripten) | **7.9.3** (`V7_9_3`) recommended | `scripts/build-occt-793-wasm.ps1` |
| WASM (compare) | 8.0.0.p1 (`V8_0_0_p1`) experimental | Shading regressions; not for demos/release |

Do **not** apply OCCT 8 GLES workarounds unconditionally under `__EMSCRIPTEN__`. Example: `Occt_view::refresh_shape_shading_` must not force a fixed AIS `SetColor` on 7.9.3 (washes out material presets). Gate with `OCC_VERSION_HEX >= 0x080000`, and when a color is required on OCCT 8 prefer the material's own color.

Details: [docs/building-occt.md](../../docs/building-occt.md), [workflows/local-dev.md](../workflows/local-dev.md).

## Shared `src/` must compile on both
Expand Down
38 changes: 38 additions & 0 deletions agents/drafts/issues/active/gh-218-cross-section-tool.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
github_issue: 218
github_pr: 219
status: active
paired_draft: ../prs/active/gh-219-cross-section-tool.md
---

# Add temporary shape cross-section preview tool

**Suggested labels:** `enhancement`, `ui`, `feature-request`

---

## Title (GitHub)

Add temporary shape cross-section preview tool

## Body (GitHub)

See https://github.com/trailcode/EzyCad/issues/218

### Summary

Interactive **Shape cross-section** tool: shared local plane cut of selected solids with temporary AIS preview; Invert normal, Hide back side, Clip; async wires + desktop parallel pool (no sketch commit in v0).

### Acceptance criteria

- [x] Auto-preview on enter / selection / plane / offset / Invert
- [x] Hide back side (default on); Clip undoable half-space
- [x] Bold empty-selection prompt; leave mode or clear selection removes preview
- [x] Focused tests `Shp_cross_section.*` / `Shp_test.Cross_section*`
- [x] Docs + CHANGELOG updated

### Related

- PR: https://github.com/trailcode/EzyCad/pull/219
- Plan: `agents/plans/cross-section-tool.md`
- Related tracking: #220
38 changes: 38 additions & 0 deletions agents/drafts/issues/active/gh-220-wasm-alt-drag-multiselect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
---
github_issue: 220
status: active
---

# WASM: Alt + LMB drag does not multi-select shapes

**Suggested labels:** `bug`

**Opened:** https://github.com/trailcode/EzyCad/issues/220

---

## Title (GitHub)

WASM: Alt + LMB drag does not multi-select shapes

## Body (GitHub)

See https://github.com/trailcode/EzyCad/issues/220

### Summary

Desktop: **Alt + LMB drag** rubber-band multi-selects shapes via OCCT `AIS_ViewController`. WASM: same gesture does not select multiple shapes.

### Acceptance criteria

- [ ] WASM Alt + LMB drag multi-selects like desktop
- [ ] Desktop unchanged
- [ ] Docs note Alt+drag (and any Web caveats)
- [ ] Plan updated: `agents/plans/wasm-alt-drag-multiselect.md`

### Related

- Issue: https://github.com/trailcode/EzyCad/issues/220
- Plan: `agents/plans/wasm-alt-drag-multiselect.md` (tracking on PR #219; bug not fixed there)
- Related: #93 / `gh-93-emscripten-web-hotkeys-followup.md`
- PR that added tracking: https://github.com/trailcode/EzyCad/pull/219
32 changes: 32 additions & 0 deletions agents/drafts/prs/active/gh-219-cross-section-tool.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
github_issue: 218
github_pr: 219
status: active
paired_draft: ../issues/active/gh-218-cross-section-tool.md
---

# PR - Trailcode/cross-section

## Title

Add temporary shape cross-section preview tool

## Summary

- Temporary shape cross-section preview (local XY/XZ/YZ + offset, Invert normal, Hide back side, Clip).
- Async section wires + desktop parallel pool; WASM serial (see `wasm-multithreading.md`).
- Shape local frames for plane orientation / persistence.

## Related

- Issue: https://github.com/trailcode/EzyCad/issues/218
- PR: https://github.com/trailcode/EzyCad/pull/219
- Branch: `Trailcode/cross-section`
- Plan: `agents/plans/cross-section-tool.md`

## Test Plan

- [ ] Desktop Release build
- [ ] `EzyCad_tests --gtest_filter=Shp_cross_section.*:Shp_test.Cross_section*`
- [ ] Manual enter / selection / plane / offset / Hide back / Clip / Esc
- [ ] Docs sync checklist
2 changes: 2 additions & 0 deletions agents/plans/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ sketch-mode-shape-faint (parallel UX: ghost/wire shapes while sketching)
| [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) |
24 changes: 17 additions & 7 deletions agents/plans/cross-section-tool.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
status: planning
status: implemented-v0
topic: cross-section-tool
depends_on: shp-origin-orientation
blocks:
Expand Down Expand Up @@ -32,12 +32,12 @@ Fail closed on empty section (status message). No requirement to create a `Sketc

## Experiment checklist

- [ ] Box mid-plane → rectangle-like wires.
- [ ] Cylinder mid-plane → circle (or dense curve).
- [ ] Offset along normal; miss solid clear failure.
- [ ] Multi-face / boolean solids: junk edges? duplicates?
- [ ] Curve types returned (`GeomAbs_*`) — informs sketch import strategy.
- [ ] WASM vs desktop parity ([occt-wasm-dual-version](../conventions/occt-wasm-dual-version.md)).
- [x] Box mid-plane -> four line edges (focused unit test).
- [x] Cylinder mid-plane -> circular edge (focused unit test).
- [x] Offset along normal; miss solid -> clear failure (focused unit test).
- [x] Multi-face / boolean solids: junk edges? duplicates? (fused two-box mid-plane returns **8** line edges, not a clean 4-edge rectangle — sketch import will need weld/dedup).
- [x] Curve types returned (`GeomAbs_*`) -> preview status counts lines, circles, ellipses, B-splines, and other curves.
- [x] WASM vs desktop parity ([occt-wasm-dual-version](../conventions/occt-wasm-dual-version.md)).

## Likely touch points

Expand All @@ -58,3 +58,13 @@ Enough evidence to either:
Import into `Sketch_edges`; undoable new sketch; script binding (unless useful for tests).

**Related UX:** [sketch-mode-shape-faint.md](sketch-mode-shape-faint.md) — keep the solid visible but faint under section preview.

## Implemented v0 findings

- `Shp` now has a persisted `gp_Ax3` local frame. It defaults to a world-aligned frame at the shape bounding-box center and follows baked move/rotate/scale transforms.
- `Shp_cross_section` computes one shared cutting plane for the selection with `BRepAlgoAPI_Section` (`Approximation(false)` for exact curve types): orientation from the first selected solid's local axes, origin at the selection bbox center, plus offset. Section edges aggregate into a temporary topmost cyan AIS wire preview, with one translucent yellow plane outline and positive-normal arrow. None of this temporary geometry enters the document or undo history.
- Preview updates fail closed only when the shared plane misses every selected solid, or a hard OCCT failure occurs. Solids the plane does not intersect are skipped and counted in the status message; the yellow plane annotation remains.
- The first curve evidence supports line and circle handling. Ellipse/B-spline/other counts are exposed for further manual experiments before sketch import rules are chosen.
- Boolean solids are not yet sketch-ready: a fused two-box mid-plane yields 8 line edges (likely unmerged/overlapping segments) instead of one 4-edge outer loop.
- Desktop Release build and focused section tests pass with OCCT 8.0.0. The Emscripten Release build also passes with OCCT 7.9.3.
- Desktop multi-solid preview sections solids on a `std::thread` worker pool (`for_each_index_` / `section_shapes_on_plane_`); WASM remains single-threaded for that pool. Interactive Options use `request_preview` + `poll`: plane AIS updates immediately; section wires run async with cancel + latest-pending (desktop `std::async`; WASM one solid per poll). WASM pthread enablement is tracked in [wasm-multithreading.md](wasm-multithreading.md).
73 changes: 73 additions & 0 deletions agents/plans/wasm-alt-drag-multiselect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
status: planned
topic: wasm-alt-drag-multiselect
depends_on: []
blocks: []
github_issue: 220
---

# WASM Alt + LMB drag multi-select

**Load only when** the prompt is about WASM/Emscripten Alt+drag, rectangle / rubber-band selection, or multi-select failing on web. Skip otherwise ([token-lean](../conventions/token-lean.md)). Index: [plans/README.md](README.md).

**Issue:** https://github.com/trailcode/EzyCad/issues/220

## Context

On desktop, holding **Alt** and **left-dragging** in the 3D view activates OCCT `AIS_ViewController` rectangle selection (`SelectRectangle` / rubber band) and multi-selects shapes under the box.

On the WASM build the same gesture does **not** multi-select.

EzyCad already maps modifiers into OCCT flags:

- `Occt_view::key_flags_from_glfw_` — `GLFW_MOD_ALT` → `Aspect_VKeyFlags_ALT`
- Mouse press/release: `PressMouseButton` / `ReleaseMouseButton` with `theMods`
- Mouse move: `UpdateMousePosition(..., key_flags_from_glfw_window_(), ...)` which polls `glfwGetKey(... LEFT/RIGHT_ALT ...)`

Related input/hotkey tracking: [#93](https://github.com/trailcode/EzyCad/issues/93), draft `agents/drafts/issues/active/gh-93-emscripten-web-hotkeys-followup.md`. OCCT desktop vs wasm kit: [occt-wasm-dual-version](../conventions/occt-wasm-dual-version.md).

## Goal

Make **Alt + LMB drag** multi-select on WASM match desktop, without changing desktop gesture mapping or selection schemes.

## Likely causes (investigate in order)

1. **Alt not present on pointer events under Emscripten/GLFW** — browser menu focus, `preventDefault`, or incomplete `mods` on `glfwSetMouseButtonCallback`.
2. **`glfwGetKey(ALT)` false during drag** — rubber-band gesture needs Alt on move updates (`key_flags_from_glfw_window_`), not only on button press.
3. **ImGui / focus** — canvas loses keyboard focus when Alt is pressed; Alt never reaches GLFW.
4. **OCCT 7.9.3 wasm kit** — confirm default `MouseGestureMap` still binds Alt+LMB to select-rectangle (unlikely difference, but verify if input looks correct).

## Approach

### Phase 0 — reproduce and instrument

- [ ] Confirm desktop Alt+LMB rubber band still works.
- [ ] On WASM, log (temporary) `mods` on LMB press/release and Alt from `key_flags_from_glfw_window_` during drag.
- [ ] Note browser (Chrome/Firefox/Edge) and whether the OS/browser steals Alt.

### Phase 1 — fix input path

- [ ] Ensure Alt is forwarded for press, move, and release while the gesture is active (Emscripten/GLFW and/or synthetic modifier from `event.altKey` if GLFW is incomplete).
- [ ] Avoid focusing browser chrome on Alt when the canvas has focus (as far as the platform allows).
- [ ] Keep `GUI::on_mouse_button` / sketch `mods == 0` click paths unchanged for unmodified LMB.

### Phase 2 — docs and parity

- [ ] Document Alt+drag multi-select in `docs/usage.md` and/or `docs/usage-occt-view.md`; call out any remaining Web limitation.
- [ ] Manual check: Ctrl+click multi-select still works on WASM if it already does; Alt+drag matches desktop.
- [ ] Close #220 when done; update this plan status.

## Out of scope

- WASM pthreads / parallel OCCT ([wasm-multithreading.md](wasm-multithreading.md)).
- Broader #93 hotkey parity beyond what this gesture needs.
- Changing default OCCT mouse gesture map on desktop.

## Related code

| Area | Path |
| ---------------------------- | ----------------------------------------- |
| Modifier → OCCT flags | `src/gui_occt_view.cpp` (`key_flags_*`) |
| Mouse → view controller | `src/gui_occt_view.cpp` (`on_mouse_*`) |
| GLFW → GUI | `src/main.cpp`, `src/gui.cpp` |
| Draft | `agents/drafts/issues/active/gh-220-*.md` |
Loading
Loading