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: 1 addition & 1 deletion docs/ezycad_code_style.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ User-facing Markdown (now in `docs/`: `usage.md`, `usage-*.md`, `scripting.md`,

- **Reader-first order** (`.cpp`): Put **public API and high-level workflow** at the top of the file (constructors, main entry points, orchestration). Put **lower-level details** below so the first screen shows what the module does before how it does it.
- **Helper functions** (`.cpp`): Prefer **file-local static helpers** in an anonymous namespace at the **bottom** of the implementing `.cpp` file. Forward-declare them near the top (or above their first use) when needed. Avoid large helper blocks at the top of the file; the goal is high-level code first, helpers last for readability.
- **PIMPL** (`class Foo; class Foo::Impl`): Use when hiding implementation details or when you want to swap implementations (e.g. `Sketch_nodes`, `Sketch_delta`). Keep the public surface in the header; put data members, private record types, and apply/clone logic in `Impl` inside the `.cpp`.
- **PIMPL** (`class Foo; class Foo::Impl`): Use when hiding implementation details or when you want to swap implementations (e.g. `Sketch_nodes`, `Sketch_op_recorder`). Keep the public surface in the header; put data members, private record types, and apply/clone logic in `Impl` inside the `.cpp`.
- **Templates**: Prefer putting template implementations in `.inl` files included from the header (e.g. `utl_types.inl`, `utl.inl`).
- **OCCT handles**: Use `opencascade::handle<T>` and project aliases (e.g. `AIS_Shape_ptr`, `Shp_ptr`).
- **Result/error handling**: See **Fail fast** below. Use `Result<T>` and `Status` from `utl.h`, `CHK_RET(...)` for early return on failure.
Expand Down
2 changes: 1 addition & 1 deletion src/doc/shape.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ Full GLFW -> `GUI` routing before these delegates: [`src/doc/gui.md`](gui.md).
| --- | --- |
| `Occt_view::push_undo_snapshot()` | Before booleans, fillet/chamfer, primitive add, polar dup, transform finalize, extrude commit, revolve |
| Transform preview only | No undo until **finalize** (not on each mouse move) |
| `Sketch_delta` (sketch subsystem) | Separate from shape ops; shape list captured in view snapshots |
| `Sketch_op_delta` (sketch subsystem) | Separate from shape ops; shape list captured in view snapshots |

## Persistence

Expand Down
6 changes: 3 additions & 3 deletions src/doc/sketch.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,10 @@ Supporting (not owned sub-objects):
sketch_display.cpp visibility, edge styling, list hover, set_current
sketch_operations.cpp operation axis, mirror, revolve
sketch_json.* JSON serialization
sketch_delta.* undo/redo (Sketch_op_recorder, Sketch_delta)
sketch_op_recorder.* undo/redo (Sketch_op_recorder; Sketch_op_delta in .cpp)
```

`Sketch` grants `friend` access to `Sketch_json`, `Sketch_delta`, `Sketch_topo`, `Sketch_edges`, `Sketch_dims`, `Sketch_node_marks`, and `Sketch_tools` for coordinated mutations without exposing internals publicly.
`Sketch` grants `friend` access to `Sketch_json`, `Sketch_op_delta`, `Sketch_topo`, `Sketch_edges`, `Sketch_dims`, `Sketch_node_marks`, and `Sketch_tools` for coordinated mutations without exposing internals publicly.

## Public API overview

Expand Down Expand Up @@ -209,7 +209,7 @@ Prefer these visitors in JSON/delta/topo code over iterating `std::list<Sketch_e
| `sketch_display.cpp` | Visibility, edge/face styling, `set_current`, list hover |
| `sketch_operations.cpp` | Operation axis, mirror, revolve |
| `sketch_json.h` | `.ezy` / project JSON for sketches |
| `sketch_delta.h` | Undo/redo deltas keyed by `sketch_id` |
| `sketch_op_recorder.h` | Undo/redo recorder; `Sketch_op_delta` lives in `.cpp` |

## Edge and face model

Expand Down
22 changes: 11 additions & 11 deletions src/doc/undo-redo.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Developer reference for EzyCad's document history. Public C++ entry points:

- [`delta.h`](../delta.h) — abstract undo step
- [`sketch_delta.h`](../sketch_delta.h) — sketch element deltas and recorder
- [`sketch_op_recorder.h`](../sketch_op_recorder.h) — sketch operation recorder (public API)
- [`gui_occt_view.h`](../gui_occt_view.h) — stack storage and `undo()` / `redo()`

Maintainers: update this file when undo stack layout, delta types, or push/pop contracts change (see [agents/conventions/token-lean.md](../../agents/conventions/token-lean.md#developer-docs-in-srcdoc)). User-facing shortcuts are documented in [`docs/usage.md`](../../docs/usage.md).
Expand All @@ -16,7 +16,7 @@ The implementation uses **two strategies** on one stack:

| Strategy | When used | Stored payload |
| --- | --- | --- |
| **Element delta** | Sketch geometry edits | `std::unique_ptr<Delta>` (`Sketch_delta` today) |
| **Element delta** | Sketch geometry edits | `std::unique_ptr<Delta>` (`Sketch_op_delta` in `sketch_op_recorder.cpp`) |
| **Full JSON snapshot** | Everything else | `to_json()` string of the whole document |

Sketch deltas are cheaper and precise; JSON snapshots are simple and cover arbitrary document changes (shape booleans, sketch add/remove, file load, etc.).
Expand Down Expand Up @@ -58,7 +58,7 @@ Snapshot undo/redo calls `load(state.json, false)` so **camera pan/zoom/rotate a

### Stable sketch identity

`Sketch_delta` keys sketches by stable `sketch_id` (not display name or list index). Node indices are never compacted; undo tombstones nodes created during an operation. See [sketch.md](sketch.md#requirements-and-invariants).
`Sketch_op_delta` keys sketches by stable `sketch_id` (not display name or list index). Node indices are never compacted; undo tombstones nodes created during an operation. See [sketch.md](sketch.md#requirements-and-invariants).

## Architecture

Expand All @@ -69,13 +69,13 @@ GUI (menus, hotkeys, some UI-driven snapshots)
| m_undo_stack / m_redo_stack (Undo_entry)
|
+-- push_undo_snapshot() --> entry.json = to_json()
+-- push_undo_delta() --> entry.delta = Sketch_delta
+-- push_undo_delta() --> entry.delta = Sketch_op_delta
+-- pop_undo_snapshot() --> drop last entry (failed/aborted edit)

Sketch edits
Sketch_op_recorder (RAII)
note_prev_* / note_curr_* during mutation
commit() --> push_undo_delta(Sketch_delta)
commit() --> push_undo_delta(Sketch_op_delta)
cancel() --> discard (destructor auto-cancels if not committed)

Delta (abstract)
Expand All @@ -84,7 +84,7 @@ Delta (abstract)
clone() copy for opposite stack
```

`Sketch_delta` is currently the only `Delta` subclass.
`Sketch_op_delta` is currently the only `Delta` subclass (defined in [`sketch_op_recorder.cpp`](../sketch_op_recorder.cpp), not the public header).

## Core types

Expand All @@ -100,11 +100,11 @@ class Delta {

Subclasses record the **forward** change. Undo applies `apply_reverse`; redo reapplies `apply_forward`.

### `Sketch_op_recorder` ([`sketch_delta.h`](../sketch_delta.h))
### `Sketch_op_recorder` ([`sketch_op_recorder.h`](../sketch_op_recorder.h))

RAII scope around one sketch edit:

1. **Construction** — captures live node positions and linear edges at operation start; allocates a `Sketch_delta` for the sketch's `get_id()`.
1. **Construction** — captures live node positions and linear edges at operation start; initializes `Sketch_op_data` for the sketch's `get_id()`.
2. **Mutation** — sketch code calls `note_*` helpers as it changes geometry.
3. **`commit()`** — if any notes were recorded, pushes the delta via `Occt_view::push_undo_delta()`.
4. **`cancel()`** or scope exit without commit — nothing is pushed (used for no-op mirror, failed tools, etc.).
Expand All @@ -116,13 +116,13 @@ Recorder notes (deduplicated by geometry):
| `note_prev_linear_edge` | Edge removed or split away (must have existed at op start) |
| `note_curr_linear_edge` | New linear segment added |
| `note_prev_arc_edge` / `note_curr_arc_edge` | Arc circle segment removed / added |
| `note_curr_node` | New node not live at op start |
| `note_curr_node` | New node not live at op start (stores `permanent` for redo) |
| `note_prev_length_dim` / `note_curr_length_dim` | Dimension removed / added |
| `note_prev_operation_axis` / `note_curr_operation_axis` | Operation axis before / after |

`note_prev_linear_edge` only records edges that were present when the recorder opened (`linear_edge_at_op_start_`), so incidental splits of pre-existing geometry are not mistaken for undoable removals of the user's new work.

### `Sketch_delta` apply logic ([`sketch_delta.cpp`](../sketch_delta.cpp))
### `Sketch_op_delta` apply logic ([`sketch_op_recorder.cpp`](../sketch_op_recorder.cpp))

**Forward (redo):** add `curr_*` linear edges and arcs, restore `curr_*` dimensions and operation axis, refresh faces.

Expand Down Expand Up @@ -199,7 +199,7 @@ Hotkeys are handled in `GUI::on_key` (`gui_mode.cpp`) when dist/angle edit popup
1. Open a `Sketch_op_recorder` around the mutation.
2. Call `note_prev_*` before removing or splitting existing geometry; `note_curr_*` after adding.
3. `commit()` at success; `cancel()` on no-op or error.
4. If redo/undo needs logic not covered by existing note types, extend `Sketch_delta::Impl` and both `apply_forward_` / `apply_reverse_`.
4. If redo/undo needs logic not covered by existing note types, extend `Sketch_op_data` and both `apply_forward_` / `apply_reverse_` in `sketch_op_recorder.cpp`.

### Non-sketch document change

Expand Down
2 changes: 1 addition & 1 deletion src/sketch.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
#include "utl_geom.h"
#include "mode.h"
#include "gui_occt_view.h"
#include "sketch_delta.h"
#include "sketch_op_recorder.h"
#include "utl.h"

using namespace glm;
Expand Down
3 changes: 2 additions & 1 deletion src/sketch.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ class Sketch
private:
friend class Sketch_json;
friend class Sketch_access;
friend class Sketch_delta;
friend class Sketch_op_delta;
friend struct Sketch_op_data;
friend class Sketch_op_recorder;
friend class Sketch_topo;
friend class Sketch_dims;
Expand Down
2 changes: 1 addition & 1 deletion src/sketch_dims.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include "mode.h"
#include "gui_occt_view.h"
#include "sketch.h"
#include "sketch_delta.h"
#include "sketch_op_recorder.h"
#include "sketch_edge.h"
#include "utl_geom.h"

Expand Down
2 changes: 1 addition & 1 deletion src/sketch_edges.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#include "gui_occt_view.h"
#include "sketch.h"
#include "sketch_delta.h"
#include "sketch_op_recorder.h"
#include "sketch_edge.h"
#include "sketch_topo.h"
#include "utl_geom.h"
Expand Down
1 change: 0 additions & 1 deletion src/sketch_edges.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ class Sketch_edges
private:
friend class Sketch;
friend class Sketch_topo;
friend class Sketch_delta;

void add_edge_raw_(const gp_Pnt2d& pt_a, const gp_Pnt2d& pt_b);
void add_edge_impl_(const gp_Pnt2d& pt_a, const gp_Pnt2d& pt_b, Sketch_op_recorder* rec);
Expand Down
2 changes: 0 additions & 2 deletions src/sketch_node_marks.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ class Sketch_node_marks
void trim_trailing();

private:
friend class Sketch_delta;

void apply_style_(AIS_Shape_ptr& shp, bool origin) const;

Sketch& m_sketch;
Expand Down
Loading
Loading