diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index c58ecc8..ee2e292 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -7,7 +7,7 @@ on: paths: - ".github/workflows/docs.yml" - ".readthedocs.yaml" - - "docs/**" + - "doc/**" - "usage.md" - "usage-*.md" - "scripting.md" @@ -18,7 +18,7 @@ on: paths: - ".github/workflows/docs.yml" - ".readthedocs.yaml" - - "docs/**" + - "doc/**" - "usage.md" - "usage-*.md" - "scripting.md" @@ -36,7 +36,7 @@ jobs: python-version: "3.13" - name: Install doc dependencies - run: pip install -r docs/requirements.txt + run: pip install -r doc/requirements.txt - name: Build HTML (warnings are errors; matches Read the Docs) - run: sphinx-build -b html -W --keep-going docs docs/_build + run: sphinx-build -b html -W --keep-going doc doc/_build diff --git a/.gitignore b/.gitignore index 43c59c6..fae8be4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ /build* -/docs/_build +/doc/_build /.vscode/settings.json # Legacy name; some toolchains write here. Primary vendored deps live in third_party/. /thirdParty diff --git a/.readthedocs.yaml b/.readthedocs.yaml index b76b227..a5d5e8d 100644 --- a/.readthedocs.yaml +++ b/.readthedocs.yaml @@ -17,9 +17,9 @@ build: python: "3.13" sphinx: - configuration: docs/conf.py + configuration: doc/conf.py fail_on_warning: true python: install: - - requirements: docs/requirements.txt + - requirements: doc/requirements.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 6259358..d1e1364 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -594,6 +594,7 @@ if(MSVC) set(DOC_FILES ${CMAKE_CURRENT_SOURCE_DIR}/README.md ${CMAKE_CURRENT_SOURCE_DIR}/ezycad_code_style.md + ${CMAKE_CURRENT_SOURCE_DIR}/ezycad_doc_style.md ${CMAKE_CURRENT_SOURCE_DIR}/CHANGELOG.md ${CMAKE_CURRENT_SOURCE_DIR}/usage.md ${CMAKE_CURRENT_SOURCE_DIR}/usage-settings.md diff --git a/README.md b/README.md index b99dfe8..a8053ac 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # EzyCad +![EzyCad splash screen](res/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). ## Features @@ -88,7 +90,7 @@ Ensure the following dependencies are installed: ### 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. -**Code style:** When contributing, please follow the project's style guide: [ezycad_code_style.md](ezycad_code_style.md). Both human developers and AI coding agents (e.g. Cursor, GitHub Copilot, ChatGPT) should adhere to it so that patches stay consistent and reviewable. Optional assistant-oriented snippets live under [agents/](agents/) (the repo does not commit `.cursor/`). +**Style guides:** [ezycad_code_style.md](ezycad_code_style.md) for C++ in `src/`; [ezycad_doc_style.md](ezycad_doc_style.md) for user guides and [Read the Docs](https://ezycad.readthedocs.io/). Both human developers and AI coding agents should follow the relevant guide. Optional assistant-oriented snippets live under [agents/](agents/) (the repo does not commit `.cursor/`). ## In-tree third-party libraries diff --git a/agents/README.md b/agents/README.md index 5f5cc03..06be572 100644 --- a/agents/README.md +++ b/agents/README.md @@ -7,3 +7,4 @@ 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`. | +| *(repo root)* [ezycad_doc_style.md](../ezycad_doc_style.md) | User guides, Read the Docs, images, in-app doc URLs. | diff --git a/docs/.gitignore b/doc/.gitignore similarity index 100% rename from docs/.gitignore rename to doc/.gitignore diff --git a/docs/_static/.gitkeep b/doc/_static/.gitkeep similarity index 100% rename from docs/_static/.gitkeep rename to doc/_static/.gitkeep diff --git a/docs/conf.py b/doc/conf.py similarity index 89% rename from docs/conf.py rename to doc/conf.py index f363f5b..79a2fd3 100644 --- a/docs/conf.py +++ b/doc/conf.py @@ -1,5 +1,5 @@ # Sphinx configuration for EzyCad user documentation (Read the Docs). -# User guides live at the repository root; they are synced into docs/ at build time +# User guides live at the repository root; they are synced into doc/ at build time # so cross-links (usage.md, usage-sketch.md, ...) and res/icons/ paths keep working. from __future__ import annotations @@ -26,8 +26,15 @@ def _sync_user_docs() -> None: if src.is_file(): shutil.copy2(src, DOCS_DIR / name) + res_dst = DOCS_DIR / "res" + res_dst.mkdir(exist_ok=True) + + splash_src = PROJECT_ROOT / "res" / "AI-gen-splashscreen_05_01_2026_512.png" + if splash_src.is_file(): + shutil.copy2(splash_src, res_dst / splash_src.name) + icons_src = PROJECT_ROOT / "res" / "icons" - icons_dst = DOCS_DIR / "res" / "icons" + icons_dst = res_dst / "icons" if icons_src.is_dir(): shutil.copytree(icons_src, icons_dst, dirs_exist_ok=True) diff --git a/docs/index.rst b/doc/index.rst similarity index 100% rename from docs/index.rst rename to doc/index.rst diff --git a/docs/readthedocs.md b/doc/readthedocs.md similarity index 74% rename from docs/readthedocs.md rename to doc/readthedocs.md index 7ddbcb8..58f4b3b 100644 --- a/docs/readthedocs.md +++ b/doc/readthedocs.md @@ -1,5 +1,7 @@ # Read the Docs maintenance +Author conventions (Markdown, images, links): **[ezycad_doc_style.md](../ezycad_doc_style.md)**. + Published site: **https://ezycad.readthedocs.io/** ## Repository automation @@ -9,7 +11,7 @@ Published site: **https://ezycad.readthedocs.io/** | [`.readthedocs.yaml`](../.readthedocs.yaml) | RTD build config (Sphinx, Python 3.13). | | [`.github/workflows/docs.yml`](../.github/workflows/docs.yml) | GitHub Actions: builds docs on push/PR when guides change. | -User guides stay at the **repository root** (`usage.md`, etc.). `docs/conf.py` copies them plus `res/icons/` and `doc/gen/` into `docs/` at build time. +User guides stay at the **repository root** (`usage.md`, etc.). `doc/conf.py` copies them plus `res/icons/` into `doc/` at build time. Screenshots in guides use paths under `doc/gen/` (committed in this folder). Use Markdown image syntax `![alt](path)` for icons and screenshots. Raw HTML `` is not rewritten by Sphinx and will break on Read the Docs. @@ -24,8 +26,8 @@ Configure at [EzyCad admin](https://app.readthedocs.org/dashboard/ezycad/): ## Local build ```bash -pip install -r docs/requirements.txt -sphinx-build -b html docs docs/_build +pip install -r doc/requirements.txt +sphinx-build -b html -W doc doc/_build ``` -Open `docs/_build/index.html`. +Open `doc/_build/index.html`. diff --git a/docs/requirements.txt b/doc/requirements.txt similarity index 100% rename from docs/requirements.txt rename to doc/requirements.txt diff --git a/ezycad_code_style.md b/ezycad_code_style.md index d84539e..b44ea16 100644 --- a/ezycad_code_style.md +++ b/ezycad_code_style.md @@ -33,6 +33,10 @@ Use this style when editing or adding C/C++ code in the EzyCad project (files un - **Short control flow**: When the body is a single statement you may omit braces; **`AllowShortIfStatementsOnASingleLine: false`** means clang-format will not merge an `if` into one physical line (typically the condition on one line and the statement on the next). Use braces for multi-line or nested bodies. **`for`/`while`** (and other constructs not listed above) follow **`BasedOnStyle: LLVM`** unless overridden in `.clang-format`. - Use **`// clang-format off`** / **`// clang-format on`** only where layout must be preserved (e.g. macro-like blocks, tables). Prefer running clang-format; it is the source of truth for formatting. +## Documentation + +User-facing Markdown (`usage.md`, `usage-*.md`, `scripting.md`, Read the Docs, images, in-app help URLs) is covered in **[ezycad_doc_style.md](ezycad_doc_style.md)**. This file is for **`src/` C++ only**. + ## Versioning and releases - **Product version** lives in **`src/version.h`**: `EZYCAD_VERSION_MAJOR`, `EZYCAD_VERSION_MINOR`, `EZYCAD_VERSION_PATCH`, and `EZYCAD_VERSION_STRING`. Follow [Semantic Versioning](https://semver.org/spec/v2.0.0.html) (MAJOR.MINOR.PATCH). The header is hand-maintained so it stays valid regardless of build system (CMake or otherwise). diff --git a/ezycad_doc_style.md b/ezycad_doc_style.md new file mode 100644 index 0000000..360f20f --- /dev/null +++ b/ezycad_doc_style.md @@ -0,0 +1,66 @@ +# EzyCad documentation style + +Use this guide when editing **user-facing Markdown** at the repository root (`usage.md`, `usage-*.md`, `scripting.md`, `README.md`, `CHANGELOG.md`). For C++ in `src/`, see **[ezycad_code_style.md](ezycad_code_style.md)**. + +Published HTML: **[https://ezycad.readthedocs.io/](https://ezycad.readthedocs.io/)** (`/en/latest/` tracks `main`). Build plumbing is described in **[doc/readthedocs.md](doc/readthedocs.md)** (Read the Docs dashboard, local `sphinx-build`). + +## Canonical files (edit these) + +| File | Purpose | +|------|---------| +| `usage.md` | Main usage guide | +| `usage-sketch.md` | 2D sketching | +| `usage-settings.md` | Settings pane and JSON | +| `usage-occt-view.md` | 3D viewer (OCCT) | +| `scripting.md` | Lua / Python consoles | +| `README.md` | Project overview | +| `CHANGELOG.md` | Release notes ([Keep a Changelog](https://keepachangelog.com/)) | + +Do **not** edit generated copies under `doc/` for content. At build time, `doc/conf.py` syncs root guides plus `res/icons/` into `doc/` (see `doc/.gitignore`). Screenshots stay in `doc/gen/`. + +## Writing conventions + +- **Audience**: Machinists and hobby CAD users; prefer plain language and short steps. +- **Headings**: Use `##` / `###` for sections Sphinx/MyST can index; keep a stable **Table of Contents** in `usage.md` when adding major sections. +- **Keyboard shortcuts**: Use `Tab`, `Ctrl+Z`, etc. They render on Read the Docs via MyST. +- **Tables**: GFM pipe tables are fine on Read the Docs. +- **Cross-links**: Link other guides as `usage-sketch.md`, `usage-settings.md#view-menu`, or `#anchor` within the same file. Prefer anchors that match heading text (MyST slugifies headings for URLs). +- **Encoding**: The **ASCII-only** rule in `ezycad_code_style.md` applies to `src/`, not to these guides; Unicode in user docs is acceptable when it helps clarity. + +## Images + +| Kind | Path | Syntax | +|------|------|--------| +| Toolbar icons | `res/icons/Name.png` | `![alt](res/icons/Name.png)` | +| Screenshots | `doc/gen/name.png` | `![alt](doc/gen/name.png)` | + +Rules: + +- Use **Markdown image syntax only**. Do **not** use raw HTML `` — Sphinx leaves those paths unchanged and icons **break** on Read the Docs. +- Commit new PNGs under `res/icons/` or `doc/gen/` with the guide change. +- After image or guide edits, run `sphinx-build -b html -W doc doc/_build` locally, or confirm the Read the Docs build is green (`fail_on_warning: true` in [`.readthedocs.yaml`](.readthedocs.yaml)). + +## Links from the application + +- **Help → Usage Guide** should open Read the Docs, e.g. `https://ezycad.readthedocs.io/en/latest/usage.html`, not a GitHub blob URL. +- In-app help tooltips (Settings **?** buttons, etc.) should use the same base URL and heading anchors (e.g. `#view-roll`). +- When you rename a heading, check for broken anchors in `src/` (grep for `readthedocs.io` and old `#fragments`). + +## Build and CI (reference) + +| Item | Location | +|------|----------| +| Read the Docs config | [`.readthedocs.yaml`](.readthedocs.yaml) | +| Sphinx | [`doc/conf.py`](doc/conf.py), [`doc/index.rst`](doc/index.rst) | +| Python deps | [`doc/requirements.txt`](doc/requirements.txt) | +| GitHub Actions | [`.github/workflows/docs.yml`](.github/workflows/docs.yml) | + +```bash +pip install -r doc/requirements.txt +sphinx-build -b html -W doc doc/_build +``` + +## Related docs + +- **[ezycad_code_style.md](ezycad_code_style.md)** — C++ style, versioning (`version.h`, `CHANGELOG.md`). +- **[doc/readthedocs.md](doc/readthedocs.md)** — RTD integrations, webhooks, PR previews. diff --git a/usage-settings.md b/usage-settings.md index a7a7437..9486d96 100644 --- a/usage-settings.md +++ b/usage-settings.md @@ -40,7 +40,7 @@ Open **View -> Settings**. The window title is **Settings**. Between those, the pane has **six** collapsible sections. Expand a section to see its controls; when collapsed, only the section title bar is visible. -1. **3D view navigation** — **View rotation step** (degrees per key press for **NumPad 8**/**2**/**4**/**6** orbit and **Shift+NumPad 4**/**6** roll; default **45**). **Zoom scroll scale** (multiplier for wheel and **+**/**-** zoom; default **4**). Hold **Shift** while zooming for a Blender-style finer step (multiply by **0.1**). Numpad shortcuts are documented with **Num Lock off**; with **Num Lock on**, use main-row alternatives in [usage.md -> View navigation](usage.md#view-navigation). Stored as **`gui.view_roll_step_deg`** and **`gui.view_zoom_scroll_scale`**. See **[usage-occt-view.md](usage-occt-view.md)**. +1. **3D view navigation** — **View rotation step** (degrees per key press for **NumPad 8**/**2**/**4**/**6** orbit and **Shift+NumPad 4**/**6** roll; default **45**; **`?`** opens [view roll](https://ezycad.readthedocs.io/en/latest/usage.html#view-roll) on Read the Docs). **Zoom scroll scale** (multiplier for wheel and **+**/**-** zoom; default **4**). Hold **Shift** while zooming for a Blender-style finer step (multiply by **0.1**). Numpad shortcuts are documented with **Num Lock off**; with **Num Lock on**, use main-row alternatives in [usage.md -> View navigation](usage.md#view-navigation). Stored as **`gui.view_roll_step_deg`** and **`gui.view_zoom_scroll_scale`**. See **[usage-occt-view.md](usage-occt-view.md)**. 2. **UI corner rounding** — Sliders **0** to **16** for **Windows, frames, popups**; **Scrollbars and sliders** (has `(?)`); **Tabs**. diff --git a/usage-sketch.md b/usage-sketch.md index b67fd2e..391982d 100644 --- a/usage-sketch.md +++ b/usage-sketch.md @@ -15,6 +15,7 @@ This guide covers all 2D sketching tools and operations in EzyCad. For the main 10. [Dimension Tool](#dimension-tool) 11. [Add Node Tool](#add-node-tool) 12. [Create Sketch from Planar Face Tool](#create-sketch-from-planar-face-tool) +13. [Image underlay](#image-underlay) --- @@ -706,4 +707,39 @@ The create sketch from planar face tool allows you to extract the boundary of a | **Boundary extraction** | Uses `BRepTools::OuterWire()` on the selected face | | **Sketch plane** | Determined from the face's underlying surface geometry | | **Supported faces** | Only `Geom_Plane` surfaces - other surface types are rejected | -| **Sketch list** | Created sketch is added and can be managed like any other sketch | \ No newline at end of file +| **Sketch list** | Created sketch is added and can be managed like any other sketch | + +### Image underlay + +Import a reference image (PNG, JPEG, or BMP) behind a sketch for tracing or alignment. Open **Sketch properties** from the [Sketch List](usage.md#sketch-list) (**`[P]`** on the sketch row) or use the underlay controls there after import. + +**Sketch List shortcuts** + +| Control | Action | +| --- | --- | +| Underlay checkbox | Show or hide the underlay for that sketch (only when an image is loaded) | +| **`[P]`** | Open **Sketch properties** for import, calibration, and transform | + +**Sketch properties — Image underlay** + +| Control | Action | +| --- | --- | +| **Import image...** | Load PNG/JPEG/BMP into the current sketch | +| **Remove underlay** | Clear the image from the sketch | +| **White paper -> transparent** | Treat bright pixels as clear (typical for scanned line drawings; turn off for photos) | +| **Tint visible lines** / **Line color** | Recolor non-transparent pixels after the white key (default yellow works on dark backgrounds) | +| **Opacity** | Overall underlay transparency (**0**–**1**) | + +**Calibrate from sketch edges** (sketch must be **current** in the Sketch List): + +| Button | Action | +| --- | --- | +| **Set X from edge...** | Two clicks along bitmap width (+U), then enter the real drawing distance (same units as sketch dimensions) | +| **Set Y from edge...** | Two clicks along bitmap height (+V), then enter the drawing distance for Y | +| **Define underlay datum...** | Two picks on the sketch plane: corner **(0,0)**, then direction along +U (keeps current half width and height) | + +After edge calibration, bitmap axes may be non-orthogonal (shear). The **Transform** sliders (**Center X/Y**, **Half width/height**, **Rotation**) then stay disabled so they do not overwrite that affine fit; use calibration picks or adjust before shear is introduced. + +**Transform** (orthogonal underlay only): sliders and **Rotation value** adjust center, half extents, and rotation on the sketch plane; changes apply in real time and support undo. + +Default underlay highlight tint for new imports: **Settings -> Sketch -> Underlay highlight color** (see [usage-settings.md](usage-settings.md#settings-pane)). \ No newline at end of file diff --git a/usage.md b/usage.md index ecd6927..1079202 100644 --- a/usage.md +++ b/usage.md @@ -1,5 +1,7 @@ # EzyCad Usage Guide +![EzyCad splash screen](res/AI-gen-splashscreen_05_01_2026_512.png) + ## Table of Contents 1. [Introduction](#introduction) 2. [Getting Started](#getting-started) @@ -78,12 +80,20 @@ For **View** (Settings, pane toggles, consoles), saving preferences, and the **S The **Sketch List** pane lists all 2D sketches in the current document. Open it from **View -> Sketch List**. -For each sketch you can: +Each row is laid out left to right: + +- **Expand** - Click **`>`** / **`v`** to show or hide details for that sketch (tooltip *Expand details* / *Collapse details*). +- **Set current** - Radio button (circle). The current sketch is used for editing and for operations such as [extrude](#extrude-sketch-face-tool-e). +- **Rename** - Click the name field and type a new name. +- **Visibility** - Checkbox to show or hide the sketch in the 3D view. +- **Underlay** - Checkbox to show or hide an [image underlay](usage-sketch.md#image-underlay) when one is imported (disabled until an underlay exists; tooltip *Display underlay*). +- **Sketch properties** - **`[P]`** opens the **Sketch properties** window (import/remove underlay, calibration, transform). See [Image underlay](usage-sketch.md#image-underlay). +- **Delete** - Right-click the name and choose **Delete**. -- **Set current** - Use the radio button (circle) to make this sketch the current one. The current sketch is used for editing and for operations such as [extrude](#extrude-sketch-face-tool-e). -- **Rename** - Click the name field and type to change the sketch's name. -- **Visibility** - Use the checkbox to show or hide the sketch in the 3D view. -- **Delete** - Right-click the sketch name and choose **Delete** to remove the sketch from the document. +When expanded, the row shows: + +- **Dimensions** - Table of length dimensions: visibility, editable name, and **offset** (label distance from the edge; **0** = automatic). +- **Nodes**, **Edges**, **Faces** - Collapsible lists of element labels for inspection (read-only names). The window can be closed with its close button; use **View -> Sketch List** again to show it. @@ -621,16 +631,18 @@ More context on the 3D viewer stack: **[3D viewer (Open CASCADE)](usage-occt-vie ## Support ### Documentation -- [This usage guide](#ezycad-usage-guide) +- **Online** - [ezycad.readthedocs.io](https://ezycad.readthedocs.io/en/latest/usage.html) (built from this repository; same content as the guides below). Open from **Help -> Usage Guide**. +- [This usage guide](#ezycad-usage-guide) (source: [usage.md](usage.md)) - [Settings](usage-settings.md) (Settings pane, View menu, JSON settings file, startup project) - [3D viewer (Open CASCADE)](usage-occt-view.md) -- [2D Sketching](usage-sketch.md) (including [add node](usage-sketch.md#add-node-tool)) +- [2D Sketching](usage-sketch.md) (including [add node](usage-sketch.md#add-node-tool) and [image underlay](usage-sketch.md#image-underlay)) - [Scripting (Lua / Python)](scripting.md) -- Hosted docs and video tutorials are not published yet; this repository's markdown guides are the reference for now. + +The markdown files in the repository remain the canonical source; Read the Docs publishes them on each update. Video tutorials are not published yet. ### Code quality and ongoing work -Contributors should follow **[ezycad_code_style.md](ezycad_code_style.md)** for C++ in `src/`. Sketching, UI, and build paths are still being refined; prefer small, focused changes and match existing patterns in the files you touch. +Contributors should follow **[ezycad_code_style.md](ezycad_code_style.md)** for C++ in `src/` and **[ezycad_doc_style.md](ezycad_doc_style.md)** when editing these guides. Sketching, UI, and build paths are still being refined; prefer small, focused changes and match existing patterns in the files you touch. ### Community - [User forums](https://github.com/trailcode/EzyCad/discussions)