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

## [Unreleased]

### 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**).
- Persisted in `.ezy`: `parentId`, `order`, `isGroup`, `visible`; UI expand state and current group in `ui.shapeList.expanded` / `ui.shapeList.currentGroupId`.

### Import / export

- **File -> Import** opens an **Import** dialog with file metadata, optional **Union shapes** for STEP, then **Import into project**. The dialog closes after a successful import. Multi-body STEP assemblies import as a **group tree** of Shape List entries unless **Union shapes** is checked. STEP product/part names are used in the Shape List when present (with `.001` suffixes if needed).
- Removed the **Tools** menu (**Inspector** lives under **File -> Import**). Removed **File -> Sketch underlay image...** (import underlays from **Sketch properties**).

### Project units

- **File -> Project units:** Choose **Inches** or **Millimeters** for sketch/display lengths (dimensions, Tab distance, add-primitive dialogs, chamfer/fillet, grid Settings fields). Stored in the `.ezy` as `projectUnit`. Changing units remaps the UI only; geometry is not rewritten. Export units remain a separate dialog.
Expand Down
6 changes: 4 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Emscripten")
-s USE_WEBGL2=1 \
-s USE_GLFW=3 \
-s USE_ZLIB=1 \
-s EXPORTED_FUNCTIONS=\"['_main', '_on_file_selected', '_on_import_file_selected', '_on_sketch_underlay_selected', '_on_save_file_selected', '_on_save_file_failed', '_emscripten_save_settings_on_unload']\" \
-s EXPORTED_FUNCTIONS=\"['_main', '_on_file_selected', '_on_import_file_selected', '_on_inspector_file_selected', '_on_sketch_underlay_selected', '_on_save_file_selected', '_on_save_file_failed', '_emscripten_save_settings_on_unload']\" \
-s EXPORTED_RUNTIME_METHODS=\"['ccall']\" \
-s FETCH=1 \
--preload-file ${CMAKE_SOURCE_DIR}/third_party/imgui/fonts/DroidSans.ttf@/DroidSans.ttf \
Expand Down Expand Up @@ -312,7 +312,7 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "Emscripten")
-s USE_WEBGL2=1 \
-s USE_GLFW=3 \
-s USE_ZLIB=1 \
-s EXPORTED_FUNCTIONS=\"['_main', '_on_file_selected', '_on_import_file_selected', '_on_sketch_underlay_selected', '_on_save_file_selected', '_on_save_file_failed', '_emscripten_save_settings_on_unload']\" \
-s EXPORTED_FUNCTIONS=\"['_main', '_on_file_selected', '_on_import_file_selected', '_on_inspector_file_selected', '_on_sketch_underlay_selected', '_on_save_file_selected', '_on_save_file_failed', '_emscripten_save_settings_on_unload']\" \
-s EXPORTED_RUNTIME_METHODS=\"['ccall']\" \
-s FETCH=1 \
--preload-file ${CMAKE_SOURCE_DIR}/third_party/imgui/fonts/DroidSans.ttf@/DroidSans.ttf \
Expand Down Expand Up @@ -840,3 +840,5 @@ if(EXISTS ${GITIGNORE_FILE})
target_sources(${PROJECT_NAME} PRIVATE ${GITIGNORE_FILE})
set_source_files_properties(${GITIGNORE_FILE} PROPERTIES HEADER_FILE_ONLY TRUE)
endif()


52 changes: 52 additions & 0 deletions agents/drafts/issues/active/gh-212-project-units.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Project units: Inch/Millimeter display for sketches and New defaults

**Suggested labels:** `enhancement`, `ui`

---

## Title (GitHub)

Project units: Inch/Millimeter display for sketches and New defaults

## Body (GitHub)

### Summary

Add selectable project length units (Inches / Millimeters) for display and input, without rewriting stored geometry. Include Settings defaults for File -> New (unit + 2D view framing).

### Problem

- Sketch and display lengths were hard-coded as inches.
- Users designing metric parts (or switching between house-scale and small parts) had no way to work in millimeters.
- Default 2D view framing lived under 3D view navigation and was easy to mis-set on a wide slider.

### Implemented scope (for drafts after work begins)

