diff --git a/agents.md b/agents.md index 4c26113..c05411a 100644 --- a/agents.md +++ b/agents.md @@ -21,6 +21,8 @@ Pointer for AI coding assistants. Details live in [agents/README.md](agents/READ - Script consoles: [src/doc/script.md](src/doc/script.md) (read; update when bindings or console UI change) - Utilities: [src/doc/utility.md](src/doc/utility.md) (read; update when utl_* contracts or I/O change) - Build/test: [agents/workflows/local-dev.md](agents/workflows/local-dev.md) or root README +- OCCT APIs / WASM (desktop 8 vs wasm 7.9.3): [agents/conventions/occt-wasm-dual-version.md](agents/conventions/occt-wasm-dual-version.md) — until wasm works on OCCT 8 +- OCCT handles (`Handle` vs `*_ptr`): [agents/conventions/occt-handles.md](agents/conventions/occt-handles.md) - Release (maintainers only): [agents/workflows/release.md](agents/workflows/release.md) - Open work context: one file under [agents/drafts/](agents/drafts/) if relevant diff --git a/agents/README.md b/agents/README.md index acc48d4..d1c381c 100644 --- a/agents/README.md +++ b/agents/README.md @@ -6,21 +6,23 @@ Root markers: [AGENTS.md](../AGENTS.md) / [agents.md](../agents.md). ## Quick index -| Need | File | -| ------------------------- | -------------------------------------------------------------------------------------------------------------------- | -| ASCII / `src/` edits | [conventions/ascii-source.md](conventions/ascii-source.md) | -| C++ style (full) | [docs/ezycad_code_style.md](../docs/ezycad_code_style.md) | -| User docs when UI changes | [conventions/user-docs-sync.md](conventions/user-docs-sync.md) | -| Sketch module (dev doc) | [src/doc/sketch.md](../src/doc/sketch.md) — read when editing sketch code; update if API/architecture changes | -| Shape module (dev doc) | [src/doc/shape.md](../src/doc/shape.md) — read when editing `shp_*` code; update if API/operations change | -| GUI module (dev doc) | [src/doc/gui.md](../src/doc/gui.md) — read when editing `gui_*` / viewer shell; update if routing or settings change | -| Script module (dev doc) | [src/doc/script.md](../src/doc/script.md) — read when editing `scr_*`; update if bindings change | -| Utility module (dev doc) | [src/doc/utility.md](../src/doc/utility.md) — read when editing `utl_*`; update if shared helpers or I/O change | -| Build / test / wasm | [workflows/local-dev.md](workflows/local-dev.md) | -| Release | [workflows/release.md](workflows/release.md) | -| Issue/PR drafts | [drafts/](drafts/) — [github-drafts.md](conventions/github-drafts.md) | -| Token-saving rules | [conventions/token-lean.md](conventions/token-lean.md) | -| Markdown tables | [conventions/markdown-tables.md](conventions/markdown-tables.md) — align GFM pipes for source + preview | -| Outreach (optional) | [outreach/discoverability.md](outreach/discoverability.md) | +| Need | File | +| ---------------------------- | -------------------------------------------------------------------------------------------------------------------- | +| ASCII / `src/` edits | [conventions/ascii-source.md](conventions/ascii-source.md) | +| C++ style (full) | [docs/ezycad_code_style.md](../docs/ezycad_code_style.md) | +| User docs when UI changes | [conventions/user-docs-sync.md](conventions/user-docs-sync.md) | +| Sketch module (dev doc) | [src/doc/sketch.md](../src/doc/sketch.md) — read when editing sketch code; update if API/architecture changes | +| Shape module (dev doc) | [src/doc/shape.md](../src/doc/shape.md) — read when editing `shp_*` code; update if API/operations change | +| GUI module (dev doc) | [src/doc/gui.md](../src/doc/gui.md) — read when editing `gui_*` / viewer shell; update if routing or settings change | +| Script module (dev doc) | [src/doc/script.md](../src/doc/script.md) — read when editing `scr_*`; update if bindings change | +| Utility module (dev doc) | [src/doc/utility.md](../src/doc/utility.md) — read when editing `utl_*`; update if shared helpers or I/O change | +| Build / test / wasm | [workflows/local-dev.md](workflows/local-dev.md) | +| OCCT desktop 8 vs wasm 7.9.3 | [conventions/occt-wasm-dual-version.md](conventions/occt-wasm-dual-version.md) — until wasm works on OCCT 8 | +| OCCT handles (`*_ptr`) | [conventions/occt-handles.md](conventions/occt-handles.md) — prefer aliases over `Handle()` for clang-format | +| Release | [workflows/release.md](workflows/release.md) | +| Issue/PR drafts | [drafts/](drafts/) — [github-drafts.md](conventions/github-drafts.md) | +| Token-saving rules | [conventions/token-lean.md](conventions/token-lean.md) | +| Markdown tables | [conventions/markdown-tables.md](conventions/markdown-tables.md) — align GFM pipes for source + preview | +| Outreach (optional) | [outreach/discoverability.md](outreach/discoverability.md) | Full user-doc style: [docs/ezycad_doc_style.md](../docs/ezycad_doc_style.md). OCCT build: [docs/building-occt.md](../docs/building-occt.md). diff --git a/agents/conventions/occt-handles.md b/agents/conventions/occt-handles.md new file mode 100644 index 0000000..55515d3 --- /dev/null +++ b/agents/conventions/occt-handles.md @@ -0,0 +1,29 @@ +# OCCT handles vs `Handle()` macro + +Prefer the pattern in [`src/utl_types.h`](../../src/utl_types.h): + +```cpp +using AIS_Shape_ptr = opencascade::handle; +``` + +Use those `*_ptr` aliases (or `opencascade::handle` inline) in new and touched code. + +## Why not `Handle(T)`? + +OCCT's `Handle(T)` macro is valid and expands to `opencascade::handle`, but **clang-format does not treat it as a type**. With `PointerAlignment: Left`, format runs produce awkward spacing such as: + +```cpp +const Handle(Geom_TrimmedCurve) & curve; // bad (formatter) +const Geom_TrimmedCurve_ptr& curve; // good +``` + +Do **not** paper over this with `// clang-format off` for routine handle declarations. + +## Agent rules + +1. For a type used as a handle in EzyCad, add or reuse a `using TypeName_ptr = opencascade::handle;` in `utl_types.h` (forward-declare the class there if needed, matching existing entries). +2. Prefer `TypeName_ptr` in signatures, locals, and members. +3. `DownCast`: `TypeName_ptr::DownCast(obj)` (or `opencascade::handle::DownCast(obj)`), not `Handle(TypeName)::DownCast(obj)`. +4. When editing a function that already uses `Handle(...)`, convert that local scope to `*_ptr` / `opencascade::handle` if the change is small; do not mass-rewrite unrelated files. + +Style summary: [docs/ezycad_code_style.md](../../docs/ezycad_code_style.md) (OCCT handles). diff --git a/agents/conventions/occt-wasm-dual-version.md b/agents/conventions/occt-wasm-dual-version.md new file mode 100644 index 0000000..cb15bb7 --- /dev/null +++ b/agents/conventions/occt-wasm-dual-version.md @@ -0,0 +1,41 @@ +# OCCT desktop vs WASM (until v8 wasm works) + +**Temporary:** keep this file until EzyCad WASM builds and runs correctly against OCCT **8.x** (GLES shading and any remaining regressions fixed; see [docs/bugs.md](../../docs/bugs.md)). Then delete this convention and drop the pointers from `AGENTS.md` / `agents/README.md` / `token-lean.md`. + +## Pins + +| Target | OCCT version | Notes | +| ----------------- | ----------------------------------- | ------------------------------------------ | +| Desktop (Windows) | **8.0.0** | Prebuilts + `TKOpenGl` | +| WASM (Emscripten) | **7.9.3** (`V7_9_3`) recommended | `scripts/build-occt-793-wasm.ps1` | +| WASM (compare) | 8.0.0.p1 (`V8_0_0_p1`) experimental | Shading regressions; not for demos/release | + +Details: [docs/building-occt.md](../../docs/building-occt.md), [workflows/local-dev.md](../workflows/local-dev.md). + +## Shared `src/` must compile on both + +Most app code is one tree linked against **desktop 8** and **wasm 7.9.3**. Prefer the **API intersection**. Do not assume an OCCT 8-only symbol or overload is available on the wasm kit. + +### `Standard_Failure` messages + +Use `standard_failure_message(e)` from [`utl_occt.h`](../../src/utl_occt.h) — not raw `what()` or `GetMessageString()`: + +```cpp +catch (const Standard_Failure& e) +{ + const char* msg = standard_failure_message(e); + // ... +} +``` + +OCCT **8** (desktop) deprecates `GetMessageString()` in favor of `what()`; OCCT **7.9.3** (wasm) has no `what()` on `Standard_Failure`. The helper picks the right API via `OCC_VERSION_HEX` so shared code builds on both without warnings or missing-member errors. + +### Other dual-version habits + +- Prefer existing call patterns already used for both targets over newer OCCT 8 helpers. +- If you must use an 8-only API, gate it or verify a wasm 7.9.3 configure/build still succeeds. +- Default wasm work to **7.9.3**; use the v8 wasm script only when comparing upstream regressions. + +## When retiring this note + +After wasm on OCCT 8 is the supported path: switch demo/release scripts to `build-occt-v8-wasm.ps1`, update [docs/building-occt.md](../../docs/building-occt.md) / [docs/bugs.md](../../docs/bugs.md), then remove this file and its index links. diff --git a/agents/conventions/token-lean.md b/agents/conventions/token-lean.md index 515ccdb..85dda0c 100644 --- a/agents/conventions/token-lean.md +++ b/agents/conventions/token-lean.md @@ -15,6 +15,8 @@ Goal: give assistants **only what they need** for the task at hand. Full style g | Task | Read | | ---------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | | Build / test | [workflows/local-dev.md](../workflows/local-dev.md) — or root [README.md](../../README.md#building-instructions) | +| OCCT / WASM (shared `src/` APIs) | [occt-wasm-dual-version.md](occt-wasm-dual-version.md) — desktop 8 vs wasm 7.9.3 until wasm works on OCCT 8 | +| OCCT handles | [occt-handles.md](occt-handles.md) — `*_ptr` / `opencascade::handle` over `Handle()` (clang-format) | | User-visible UI/settings | [user-docs-sync.md](user-docs-sync.md) + target `docs/usage-*.md` only | | Sketch subsystem (`src/sketch*`, `tests/sketch_*_tests.cpp`, sketch behavior in `occt_view` / `gui`) | [src/doc/sketch.md](../../src/doc/sketch.md) — read before editing; update when API, invariants, module layout, or workflows change | | Shape module (`src/shp*`, shape ops in `occt_view` / `gui`) | [src/doc/shape.md](../../src/doc/shape.md) — read before editing; update when API, operation patterns, or registration/undo change | diff --git a/agents/drafts/issues/active/gh-196-occt-dual-version-handle-warnings.md b/agents/drafts/issues/active/gh-196-occt-dual-version-handle-warnings.md new file mode 100644 index 0000000..ae07787 --- /dev/null +++ b/agents/drafts/issues/active/gh-196-occt-dual-version-handle-warnings.md @@ -0,0 +1,37 @@ +--- +github_issue: 196 +github_pr: 197 +status: active +paired_draft: ../prs/active/gh-197-occt-dual-version-handle-warnings.md +--- + +# OCCT dual-version (desktop 8 / WASM 7.9.3) harden + +**Suggested labels:** `bug`, `documentation`, `refactor` + +--- + +## Title (GitHub) + +OCCT dual-version (desktop 8 / WASM 7.9.3): Handle aliases, failure messages, build warning cleanup + +## Body (GitHub) + +Filed: https://github.com/trailcode/EzyCad/issues/196 + +### Summary + +Shared `src/` must build against desktop OCCT **8.0.0** and recommended WASM OCCT **7.9.3** until OCCT 8 GLES shading works for wasm. Harden that split: stop using `Handle(T)`, add dual-version `Standard_Failure` messaging, document agent conventions, clear native/WASM warnings. + +### Acceptance criteria + +- [x] `standard_failure_message()` used at `Standard_Failure` catch sites +- [x] `Handle(...)` -> `*_ptr` aliases in `utl_types.h` +- [x] Agent conventions wired (`occt-wasm-dual-version.md`, `occt-handles.md`) +- [x] Native/WASM listed warnings cleared +- [ ] CI green + +### Related + +- PR: https://github.com/trailcode/EzyCad/pull/197 +- Draft: `agents/drafts/prs/active/gh-197-occt-dual-version-handle-warnings.md` diff --git a/agents/drafts/prs/active/gh-197-occt-dual-version-handle-warnings.md b/agents/drafts/prs/active/gh-197-occt-dual-version-handle-warnings.md new file mode 100644 index 0000000..3d3dfe7 --- /dev/null +++ b/agents/drafts/prs/active/gh-197-occt-dual-version-handle-warnings.md @@ -0,0 +1,36 @@ +--- +github_issue: 196 +github_pr: 197 +status: active +paired_draft: ../issues/active/gh-196-occt-dual-version-handle-warnings.md +--- + +# PR - OCCT dual-version harden + +## Title + +OCCT dual-version harden: Handle aliases, failure messages, warning cleanup + +## Summary + +- Desktop OCCT 8 vs WASM 7.9.3: `standard_failure_message()`, `*_ptr` over `Handle(T)`, agent conventions. +- Compiler warning cleanup (native + emscripten dock flags). + +## Related + +- Issue: https://github.com/trailcode/EzyCad/issues/196 +- PR: https://github.com/trailcode/EzyCad/pull/197 +- Branch: `Trailcode/gen-fixes-refactor` + +## Test Plan + +- [x] Native Debug rebuild clean of listed warnings +- [x] WASM build-em-793 dock enum warning fixed +- [ ] CI Windows MSVC +- [ ] Spot-check OCCT error paths and Esc cancel + +## Post-merge + +- [ ] Archive this draft and paired issue draft +- [ ] Close #196 if fully addressed +- [ ] Consider `CHANGELOG.md` `[Unreleased]` note diff --git a/agents/workflows/local-dev.md b/agents/workflows/local-dev.md index 76f5d93..b8930ff 100644 --- a/agents/workflows/local-dev.md +++ b/agents/workflows/local-dev.md @@ -47,6 +47,8 @@ See root [README.md](../../README.md#building-instructions) and [docs/building-o ## WebAssembly (Emscripten) +**Agent note:** desktop uses OCCT **8**, recommended wasm uses **7.9.3** until OCCT 8 wasm works. Shared `src/` must compile on both — see [conventions/occt-wasm-dual-version.md](../conventions/occt-wasm-dual-version.md). + Full OCCT + EzyCad wasm instructions live in [docs/building-occt.md](../../docs/building-occt.md#webassembly-emscripten) and the root README. High-level flow (after `emsdk_env`): diff --git a/docs/ezycad_code_style.md b/docs/ezycad_code_style.md index 3ccb4d8..69f0814 100644 --- a/docs/ezycad_code_style.md +++ b/docs/ezycad_code_style.md @@ -69,7 +69,8 @@ User-facing Markdown (now in `docs/`: `usage.md`, `usage-*.md`, `scripting.md`, - **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_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` and project aliases (e.g. `AIS_Shape_ptr`, `Shp_ptr`). +- **OCCT handles**: Prefer `opencascade::handle` and project `*_ptr` aliases from `utl_types.h` (e.g. `AIS_Shape_ptr`, `Shp_ptr`). Avoid the OCCT `Handle(T)` macro in new/touched code -- clang-format mishandles it with `PointerAlignment: Left` (e.g. `Handle(Foo) &`). See [agents/conventions/occt-handles.md](../agents/conventions/occt-handles.md). +- **OCCT desktop vs WASM**: Until WASM runs correctly on OCCT 8, desktop is OCCT **8** and recommended WASM is **7.9.3**. Prefer APIs available on both; for `Standard_Failure` use `standard_failure_message(e)` from `utl_occt.h` (not raw `what()` / `GetMessageString()`). See [agents/conventions/occt-wasm-dual-version.md](../agents/conventions/occt-wasm-dual-version.md). - **Result/error handling**: See **Fail fast** below. Use `Result` and `Status` from `utl.h`, `CHK_RET(...)` for early return on failure. - **Assertions**: See **Fail fast** below. Use `EZY_ASSERT` and `EZY_ASSERT_MSG` from `utl_dbg.h`; use `DBG_MSG` for debug logging. diff --git a/src/doc/utility.md b/src/doc/utility.md index ae55d47..376c3c1 100644 --- a/src/doc/utility.md +++ b/src/doc/utility.md @@ -24,7 +24,7 @@ Typical uses: | [`utl_types.h`](../utl_types.h) | OCCT/AIS handle typedefs, `ScreenCoords`, `Export_format`, `DECL_PTR`, `SafeType` | | [`utl_geom.h`](../utl_geom.h) / [`.cpp`](../utl_geom.cpp) | 2D/3D geometry, wires, dimensions, Boost polygon tests, plane projection | | [`utl_geom_boost.inl`](../utl_geom_boost.inl) | `ezy_geom` Boost.Geometry aliases | -| [`utl_occt.h`](../utl_occt.h) / [`.cpp`](../utl_occt.cpp) | `TopAbs` name table, `try_make_solid` | +| [`utl_occt.h`](../utl_occt.h) / [`.cpp`](../utl_occt.cpp) | `TopAbs` name table, `try_make_solid`, `standard_failure_message` | | [`utl_json.h`](../utl_json.h) / [`.cpp`](../utl_json.cpp) | JSON serializers for `gp_Pnt`, `gp_Pln`, etc. | | [`utl_io.h`](../utl_io.h) / [`.cpp`](../utl_io.cpp) | `.ezy` zip v3 pack/unpack, format sniff, base64 | | [`utl_asset_store.h`](../utl_asset_store.h) / [`.cpp`](../utl_asset_store.cpp) | Content-addressed RGBA blobs for sketch underlay assets | @@ -102,10 +102,11 @@ Includes [`utl_geom_boost.inl`](../utl_geom_boost.inl) for `ezy_geom` polygon / ## OCCT helpers (`utl_occt`) -| API | Role | -| -------------------------- | -------------------------------------------------------- | -| `c_names_TopAbs_ShapeEnum` | String names parallel to OCCT enum (selection filter UI) | -| `try_make_solid(shape)` | Wrap closed shell as solid when possible | +| API | Role | +| ----------------------------- | --------------------------------------------------------------------- | +| `c_names_TopAbs_ShapeEnum` | String names parallel to OCCT enum (selection filter UI) | +| `try_make_solid(shape)` | Wrap closed shell as solid when possible | +| `standard_failure_message(e)` | OCCT 7/8-safe message from `Standard_Failure` (see dual-version note) | ## JSON geom (`utl_json`) diff --git a/src/gui.cpp b/src/gui.cpp index 4b53557..9e13126 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -227,7 +227,10 @@ void GUI::load_examples_list_() void GUI::seed_default_dock_layout_(ImGuiID dockspace_id) { ImGui::DockBuilderRemoveNode(dockspace_id); - ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_DockSpace | ImGuiDockNodeFlags_PassthruCentralNode); + // Cast private DockSpace flag: mixing ImGuiDockNodeFlagsPrivate_ with ImGuiDockNodeFlags_ + // triggers -Wdeprecated-enum-enum-conversion (e.g. emscripten/clang). + ImGui::DockBuilderAddNode(dockspace_id, static_cast(ImGuiDockNodeFlags_DockSpace) | + ImGuiDockNodeFlags_PassthruCentralNode); ImGui::DockBuilderSetNodeSize(dockspace_id, ImGui::GetMainViewport()->WorkSize); ImGuiID dock_main = dockspace_id; diff --git a/src/gui.h b/src/gui.h index bba4c1f..51631d3 100644 --- a/src/gui.h +++ b/src/gui.h @@ -124,8 +124,8 @@ inline constexpr float k_gui_imgui_border_slider_max = 2.f; inline constexpr float k_gui_imgui_padding_slider_max = 24.f; inline constexpr float k_gui_imgui_spacing_slider_max = 24.f; -/// ImGui layout for **dark mode** / **light mode** (Settings -> UI; persisted under gui.imgui_style_dark / gui.imgui_style_light). -/// The Settings pane edits whichever theme matches the current Dark mode checkbox. +/// ImGui layout for **dark mode** / **light mode** (Settings -> UI; persisted under gui.imgui_style_dark / +/// gui.imgui_style_light). The Settings pane edits whichever theme matches the current Dark mode checkbox. struct Gui_imgui_style_settings { float rounding_general{0.f}; @@ -499,43 +499,43 @@ class GUI bool m_angle_edit_focus_pending{false}; // Mode related - Mode m_mode = Mode::Normal; - Chamfer_mode m_chamfer_mode = Chamfer_mode::Shape; - Fillet_mode m_fillet_mode = Fillet_mode::Shape; - int m_edge_dim_label_h = 3; - float m_edge_dim_line_width = k_gui_edge_dim_line_width_default; - float m_edge_dim_arrow_size = k_gui_edge_dim_arrow_size_default; - float m_edge_dim_color[3] = {k_gui_edge_dim_color_default[0], k_gui_edge_dim_color_default[1], - k_gui_edge_dim_color_default[2]}; - float m_edge_dim_text_scale = k_gui_edge_dim_text_scale_default; - int m_edge_dim_arrow_style = 0; - int m_edge_dim_arrow_orientation = 0; - int m_edge_dim_text_render_mode = k_gui_edge_dim_text_render_mode_default; - bool m_show_sketch_dimensions = true; - float m_permanent_node_anno_scale = k_gui_permanent_node_anno_scale_default; - float m_origin_marker_color[3] = {k_gui_origin_marker_color_default[0], k_gui_origin_marker_color_default[1], - k_gui_origin_marker_color_default[2]}; - float m_sketch_edge_color[4] = {k_gui_sketch_edge_color_default[0], k_gui_sketch_edge_color_default[1], - k_gui_sketch_edge_color_default[2], k_gui_sketch_edge_color_default[3]}; + Mode m_mode = Mode::Normal; + Chamfer_mode m_chamfer_mode = Chamfer_mode::Shape; + Fillet_mode m_fillet_mode = Fillet_mode::Shape; + int m_edge_dim_label_h = 3; + float m_edge_dim_line_width = k_gui_edge_dim_line_width_default; + float m_edge_dim_arrow_size = k_gui_edge_dim_arrow_size_default; + float m_edge_dim_color[3] = {k_gui_edge_dim_color_default[0], k_gui_edge_dim_color_default[1], + k_gui_edge_dim_color_default[2]}; + float m_edge_dim_text_scale = k_gui_edge_dim_text_scale_default; + int m_edge_dim_arrow_style = 0; + int m_edge_dim_arrow_orientation = 0; + int m_edge_dim_text_render_mode = k_gui_edge_dim_text_render_mode_default; + bool m_show_sketch_dimensions = true; + float m_permanent_node_anno_scale = k_gui_permanent_node_anno_scale_default; + float m_origin_marker_color[3] = {k_gui_origin_marker_color_default[0], k_gui_origin_marker_color_default[1], + k_gui_origin_marker_color_default[2]}; + float m_sketch_edge_color[4] = {k_gui_sketch_edge_color_default[0], k_gui_sketch_edge_color_default[1], + k_gui_sketch_edge_color_default[2], k_gui_sketch_edge_color_default[3]}; float m_sketch_edge_selection_color[4] = { k_gui_sketch_edge_selection_color_default[0], k_gui_sketch_edge_selection_color_default[1], k_gui_sketch_edge_selection_color_default[2], k_gui_sketch_edge_selection_color_default[3]}; float m_sketch_edge_highlight_color[4] = { k_gui_sketch_edge_highlight_color_default[0], k_gui_sketch_edge_highlight_color_default[1], k_gui_sketch_edge_highlight_color_default[2], k_gui_sketch_edge_highlight_color_default[3]}; - float m_sketch_edge_line_width = k_gui_sketch_edge_line_width_default; - float m_sketch_face_color[4] = {k_gui_sketch_face_color_default[0], k_gui_sketch_face_color_default[1], - k_gui_sketch_face_color_default[2], k_gui_sketch_face_color_default[3]}; + float m_sketch_edge_line_width = k_gui_sketch_edge_line_width_default; + float m_sketch_face_color[4] = {k_gui_sketch_face_color_default[0], k_gui_sketch_face_color_default[1], + k_gui_sketch_face_color_default[2], k_gui_sketch_face_color_default[3]}; float m_sketch_face_selection_color[4] = { k_gui_sketch_face_selection_color_default[0], k_gui_sketch_face_selection_color_default[1], k_gui_sketch_face_selection_color_default[2], k_gui_sketch_face_selection_color_default[3]}; float m_sketch_face_highlight_color[4] = { k_gui_sketch_face_highlight_color_default[0], k_gui_sketch_face_highlight_color_default[1], k_gui_sketch_face_highlight_color_default[2], k_gui_sketch_face_highlight_color_default[3]}; - bool m_add_mid_pt_line_edges = false; - bool m_add_mid_pt_rect_edges = true; - bool m_add_mid_pt_slot_edges = false; - bool m_edge_from_center = false; + bool m_add_mid_pt_line_edges = false; + bool m_add_mid_pt_rect_edges = true; + bool m_add_mid_pt_slot_edges = false; + bool m_edge_from_center = false; /// Degrees per numpad orbit (8/2/4/6) and Blender-style roll (Shift+NumPad 4/6); persisted in `gui.view_roll_step_deg`. double m_view_roll_step_deg = k_gui_view_roll_step_deg_default; /// Multiplier for `UpdateZoom(Aspect_ScrollDelta(..., int(y * scale)))`; persisted in `gui.view_zoom_scroll_scale`. diff --git a/src/gui_occt_glfw_win.h b/src/gui_occt_glfw_win.h index 7fec409..3943368 100644 --- a/src/gui_occt_glfw_win.h +++ b/src/gui_occt_glfw_win.h @@ -28,6 +28,8 @@ #include #include +#include "utl_types.h" + struct GLFWwindow; //! GLFWwindow wrapper implementing Aspect_Window interface. @@ -46,7 +48,7 @@ class Occt_glfw_win : public Aspect_Window void Close(); //! Return X Display connection. - const Handle(Aspect_DisplayConnection) & GetDisplay() const { return myDisplay; } + const Aspect_DisplayConnection_ptr& GetDisplay() const { return myDisplay; } //! Return GLFW window. GLFWwindow* getGlfwWindow() { return myGlfwWindow; } @@ -104,12 +106,12 @@ class Occt_glfw_win : public Aspect_Window virtual Aspect_FBConfig NativeFBConfig() const override { return NULL; } protected: - Handle(Aspect_DisplayConnection) myDisplay; - GLFWwindow* myGlfwWindow; - int myXLeft; - int myYTop; - int myXRight; - int myYBottom; + Aspect_DisplayConnection_ptr myDisplay; + GLFWwindow* myGlfwWindow; + int myXLeft; + int myYTop; + int myXRight; + int myYBottom; }; #endif // _Occt_glfw_win_Header diff --git a/src/gui_occt_view.cpp b/src/gui_occt_view.cpp index 5174455..366359a 100644 --- a/src/gui_occt_view.cpp +++ b/src/gui_occt_view.cpp @@ -105,10 +105,10 @@ void Occt_view::init_viewer() if (m_occt_window.IsNull() || m_occt_window->getGlfwWindow() == nullptr) { // create graphic driver - Handle(Aspect_DisplayConnection) aDisp = new Aspect_DisplayConnection(); - Handle(OpenGl_GraphicDriver) aDriver = new OpenGl_GraphicDriver(aDisp, true); - aDriver->ChangeOptions().swapInterval = 0; // no window, no swap - Handle(V3d_Viewer) myViewer = new V3d_Viewer(aDriver); + Aspect_DisplayConnection_ptr aDisp = new Aspect_DisplayConnection(); + OpenGl_GraphicDriver_ptr aDriver = new OpenGl_GraphicDriver(aDisp, true); + aDriver->ChangeOptions().swapInterval = 0; // no window, no swap + V3d_Viewer_ptr myViewer = new V3d_Viewer(aDriver); // create offscreen window const TCollection_AsciiString aWinName("OCCT offscreen window"); @@ -116,13 +116,13 @@ void Occt_view::init_viewer() #if defined(_WIN32) const TCollection_AsciiString aClassName("OffscreenClass"); // empty callback! - Handle(WNT_WClass) aWinClass = new WNT_WClass(aClassName.ToCString(), nullptr, 0); - Handle(WNT_Window) aWindow = new WNT_Window(aWinName.ToCString(), aWinClass, 0x80000000, // WS_POPUP - 64, 64, aWinSize.x(), aWinSize.y(), Quantity_NOC_BLACK); + WNT_WClass_ptr aWinClass = new WNT_WClass(aClassName.ToCString(), nullptr, 0); + WNT_Window_ptr aWindow = new WNT_Window(aWinName.ToCString(), aWinClass, 0x80000000, // WS_POPUP + 64, 64, aWinSize.x(), aWinSize.y(), Quantity_NOC_BLACK); #elif defined(__APPLE__) - Handle(Cocoa_Window) aWindow = new Cocoa_Window(aWinName.ToCString(), 64, 64, aWinSize.x(), aWinSize.y()); + Cocoa_Window_ptr aWindow = new Cocoa_Window(aWinName.ToCString(), 64, 64, aWinSize.x(), aWinSize.y()); #else - Handle(Xw_Window) aWindow = new Xw_Window(aDisp, aWinName.ToCString(), 64, 64, aWinSize.x(), aWinSize.y()); + Xw_Window_ptr aWindow = new Xw_Window(aDisp, aWinName.ToCString(), 64, 64, aWinSize.x(), aWinSize.y()); #endif aWindow->SetVirtual(true); m_view = new V3d_View(myViewer); @@ -131,13 +131,13 @@ void Occt_view::init_viewer() return; } - Handle(OpenGl_GraphicDriver) aGraphicDriver = new OpenGl_GraphicDriver(m_occt_window->GetDisplay(), false); + OpenGl_GraphicDriver_ptr aGraphicDriver = new OpenGl_GraphicDriver(m_occt_window->GetDisplay(), false); aGraphicDriver->ChangeOptions().buffersNoSwap = true; aGraphicDriver->ChangeOptions().buffersOpaqueAlpha = true; aGraphicDriver->ChangeOptions().sRGBDisable = true; // Otherwise colors are wrong when native. - Handle(V3d_Viewer) aViewer = new V3d_Viewer(aGraphicDriver); + V3d_Viewer_ptr aViewer = new V3d_Viewer(aGraphicDriver); aViewer->SetDefaultLights(); aViewer->SetLightOn(); @@ -151,8 +151,8 @@ void Occt_view::init_viewer() m_ctx = new AIS_InteractiveContext(aViewer); #else // __EMSCRIPTEN__ - Handle(Aspect_DisplayConnection) aDisp; - Handle(OpenGl_GraphicDriver) aDriver = new OpenGl_GraphicDriver(aDisp, false); + Aspect_DisplayConnection_ptr aDisp; + OpenGl_GraphicDriver_ptr aDriver = new OpenGl_GraphicDriver(aDisp, false); aDriver->ChangeOptions().buffersNoSwap = true; // swap has no effect in WebGL aDriver->ChangeOptions().buffersOpaqueAlpha = true; // avoid unexpected blending of canvas with page background // Match native OpenGL path (sRGBDisable) so shading/material gamma is consistent vs desktop. @@ -163,15 +163,15 @@ void Occt_view::init_viewer() return; } - Handle(V3d_Viewer) aViewer = new V3d_Viewer(aDriver); + V3d_Viewer_ptr aViewer = new V3d_Viewer(aDriver); aViewer->SetDefaultComputedMode(true); // Enable better quality rendering aViewer->SetDefaultShadingModel(Graphic3d_TypeOfShadingModel_Phong); aViewer->SetDefaultLights(); aViewer->SetLightOn(); - for (NCollection_List::Iterator aLightIter(aViewer->ActiveLights()); aLightIter.More(); + for (NCollection_List::Iterator aLightIter(aViewer->ActiveLights()); aLightIter.More(); aLightIter.Next()) { - const Handle(Graphic3d_CLight)& aLight = aLightIter.Value(); + const Graphic3d_CLight_ptr& aLight = aLightIter.Value(); if (aLight->Type() == Graphic3d_TypeOfLightSource_Directional) aLight->SetCastShadows(true); } @@ -179,7 +179,7 @@ void Occt_view::init_viewer() // ImGui owns HiDPI: canvas + GLFW window are CSS * DPR (see imgui_impl_glfw OnCanvasSizeChange). // ToScaleBacking=false so OCCT does not resize the shared canvas again; DevicePixelRatio=1 so // mouse/view coords stay in the same physical-pixel space as GLFW. - Handle(Wasm_Window) aWindow = new Wasm_Window("#canvas", false); + Wasm_Window_ptr aWindow = new Wasm_Window("#canvas", false); aWindow->SetDevicePixelRatio(1.0); myDevicePixelRatio = 1.0; @@ -193,8 +193,8 @@ void Occt_view::init_viewer() // dimensions, etc. (CSS "serif" / OS fonts are not exposed as paths to WASM.) // Preload matches CMake --preload-file ... DroidSans.ttf@/DroidSans.ttf (shared with ImGui). { - Handle(Font_FontMgr) font_mgr = Font_FontMgr::GetInstance(); - Handle(Font_SystemFont) sys_font = font_mgr->CheckFont("/DroidSans.ttf"); + Font_FontMgr_ptr font_mgr = Font_FontMgr::GetInstance(); + Font_SystemFont_ptr sys_font = font_mgr->CheckFont("/DroidSans.ttf"); if (!sys_font.IsNull()) { font_mgr->RegisterFont(sys_font, true); @@ -230,8 +230,8 @@ void Occt_view::init_viewer() m_ctx->SetAutoActivateSelection(true); // Enable automatic selection - auto highlight_style = m_ctx->HighlightStyle(); - Handle(Graphic3d_AspectFillArea3d) fill_aspect = new Graphic3d_AspectFillArea3d(); + auto highlight_style = m_ctx->HighlightStyle(); + Graphic3d_AspectFillArea3d_ptr fill_aspect = new Graphic3d_AspectFillArea3d(); fill_aspect->SetAlphaMode(Graphic3d_AlphaMode::Graphic3d_AlphaMode_Blend); fill_aspect->SetColor(Quantity_Color(0.1, 0.1, 0.1, Quantity_TOC_RGB)); highlight_style->SetColor(Quantity_NOC_YELLOW); @@ -251,7 +251,7 @@ void Occt_view::init_viewer() m_grid_color2 = glm::vec3(0.117917f, 0.117917f, 0.135135f); update_view_background_(); - Handle(AIS_ViewCube) myViewCube = new AIS_ViewCube(); + AIS_ViewCube_ptr myViewCube = new AIS_ViewCube(); myViewCube->SetTransformPersistence( new Graphic3d_TransformPers(Graphic3d_TMF_TriedronPers, Aspect_TOTP_RIGHT_LOWER, NCollection_Vec2(100, 100))); @@ -869,9 +869,9 @@ std::optional Occt_view::get_hit_point_(const AIS_Shape_ptr& shp, const TopExp_Explorer explorer(shp->Shape(), TopAbs_FACE); while (explorer.More()) { - TopoDS_Face face = TopoDS::Face(explorer.Current()); - Handle(Geom_Surface) surface = BRep_Tool::Surface(face); - GeomAPI_IntCS intersection(ray_line, surface); + TopoDS_Face face = TopoDS::Face(explorer.Current()); + Geom_Surface_ptr surface = BRep_Tool::Surface(face); + GeomAPI_IntCS intersection(ray_line, surface); if (intersection.NbPoints() > 0) return intersection.Point(1); @@ -891,14 +891,14 @@ void Occt_view::refresh_shape_shading_(const Shp_ptr& shp) // OCCT 8 GLES: Phong needs explicit color; UNLIT fallback was removed in 8.0. shp->SetColor(Quantity_Color(0.78, 0.78, 0.80, Quantity_TOC_RGB)); - const Handle(Prs3d_Drawer)& drawer = shp->Attributes(); + const Prs3d_Drawer_ptr& drawer = shp->Attributes(); if (!drawer.IsNull()) { drawer->SetFaceBoundaryDraw(false); - const Handle(Prs3d_ShadingAspect)& shading = drawer->ShadingAspect(); + const Prs3d_ShadingAspect_ptr& shading = drawer->ShadingAspect(); if (!shading.IsNull()) { - const Handle(Graphic3d_AspectFillArea3d)& aspect = shading->Aspect(); + const Graphic3d_AspectFillArea3d_ptr& aspect = shading->Aspect(); if (!aspect.IsNull()) { #if OCC_VERSION_HEX >= 0x080000 @@ -1412,9 +1412,9 @@ void Occt_view::capture_occt_grid_rect_from_viewer_(const V3d_Viewer_ptr& viewer if (viewer.IsNull() || viewer->Grid().IsNull()) return; - Handle(Aspect_Grid) ag = viewer->Grid(); - Handle(Aspect_RectangularGrid) rg = Handle(Aspect_RectangularGrid)::DownCast(ag); - Handle(V3d_RectangularGrid) vrg = Handle(V3d_RectangularGrid)::DownCast(ag); + Aspect_Grid_ptr ag = viewer->Grid(); + Aspect_RectangularGrid_ptr rg = Aspect_RectangularGrid_ptr::DownCast(ag); + V3d_RectangularGrid_ptr vrg = V3d_RectangularGrid_ptr::DownCast(ag); if (rg.IsNull()) return; @@ -1438,7 +1438,7 @@ gp_Ax3 Occt_view::grid_display_plane_() const if (!m_view.IsNull()) { - Handle(V3d_Viewer) viewer = m_view->Viewer(); + V3d_Viewer_ptr viewer = m_view->Viewer(); if (!viewer.IsNull()) return viewer->PrivilegedPlane(); } @@ -1461,7 +1461,7 @@ void Occt_view::sync_grid_plane_to_active_sketch_() if (is_headless() || m_ctx.IsNull() || !m_cur_sketch) return; - Handle(V3d_Viewer) viewer = m_ctx->CurrentViewer(); + V3d_Viewer_ptr viewer = m_ctx->CurrentViewer(); if (viewer.IsNull()) return; @@ -1476,7 +1476,7 @@ void Occt_view::refresh_viewer_grid_() if (!m_grid_visible) return; - Handle(V3d_Viewer) viewer = m_view->Viewer(); + V3d_Viewer_ptr viewer = m_view->Viewer(); if (viewer.IsNull() || !viewer->IsGridActive()) return; @@ -1491,7 +1491,7 @@ void Occt_view::apply_grid_visibility_() if (is_headless() || m_view.IsNull()) return; - Handle(V3d_Viewer) viewer = m_view->Viewer(); + V3d_Viewer_ptr viewer = m_view->Viewer(); if (viewer.IsNull()) return; @@ -1520,16 +1520,16 @@ void Occt_view::apply_occt_grid_rect_to_viewer_() m_occt_grid_rect = clamp_occt_grid_rect_params_(m_occt_grid_rect); - Handle(V3d_Viewer) viewer = m_view->Viewer(); + V3d_Viewer_ptr viewer = m_view->Viewer(); if (viewer.IsNull() || viewer->Grid().IsNull()) return; const Grid_layout layout = compute_grid_layout_(); viewer->SetPrivilegedPlane(layout.plane); - Handle(Aspect_Grid) ag = viewer->Grid(); - Handle(Aspect_RectangularGrid) rg = Handle(Aspect_RectangularGrid)::DownCast(ag); - Handle(V3d_RectangularGrid) vrg = Handle(V3d_RectangularGrid)::DownCast(ag); + Aspect_Grid_ptr ag = viewer->Grid(); + Aspect_RectangularGrid_ptr rg = Aspect_RectangularGrid_ptr::DownCast(ag); + V3d_RectangularGrid_ptr vrg = V3d_RectangularGrid_ptr::DownCast(ag); if (rg.IsNull()) return; @@ -1567,7 +1567,7 @@ void Occt_view::flush_view_events() } catch (const Standard_Failure& e) { - DBG_MSG(e.what() ? e.what() : "FlushViewEvents failed"); + DBG_MSG(std::string("FlushViewEvents failed: ") + standard_failure_message(e)); AbortViewAnimation(); m_ctx->ClearSelected(false); if (!m_shape_list_hover.IsNull()) @@ -1729,11 +1729,11 @@ void Occt_view::update_shape_list_hover_drawer_() m_shape_list_hover_drawer = new Prs3d_Drawer(); m_shape_list_hover_drawer->SetColor(qc); - Handle(Graphic3d_AspectFillArea3d) fill_aspect = new Graphic3d_AspectFillArea3d(); + Graphic3d_AspectFillArea3d_ptr fill_aspect = new Graphic3d_AspectFillArea3d(); fill_aspect->SetAlphaMode(Graphic3d_AlphaMode_Blend); fill_aspect->SetColor(Quantity_Color(0.1, 0.1, 0.1, Quantity_TOC_RGB)); m_shape_list_hover_drawer->SetBasicFillAreaAspect(fill_aspect); - Handle(Prs3d_LineAspect) wire_aspect = new Prs3d_LineAspect(qc, Aspect_TOL_SOLID, 2.0); + Prs3d_LineAspect_ptr wire_aspect = new Prs3d_LineAspect(qc, Aspect_TOL_SOLID, 2.0); m_shape_list_hover_drawer->SetWireAspect(wire_aspect); } diff --git a/src/gui_occt_view.h b/src/gui_occt_view.h index f036009..bb9d3c8 100644 --- a/src/gui_occt_view.h +++ b/src/gui_occt_view.h @@ -369,7 +369,7 @@ class Occt_view : protected AIS_ViewController Sketch_ptr m_sketch_list_hover; std::vector m_sketch_list_hover_ais; PrsDim_LengthDimension_ptr m_sketch_list_measurement_hover; - opencascade::handle m_shape_list_hover_drawer; + Prs3d_Drawer_ptr m_shape_list_hover_drawer; void update_shape_list_hover_drawer_(); void clear_sketch_list_hover_ais_(); void apply_sketch_list_hover_highlight_(); diff --git a/src/gui_settings.cpp b/src/gui_settings.cpp index 59fa571..0b35197 100644 --- a/src/gui_settings.cpp +++ b/src/gui_settings.cpp @@ -51,14 +51,14 @@ void parse_settings_headers_json(const nlohmann::json& obj, Gui_settings_headers return obj[key].get(); return fallback; }; - out.view_nav = b("view_nav", defaults.view_nav); - out.ui = b("ui", defaults.ui); - out.view_presentation = b("view_presentation", defaults.view_presentation); - out.grid = b("grid", defaults.grid); - out.sketch = b("sketch", defaults.sketch); - out.sketch_appearance = b("sketch_appearance", defaults.sketch_appearance); - out.sketch_dimensions = b("sketch_dimensions", defaults.sketch_dimensions); - out.startup = b("startup", defaults.startup); + out.view_nav = b("view_nav", defaults.view_nav); + out.ui = b("ui", defaults.ui); + out.view_presentation = b("view_presentation", defaults.view_presentation); + out.grid = b("grid", defaults.grid); + out.sketch = b("sketch", defaults.sketch); + out.sketch_appearance = b("sketch_appearance", defaults.sketch_appearance); + out.sketch_dimensions = b("sketch_dimensions", defaults.sketch_dimensions); + out.startup = b("startup", defaults.startup); } void parse_imgui_style_json(const nlohmann::json& obj, const Gui_imgui_style_settings& defaults, Gui_imgui_style_settings& out) @@ -164,23 +164,21 @@ std::string GUI::occt_view_settings_json() const {"show_sketch_dimensions", m_show_sketch_dimensions}, {k_gui_key_permanent_node_anno_scale, m_permanent_node_anno_scale}, {"origin_marker_color", {m_origin_marker_color[0], m_origin_marker_color[1], m_origin_marker_color[2]}}, - {"sketch_edge_color", - {m_sketch_edge_color[0], m_sketch_edge_color[1], m_sketch_edge_color[2], m_sketch_edge_color[3]}}, + {"sketch_edge_color", {m_sketch_edge_color[0], m_sketch_edge_color[1], m_sketch_edge_color[2], m_sketch_edge_color[3]}}, {"sketch_edge_selection_color", - {m_sketch_edge_selection_color[0], m_sketch_edge_selection_color[1], m_sketch_edge_selection_color[2], - m_sketch_edge_selection_color[3]}}, + {m_sketch_edge_selection_color[0], m_sketch_edge_selection_color[1], m_sketch_edge_selection_color[2], + m_sketch_edge_selection_color[3]}}, {"sketch_edge_highlight_color", - {m_sketch_edge_highlight_color[0], m_sketch_edge_highlight_color[1], m_sketch_edge_highlight_color[2], - m_sketch_edge_highlight_color[3]}}, + {m_sketch_edge_highlight_color[0], m_sketch_edge_highlight_color[1], m_sketch_edge_highlight_color[2], + m_sketch_edge_highlight_color[3]}}, {"sketch_edge_line_width", m_sketch_edge_line_width}, - {"sketch_face_color", - {m_sketch_face_color[0], m_sketch_face_color[1], m_sketch_face_color[2], m_sketch_face_color[3]}}, + {"sketch_face_color", {m_sketch_face_color[0], m_sketch_face_color[1], m_sketch_face_color[2], m_sketch_face_color[3]}}, {"sketch_face_selection_color", - {m_sketch_face_selection_color[0], m_sketch_face_selection_color[1], m_sketch_face_selection_color[2], - m_sketch_face_selection_color[3]}}, + {m_sketch_face_selection_color[0], m_sketch_face_selection_color[1], m_sketch_face_selection_color[2], + m_sketch_face_selection_color[3]}}, {"sketch_face_highlight_color", - {m_sketch_face_highlight_color[0], m_sketch_face_highlight_color[1], m_sketch_face_highlight_color[2], - m_sketch_face_highlight_color[3]}}, + {m_sketch_face_highlight_color[0], m_sketch_face_highlight_color[1], m_sketch_face_highlight_color[2], + m_sketch_face_highlight_color[3]}}, {"add_mid_pt_edges", m_add_mid_pt_line_edges}, {"add_mid_pt_rect_edges", m_add_mid_pt_rect_edges}, {"add_mid_pt_slot_edges", m_add_mid_pt_slot_edges}, @@ -247,23 +245,21 @@ void GUI::save_occt_view_settings() {"show_sketch_dimensions", m_show_sketch_dimensions}, {k_gui_key_permanent_node_anno_scale, m_permanent_node_anno_scale}, {"origin_marker_color", {m_origin_marker_color[0], m_origin_marker_color[1], m_origin_marker_color[2]}}, - {"sketch_edge_color", - {m_sketch_edge_color[0], m_sketch_edge_color[1], m_sketch_edge_color[2], m_sketch_edge_color[3]}}, + {"sketch_edge_color", {m_sketch_edge_color[0], m_sketch_edge_color[1], m_sketch_edge_color[2], m_sketch_edge_color[3]}}, {"sketch_edge_selection_color", - {m_sketch_edge_selection_color[0], m_sketch_edge_selection_color[1], m_sketch_edge_selection_color[2], - m_sketch_edge_selection_color[3]}}, + {m_sketch_edge_selection_color[0], m_sketch_edge_selection_color[1], m_sketch_edge_selection_color[2], + m_sketch_edge_selection_color[3]}}, {"sketch_edge_highlight_color", - {m_sketch_edge_highlight_color[0], m_sketch_edge_highlight_color[1], m_sketch_edge_highlight_color[2], - m_sketch_edge_highlight_color[3]}}, + {m_sketch_edge_highlight_color[0], m_sketch_edge_highlight_color[1], m_sketch_edge_highlight_color[2], + m_sketch_edge_highlight_color[3]}}, {"sketch_edge_line_width", m_sketch_edge_line_width}, - {"sketch_face_color", - {m_sketch_face_color[0], m_sketch_face_color[1], m_sketch_face_color[2], m_sketch_face_color[3]}}, + {"sketch_face_color", {m_sketch_face_color[0], m_sketch_face_color[1], m_sketch_face_color[2], m_sketch_face_color[3]}}, {"sketch_face_selection_color", - {m_sketch_face_selection_color[0], m_sketch_face_selection_color[1], m_sketch_face_selection_color[2], - m_sketch_face_selection_color[3]}}, + {m_sketch_face_selection_color[0], m_sketch_face_selection_color[1], m_sketch_face_selection_color[2], + m_sketch_face_selection_color[3]}}, {"sketch_face_highlight_color", - {m_sketch_face_highlight_color[0], m_sketch_face_highlight_color[1], m_sketch_face_highlight_color[2], - m_sketch_face_highlight_color[3]}}, + {m_sketch_face_highlight_color[0], m_sketch_face_highlight_color[1], m_sketch_face_highlight_color[2], + m_sketch_face_highlight_color[3]}}, {"add_mid_pt_edges", m_add_mid_pt_line_edges}, {"add_mid_pt_rect_edges", m_add_mid_pt_rect_edges}, {"add_mid_pt_slot_edges", m_add_mid_pt_slot_edges}, @@ -504,9 +500,8 @@ void GUI::parse_gui_panes_settings_(const std::string& content) g.contains("sketch_face_selection_color") ? k_gui_sketch_face_selection_color_default : m_sketch_face_highlight_color); - m_sketch_edge_line_width = - parse_bounded_float("sketch_edge_line_width", k_gui_sketch_edge_line_width_min, k_gui_sketch_edge_line_width_max, - k_gui_sketch_edge_line_width_default); + m_sketch_edge_line_width = parse_bounded_float("sketch_edge_line_width", k_gui_sketch_edge_line_width_min, + k_gui_sketch_edge_line_width_max, k_gui_sketch_edge_line_width_default); if (g.contains("edge_dim_arrow_style") && g["edge_dim_arrow_style"].is_number_integer()) { @@ -1137,7 +1132,8 @@ void GUI::settings_() ImGui::AlignTextToFramePadding(); ImGui::TextUnformatted("Edge color"); ImGui::TableSetColumnIndex(1); - if (ImGui::ColorEdit4("##sketch_edge_color", m_sketch_edge_color, ImGuiColorEditFlags_Float | ImGuiColorEditFlags_AlphaBar)) + if (ImGui::ColorEdit4("##sketch_edge_color", m_sketch_edge_color, + ImGuiColorEditFlags_Float | ImGuiColorEditFlags_AlphaBar)) appear_changed = true; ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); GUI_DOC_HELP_("Color and opacity of edges on the current sketch (alpha = opacity).", nullptr); @@ -1149,8 +1145,8 @@ void GUI::settings_() ImGui::TableSetColumnIndex(1); { float lw = m_sketch_edge_line_width; - if (ImGui::SliderFloat("##sketch_edge_lw", &lw, k_gui_sketch_edge_line_width_min, - k_gui_sketch_edge_line_width_max, "%.2f")) + if (ImGui::SliderFloat("##sketch_edge_lw", &lw, k_gui_sketch_edge_line_width_min, k_gui_sketch_edge_line_width_max, + "%.2f")) { m_sketch_edge_line_width = lw; appear_changed = true; @@ -1184,7 +1180,8 @@ void GUI::settings_() ImGui::AlignTextToFramePadding(); ImGui::TextUnformatted("Face fill color"); ImGui::TableSetColumnIndex(1); - if (ImGui::ColorEdit4("##sketch_face_color", m_sketch_face_color, ImGuiColorEditFlags_Float | ImGuiColorEditFlags_AlphaBar)) + if (ImGui::ColorEdit4("##sketch_face_color", m_sketch_face_color, + ImGuiColorEditFlags_Float | ImGuiColorEditFlags_AlphaBar)) appear_changed = true; ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); GUI_DOC_HELP_("Fill color and opacity of closed faces on the current sketch.", nullptr); diff --git a/src/shp_chamfer.cpp b/src/shp_chamfer.cpp index 26882af..d36c9e6 100644 --- a/src/shp_chamfer.cpp +++ b/src/shp_chamfer.cpp @@ -9,6 +9,7 @@ #include "mode.h" #include "gui_occt_view.h" +#include "utl_occt.h" Shp_chamfer::Shp_chamfer(Occt_view& view) : Shp_operation_base(view) @@ -99,8 +100,7 @@ Status Shp_chamfer::add_chamfer(const ScreenCoords& screen_coords, const Chamfer } catch (const Standard_Failure& e) { - const char* msg = e.GetMessageString(); - std::string err_str = msg ? msg : "Unknown OCCT error"; + const std::string err_str = standard_failure_message(e); DBG_MSG(err_str); return Status::user_error(err_str); } diff --git a/src/shp_fillet.cpp b/src/shp_fillet.cpp index 8fcc2b2..d02a22b 100644 --- a/src/shp_fillet.cpp +++ b/src/shp_fillet.cpp @@ -8,6 +8,7 @@ #include "mode.h" #include "gui_occt_view.h" +#include "utl_occt.h" Shp_fillet::Shp_fillet(Occt_view& view) : Shp_operation_base(view) @@ -95,8 +96,7 @@ Status Shp_fillet::add_fillet(const ScreenCoords& screen_coords, const Fillet_mo } catch (const Standard_Failure& e) { - const char* msg = e.GetMessageString(); - std::string err_str = msg ? msg : "Unknown OCCT error"; + const std::string err_str = standard_failure_message(e); DBG_MSG(err_str); return Status::user_error(err_str); } diff --git a/src/sketch_display.cpp b/src/sketch_display.cpp index ad5e24e..7272f99 100644 --- a/src/sketch_display.cpp +++ b/src/sketch_display.cpp @@ -21,8 +21,8 @@ namespace { constexpr float k_originating_face_full_rgba[4] = {0.3f, 0.0f, 0.0f, 1.0f}; /// Fixed style for non-current sketches (not user-configurable). -constexpr float k_background_edge_rgba[4] = {0.3f, 0.3f, 0.3f, 0.3f}; -constexpr float k_background_face_rgba[4] = {0.3f, 0.3f, 0.3f, 0.2f}; +constexpr float k_background_edge_rgba[4] = {0.3f, 0.3f, 0.3f, 0.3f}; +constexpr float k_background_face_rgba[4] = {0.3f, 0.3f, 0.3f, 0.2f}; constexpr float k_edge_highlight_line_width = 2.0f; Quantity_Color rgb_from_rgba_(const float* rgba) @@ -31,10 +31,7 @@ Quantity_Color rgb_from_rgba_(const float* rgba) Quantity_TOC_RGB); } -float transparency_from_rgba_(const float* rgba) -{ - return std::clamp(1.f - rgba[3], 0.f, 1.f); -} +float transparency_from_rgba_(const float* rgba) { return std::clamp(1.f - rgba[3], 0.f, 1.f); } void apply_rgba_style_(AIS_Shape& shp, const float* rgba, float line_width) { @@ -43,14 +40,13 @@ void apply_rgba_style_(AIS_Shape& shp, const float* rgba, float line_width) shp.SetTransparency(static_cast(transparency_from_rgba_(rgba))); } -Handle(Prs3d_Drawer) make_edge_hilight_drawer_(const float* rgba, float line_width) +Prs3d_Drawer_ptr make_edge_hilight_drawer_(const float* rgba, float line_width) { - Handle(Prs3d_Drawer) drawer = new Prs3d_Drawer(); + Prs3d_Drawer_ptr drawer = new Prs3d_Drawer(); const Quantity_Color qc = rgb_from_rgba_(rgba); drawer->SetColor(qc); drawer->SetTransparency(transparency_from_rgba_(rgba)); - Handle(Prs3d_LineAspect) line = - new Prs3d_LineAspect(qc, Aspect_TOL_SOLID, static_cast(line_width)); + Prs3d_LineAspect_ptr line = new Prs3d_LineAspect(qc, Aspect_TOL_SOLID, static_cast(line_width)); drawer->SetLineAspect(line); drawer->SetWireAspect(line); drawer->SetSeenLineAspect(line); @@ -58,28 +54,28 @@ Handle(Prs3d_Drawer) make_edge_hilight_drawer_(const float* rgba, float line_wid return drawer; } -Handle(Prs3d_Drawer) make_face_hilight_drawer_(const float* rgba) +Prs3d_Drawer_ptr make_face_hilight_drawer_(const float* rgba) { - Handle(Prs3d_Drawer) drawer = new Prs3d_Drawer(); + Prs3d_Drawer_ptr drawer = new Prs3d_Drawer(); drawer->SetupOwnDefaults(); const Quantity_Color qc = rgb_from_rgba_(rgba); const float transp = transparency_from_rgba_(rgba); drawer->SetColor(qc); drawer->SetTransparency(transp); - Handle(Prs3d_ShadingAspect) shading = new Prs3d_ShadingAspect(); + Prs3d_ShadingAspect_ptr shading = new Prs3d_ShadingAspect(); shading->SetColor(qc); shading->SetTransparency(static_cast(transp)); drawer->SetShadingAspect(shading); - Handle(Graphic3d_AspectFillArea3d) fill = new Graphic3d_AspectFillArea3d(); + Graphic3d_AspectFillArea3d_ptr fill = new Graphic3d_AspectFillArea3d(); fill->SetAlphaMode(Graphic3d_AlphaMode_Blend); fill->SetInteriorStyle(Aspect_IS_SOLID); fill->SetInteriorColor(qc); fill->SetColor(qc); drawer->SetBasicFillAreaAspect(fill); - Handle(Prs3d_LineAspect) line = new Prs3d_LineAspect(qc, Aspect_TOL_SOLID, 2.0); + Prs3d_LineAspect_ptr line = new Prs3d_LineAspect(qc, Aspect_TOL_SOLID, 2.0); drawer->SetWireAspect(line); drawer->SetFaceBoundaryAspect(line); return drawer; @@ -87,10 +83,8 @@ Handle(Prs3d_Drawer) make_face_hilight_drawer_(const float* rgba) void apply_edge_hilight_(AIS_Shape& shp, const GUI& gui) { - Handle(Prs3d_Drawer) selected = - make_edge_hilight_drawer_(gui.sketch_edge_selection_color_rgba(), k_edge_highlight_line_width); - Handle(Prs3d_Drawer) hover = - make_edge_hilight_drawer_(gui.sketch_edge_highlight_color_rgba(), k_edge_highlight_line_width); + Prs3d_Drawer_ptr selected = make_edge_hilight_drawer_(gui.sketch_edge_selection_color_rgba(), k_edge_highlight_line_width); + Prs3d_Drawer_ptr hover = make_edge_hilight_drawer_(gui.sketch_edge_highlight_color_rgba(), k_edge_highlight_line_width); shp.SetHilightAttributes(selected); shp.SetDynamicHilightAttributes(hover); } @@ -99,8 +93,8 @@ void apply_face_hilight_(AIS_Shape& shp, const GUI& gui) { // Use shaded hilight so selection/hover tint the face fill, not only a wire outline. shp.SetHilightMode(AIS_Shaded); - Handle(Prs3d_Drawer) selected = make_face_hilight_drawer_(gui.sketch_face_selection_color_rgba()); - Handle(Prs3d_Drawer) hover = make_face_hilight_drawer_(gui.sketch_face_highlight_color_rgba()); + Prs3d_Drawer_ptr selected = make_face_hilight_drawer_(gui.sketch_face_selection_color_rgba()); + Prs3d_Drawer_ptr hover = make_face_hilight_drawer_(gui.sketch_face_highlight_color_rgba()); shp.SetHilightAttributes(selected); shp.SetDynamicHilightAttributes(hover); } diff --git a/src/sketch_edge.cpp b/src/sketch_edge.cpp index d8d1821..ea62653 100644 --- a/src/sketch_edge.cpp +++ b/src/sketch_edge.cpp @@ -67,9 +67,9 @@ gp_Vec2d arc_outgoing_dir_2d_(const Sketch_edge& e, const gp_Pnt2d& from_pt, con const gp_Pnt from_3d = to_3d(pln, from_pt); const gp_Pnt to_pt_3d = to_3d(pln, to_pt); - const Handle(Geom_Curve) geom = curve.Curve().Curve(); - const double u_first = curve.FirstParameter(); - const double u_last = curve.LastParameter(); + const Geom_Curve_ptr geom = curve.Curve().Curve(); + const double u_first = curve.FirstParameter(); + const double u_last = curve.LastParameter(); GeomAPI_ProjectPointOnCurve proj_from(from_3d, geom, u_first, u_last); GeomAPI_ProjectPointOnCurve proj_to(to_pt_3d, geom, u_first, u_last); diff --git a/src/sketch_edges.cpp b/src/sketch_edges.cpp index c41cdd8..2b44928 100644 --- a/src/sketch_edges.cpp +++ b/src/sketch_edges.cpp @@ -302,9 +302,9 @@ void Sketch_edges::split_arc_at_node_(std::list::iterator itr, size } const BRepAdaptor_Curve curve(occ_edge); - const Handle(Geom_Curve) geom = curve.Curve().Curve(); - const double u_first = curve.FirstParameter(); - const double u_last = curve.LastParameter(); + const Geom_Curve_ptr geom = curve.Curve().Curve(); + const double u_first = curve.FirstParameter(); + const double u_last = curve.LastParameter(); auto param_at = [&](size_t node_idx) -> double { diff --git a/src/sketch_operations.cpp b/src/sketch_operations.cpp index 014f90b..ac4828c 100644 --- a/src/sketch_operations.cpp +++ b/src/sketch_operations.cpp @@ -133,10 +133,8 @@ Shp_rslt Sketch::revolve_selected(const double angle) } catch (const Standard_Failure& e) { - std::string error_msg = "Revolution failed: "; - const char* msg = e.GetMessageString(); - error_msg += msg ? msg : "Unknown OCCT error"; - return Shp_rslt(Result_status::Topo_error, error_msg); + return Shp_rslt(Result_status::Topo_error, + std::string("Revolution failed: ") + standard_failure_message(e)); } catch (const std::exception& e) { diff --git a/src/sketch_tools.cpp b/src/sketch_tools.cpp index f34252a..6a69bc5 100644 --- a/src/sketch_tools.cpp +++ b/src/sketch_tools.cpp @@ -753,7 +753,7 @@ void Sketch_tools::move_arc_circle_pt_(const ScreenCoords& screen_coords) gp_Pnt b = to_3d(m_sketch.m_pln, *pt); gp_Pnt c = m_sketch.to_3d_(m_tmp_node_idxs[1]); - Handle(Geom_TrimmedCurve) arc_circle = GC_MakeArcOfCircle(a, b, c); + Geom_TrimmedCurve_ptr arc_circle = GC_MakeArcOfCircle(a, b, c); if (!arc_circle) { m_sketch.m_view.remove(m_tmp_shp); @@ -850,6 +850,7 @@ void Sketch_tools::move_circle_pt_(const ScreenCoords& screen_coords) TopoDS_Wire circle = make_circle_wire(m_sketch.m_pln, pt_a, *m_last_pt); show(m_sketch.m_ctx, m_tmp_shp, circle); }; + if_edge_pt_valid_(l); } @@ -863,6 +864,7 @@ void Sketch_tools::finalize_circle_(Sketch_op_recorder& rec) clear_tmps(); m_sketch.update_faces_(); }; + if_edge_pt_valid_(l); } @@ -879,6 +881,7 @@ void Sketch_tools::move_slot_pt_(const ScreenCoords& screen_coords) if (unique(pt_a, pt_b, pt_c)) show(m_sketch.m_ctx, m_tmp_shp, make_slot_wire(m_sketch.m_pln, pt_a, pt_b, pt_c)); }; + if_edge_pt_valid_(l); } diff --git a/src/sketch_tools.h b/src/sketch_tools.h index b51ed83..090ef9e 100644 --- a/src/sketch_tools.h +++ b/src/sketch_tools.h @@ -35,7 +35,8 @@ class Sketch_tools [[nodiscard]] std::vector& tmp_edges() { return m_tmp_edges; } [[nodiscard]] const std::vector& tmp_edges() const { return m_tmp_edges; } [[nodiscard]] std::optional& last_pt() { return m_last_pt; } - [[nodiscard]] bool clear_tmps(); + /// Clears rubber-band / tmp geometry. Returns true if tmp edges were present (used by `cancel()`). + bool clear_tmps(); void clear_tmp_node_idxs() { m_tmp_node_idxs.clear(); } diff --git a/src/sketch_underlay.cpp b/src/sketch_underlay.cpp index e1e9193..dc27bbf 100644 --- a/src/sketch_underlay.cpp +++ b/src/sketch_underlay.cpp @@ -83,7 +83,7 @@ class Sketch_underlay::Impl void rebuild_and_display(const gp_Pln& pln); void ctx_erase(); - void append_list_hover_ais(std::vector>& out) const; + void append_list_hover_ais(std::vector& out) const; nlohmann::json to_json(const Ezy_asset_store& store) const; [[nodiscard]] bool from_json(const nlohmann::json& j, Ezy_asset_store& store); @@ -101,20 +101,18 @@ class Sketch_underlay::Impl void sync_visibility_(const gp_Pln& pln); void redisplay_(); - static int from_base64_char_(char c); - static bool base64_decode_(const std::string& in, std::vector& out); - static unsigned luminance_u8_(uint8_t r, uint8_t g, uint8_t b); - static void apply_key_and_tint_(uint8_t& r, uint8_t& g, uint8_t& b, uint8_t& a, bool key_white_transparent, - bool line_tint_enabled, uint8_t tr, uint8_t tg, uint8_t tb, uint8_t ta); - static void sample_rgba_bilinear_(const uint8_t* rgba, int w, int h, double xf, double yf, uint8_t out[4]); - static Handle(Image_PixMap) - make_pixmap_bottom_up_linear_(const uint8_t* rgba, int w, int h, bool key_white_transparent, bool line_tint_enabled, - uint8_t tr, uint8_t tg, uint8_t tb, uint8_t ta); - static Handle(Image_PixMap) - make_pixmap_bottom_up_warped_(const uint8_t* rgba, int w, int h, const gp_Vec2d& axis_u, const gp_Vec2d& axis_v, - bool key_white_transparent, bool line_tint_enabled, uint8_t tr, uint8_t tg, uint8_t tb, - uint8_t ta); - static bool underlay_axes_orthogonal_(const gp_Vec2d& au, const gp_Vec2d& av); + static int from_base64_char_(char c); + static bool base64_decode_(const std::string& in, std::vector& out); + static unsigned luminance_u8_(uint8_t r, uint8_t g, uint8_t b); + static void apply_key_and_tint_(uint8_t& r, uint8_t& g, uint8_t& b, uint8_t& a, bool key_white_transparent, + bool line_tint_enabled, uint8_t tr, uint8_t tg, uint8_t tb, uint8_t ta); + static void sample_rgba_bilinear_(const uint8_t* rgba, int w, int h, double xf, double yf, uint8_t out[4]); + static Image_PixMap_ptr make_pixmap_bottom_up_linear_(const uint8_t* rgba, int w, int h, bool key_white_transparent, + bool line_tint_enabled, uint8_t tr, uint8_t tg, uint8_t tb, uint8_t ta); + static Image_PixMap_ptr make_pixmap_bottom_up_warped_(const uint8_t* rgba, int w, int h, const gp_Vec2d& axis_u, + const gp_Vec2d& axis_v, bool key_white_transparent, + bool line_tint_enabled, uint8_t tr, uint8_t tg, uint8_t tb, uint8_t ta); + static bool underlay_axes_orthogonal_(const gp_Vec2d& au, const gp_Vec2d& av); static bool plane_to_uv_(const gp_Pnt2d& base, const gp_Vec2d& au, const gp_Vec2d& av, const gp_Pnt2d& p, double& out_u, double& out_v); @@ -143,8 +141,8 @@ class Sketch_underlay::Impl bool m_flip_image_u{false}; bool m_flip_image_v{false}; - opencascade::handle m_ais; - opencascade::handle m_border; + AIS_TexturedShape_ptr m_ais; + AIS_Shape_ptr m_border; }; int Sketch_underlay::Impl::from_base64_char_(char c) @@ -263,14 +261,14 @@ void Sketch_underlay::Impl::sample_rgba_bilinear_(const uint8_t* rgba, int w, in } /// Straight copy of the image to a bottom-up pixmap (optional row flip for OCCT/OpenGL), with key + tint. -Handle(Image_PixMap) Sketch_underlay::Impl::make_pixmap_bottom_up_linear_(const uint8_t* rgba, int w, int h, - bool key_white_transparent, bool line_tint_enabled, - uint8_t tr, uint8_t tg, uint8_t tb, uint8_t ta) +Image_PixMap_ptr Sketch_underlay::Impl::make_pixmap_bottom_up_linear_(const uint8_t* rgba, int w, int h, + bool key_white_transparent, bool line_tint_enabled, + uint8_t tr, uint8_t tg, uint8_t tb, uint8_t ta) { if (w <= 0 || h <= 0) return {}; - Handle(Image_PixMap) pix = new Image_PixMap(); + Image_PixMap_ptr pix = new Image_PixMap(); if (!pix->InitTrash(Image_Format_RGBA, static_cast(w), static_cast(h))) return {}; @@ -298,10 +296,10 @@ Handle(Image_PixMap) Sketch_underlay::Impl::make_pixmap_bottom_up_linear_(const /// Builds a bottom-up pixmap for AIS_TexturedShape when the underlay axes are sheared (non-orthogonal): uses an /// axis-aligned face in the sketch plane and inverse-rotated sampling so the bitmap matches OCCT UV on the AABB. -Handle(Image_PixMap) Sketch_underlay::Impl::make_pixmap_bottom_up_warped_(const uint8_t* rgba, int w, int h, - const gp_Vec2d& axis_u, const gp_Vec2d& axis_v, - bool key_white_transparent, bool line_tint_enabled, - uint8_t tr, uint8_t tg, uint8_t tb, uint8_t ta) +Image_PixMap_ptr Sketch_underlay::Impl::make_pixmap_bottom_up_warped_(const uint8_t* rgba, int w, int h, const gp_Vec2d& axis_u, + const gp_Vec2d& axis_v, bool key_white_transparent, + bool line_tint_enabled, uint8_t tr, uint8_t tg, + uint8_t tb, uint8_t ta) { const double hw = 0.5 * axis_u.Magnitude(); const double hh = 0.5 * axis_v.Magnitude(); @@ -319,7 +317,7 @@ Handle(Image_PixMap) Sketch_underlay::Impl::make_pixmap_bottom_up_warped_(const out_w = std::clamp(out_w, 1, k_max_image_dim); out_h = std::clamp(out_h, 1, k_max_image_dim); - Handle(Image_PixMap) pix = new Image_PixMap(); + Image_PixMap_ptr pix = new Image_PixMap(); if (!pix->InitTrash(Image_Format_RGBA, static_cast(out_w), static_cast(out_h))) return {}; @@ -750,7 +748,7 @@ void Sketch_underlay::Impl::redisplay_() m_ctx.Redisplay(m_ais, true); } -void Sketch_underlay::Impl::append_list_hover_ais(std::vector>& out) const +void Sketch_underlay::Impl::append_list_hover_ais(std::vector& out) const { if (!has_image() || !m_visible) return; @@ -797,7 +795,7 @@ void Sketch_underlay::Impl::build_ais_(const gp_Pln& pln) const bool is_ortho = underlay_axes_orthogonal_(m_axis_u, m_axis_v); - Handle(Image_PixMap) pix; + Image_PixMap_ptr pix; if (is_ortho || !m_raw_shear_display) { @@ -945,11 +943,11 @@ void Sketch_underlay::Impl::build_ais_(const gp_Pln& pln) if (m_visible) { m_ctx.Display(m_ais, 3, 0, false); - m_ctx.Deactivate(opencascade::handle(m_ais)); + m_ctx.Deactivate(AIS_InteractiveObject_ptr(m_ais)); if (!m_border.IsNull()) { m_ctx.Display(m_border, false); - m_ctx.Deactivate(opencascade::handle(m_border)); + m_ctx.Deactivate(AIS_InteractiveObject_ptr(m_border)); } } } @@ -1166,7 +1164,7 @@ void Sketch_underlay::rebuild_and_display(const gp_Pln& pln) { m_impl->rebuild_a void Sketch_underlay::ctx_erase() { m_impl->ctx_erase(); } -void Sketch_underlay::append_list_hover_ais(std::vector>& out) const +void Sketch_underlay::append_list_hover_ais(std::vector& out) const { m_impl->append_list_hover_ais(out); } diff --git a/src/sketch_underlay.h b/src/sketch_underlay.h index 4792ad1..d7b1647 100644 --- a/src/sketch_underlay.h +++ b/src/sketch_underlay.h @@ -96,7 +96,7 @@ class Sketch_underlay void ctx_erase(); /// Add displayed AIS objects for Sketch List row hover emphasis (image quad and border wire). - void append_list_hover_ais(std::vector>& out) const; + void append_list_hover_ais(std::vector& out) const; nlohmann::json to_json(const Ezy_asset_store& store) const; /// Returns false if JSON is invalid or image decode fails. diff --git a/src/utl_geom.cpp b/src/utl_geom.cpp index 8f4b56d..1995ea9 100644 --- a/src/utl_geom.cpp +++ b/src/utl_geom.cpp @@ -267,8 +267,8 @@ TopoDS_Wire make_circle_wire(const gp_Pln& pln, const gp_Pnt2d& center, const gp gp_Dir normal = pln.Axis().Direction(); // Create circle geometry - gp_Ax2 circle_axis(center_3d, normal); - Handle(Geom_Circle) circle = new Geom_Circle(circle_axis, radius); + gp_Ax2 circle_axis(center_3d, normal); + Geom_Circle_ptr circle = new Geom_Circle(circle_axis, radius); // Make edge and wire BRepBuilderAPI_MakeEdge edge_maker(circle, 0.0, 2.0 * std::numbers::pi); @@ -360,7 +360,7 @@ TopoDS_Wire make_slot_wire(const gp_Pln& plane, const gp_Pnt2d& pt_a, const gp_P } // Function to get the directional vectors at the start and end of a Geom_TrimmedCurve -std::pair get_start_end_tangents(const Handle(Geom_TrimmedCurve) & curve) +std::pair get_start_end_tangents(const Geom_TrimmedCurve_ptr& curve) { // Get the start and end parameters double u_start = curve->FirstParameter(); @@ -436,12 +436,12 @@ std::optional plane_from_face(const TopoDS_Face& face) return std::nullopt; // Get the underlying surface - Handle(Geom_Surface) surface = BRep_Tool::Surface(face); + Geom_Surface_ptr surface = BRep_Tool::Surface(face); if (surface.IsNull()) return std::nullopt; // Check if the surface is a plane and cast it - Handle(Geom_Plane) plane_surface = Handle(Geom_Plane)::DownCast(surface); + Geom_Plane_ptr plane_surface = Geom_Plane_ptr::DownCast(surface); if (plane_surface.IsNull()) return std::nullopt; @@ -538,7 +538,7 @@ gp_Pnt2d mirror_point(const gp_Pnt2d& p1, const gp_Pnt2d& p2, const gp_Pnt2d& po gp_Vec2d line_vec(p1, p2); gp_Dir2d line_dir(line_vec); - Handle(Geom2d_Curve) line_ptr = new Geom2d_Line(p1, line_dir); + Geom2d_Curve_ptr line_ptr = new Geom2d_Line(p1, line_dir); // Project the point onto the line Geom2dAPI_ProjectPointOnCurve projector(point_to_mirror, line_ptr); EZY_ASSERT(projector.NbPoints() != 0); @@ -571,12 +571,12 @@ namespace { constexpr double k_dim_text_height_base = 16.0; -Handle(Prs3d_DimensionAspect) clone_dimension_aspect(const PrsDim_LengthDimension_ptr& dim) +Prs3d_DimensionAspect_ptr clone_dimension_aspect(const PrsDim_LengthDimension_ptr& dim) { if (dim.IsNull()) return new Prs3d_DimensionAspect(); - const Handle(Prs3d_DimensionAspect)& cur = dim->DimensionAspect(); + const Prs3d_DimensionAspect_ptr& cur = dim->DimensionAspect(); if (!cur.IsNull()) return new Prs3d_DimensionAspect(*cur); @@ -621,13 +621,13 @@ Prs3d_DimensionArrowOrientation arrow_orientation_from_index(const int idx) } } -void apply_dimension_label_text_aspect(const Handle(Prs3d_TextAspect) & text, const Quantity_Color& col, +void apply_dimension_label_text_aspect(const Prs3d_TextAspect_ptr& text, const Quantity_Color& col, const Length_dimension_style& style) { text->SetColor(col); text->SetHeight(k_dim_text_height_base * static_cast(style.text_height_scale)); - Handle(Graphic3d_AspectText3d) gtext = new Graphic3d_AspectText3d(); + Graphic3d_AspectText3d_ptr gtext = new Graphic3d_AspectText3d(); gtext->SetColor(col); gtext->SetDisplayType(Aspect_TODT_NORMAL); gtext->SetStyle(Aspect_TOST_NORMAL); @@ -648,12 +648,12 @@ void apply_length_dimension_style(const PrsDim_LengthDimension_ptr& dim, const L if (dim.IsNull()) return; - Handle(Prs3d_DimensionAspect) aspect = clone_dimension_aspect(dim); + Prs3d_DimensionAspect_ptr aspect = clone_dimension_aspect(dim); const Quantity_Color col(style.color_rgb[0], style.color_rgb[1], style.color_rgb[2], Quantity_TOC_RGB); Aspect_TypeOfLine typ = Aspect_TOL_SOLID; - if (const Handle(Prs3d_LineAspect)& la = aspect->LineAspect(); !la.IsNull()) + if (const Prs3d_LineAspect_ptr& la = aspect->LineAspect(); !la.IsNull()) typ = la->Aspect()->Type(); aspect->SetLineAspect(new Prs3d_LineAspect(col, typ, static_cast(style.line_width))); @@ -664,8 +664,8 @@ void apply_length_dimension_style(const PrsDim_LengthDimension_ptr& dim, const L aspect->MakeArrows3d(arrows_3d); aspect->SetArrowOrientation(arrow_orientation_from_index(style.arrow_orientation)); - Handle(Prs3d_ArrowAspect) arrow; - if (const Handle(Prs3d_ArrowAspect)& cur_arrow = aspect->ArrowAspect(); !cur_arrow.IsNull()) + Prs3d_ArrowAspect_ptr arrow; + if (const Prs3d_ArrowAspect_ptr& cur_arrow = aspect->ArrowAspect(); !cur_arrow.IsNull()) arrow = new Prs3d_ArrowAspect(*cur_arrow); else arrow = new Prs3d_ArrowAspect(); @@ -678,7 +678,7 @@ void apply_length_dimension_style(const PrsDim_LengthDimension_ptr& dim, const L if (style.text_render_mode == 1) { aspect->SetCommonColor(col); - Handle(Prs3d_TextAspect) text = aspect->TextAspect(); + Prs3d_TextAspect_ptr text = aspect->TextAspect(); if (text.IsNull()) text = new Prs3d_TextAspect(); @@ -687,7 +687,7 @@ void apply_length_dimension_style(const PrsDim_LengthDimension_ptr& dim, const L } else { - Handle(Prs3d_TextAspect) text = new Prs3d_TextAspect(); + Prs3d_TextAspect_ptr text = new Prs3d_TextAspect(); apply_dimension_label_text_aspect(text, col, style); aspect->SetTextAspect(text); } @@ -715,27 +715,27 @@ void apply_length_dimension_list_hover_style(const PrsDim_LengthDimension_ptr& d if (dim.IsNull()) return; - Handle(Prs3d_DimensionAspect) aspect = clone_dimension_aspect(dim); - const Quantity_Color qc(hover_rgb[0], hover_rgb[1], hover_rgb[2], Quantity_TOC_RGB); + Prs3d_DimensionAspect_ptr aspect = clone_dimension_aspect(dim); + const Quantity_Color qc(hover_rgb[0], hover_rgb[1], hover_rgb[2], Quantity_TOC_RGB); Aspect_TypeOfLine typ = Aspect_TOL_SOLID; - if (const Handle(Prs3d_LineAspect)& la = aspect->LineAspect(); !la.IsNull()) + if (const Prs3d_LineAspect_ptr& la = aspect->LineAspect(); !la.IsNull()) typ = la->Aspect()->Type(); aspect->SetLineAspect(new Prs3d_LineAspect(qc, typ, hover_line_width)); - if (const Handle(Prs3d_ArrowAspect)& cur_arrow = aspect->ArrowAspect(); !cur_arrow.IsNull()) + if (const Prs3d_ArrowAspect_ptr& cur_arrow = aspect->ArrowAspect(); !cur_arrow.IsNull()) { - Handle(Prs3d_ArrowAspect) arrow = new Prs3d_ArrowAspect(*cur_arrow); + Prs3d_ArrowAspect_ptr arrow = new Prs3d_ArrowAspect(*cur_arrow); arrow->SetColor(qc); aspect->SetArrowAspect(arrow); } aspect->SetCommonColor(qc); - if (const Handle(Prs3d_TextAspect)& text = aspect->TextAspect(); !text.IsNull()) + if (const Prs3d_TextAspect_ptr& text = aspect->TextAspect(); !text.IsNull()) { - Handle(Prs3d_TextAspect) t = new Prs3d_TextAspect(*text); + Prs3d_TextAspect_ptr t = new Prs3d_TextAspect(*text); t->SetColor(qc); aspect->SetTextAspect(t); } @@ -920,11 +920,11 @@ bool is_face_contained(const TopoDS_Shape& shape_a, const TopoDS_Shape& shape_b) const TopoDS_Face& face_b = TopoDS::Face(shape_b); // Check surface compatibility (both planar and coplanar) - Handle(Geom_Surface) surface_a = BRep_Tool::Surface(face_a); - Handle(Geom_Surface) surface_b = BRep_Tool::Surface(face_b); + Geom_Surface_ptr surface_a = BRep_Tool::Surface(face_a); + Geom_Surface_ptr surface_b = BRep_Tool::Surface(face_b); - Handle(Geom_Plane) plane_a = Handle(Geom_Plane)::DownCast(surface_a); - Handle(Geom_Plane) plane_b = Handle(Geom_Plane)::DownCast(surface_b); + Geom_Plane_ptr plane_a = Geom_Plane_ptr::DownCast(surface_a); + Geom_Plane_ptr plane_b = Geom_Plane_ptr::DownCast(surface_b); if (plane_a.IsNull() || plane_b.IsNull()) throw std::runtime_error("Both faces must be planar."); @@ -1030,8 +1030,8 @@ ezy_geom::polygon_2d to_boost(const TopoDS_Shape& shape, const gp_Pln& pln2) const TopoDS_Face& face = TopoDS::Face(shape); // Get the surface and verify it's a plane - Handle(Geom_Surface) surface = BRep_Tool::Surface(face); - Handle(Geom_Plane) plane = Handle(Geom_Plane)::DownCast(surface); + Geom_Surface_ptr surface = BRep_Tool::Surface(face); + Geom_Plane_ptr plane = Geom_Plane_ptr::DownCast(surface); EZY_ASSERT_MSG(!plane.IsNull(), "Face surface must be planar."); // Get the plane's coordinate system @@ -1499,12 +1499,12 @@ std::optional snap_foot_to_open_segment_interior_if_close(const gp_Pnt namespace { -Handle(Geom_TrimmedCurve) edge_trimmed_curve_(const TopoDS_Edge& edge) +Geom_TrimmedCurve_ptr edge_trimmed_curve_(const TopoDS_Edge& edge) { - Standard_Real f = 0.0; - Standard_Real l = 0.0; - Handle(Geom_Curve) c = BRep_Tool::Curve(edge, f, l); - Handle(Geom_TrimmedCurve) ret = new Geom_TrimmedCurve(c, f, l); + double f = 0.0; + double l = 0.0; + Geom_Curve_ptr c = BRep_Tool::Curve(edge, f, l); + Geom_TrimmedCurve_ptr ret = new Geom_TrimmedCurve(c, f, l); if (edge.Orientation() == TopAbs_REVERSED) ret->Reverse(); return ret; @@ -1530,9 +1530,9 @@ bool on_open_arc_parameter_(double u, double u_first, double u_last) bool point_on_open_arc_interior_2d(const gp_Pnt2d& p, const TopoDS_Edge& arc_edge, const gp_Pln& pln) { const BRepAdaptor_Curve curve(arc_edge); - const Handle(Geom_Curve) geom = curve.Curve().Curve(); - const double u_first = curve.FirstParameter(); - const double u_last = curve.LastParameter(); + const Geom_Curve_ptr geom = curve.Curve().Curve(); + const double u_first = curve.FirstParameter(); + const double u_last = curve.LastParameter(); GeomAPI_ProjectPointOnCurve proj(to_3d(pln, p), geom, u_first, u_last); if (proj.NbPoints() == 0 || proj.LowerDistance() > Precision::Confusion()) @@ -1557,8 +1557,8 @@ std::vector segment_arc_intersections_2d(const gp_Pnt2d& seg_a, const if (a3.Distance(b3) <= Precision::Confusion()) return ret; - Handle(Geom_TrimmedCurve) seg = GC_MakeSegment(a3, b3); - Handle(Geom_TrimmedCurve) arc_c = edge_trimmed_curve_(arc_edge); + Geom_TrimmedCurve_ptr seg = GC_MakeSegment(a3, b3); + Geom_TrimmedCurve_ptr arc_c = edge_trimmed_curve_(arc_edge); GeomAPI_ExtremaCurveCurve ext(seg, arc_c); for (int i = 1; i <= ext.NbExtrema(); ++i) @@ -1589,9 +1589,9 @@ std::vector segment_arc_intersections_2d(const gp_Pnt2d& seg_a, const std::vector arc_arc_intersections_2d(const TopoDS_Edge& arc_a, const TopoDS_Edge& arc_b, const gp_Pln& pln) { - std::vector ret; - Handle(Geom_TrimmedCurve) curve_a = edge_trimmed_curve_(arc_a); - Handle(Geom_TrimmedCurve) curve_b = edge_trimmed_curve_(arc_b); + std::vector ret; + Geom_TrimmedCurve_ptr curve_a = edge_trimmed_curve_(arc_a); + Geom_TrimmedCurve_ptr curve_b = edge_trimmed_curve_(arc_b); GeomAPI_ExtremaCurveCurve ext(curve_a, curve_b); for (int i = 1; i <= ext.NbExtrema(); ++i) diff --git a/src/utl_geom.h b/src/utl_geom.h index cb89b5a..a729f24 100644 --- a/src/utl_geom.h +++ b/src/utl_geom.h @@ -75,7 +75,7 @@ Slot_pnts get_slot_points(const gp_Pnt2d& pt_a, const gp_Pnt2d& pt_b, const gp_P TopoDS_Wire make_slot_wire(const gp_Pln& plane, const gp_Pnt2d& pt_a, const gp_Pnt2d& pt_b, const gp_Pnt2d& pt_c); // Function to get the directional vectors at the start and end of a Geom_TrimmedCurve -std::pair get_start_end_tangents(const Handle(Geom_TrimmedCurve) & curve); +std::pair get_start_end_tangents(const Geom_TrimmedCurve_ptr& curve); std::pair get_edge_endpoints(const TopoDS_Edge& edge); std::pair get_edge_endpoints(const gp_Pln& pln, const TopoDS_Edge& edge); diff --git a/src/utl_occt.cpp b/src/utl_occt.cpp index 5166627..4abeab0 100644 --- a/src/utl_occt.cpp +++ b/src/utl_occt.cpp @@ -4,11 +4,23 @@ #include #include #include +#include +#include #include #include #include #include +const char* standard_failure_message(const Standard_Failure& e) +{ +#if OCC_VERSION_HEX >= 0x080000 + const char* msg = e.what(); +#else + const char* msg = e.GetMessageString(); +#endif + return (msg && msg[0]) ? msg : "Unknown OCCT error"; +} + namespace { TopoDS_Shape solid_from_shell(const TopoDS_Shell& shell) diff --git a/src/utl_occt.h b/src/utl_occt.h index 92dbf47..6b87d11 100644 --- a/src/utl_occt.h +++ b/src/utl_occt.h @@ -30,3 +30,10 @@ static_assert(c_names_TopAbs_ShapeEnum.size() == static_cast(TopAbs /// When \a shape is a closed shell (or compound of closed shells), wrap it as a solid. /// Otherwise returns \a shape unchanged. TopoDS_Shape try_make_solid(const TopoDS_Shape& shape); + +class Standard_Failure; + +/// Message from `Standard_Failure` for logging / `Status` text. +/// Uses `what()` on OCCT 8+ and `GetMessageString()` on OCCT 7.x (wasm) so shared code builds +/// without deprecation warnings or missing-member errors. Never returns null or empty. +const char* standard_failure_message(const Standard_Failure& e); diff --git a/src/utl_ply_io.cpp b/src/utl_ply_io.cpp index b03b442..b9ca90e 100644 --- a/src/utl_ply_io.cpp +++ b/src/utl_ply_io.cpp @@ -603,9 +603,9 @@ Status export_ply_binary_file(const TopoDS_Shape& shape, const std::string& file for (TopExp_Explorer exp(shape, TopAbs_FACE); exp.More(); exp.Next()) { - const TopoDS_Face& face = TopoDS::Face(exp.Current()); - TopLoc_Location loc; - const Handle(Poly_Triangulation)& tri = BRep_Tool::Triangulation(face, loc); + const TopoDS_Face& face = TopoDS::Face(exp.Current()); + TopLoc_Location loc; + const Poly_Triangulation_ptr& tri = BRep_Tool::Triangulation(face, loc); if (tri.IsNull()) continue; diff --git a/src/utl_types.h b/src/utl_types.h index 2fb25ea..0e12b8b 100644 --- a/src/utl_types.h +++ b/src/utl_types.h @@ -1,11 +1,8 @@ #pragma once -#include #include #include #include -#include -#include #include "sketch_ais.h" @@ -14,36 +11,90 @@ class Sketch; class AIS_InteractiveObject; class AIS_InteractiveContext; -class Occt_glfw_win; -class V3d_View; -class V3d_Viewer; class AIS_Shape; -class Geom_TrimmedCurve; -class Geom_Plane; -class Geom_Line; +class AIS_TexturedShape; +class AIS_ViewCube; +class Aspect_DisplayConnection; +class Aspect_Grid; +class Aspect_RectangularGrid; +class Cocoa_Window; +class Font_FontMgr; +class Font_SystemFont; +class Geom2d_Curve; +class Geom_Circle; class Geom_Curve; +class Geom_Line; +class Geom_Plane; class Geom_Surface; -class PrsDim_LengthDimension; +class Geom_TrimmedCurve; +class Graphic3d_AspectFillArea3d; +class Graphic3d_AspectText3d; class Graphic3d_Camera; +class Graphic3d_CLight; +class Image_PixMap; +class Occt_glfw_win; +class OpenGl_GraphicDriver; +class Poly_Triangulation; +class Prs3d_ArrowAspect; +class Prs3d_DimensionAspect; +class Prs3d_Drawer; +class Prs3d_LineAspect; +class Prs3d_ShadingAspect; +class Prs3d_TextAspect; +class PrsDim_LengthDimension; class StdSelect_BRepOwner; +class V3d_RectangularGrid; +class V3d_View; +class V3d_Viewer; +class Wasm_Window; +class WNT_WClass; +class WNT_Window; +class Xw_Window; -using AIS_InteractiveObject_ptr = opencascade::handle; -using AIS_InteractiveContext_ptr = opencascade::handle; -using Occt_glfw_win_ptr = opencascade::handle; -using V3d_View_ptr = opencascade::handle; -using V3d_Viewer_ptr = opencascade::handle; -using AIS_Shape_ptr = opencascade::handle; -using Geom_TrimmedCurve_ptr = opencascade::handle; -using Geom_Plane_ptr = opencascade::handle; -using Geom_Line_ptr = opencascade::handle; -using Geom_Curve_ptr = opencascade::handle; -using Geom_Surface_ptr = opencascade::handle; -using PrsDim_LengthDimension_ptr = opencascade::handle; -using Graphic3d_Camera_ptr = opencascade::handle; -using StdSelect_BRepOwner_ptr = opencascade::handle; -using Sketch_AIS_edge_ptr = opencascade::handle; -using Sketch_AIS_node_mark_ptr = opencascade::handle; -using Sketch_face_shp_ptr = opencascade::handle; +using AIS_InteractiveObject_ptr = opencascade::handle; +using AIS_InteractiveContext_ptr = opencascade::handle; +using AIS_Shape_ptr = opencascade::handle; +using AIS_TexturedShape_ptr = opencascade::handle; +using AIS_ViewCube_ptr = opencascade::handle; +using Aspect_DisplayConnection_ptr = opencascade::handle; +using Aspect_Grid_ptr = opencascade::handle; +using Aspect_RectangularGrid_ptr = opencascade::handle; +using Cocoa_Window_ptr = opencascade::handle; +using Font_FontMgr_ptr = opencascade::handle; +using Font_SystemFont_ptr = opencascade::handle; +using Geom2d_Curve_ptr = opencascade::handle; +using Geom_Circle_ptr = opencascade::handle; +using Geom_Curve_ptr = opencascade::handle; +using Geom_Line_ptr = opencascade::handle; +using Geom_Plane_ptr = opencascade::handle; +using Geom_Surface_ptr = opencascade::handle; +using Geom_TrimmedCurve_ptr = opencascade::handle; +using Graphic3d_AspectFillArea3d_ptr = opencascade::handle; +using Graphic3d_AspectText3d_ptr = opencascade::handle; +using Graphic3d_Camera_ptr = opencascade::handle; +using Graphic3d_CLight_ptr = opencascade::handle; +using Image_PixMap_ptr = opencascade::handle; +using Occt_glfw_win_ptr = opencascade::handle; +using OpenGl_GraphicDriver_ptr = opencascade::handle; +using Poly_Triangulation_ptr = opencascade::handle; +using Prs3d_ArrowAspect_ptr = opencascade::handle; +using Prs3d_DimensionAspect_ptr = opencascade::handle; +using Prs3d_Drawer_ptr = opencascade::handle; +using Prs3d_LineAspect_ptr = opencascade::handle; +using Prs3d_ShadingAspect_ptr = opencascade::handle; +using Prs3d_TextAspect_ptr = opencascade::handle; +using PrsDim_LengthDimension_ptr = opencascade::handle; +using Sketch_AIS_edge_ptr = opencascade::handle; +using Sketch_AIS_node_mark_ptr = opencascade::handle; +using Sketch_face_shp_ptr = opencascade::handle; +using StdSelect_BRepOwner_ptr = opencascade::handle; +using V3d_RectangularGrid_ptr = opencascade::handle; +using V3d_View_ptr = opencascade::handle; +using V3d_Viewer_ptr = opencascade::handle; +using Wasm_Window_ptr = opencascade::handle; +using WNT_WClass_ptr = opencascade::handle; +using WNT_Window_ptr = opencascade::handle; +using Xw_Window_ptr = opencascade::handle; #define DECL_PTR(TypeName) \ using uptr = std::unique_ptr; \ diff --git a/tests/doc_link_tests.cpp b/tests/doc_link_tests.cpp index 2eb2809..7395794 100644 --- a/tests/doc_link_tests.cpp +++ b/tests/doc_link_tests.cpp @@ -21,7 +21,7 @@ struct Parsed_url { std::wstring host; std::wstring path; - std::wstring fragment; + std::string fragment; bool https = true; INTERNET_PORT port = INTERNET_DEFAULT_HTTPS_PORT; }; @@ -69,10 +69,7 @@ Parsed_url parse_doc_url(const std::string& url) p.path = L"/"; if (hash != std::string::npos) - { - std::string frag = u.substr(hash + 1); - p.fragment.assign(frag.begin(), frag.end()); - } + p.fragment = u.substr(hash + 1); return p; } @@ -182,7 +179,7 @@ bool check_doc_url(const std::string& url) if (!p.fragment.empty() && !body_for_anchor.empty()) { // Check for common Sphinx/ReadTheDocs anchor patterns - std::string frag(p.fragment.begin(), p.fragment.end()); + const std::string& frag = p.fragment; if (body_for_anchor.find("id=\"" + frag + "\"") != std::string::npos || body_for_anchor.find("name=\"" + frag + "\"") != std::string::npos || body_for_anchor.find("href=\"#" + frag + "\"") != std::string::npos ||