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

### Added

- **Shape List Zoom to**: right-click a shape or group name (or the **M** button on a solid) and choose **Zoom to** to frame that solid, or all descendant solids of a group, in the 3D view while keeping the current camera orientation.

- **Shape copy / paste** (<kbd>Ctrl</kbd>+<kbd>C</kbd> / <kbd>Ctrl</kbd>+<kbd>V</kbd>): in-app clipboard for selected solids, or a Shape List group subtree when the selection matches that group's descendant solids. Paste deep-copies under the current group (new ids, uniquified names, same pose) with one undo step. Survives **New** so you can copy, start a blank project, and paste. Remappable as **`edit.copy`** / **`edit.paste`**. Does not use the OS clipboard; sketch geometry is not copied.

- **Align shafts** (<kbd>J</kbd>): pick two cylindrical faces (first moves, second is fixed), coaxially align, drag axial insert depth; with Options **Clock rotation** (default off), LMB or <kbd>Shift</kbd>+<kbd>Tab</kbd> rotates about the shared axis for tooth clocking (<kbd>Enter</kbd> during depth skips clocking). <kbd>Tab</kbd> edits depth or angle by phase. Options **Flip direction** reverses axis sense. Bakes like Move/Rotate (`Shape_geom_delta`); radius mismatch logs a warning but still places. Remappable as **`mode.cyl_align`**.
Expand Down
44 changes: 43 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,49 @@ add_definitions(-DGLM_FORCE_RADIANS)
# Link OpenGL libraries
target_link_libraries(${PROJECT_NAME} ${OPENGL_LIBRARIES} ${OPENGL_gl_LIBRARY})

source_group("imgui" FILES ${imguiSrc})
# IDE filters under EzyCad_lib: nest vendored sources under third_party (disk paths unchanged).
# Use TREE + target_sources (headers) so the .vcxproj changes and VS reloads Solution Explorer.
set(_ezy_tp_ide_files)
foreach(f ${imguiSrc})
if(IS_ABSOLUTE "${f}")
list(APPEND _ezy_tp_ide_files "${f}")
else()
list(APPEND _ezy_tp_ide_files "${CMAKE_SOURCE_DIR}/${f}")
endif()
endforeach()
list(APPEND _ezy_tp_ide_files
"${CMAKE_SOURCE_DIR}/third_party/tinyfiledialogs/tinyfiledialogs.c"
"${CMAKE_SOURCE_DIR}/third_party/tinyfiledialogs/tinyfiledialogs.h")
get_filename_component(_ezy_te_abs "${EZYCAD_IMGUI_TEXT_EDITOR_CPP}" ABSOLUTE)
list(APPEND _ezy_tp_ide_files "${_ezy_te_abs}")
get_filename_component(_ezy_te_dir "${_ezy_te_abs}" DIRECTORY)
if(EXISTS "${_ezy_te_dir}/TextEditor.h")
list(APPEND _ezy_tp_ide_files "${_ezy_te_dir}/TextEditor.h")
endif()
# Vendored TextEditor lives under third_party/; FetchContent fallback is outside — group flat then.
file(TO_CMAKE_PATH "${_ezy_te_abs}" _ezy_te_cmake)
file(TO_CMAKE_PATH "${CMAKE_SOURCE_DIR}/third_party" _ezy_tp_root)
string(FIND "${_ezy_te_cmake}" "${_ezy_tp_root}" _ezy_te_under_tp)
if(_ezy_te_under_tp EQUAL 0)
source_group(TREE "${CMAKE_SOURCE_DIR}/third_party" PREFIX "third_party" FILES ${_ezy_tp_ide_files})
else()
list(REMOVE_ITEM _ezy_tp_ide_files "${_ezy_te_abs}")
if(EXISTS "${_ezy_te_dir}/TextEditor.h")
list(REMOVE_ITEM _ezy_tp_ide_files "${_ezy_te_dir}/TextEditor.h")
endif()
source_group(TREE "${CMAKE_SOURCE_DIR}/third_party" PREFIX "third_party" FILES ${_ezy_tp_ide_files})
source_group("third_party" FILES "${_ezy_te_abs}")
if(EXISTS "${_ezy_te_dir}/TextEditor.h")
source_group("third_party" FILES "${_ezy_te_dir}/TextEditor.h")
endif()
endif()
set(_ezy_tp_headers
"${CMAKE_SOURCE_DIR}/third_party/tinyfiledialogs/tinyfiledialogs.h")
if(EXISTS "${_ezy_te_dir}/TextEditor.h")
list(APPEND _ezy_tp_headers "${_ezy_te_dir}/TextEditor.h")
endif()
target_sources(${PROJECT_NAME}_lib PRIVATE ${_ezy_tp_headers})
set_source_files_properties(${_ezy_tp_headers} PROPERTIES HEADER_FILE_ONLY TRUE)