**Code changes:**

- `src/utl_types.h`: `Project_unit`, `k_mm_per_inch`
- `src/gui_occt_view.*`: `to_model` / `to_display` / `get_display_to_model_scale`, persist `projectUnit`, New applies default unit
- Length I/O call sites use display scale; import/export keep inch-based `get_dimension_scale()`
- `src/gui_settings.cpp`: **New project defaults** section; drag fields for 2D framing
- `tests/skt_tests.cpp`: `ProjectUnit_displayConversionAndJsonRoundTrip`

**Documentation:**

- `docs/usage.md`, `usage-settings.md`, `usage-sketch.md`, `scripting.md`, `CHANGELOG.md`
- `src/doc/gui.md`, `src/doc/utility.md`

### Acceptance criteria

- [x] File -> Project units switches Inch/Millimeter without rewriting geometry
- [x] `.ezy` persists `projectUnit`; older files default to Inches
- [x] Settings -> New project defaults for unit + framing
- [x] File -> New applies those defaults
- [x] Grid Settings show project unit suffixes
- [x] Export unit picker independent
- [x] Unit test passes
- [x] User docs / CHANGELOG updated

## Related

- Issue: https://github.com/trailcode/EzyCad/issues/212
- PR: (see `agents/drafts/prs/active/`)
61 changes: 61 additions & 0 deletions agents/drafts/issues/active/gh-214-shape-list-hierarchy-phase3.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
github_issue: 214
status: active
paired_draft: gh-215-shape-list-hierarchy-phase2.md
---

# Shape List hierarchy phase 3

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

---

## Title (GitHub)

Shape List hierarchy phase 3: parent transforms and advanced assembly model

## Body (GitHub)

### Summary

Longer-term Shape List / document hierarchy work that should **not** ship with the organizational outliner. Phase 1 delivered folder-style groups without changing leaf BREP or transform semantics. Phase 2 covers outliner polish (reorder, duplicate, selection). Phase 3 is the product decision layer: inherited placement, optional boolean history, and part-local frames.

### Context

- Phase 1: organizational groups only — parents are folders; leaf solids remain the only move/boolean targets.
- Phase 2: #215 reorder, duplicate group, selection polish.
- Related: #59 (compound/assembly modeling; XCAF/instance transforms overlap this phase).

### Scope (candidates — pick deliberately)

**Parent transform inheritance**

- Move / rotate / scale a group applies to descendants (relative placement).
- Needs clear interaction with `Shp_move` / `Shp_rotate` / `Shp_scale`, undo, and baking vs live local transforms.

**Boolean feature history tree**

- Fuse/cut/common keep inputs as children instead of today's replace-input model.
- Separate product decision; conflicts with current boolean UX and deltas.

**Part-local origins / planes**

- FreeCAD-like coordinate objects under a part/group — new object types, not just grouping.

**Cross-sketch parenting**

- Explicitly **out of product intent** for now: sketches stay in Sketch List.

### Acceptance criteria (once scoped)

- [ ] Written design note choosing which of the candidates ship (and which stay deferred)
- [ ] Implementation matches that design; leaf-only ops remain safe where inheritance does not apply
- [ ] Undo/redo covers new transform or history semantics
- [ ] User docs and CHANGELOG updated
- [ ] Tests for the chosen model (placement inheritance and/or history)

### Related

- Issue: https://github.com/trailcode/EzyCad/issues/214
- #59 Compound / assembly modeling in EzyCad
- #215 Shape List hierarchy phase 2
60 changes: 60 additions & 0 deletions agents/drafts/issues/active/gh-215-shape-list-hierarchy-phase2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
github_issue: 215
status: active
paired_draft: gh-214-shape-list-hierarchy-phase3.md
---

# Shape List hierarchy phase 2

**Suggested labels:** `enhancement`, `ui`

---

## Title (GitHub)

Shape List hierarchy phase 2: reorder, duplicate group, selection polish

## Body (GitHub)

### Summary

Follow-up work after the organizational Shape List outliner (phase 1). Phase 1 already covers groups, current group, DnD reparent, cascade delete/ungroup, visibility, boolean result parenting, and STEP XCAF assembly import as groups. Phase 2 hardens outliner workflows that still feel incomplete without changing leaf BREP or adding parent transforms.

