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

### Added

- **STEP Import as**: the Import dialog replaces the **Union shapes** checkbox with an **Import as** combo (**Preserve hierarchy** default, **Flat solids**, **Union shapes**). Hierarchy keeps XCAF assembly groups and product/instance names; flat adds leaf solids at the document root; union fuses into one solid.

- **STEP import progress**: on **Import into project**, an **Importing...** modal appears while transferring. Desktop shows stage/progress and Cancel (OCCT transfer on a background thread). Web shows a simple wait dialog (no Cancel; transfer runs on the main thread after the dialog paints). The Import dialog no longer shows a file metadata summary (opens immediately after file pick).

- **Configurable hotkeys**: **Settings -> Keyboard shortcuts** remaps shape tools (Move/Rotate/Scale/Extrude/Chamfer/Fillet/Polar duplicate/Cross-section), sketch tools (inspection, from face, operation axis, node/line/multi-line/arc/square/rectangle/circle/slot, Dimension), boolean commands (Cut/Fuse/Common), Delete, New/Open/Save, and Undo/Redo. Bindings persist as **`gui.hotkeys`** (human-readable chords; missing keys use defaults). Toolbar tooltips follow remaps. **Delete** / **Backspace** stay fixed delete aliases; <kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>Z</kbd> stays a fixed redo alias. Fixed, unsupported, and conflicting chords are rejected on assign with a status toast (and inline message); remaps accept letters, digits, and <kbd>Space</kbd> only (punctuation/numpad rejected); per-row **Reset** rejects when the factory chord is already bound elsewhere (same conflict message as assign); hotkey capture clears when Settings closes. A **?** at the top of the section opens the [Keyboard shortcuts](https://ezycad.readthedocs.io/en/latest/usage-settings.html#keyboard-shortcuts) settings guide.

- **Extrude Twist**: Options **Twist** checkbox. Two-phase flow locks height first, then sets twist angle about the face centroid (mouse, or <kbd>Shift+Tab</kbd> for degrees). Height length dim is cleared on lock; a temporary angle annotation on the extruded front face shows degrees during twist. With **Both sides**, ends twist symmetrically by +/- half the angle. Geometry uses ruled thru-sections with compatibility off (keeps tooth pairing) and cuts twisted hole solids so face bores survive; straight prism when twist is zero. Dense-face **Extrude fast preview** also applies during Twist (face copies translate and rotate; finalize builds the solid).
Expand Down
23 changes: 10 additions & 13 deletions docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ Each row (left to right):
- **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).
- **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).

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 preserve product/assembly groups in the tree (unless **Union shapes** is checked).
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.

The **current group** and rows that match the **current 3D selection** use a highlighted full-row style. Hovering a visible solid row also highlights that shape in the 3D view (**Settings -> View presentation -> Element hover color**).

Expand Down Expand Up @@ -249,18 +249,13 @@ The typical modeling workflow in EzyCad follows these steps:

### Import dialog

**File -> Import** opens an **Import** window for STEP or PLY. Review metadata, optionally enable **Union shapes** (STEP), then click **Import into project**. The window closes after a successful import.

| Format | What the Import dialog shows |
| -------------------------- | --------------------------------------------------------- |
| **STEP** (`.step`, `.stp`) | Roots/shapes, import bodies, named bodies, topology, bbox |
| **PLY** (`.ply`) | Encoding, vertex and face counts from the header |
**File -> Import** opens an **Import** window for STEP or PLY. Choose how STEP assemblies land in the Shape List (**Import as**, default **Preserve hierarchy**), then click **Import into project**. STEP import shows an **Importing...** dialog while transferring (desktop also shows stage/progress and Cancel). The window closes after a successful import.

**How to use:**
1. Choose **File -> Import**
2. Pick a `.step`, `.stp`, or `.ply` file
3. Review the label/value table; for STEP, optionally enable **Union shapes**
4. Click **Import into project**
3. For STEP, choose **Import as** if needed
4. Click **Import into project** (STEP may show a progress modal while transferring)