set(SRC_SHP)
set(SRC_GUI)
Expand Down
62 changes: 62 additions & 0 deletions agents/drafts/issues/active/gh-248-zoom-to-shaft-align-ide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
github_issue: 248
github_pr: 249
status: active
paired_draft: ../prs/active/gh-249-zoom-to-shaft-align-ide.md
---

# Shape List Zoom to, shaft-align mode rename, and third_party IDE filters

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

---

## Title (GitHub)

Shape List Zoom to, shaft-align mode rename, and third_party IDE filters

## Body (GitHub)

### Summary

Add Shape List **Zoom to**, rename Align shafts mode to `Mode::Shape_shaft_align`, nest vendored compile units under a `third_party` IDE filter in Visual Studio, and keep developer docs aligned with Options / Tab / Enter routing for Align shafts.

### Problem

- No quick way to frame a Shape List solid or group in the 3D view without changing camera orientation manually.
- Mode name `Shape_cyl_align` no longer matches the user-facing **Align shafts** tool.
- TextEditor / tinyfiledialogs / imgui sat in default or top-level VS filters instead of under `third_party`.
- `gui.md` Options / keyboard dispatch needed explicit Align shafts coverage.

### Scope

- **Zoom to** on Shape List name and **M** context menus; `Occt_view::fit_shapes_in_view` (solid or group descendant solids; keeps camera orientation).
- Rename `Mode::Shape_cyl_align` → `Mode::Shape_shaft_align` (hotkey id `mode.cyl_align` / `Shp_cyl_align` unchanged for now).
- CMake `source_group(TREE ...)` so `EzyCad_lib` shows `third_party/{imgui,ImGuiColorTextEdit,tinyfiledialogs}`.
- `src/doc/gui.md` / `shape.md`, `docs/usage.md`, `CHANGELOG.md`.

### Acceptance criteria

- [ ] Shape List solid/group **Zoom to** frames selection with current camera orientation
- [ ] Empty group **Zoom to** disabled; solids with null geometry not zoomable via name menu
- [ ] Mode enum / Options / hotkey dispatch use `Shape_shaft_align`
- [ ] VS Solution Explorer (`EzyCad_lib`) shows vendored sources under `third_party` after CMake reconfigure + reload
- [ ] User docs and CHANGELOG mention Zoom to; developer docs list Align shafts Options/key routing

### Out of scope

- Renaming `Shp_cyl_align` / `mode.cyl_align` / `Gui_action::Mode_cyl_align`
- Changing Zoom to camera orientation (fit only)

### Files touched

- `src/gui.cpp`, `src/gui.h`, `src/gui_mode.cpp`, `src/gui_occt_view.cpp`, `src/gui_occt_view.h`, `src/mode.h`
- `CMakeLists.txt`
- `docs/usage.md`, `CHANGELOG.md`, `src/doc/gui.md`, `src/doc/shape.md`
- `agents/drafts/issues/active/gh-248-zoom-to-shaft-align-ide.md` (this draft)

### Related