### Context (phase 1 done)

- Hierarchical Shape List with organizational groups (`parentId` / `order` / `isGroup`)
- Current group; new primitives/extrudes/revolves land under it
- Group / New group / Ungroup, DnD reparent, cascade delete, Ctrl multi-select
- STEP import preserves XCAF product/assembly groups (unless **Union shapes**)

Related: #59 (broader compound/assembly modeling; this issue is the next Shape List slice).

### Scope

**In scope**

- **Reorder without reparent** — drag between siblings (or explicit move up/down) to change `sibling_order` under the same parent without changing `parent_id`.
- **Duplicate group** — deep-copy a group subtree (structure + leaf solids), unique names, undoable.
- **Selection / hover polish** — e.g. Select children only, clearer empty-group vs solid selection feedback, optional middle-click or context-menu variants for subtree selection.
- Optional stretch: scripting helpers for `parent_id` / children / `group()` / `ungroup()` if low cost.

**Out of scope (phase 3)**

- Parent transform inheritance (moving a group moves children)
- Boolean feature-history trees (fuse keeps inputs as children)
- Part-local origins / planes
- Cross-sketch parenting

### Acceptance criteria

- [ ] User can reorder siblings under the same parent without reparenting to another group
- [ ] Duplicate group creates an independent deep copy (structure + solids) with undo
- [ ] At least one polished subtree-selection path beyond click-group selects all descendant solids
- [ ] Docs (`docs/usage.md`, `src/doc/gui.md` / `shape.md`) and CHANGELOG updated
- [ ] Unit tests for reorder and duplicate-group (plus any selection helpers that are non-UI)

### Related

- Issue: https://github.com/trailcode/EzyCad/issues/215
- #59 Compound / assembly modeling in EzyCad
- #214 Shape List hierarchy phase 3
82 changes: 82 additions & 0 deletions agents/drafts/issues/active/gh-217-shape-list-hierarchy-phase1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
github_issue: 217
github_pr: 216
status: active
paired_draft: ../../prs/active/gh-216-shape-list-hierarchy-phase1.md
---

# Shape List hierarchy phase 1

**Suggested labels:** `enhancement`, `ui`

---

## Title (GitHub)

Shape List hierarchy phase 1: organizational groups and outliner

## Body (GitHub)

### Summary

Documents the Shape List organizational hierarchy and related import/outliner work landed in PR #216 (phase 1). Groups are folder nodes in the document tree (no parent transform inheritance). Follow-ups: #215 (phase 2), #214 (phase 3), #59 (broader assembly modeling).

### Problem

- Shape List was a flat list of solids with no parent/child outliner.
- Multi-body STEP assemblies flattened; no way to organize parts into folders for visibility, selection, or parenting new geometry.
- Hide-all and selection UX did not support group-oriented workflows.

### Implemented scope

**Document model**

- `Shp` nodes gain `parent_id`, `sibling_order`, `is_group` (empty compound; never displayed).
- `.ezy` persists `parentId`, `order`, `isGroup`, `visible`.
- Undo: `Shape_tree_delta` for reparent / group / ungroup; shape add/remove records include hierarchy fields.

**Shape List UI**

