diff --git a/CHANGELOG.md b/CHANGELOG.md index 7a1f2e65..6b598ab7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed +- **Sketch from face profile wire**: the dark-red originating-face boundary no longer stays drawn after leaving sketch mode (e.g. after Revolve returns to Normal). It follows sketch edge visibility and only appears while sketch tools (or polar duplicate) show the sketch. + - **`gui.hotkeys` load**: duplicate-chord cleanup no longer leaves two actions on the same key when the later row's factory chord is the colliding key (e.g. Move and Rotate both `"R"`). Earlier remaps that steal a later action's factory chord are restored to defaults so each binding stays unique. ## [0.4.0] - 2026-07-25 diff --git a/docs/usage-sketch.md b/docs/usage-sketch.md index 27452819..76da6acb 100644 --- a/docs/usage-sketch.md +++ b/docs/usage-sketch.md @@ -952,7 +952,7 @@ The create sketch from planar face tool allows you to extract the boundary of a - The face must be planar (flat) - curved surfaces like cylinders, spheres, or complex surfaces will show an error - The system will automatically extract the outer boundary of the face 3. **Sketch Created**: A new sketch is automatically created with: - - The face boundary as the initial wire + - The face boundary as the initial wire (shown as a dark-red profile while sketch tools are active; hidden in Normal and other non-sketch modes, like other sketch edges) - The sketch plane aligned with the face plane - A permanent **Origin** marker (**cyan + inside a circle**) at the **center of the face boundary's bounding box** (a fixed reference on the sketch plane) - The sketch name set to "Sketch from face" diff --git a/src/doc/sketch.md b/src/doc/sketch.md index aac78238..79ce21c1 100644 --- a/src/doc/sketch.md +++ b/src/doc/sketch.md @@ -89,7 +89,7 @@ Sketch(const std::string& name, Occt_view& view, const gp_Pln& pln); Sketch(const std::string& name, Occt_view& view, const gp_Pln& pln, const TopoDS_Wire& outer_wire); ``` -The wire overload creates a sketch **from a planar face**; `m_originating_face` is displayed and its vertices contribute to snap targets. `ensure_origin_node_()` places the origin at the wire bounding-box center (or plane `(0,0)` for plane-only sketches); call `m_nodes.finalize()` so `cancel_elm()` / `on_mode()` does not roll it back. +The wire overload creates a sketch **from a planar face**; `m_originating_face` is the dark-red outer-wire cue and its vertices contribute to snap targets. Display follows `set_show_edges` (same as sketch edges), so `Occt_view::on_mode` hides it outside sketch modes. `ensure_origin_node_()` places the origin at the wire bounding-box center (or plane `(0,0)` for plane-only sketches); call `m_nodes.finalize()` so `cancel_elm()` / `on_mode()` does not roll it back. ### Input routing (from UI / `Occt_view`) @@ -117,7 +117,7 @@ Full GLFW -> `GUI` -> view routing: [`src/doc/gui.md`](gui.md). | Method | Purpose | | ----------------------------------------------------- | --------------------------------------------------------------------------- | | `set_visible` / `is_visible` | Show or hide the whole sketch in the viewer | -| `set_show_faces` / `set_show_edges` / `set_show_dims` | Layer toggles for faces, edges, dimensions | +| `set_show_faces` / `set_show_edges` / `set_show_dims` | Layer toggles for faces, edges (+ originating-face wire), dimensions | | `set_edge_style(Full / Background / Hidden)` | Current vs background appearance (edge/face colors from Settings -> Sketch) | | `set_current()` | Make this sketch current in `Occt_view` | | `refresh_annotations(Sketch_annotation_refresh)` | Rebuild dims, node marks, and/or edge-face styles after settings changes | diff --git a/src/gui_hotkeys.cpp b/src/gui_hotkeys.cpp index 61da2022..c1e6f6fc 100644 --- a/src/gui_hotkeys.cpp +++ b/src/gui_hotkeys.cpp @@ -288,6 +288,7 @@ const char* Gui_hotkeys::action_label(Gui_action action) const int i = static_cast(action); if (i < 0 || i >= k_count) return ""; + return c_actions[i].label; } @@ -296,6 +297,7 @@ Key_chord Gui_hotkeys::default_chord(Gui_action action) const int i = static_cast(action); if (i < 0 || i >= k_count) return {}; + return c_actions[i].def; } @@ -304,6 +306,7 @@ std::optional Gui_hotkeys::action_from_id(std::string_view id) for (const Action_meta& m : c_actions) if (id == m.id) return m.action; + return std::nullopt; } @@ -341,6 +344,7 @@ std::optional Gui_hotkeys::parse_chord(std::string_view text) // Trim spaces while (!part.empty() && part.front() == ' ') part.remove_prefix(1); + while (!part.empty() && part.back() == ' ') part.remove_suffix(1); diff --git a/src/skt_display.cpp b/src/skt_display.cpp index 0bdfac7c..6573e67a 100644 --- a/src/skt_display.cpp +++ b/src/skt_display.cpp @@ -252,11 +252,23 @@ void Sketch::set_show_faces(bool show) void Sketch::set_show_edges(bool show) { if (show && m_visible) + { for (Edge& e : m_edges.edges()) m_ctx.Display(e.shp, AIS_WireFrame, 0, false); + + // Originating-face wire is the from-face profile cue; follow edge visibility so + // Occt_view::on_mode hide outside sketch modes (and polar-dup current-only) applies. + if (m_originating_face) + m_ctx.Display(m_originating_face, AIS_WireFrame, 0, false); + } else + { for (Edge& e : m_edges.edges()) m_ctx.Erase(e.shp, false); + + if (m_originating_face) + m_ctx.Erase(m_originating_face, false); + } } void Sketch::append_list_hover_ais(std::vector& out) const