- Issue: https://github.com/trailcode/EzyCad/issues/248
- Prior: Align shafts (#247 / #246)
- Branch: `Trailcode/zoom-to`
48 changes: 48 additions & 0 deletions agents/drafts/prs/active/gh-249-zoom-to-shaft-align-ide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
github_issue: 248
github_pr: 249
status: active
paired_draft: ../issues/active/gh-248-zoom-to-shaft-align-ide.md
---

# PR - Zoom to / shaft-align / third_party IDE

## Title

Shape List Zoom to, shaft-align mode rename, and third_party IDE filters

## Summary

- Shape List **Zoom to** (name and **M** menus) via `Occt_view::fit_shapes_in_view` — frames a solid or group descendant solids while keeping camera orientation.
- Rename `Mode::Shape_cyl_align` → `Mode::Shape_shaft_align` (hotkey id `mode.cyl_align` / `Shp_cyl_align` unchanged).
- Nest imgui / TextEditor / tinyfiledialogs under `third_party` IDE filters in `EzyCad_lib` (CMake `source_group`).
- Sync `gui.md` Align shafts Options / Tab / Enter / dist-edit routing; `usage.md` + CHANGELOG for Zoom to.

## Files Changed

- `src/gui.cpp`, `src/gui.h`, `src/gui_mode.cpp`, `src/gui_occt_view.cpp`, `src/gui_occt_view.h`, `src/mode.h`
- `CMakeLists.txt`
- `docs/usage.md`, `CHANGELOG.md`, `src/doc/gui.md`, `src/doc/shape.md`
- `agents/drafts/issues/active/gh-248-zoom-to-shaft-align-ide.md`
- `agents/drafts/prs/active/gh-249-zoom-to-shaft-align-ide.md` (this draft)

## Related

- Issue: https://github.com/trailcode/EzyCad/issues/248
- PR: https://github.com/trailcode/EzyCad/pull/249
- Branch: `Trailcode/zoom-to`
- Prior: Align shafts (#247 / #246)

## Test Plan

- [ ] Build Release `EzyCad`
- [ ] Shape List solid: right-click name / **M** → **Zoom to** frames solid, orientation unchanged
- [ ] Group with solids: **Zoom to** frames all descendants; empty group item disabled
- [ ] Align shafts (**J**): Options Flip / Clock rotation still work after mode rename
- [ ] Reconfigure CMake, reload `build/EzyCad.sln`: `EzyCad_lib` → `third_party/{imgui,ImGuiColorTextEdit,tinyfiledialogs}`
- [ ] Spot-check `docs/usage.md` Shape List, `src/doc/gui.md` Options/keyboard, CHANGELOG

## Notes

- Closes #248
- Out of scope: renaming `Shp_cyl_align` / `mode.cyl_align` / `Gui_action::Mode_cyl_align`
4 changes: 2 additions & 2 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,10 +123,10 @@ Each row (left to right):

- **Visibility** - Checkbox to show or hide that node. Hiding a **group** hides its whole subtree in the 3D view.
- **Solid / wire** - Checkbox (solids only) to switch **shaded** or **wireframe**.
- **M** - Solids only: material popup; right-click for **Shape info...** or **Delete**.
- **M** - Solids only: material popup; right-click for **Zoom to**, **Shape info...**, or **Delete**.
- **Name** - Expandable tree row with an editable name. Click the row to select that solid (or all descendant solids for a group) and update the current group. **Ctrl+click** toggles multi-select. Drag to reparent (empty area below the list = document root).
- **Copy / Paste** - <kbd>Ctrl</kbd>+<kbd>C</kbd> / <kbd>Ctrl</kbd>+<kbd>V</kbd> (remappable) copy selected solids, or a whole group subtree when you clicked that group (all its descendant solids are selected). Paste inserts an independent deep copy under the current group, at the same pose. If you still have that copied group as the current group, paste places a sibling copy beside it (not nested inside it). This is an in-app clipboard (survives **New**; it does not use the system clipboard). Sketch edges are not copied.
- **Right-click the name** - Solids: **Shape info...** / **Delete**. Groups: **Ungroup** (moves **all** direct children to the group's parent, then removes the group) / **Delete** (cascade-deletes the whole subtree).
- **Right-click the name** - Solids: **Zoom to** / **Shape info...** / **Delete**. Groups: **Zoom to** (fits all descendant solids; disabled when the group has none) / **Ungroup** (moves **all** direct children to the group's parent, then removes the group) / **Delete** (cascade-deletes the whole subtree). **Zoom to** keeps the current camera orientation and frames the solid or group with a little padding.

Boolean results stay under the shared parent of their inputs when all inputs share one parent; otherwise they are placed at the document root. **File -> Import** STEP assemblies use **Import as** (default **Preserve hierarchy**) to keep product/assembly groups in the tree, import **Flat solids** at the root, or **Union shapes** into one solid.

Expand Down
Loading
Loading