- Tree table: expand/collapse, vis / solid-wire / material on the left, name on the right.
- **Current group**: click a group (including empty) to set it; new primitives, extrudes, revolves, PLY, and unioned STEP import parent under it.
- **New group** / **Group** / **Ungroup** (all direct children move up); cascade delete of group subtrees.
- Drag-drop reparent (onto group, onto solid → that solid's parent, empty pad below list → document root).
- Ctrl multi-select; group click selects descendant solids.
- Persist `ui.shapeList.expanded` and `ui.shapeList.currentGroupId`.

**Operations / import**

- Booleans / polar dup: result parent = shared operand parent, else root.
- Hide all no longer stomps per-shape visibility flags (effective visibility via ancestors + overlays).
- STEP XCAF assembly → Shape List group tree (unless **Union shapes**); product/part names used when present.
- File → Import dialog (metadata, optional union) — related import UX on the same branch.

**Tests / docs**

- `tests/shp_tests.cpp`: group/ungroup, hierarchy JSON, fuse parent, current-group parenting, etc.
- `docs/usage.md`, `CHANGELOG.md`, `src/doc/shape.md`, `gui.md`, `utility.md`.

### Acceptance criteria

- [x] Group / ungroup / reparent / cascade delete with undo
- [x] Current group; empty groups selectable; new solids parent under it
- [x] DnD to group, to sibling-via-solid, and to document root (empty pad)
- [x] Group visibility hides subtree; Hide all preserves per-node flags
- [x] Boolean results inherit shared parent when applicable
- [x] STEP assembly import as group tree (optional union)
- [x] `.ezy` round-trip of hierarchy + UI expand/current group
- [x] Unit tests and user/developer docs updated

### Out of scope (follow-ups)

- #215 — sibling reorder without reparent, duplicate group, selection polish
- #214 — parent transform inheritance, boolean history tree, part-local frames
- #59 — broader compound / assembly modeling

### Related

- Issue: https://github.com/trailcode/EzyCad/issues/217
- PR: https://github.com/trailcode/EzyCad/pull/216
- #215 Shape List hierarchy phase 2
- #214 Shape List hierarchy phase 3
- #59 Compound / assembly modeling in EzyCad
35 changes: 35 additions & 0 deletions agents/drafts/prs/active/gh-213-project-units.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# PR - Project units and New project defaults

## Title

Project units and New project defaults

## Summary

- Add **File -> Project units** (Inches / Millimeters) for on-the-fly display/input; model space stays inch-scaled.
- Persist `projectUnit` in `.ezy`; **Settings -> New project defaults** for New unit + 2D framing.
- Route length I/O through `get_display_to_model_scale()`; keep import/export on inch-based scale.

## Files Changed

- `src/utl_types.h`, `src/gui_occt_view.*`, `src/gui*.cpp`, `src/skt_*.cpp`, `src/shp_*.cpp`, `src/scr_*.cpp`
- `tests/skt_tests.cpp`
- `docs/usage*.md`, `docs/scripting.md`, `CHANGELOG.md`, `src/doc/gui.md`, `src/doc/utility.md`
- `res/ezycad_settings.json`
- `agents/drafts/issues/active/gh-212-project-units.md`
- `agents/drafts/prs/active/gh-213-project-units.md`

## Related

- Issue: https://github.com/trailcode/EzyCad/issues/212
- PR: https://github.com/trailcode/EzyCad/pull/213

## Test Plan

- [ ] Build `EzyCad` / `EzyCad_tests` (Debug)
- [ ] `EzyCad_tests.exe --gtest_filter=Sketch_test.ProjectUnit_displayConversionAndJsonRoundTrip`
- [ ] Switch File -> Project units; confirm dims remap, geometry unchanged
- [ ] Save/reload and old-file default to Inches
- [ ] New project defaults + File -> New
- [ ] Grid Settings unit suffixes; Export picker independent
- [ ] Docs / CHANGELOG spot-check
32 changes: 32 additions & 0 deletions agents/drafts/prs/active/gh-216-shape-list-hierarchy-phase1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
github_pr: 216
github_issue: 217
status: active
paired_draft: ../../issues/active/gh-217-shape-list-hierarchy-phase1.md
---

# PR - Shape List hierarchy phase 1

## Title

Shape List hierarchy phase 1: organizational groups and outliner

## Summary

- Organizational Shape List hierarchy (groups, current group, DnD including drop-to-root).
- Boolean/extrude parenting; Hide all preserves visibility flags.
- STEP XCAF assembly → group tree; Import dialog on this branch.
- Docs, CHANGELOG, tests.

## Related

- Issue: https://github.com/trailcode/EzyCad/issues/217
- PR: https://github.com/trailcode/EzyCad/pull/216
- Follow-ups: #215, #214, #59

## Test plan

- [ ] Shape List group / current group / DnD / ungroup / cascade delete
- [ ] Hide all / group visibility
- [ ] STEP import with/without Union shapes
- [ ] `EzyCad_tests.exe --gtest_filter=Shp_test.*`
Loading
Loading