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 @@ -29,6 +29,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Changed

- **Sketch snap:** unified axis-guide feedback in sketch mode; direct snap to nodes on **other visible sketches** (projected onto the current plane) restored; dimension-tool node hover no longer mutates stored node coordinates.
- **Documentation:** [usage-sketch.md](usage-sketch.md#sketch-snapping) adds a **Sketch snapping** section (axis alignment, vertex lock, cross-sketch targets, add-node edge interior). [usage.md](usage.md#sketch-list) clarifies Sketch List **Nodes** vs topology vertices. [usage-settings.md](usage-settings.md#sketch-tools) links to the snap section.
- **View roll** (**Shift**+**NumPad 4**/**6**, main **4**/**6**, or **Left**/**Right** arrow): same roll as **Shift**+**4**/**6**; helps when Num Lock makes the numpad send arrows. Handled on key **repeat** as well as press; **Shift**+main **4**/**6** no longer fall through to the selection filter.
- **Keyboard zoom** (**NumPad +/-**, **Shift+=**, **-**): each repeated OS key event zooms again so holding the key zooms continuously (uses GLFW key repeat).
- **Zoom:** **Zoom scroll scale** in Settings replaces the hard-coded wheel multiplier (**4**); stored as **`gui.view_zoom_scroll_scale`**. Hold **Shift** while scrolling or using +/- for Blender-style finer zoom (**x0.1** on the delta).
Expand Down
17 changes: 14 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
# EzyCad

[![GitHub](https://img.shields.io/github/stars/trailcode/EzyCad?style=social)](https://github.com/trailcode/EzyCad)
[![Documentation](https://img.shields.io/badge/docs-readthedocs-blue)](https://ezycad.readthedocs.io/en/latest/usage.html)
[![WebAssembly](https://img.shields.io/badge/run_in-browser-WebAssembly-green)](https://trailcode.github.io/EzyCad/EzyCad.html)

**Repository:** [https://github.com/trailcode/EzyCad](https://github.com/trailcode/EzyCad)

![EzyCad splash screen](doc/gen/AI-gen-splashscreen_05_01_2026_512.png)

EzyCad (Easy CAD) is a CAD application for hobbyist machinists to design and edit 2D and 3D models for machining projects. It supports creating precise parts with tools for sketching, extruding, and applying geometric operations, using OpenGL, ImGui, and Open CASCADE Technology (OCCT). Export models to formats like STEP or STL for CNC machines or 3D printers, or [run EzyCad in your browser (WebAssembly)](https://trailcode.github.io/EzyCad/EzyCad.html).
EzyCad (Easy CAD) is an open-source CAD application for hobbyist machinists to design and edit 2D and 3D models for machining projects. It supports creating precise parts with tools for sketching, extruding, and applying geometric operations, using OpenGL, Dear ImGui, and Open CASCADE Technology (OCCT). Export models to formats like STEP or STL for CNC machines or 3D printers, or [run EzyCad in your browser (WebAssembly)](https://trailcode.github.io/EzyCad/EzyCad.html). Project home: [trailcode.github.io/EzyCad](https://trailcode.github.io/EzyCad/).

> **Not EZCAD laser software:** [EzyCad](https://github.com/trailcode/EzyCad) (with a **y**) is hobbyist mechanical CAD built on OCCT — unrelated to EZCAD2/EZCAD3 laser marking products.

## Features
- 2D and 3D modeling capabilities.
Expand Down Expand Up @@ -77,15 +85,18 @@ Ensure the following dependencies are installed:
- Build the project.
- Serve the WebAssembly: `python.exe -m http.server 8000`
- Or build and serve: `ninja && python.exe -m http.server 8000`
- **GitHub Pages HTML:** After changing `web/index.html` or `web/EzyCad.html`, sync to [trailcode.github.io](https://github.com/trailcode/trailcode.github.io) with `scripts/sync-github-pages-html.ps1` (see script header).
- Dear ImGui under `third_party/imgui/` carries EzyCad-specific changes (font rendering); see [In-tree third-party libraries](#in-tree-third-party-libraries) at the end of this README.

### Artwork
- Icons from: https://wiki.freecad.org/Artwork

## Support and Contributions
- Report issues or suggest features on the GitHub repository.
- Contribute by developing features and fixing bugs. Pull requests are welcome!
- **Project home:** [trailcode.github.io/EzyCad](https://trailcode.github.io/EzyCad/)
- Report issues or suggest features on the [GitHub repository](https://github.com/trailcode/EzyCad).
- Contribute by developing features and fixing bugs. Pull requests are welcome!
- Additional resources, including video tutorials and online documentation, are linked in [usage.md](usage.md).
- Outreach draft posts (forums, Reddit, awesome lists): [agents/discoverability-outreach.md](agents/discoverability-outreach.md).

### We need development help
EzyCad is maintained by a small team and we would love more contributors. If you can help with features, bug fixes, documentation, or testing - please jump in. Every contribution helps move the project forward.
Expand Down
1 change: 1 addition & 0 deletions agents/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ To use a note in **Cursor**, copy or symlink the relevant file into your user or
| File | Intent |
| --- | --- |
| [ezycad-ascii-source.md](ezycad-ascii-source.md) | ASCII-only comments and strings in `src/`; points at `ezycad_code_style.md` and `scripts/check-nonascii-src.ps1`. |
| [discoverability-outreach.md](discoverability-outreach.md) | Draft posts for forums, Reddit, awesome lists (SEO / backlinks). |
| *(repo root)* [ezycad_doc_style.md](../ezycad_doc_style.md) | User guides, Read the Docs, images, in-app doc URLs. |
85 changes: 85 additions & 0 deletions agents/discoverability-outreach.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# EzyCad discoverability — outreach drafts

Copy-paste templates for posts that link back to the project. Update URLs or screenshots before publishing.

**Canonical links**

| Resource | URL |
| --- | --- |
| GitHub | https://github.com/trailcode/EzyCad |
| Documentation | https://ezycad.readthedocs.io/ |
| Landing page | https://trailcode.github.io/EzyCad/ |
| Run in browser (WebAssembly) | https://trailcode.github.io/EzyCad/EzyCad.html |
| Releases | https://github.com/trailcode/EzyCad/releases |

**Search tip for others:** `trailcode EzyCad` or `site:github.com EzyCad trailcode`

---

## Open CASCADE forum (showcase)

**Title:** EzyCad — hobbyist CAD with OCCT + Dear ImGui + OpenGL (WebAssembly in the browser)

**Body:**

Hello,

I've been building **EzyCad** (Easy CAD), an open-source CAD app aimed at hobbyist machinists. It uses Open CASCADE for geometry, Dear ImGui for the UI, and OpenGL/GLFW for rendering. Desktop (Windows) and a **WebAssembly** build are available.

- Source: https://github.com/trailcode/EzyCad
- Docs: https://ezycad.readthedocs.io/
- Run in browser: https://trailcode.github.io/EzyCad/EzyCad.html

If you're integrating OCCT with ImGui in one GLFW window, some of our render-loop choices may be useful as a reference. Feedback and contributors welcome.

---

## Reddit (r/hobbycnc, r/CNC, r/opencascade)

**Title:** EzyCad — open-source hobbyist CAD (OCCT + ImGui), runs in the browser

**Body:**

I maintain **EzyCad**, a small open-source CAD project for designing parts for machining/3D printing. Stack: Open CASCADE, Dear ImGui, OpenGL. Exports STEP/STL.

- GitHub: https://github.com/trailcode/EzyCad
- Run in browser, no install: https://trailcode.github.io/EzyCad/EzyCad.html

Looking for testers and contributors. Not related to EZCAD laser software — name is EzyCad with a "y".

---

## Awesome list PR (e.g. awesome-opencascade or CAD lists)

**One-line description:**

[EzyCad](https://github.com/trailcode/EzyCad) — Open-source hobbyist CAD using OCCT, Dear ImGui, and OpenGL; desktop and WebAssembly builds.

---

## YouTube video description block

```
EzyCad — open-source hobbyist CAD (Open CASCADE / OCCT, Dear ImGui, OpenGL)

GitHub: https://github.com/trailcode/EzyCad
Documentation: https://ezycad.readthedocs.io/
Run in browser: https://trailcode.github.io/EzyCad/EzyCad.html

Keywords: EzyCad, trailcode, OCCT, Open CASCADE, ImGui, CAD, CNC, machining, WebAssembly
```

---

## Show HN (Hacker News)

**Title:** Show HN: EzyCad – open-source hobbyist CAD with OCCT and ImGui (runs in the browser)

**Body:**

EzyCad is a CAD app I'm building for hobbyist machinists: sketch, extrude, export STEP/STL. Uses Open CASCADE, Dear ImGui, OpenGL. You can run it in the browser via Emscripten or build from source on Windows.

https://trailcode.github.io/EzyCad/
https://github.com/trailcode/EzyCad

Happy for feedback on UX, performance, and what would make this useful alongside FreeCAD/Fusion.
50 changes: 50 additions & 0 deletions agents/issues/006-pr-body.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
### Summary

Simplify sketch node snapping around a single axis-guide model, fix a dimension-tool hover bug, restore direct snap to nodes on other visible sketches, and document how snap works for users.

### Problem

- `try_get_node_idx_snap` had overlapping paths (direct vertex snap, outside snap, axis snap) and dead annotation code (`update_node_snap_anno_`, `m_snap_anno`).
- `try_pick_existing_node` passed a stored node reference into snap logic, which could mutate sketch geometry during dimension-tool hover.
- The recent snap simplification dropped direct snap to **outside** sketch points (nodes on other visible sketches).
- User guides described snap only generically ("snaps to nodes and geometry") with no explanation of axis alignment vs vertex lock or cross-sketch targets.

### Implemented scope

**Code (`src/sketch_nodes.cpp`, `src/sketch_nodes.h`):**

- Unified snap feedback through axis guides (`show_snap_guides_at_`, `update_axis_snap_anno_`).
- Shared vertex snap threshold helper (`vertex_snap_threshold_sq_`).
- **Fix:** dimension pick hover uses `show_snap_guides_at_` on a copy of the picked position (no mutation of stored nodes).
- **Restore:** direct snap to `m_outside_snap_pts` (other visible sketches, projected onto the current plane).
- **Keep:** in-sketch vertex lock via dual-axis convergence (not proximity snap) so add-node edge-interior placement still works.
- Removed dead `update_node_snap_anno_`, `m_snap_anno`, `m_last_snap_pt`.

**Documentation:**

- `usage-sketch.md` — new **Sketch snapping** section (axis guides, vertex lock, edge interior, cross-sketch).
- `usage-settings.md` — link from Sketch options to snap section.
- `usage.md` — Sketch List **Nodes** clarifies user-placed points only.
- `CHANGELOG.md` — `[Unreleased]` entries.

### Acceptance criteria

- [ ] Dimension tool hover near a node shows snap guides without moving stored node coordinates.
- [ ] Snapping works to nodes on other **visible** sketches (e.g. polar duplicate, multi-sketch alignment).
- [ ] Add-node edge-interior split still works (near-miss onto segment interior).
- [ ] All `Sketch_test` cases pass.
- [ ] User guide **Sketch snapping** section matches in-app behavior.

### Files touched

- `src/sketch_nodes.cpp`
- `src/sketch_nodes.h`
- `usage-sketch.md`
- `usage-settings.md`
- `usage.md`
- `CHANGELOG.md`

### Related

- Prior simplification: axis-only snap model in `try_get_node_idx_snap`.
- #102 — polar duplicate sketch snap expectations.
64 changes: 64 additions & 0 deletions agents/issues/006-sketch-snap-unification-and-docs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Sketch snap unification, fixes, and documentation

**Opened on GitHub:** https://github.com/trailcode/EzyCad/issues/111

**Suggested labels:** `enhancement`, `sketch`, `docs`

---

## Title (GitHub)

Sketch snap: unify axis guides, fix dimension hover, restore cross-sketch snap, document behavior

## Body (GitHub)

### Summary

Simplify sketch node snapping around a single axis-guide model, fix a dimension-tool hover bug, restore direct snap to nodes on other visible sketches, and document how snap works for users.

### Problem

- `try_get_node_idx_snap` had overlapping paths (direct vertex snap, outside snap, axis snap) and dead annotation code (`update_node_snap_anno_`, `m_snap_anno`).
- `try_pick_existing_node` passed a stored node reference into snap logic, which could mutate sketch geometry during dimension-tool hover.
- The recent snap simplification dropped direct snap to **outside** sketch points (nodes on other visible sketches).
- User guides described snap only generically ("snaps to nodes and geometry") with no explanation of axis alignment vs vertex lock or cross-sketch targets.

### Implemented scope

**Code (`src/sketch_nodes.cpp`, `src/sketch_nodes.h`):**

- Unified snap feedback through axis guides (`show_snap_guides_at_`, `update_axis_snap_anno_`).
- Shared vertex snap threshold helper (`vertex_snap_threshold_sq_`).
- **Fix:** dimension pick hover uses `show_snap_guides_at_` on a copy of the picked position (no mutation of stored nodes).
- **Restore:** direct snap to `m_outside_snap_pts` (other visible sketches, projected onto the current plane).
- **Keep:** in-sketch vertex lock via dual-axis convergence (not proximity snap) so add-node edge-interior placement still works.
- Removed dead `update_node_snap_anno_`, `m_snap_anno`, `m_last_snap_pt`.

**Documentation:**

- `usage-sketch.md` — new **Sketch snapping** section (axis guides, vertex lock, edge interior, cross-sketch).
- `usage-settings.md` — link from Sketch options to snap section.
- `usage.md` — Sketch List **Nodes** clarifies user-placed points only.
- `CHANGELOG.md` — `[Unreleased]` entries.

### Acceptance criteria

- [ ] Dimension tool hover near a node shows snap guides without moving stored node coordinates.
- [ ] Snapping works to nodes on other **visible** sketches (e.g. polar duplicate, multi-sketch alignment).
- [ ] Add-node edge-interior split still works (near-miss onto segment interior).
- [ ] All `Sketch_test` cases pass.
- [ ] User guide **Sketch snapping** section matches in-app behavior.

### Files touched

- `src/sketch_nodes.cpp`
- `src/sketch_nodes.h`
- `usage-sketch.md`
- `usage-settings.md`
- `usage.md`
- `CHANGELOG.md`

### Related

- Prior simplification commits: axis-only snap model in `try_get_node_idx_snap`.
- `agents/issues/004-polar-dup-sketch-based-reference.md` — polar duplicate sketch snap expectations.
35 changes: 35 additions & 0 deletions agents/issues/007-ui-improve4-pr-body.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
## Summary

UI and sketch workflow polish on `Trailcode/ui_improve4` (8 commits vs `main`):

- **Sketch snap:** simplify `try_get_node_idx_snap` to axis-guide feedback; restore direct snap to nodes on other visible sketches; fix dimension-tool hover mutating stored node coordinates; remove dead vertex snap annotation code.
- **Sketch List:** changing the current sketch no longer forces **Sketch inspection mode** when a sketch tool is already active (e.g. **Add line** stays active).
- **Shape List:** hovering a visible shape row highlights that shape in the 3D view; configurable hover color in **Settings**; pane highlight styling.
- **3D view grid:** Settings exposes rectangular grid step and graphic extent / Z offset (`occt_view` JSON).
- **Docs / discoverability:** new **Sketch snapping** section in `usage-sketch.md`; Sketch List and settings cross-links; GitHub Pages landing page (`web/index.html`) and sync script; Read the Docs / SEO metadata updates.

Closes #111.

## Commits

| Commit | Description |
| --- | --- |
| `66f7f24` | Shape List hover drives 3D shape highlight |
| `0bd8936` | Shape List pane highlight; grid + hover color settings |
| `eda08e7` | SEO / GitHub Pages landing page and doc metadata |
| `4850d84` / `d126307` | Sketch snap simplification (axis guides) |
| `98dafc6` | User guide: sketch snapping section |
| `bae40ae` | Agent issue draft (#111) |
| `7c4bd04` | Sketch List: preserve active sketch tool when switching sketches |

## Test plan

- [ ] Sketch mode: move cursor near nodes — axis guides appear; vertex locks when X and Y align to the same point.
- [ ] Dimension tool: hover a node — guides show; node coordinates do not drift.
- [ ] Two visible sketches: snap to a node on the other sketch while editing the current one.
- [ ] Add node: near-miss onto a straight edge interior still splits the edge.
- [ ] Sketch List: in **Add line**, switch current sketch — tool stays **Add line** (not inspection).
- [ ] Sketch List: from **Normal**, switch current sketch — enters **Sketch inspection**.
- [ ] Shape List: hover a visible shape row — shape highlights in 3D; color follows **Settings**.
- [ ] Settings: grid step / extent changes persist and affect the view grid.
- [ ] `EzyCad_tests.exe --gtest_filter=Sketch_test.*` — all pass.
19 changes: 19 additions & 0 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,25 @@ def _verify_doc_assets() -> None:
copyright = "2026, trailcode"
author = "trailcode"

# Search and social previews (Read the Docs, Google, link unfurlers).
html_title = "EzyCad — open-source hobbyist CAD (OCCT, ImGui, OpenGL)"
html_short_title = "EzyCad"
html_meta = {
"description": (
"EzyCad (Easy CAD) is open-source hobbyist CAD for machining: sketch, "
"extrude, and export STEP/STL using Open CASCADE, Dear ImGui, and OpenGL. "
"Not EZCAD laser marking software."
),
"keywords": (
"EzyCad, CAD, Open CASCADE, OCCT, ImGui, OpenGL, CNC, machining, "
"STEP, STL, WebAssembly, Emscripten, 3D modeling"
),
}
html_theme_options = {
"navigation_depth": 4,
"collapse_navigation": False,
}

extensions = [
"myst_parser",
]
Expand Down
17 changes: 15 additions & 2 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,21 @@ EzyCad documentation
:alt: EzyCad splash screen
:align: center

EzyCad (Easy CAD) is a CAD application for hobbyist machinists. These pages are built from the
Markdown guides in the `EzyCad repository <https://github.com/trailcode/EzyCad>`_.
EzyCad (Easy CAD) is an open-source CAD application for hobbyist machinists. It uses
Open CASCADE Technology (OCCT), Dear ImGui, and OpenGL for 2D/3D modeling and exports
STEP, STL, and other formats for CNC or 3D printing.

**Source:** https://github.com/trailcode/EzyCad

**Run in browser (WebAssembly):** https://trailcode.github.io/EzyCad/EzyCad.html

.. note::

**EzyCad** (with a **y**) is mechanical CAD — not `EZCAD2/EZCAD3 <https://www.ezcad.com/>`_
laser marking software.

These pages are built from the Markdown guides in the
`EzyCad repository <https://github.com/trailcode/EzyCad>`_.

.. toctree::
:maxdepth: 2
Expand Down
2 changes: 1 addition & 1 deletion ezycad_code_style.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Use this style when editing or adding C/C++ code in the EzyCad project (files un
- Prefer clear domain prefixes for related member groups (e.g. `m_underlay_*`) instead of mixed short forms.
- **Constants** (e.g. lookup arrays for enums): `c_` prefix (e.g. `c_mode_strs`, `c_chamfer_mode_strs`).
- **Functions / methods**: snake_case (e.g. `add_new_node`, `get_node_exact`, `try_get_node_idx_snap`).
- **Private methods**: snake_case with trailing underscore (e.g. `update_node_snap_anno_`, `try_snap_outside_`).
- **Private methods**: snake_case with trailing underscore (e.g. `update_axis_snap_anno_`).
- **Type aliases**: snake_case with suffix by role, e.g. `*_ptr` for handles (`AIS_Shape_ptr`, `Shp_ptr`), `*_rslt` for result types (`Shp_rslt`). Typedefs like `ScreenCoords` are PascalCase.
- **Macros**: UPPER_SNAKE_CASE (e.g. `EZY_ASSERT`, `EZY_ASSERT_MSG`, `DBG_MSG`).

Expand Down
6 changes: 5 additions & 1 deletion res/about.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
![EzyCad splash](AI-gen-splashscreen_05_01_2026_512.png)

**EzyCad** (Easy CAD) is a CAD application for hobbyist machinists to design and edit 2D and 3D models for machining projects. It supports sketching, extruding, and geometric operations using OpenGL, Dear ImGui, and Open CASCADE Technology (OCCT). Export models to STEP, STL, and other formats for CNC or 3D printing.
**EzyCad** (Easy CAD) is an open-source CAD application for hobbyist machinists to design and edit 2D and 3D models for machining projects. It supports sketching, extruding, and geometric operations using OpenGL, Dear ImGui, and Open CASCADE Technology (OCCT). Export models to STEP, STL, and other formats for CNC or 3D printing.

**Not EZCAD laser software** — EzyCad (with a **y**) is mechanical CAD, unrelated to EZCAD2/EZCAD3 laser marking products.

Source repository: [https://github.com/trailcode/EzyCad](https://github.com/trailcode/EzyCad)

Project home: [https://trailcode.github.io/EzyCad/](https://trailcode.github.io/EzyCad/)

---

Product version appears in the application window title. MIT License; see the `LICENSE` file in the distribution.
Loading
Loading