For in-document topology of an already-loaded solid, use [Shape info](#shape-info) from the Shape List.

Expand All @@ -284,7 +279,7 @@ In addition to creating 3D shapes from sketches, EzyCad supports importing exist
**How to import:**
1. Use **File -> Import**
2. Pick a `.step`, `.stp`, or `.ply` file
3. Review metadata in the [Import dialog](#import-dialog); for STEP assemblies, optionally check **Union shapes**
3. In the [Import dialog](#import-dialog), for STEP choose **Import as** if needed
4. Click **Import into project** - geometry is added as 3D shape(s) in the document, scaled to project units (see below)
5. You can move, rotate, scale, and use imported bodies in [boolean operations](#boolean-operations) like native solids where the geometry allows it

Expand All @@ -303,9 +298,11 @@ In addition to creating 3D shapes from sketches, EzyCad supports importing exist

**STEP import notes:**
- If the file cannot be read or contains no transferable geometry, a **message** explains the failure (invalid data, empty transfer, etc.).
- Assemblies often arrive with XCAF product structure. Import builds Shape List **groups** for assemblies and leaf solids for bodies (unless **Union shapes** merges everything into one solid). The Import dialog **Import bodies** count shows how many leaf solids will be added.
- When the STEP file includes product or part names, those names appear in the Shape List (duplicate names get `.001`, `.002`, ...). Unnamed bodies stay as `Shape`.
- **Union shapes** (Import dialog) fuses those bodies into one solid before adding to the document. If union fails, the import is aborted and nothing is added.
- Assemblies often arrive with XCAF product structure. The Import dialog **Import as** combo controls how they land in the Shape List:
- **Preserve hierarchy** (default) - builds Shape List **groups** for assemblies and leaf solids for bodies; group and part names come from product/instance names in the file when present.
- **Flat solids** - adds leaf solids only at the document root (no assembly groups); keeps per-body names from the file.
- **Union shapes** - fuses those bodies into one solid before adding to the document. If union fails, the import is aborted and nothing is added.
- When the STEP file includes product or part names, those names appear in the Shape List (duplicate names get `.001`, `.002`, ...). Unnamed bodies stay as `Shape`; unnamed assemblies use `Assembly`.

**Note:** **IGES** and **STL** are available for **export** only, not import.

Expand Down
2 changes: 1 addition & 1 deletion src/doc/gui.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Typical responsibilities:
- ImGui frame: menu bar, dock space (passthrough central node for 3D input), toolbar, Sketch List, Shape List, Options, Settings, dist/angle popups.
- Mode switching (`Mode` enum in [`mode.h`](../mode.h)) and parent-mode Esc behavior.
- Persisted preferences (`ezycad_settings.json` via [`gui_settings.cpp`](../gui_settings.cpp)).
- Project I/O (`.ezy` load/save, import/export dialogs; **File -> Import** shows metadata then loads STEP/PLY).
- Project I/O (`.ezy` load/save, import/export dialogs; **File -> Import** confirms STEP/PLY with **Import as** for hierarchy / flat / union). STEP **Import into project** shows an Importing modal; desktop uses `Atomic_progress_indicator` + background Transfer + Cancel; WASM paints the modal for two frames then runs Transfer on the main thread (no Cancel).
- CAD/mesh interchange scales about the origin: project display lengths follow **File -> Project units** (`Project_unit`; Inch or Millimeter). Model space stays inch-scaled (`model = inches * dimension_scale`). STEP import converts OCCT cascade **mm** into model space; PLY import treats coords as inches. **File -> Export** asks for **Inches** or **Millimeters** (STEP/IGES declare that unit; STL/PLY write unitless coords in that scale). `.ezy` persists `projectUnit`. **Settings -> New project defaults** stores `gui.default_project_unit` and inch-based default 2D framing for **File -> New**.
- Contextual help links (`doc_urls` in `gui.h`).

Expand Down
2 changes: 1 addition & 1 deletion src/doc/shape.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ Typical uses:
- Each solid stores a `gp_Ax3` local frame. New geometry defaults to a world-aligned frame at its bounding-box center. Baked move/rotate/scale transforms update the frame; project JSON and shape undo records preserve it.
- `Shp_ptr` is `opencascade::handle<Shp>`. New shapes are allocated with `new Shp(ctx(), topo_shape)` then registered through `Occt_view::add_shp_()`. Groups use `Shp::create_group` (empty compound, never displayed).
- Hierarchy: `parent_id` (0 = root) + `sibling_order`. Organizational groups only (no transform inheritance). Helpers: `shape_children`, `shape_descendant_solids`, `group_shapes`, `ungroup_shape`, `reparent_shape`, `would_reparent_create_cycle`.
- **Current group** (`Occt_view::current_group_id`, 0 = root): Shape List click sets it; empty groups are valid. Primitives / extrude / revolve / PLY / unioned STEP import call `add_shp_(..., use_current_group=true)` so new solids land under that group. Booleans keep `assign_result_parent_`.
- **Current group** (`Occt_view::current_group_id`, 0 = root): Shape List click sets it; empty groups are valid. Primitives / extrude / revolve / PLY / unioned STEP import (`Step_import_mode::Union_shapes`) call `add_shp_(..., use_current_group=true)` so new solids land under that group. Hierarchical and flat STEP import place roots at document root (`parent_id` 0). STEP import may prepare geometry off-thread (`prepare_step_import`) then `commit_step_import` on the UI thread. Booleans keep `assign_result_parent_`.
- `Shp_operation_base` is a **`friend` of `Occt_view`** so operations can call `add_shp_()`, read selection, and use pick helpers without exposing those on the public view API.
- **`Occt_view&` must outlive** all `Shp_*` operation objects (they are member subobjects of the view).
- Boolean/polar results call `assign_result_parent_` so the new solid shares the inputs' parent when all match; otherwise root (`parent_id` 0).
Expand Down
2 changes: 2 additions & 0 deletions src/doc/utility.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ Used by **File -> Import**. Reads file bytes only until the user confirms import
| `read_step_named_bodies` | STEPCAF/XCAF bodies + product names (flat; falls back to plain reader) |
| `read_step_named_tree` | STEPCAF/XCAF assembly tree as group/leaf `Named_node`s (falls back flat) |

`Occt_view::import_step` takes `Step_import_mode` (`utl_types.h`): preserve hierarchy (default), flat root leaves, or union. Heavy work splits into `prepare_step_import` (thread-safe geometry) + `commit_step_import` (UI thread). STEP Transfer accepts optional `Atomic_progress_indicator` / `Message_ProgressRange` (`utl_occt_progress.h`). `collect` remains available for tooling but is not shown in the Import dialog.

## Logging and debug

| Component | Role |
Expand Down
Loading
Loading