From dcbda7d42ce8750fc3922e470ad725061a01eb90 Mon Sep 17 00:00:00 2001 From: Tommaso Bianchi Date: Fri, 14 Aug 2026 23:25:21 +0200 Subject: [PATCH] CAD: deliver the picked sketch ENTITY to the panel, and point Rib at it (snaporca-3648) Ported from snaporca 94b6b564de. See that commit for what is and is not measured. Co-Authored-By: Claude Opus 5 (1M context) --- src/slic3r/GUI/DesignCanvas.cpp | 2 +- src/slic3r/GUI/DesignCanvas.hpp | 2 +- src/slic3r/GUI/DesignPanel.cpp | 19 ++++++++++++++++++- src/slic3r/GUI/DesignSketchTool.cpp | 11 +++++++---- src/slic3r/GUI/DesignSketchTool.hpp | 5 ++++- 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/DesignCanvas.cpp b/src/slic3r/GUI/DesignCanvas.cpp index 8fa0278ecb..e5a1800ff3 100644 --- a/src/slic3r/GUI/DesignCanvas.cpp +++ b/src/slic3r/GUI/DesignCanvas.cpp @@ -581,7 +581,7 @@ void DesignCanvas::set_on_sketch_face_selected(std::function cb) m_sketch_tool.on_face_selected = std::move(cb); } -void DesignCanvas::set_on_display_sketch_selected(std::function cb) +void DesignCanvas::set_on_display_sketch_selected(std::function cb) { m_sketch_tool.on_display_sketch_selected = std::move(cb); } diff --git a/src/slic3r/GUI/DesignCanvas.hpp b/src/slic3r/GUI/DesignCanvas.hpp index cc6d1b2184..d4bca46e29 100644 --- a/src/slic3r/GUI/DesignCanvas.hpp +++ b/src/slic3r/GUI/DesignCanvas.hpp @@ -79,7 +79,7 @@ public: // Sketch selection (Mode::Select). void set_on_sketch_selection_changed(std::function cb); void set_on_sketch_face_selected(std::function cb); // closed loop clicked: region index passed - void set_on_display_sketch_selected(std::function cb); // committed loop clicked: (feature, region) + void set_on_display_sketch_selected(std::function cb); // committed loop clicked: (feature, region, entity) void set_on_display_sketch_activated(std::function cb); // committed sketch DOUBLE-clicked: edit it std::vector selected_loop_entities() const; // entities of the click-selected loop std::vector> region_entity_indices(const std::vector& ents) const; diff --git a/src/slic3r/GUI/DesignPanel.cpp b/src/slic3r/GUI/DesignPanel.cpp index 22e9846354..8425f6440c 100644 --- a/src/slic3r/GUI/DesignPanel.cpp +++ b/src/slic3r/GUI/DesignPanel.cpp @@ -3358,7 +3358,7 @@ DesignPanel::DesignPanel(wxWindow* parent) // Clicking a committed sketch loop on the plate (no live session) selects THAT loop: // the viewport highlights only it (cyan) and its Sketch feature's tree row is selected. // The (feature, region) pair is remembered so Extrude builds just that one loop. - m_viewport->set_on_display_sketch_selected([this](int feat, int region) { + m_viewport->set_on_display_sketch_selected([this](int feat, int region, int entity) { if (feat < 0 || feat >= int(m_doc.features.size())) return; m_sel_sketch_feat = feat; m_sel_sketch_region = region; @@ -3366,6 +3366,23 @@ DesignPanel::DesignPanel(wxWindow* parent) // any stale solid face/edge pick so Extrude treats this loop as the profile. m_sel_solid_face = m_sel_solid_edge = -1; m_pick_face = m_pick_face_body = -1; + // Rib card open: point at the LINE, do not type its index. 'Entity index' was a bare + // wxSpinCtrl ranged 0-999 standing in for a line sitting visible on screen, with nothing + // anywhere telling you which integer was which — the purest case of the thing this epic + // exists to remove. Only a stroke hit carries an entity (an interior click is a region, + // not a line), so a click inside a loop deliberately leaves the field alone rather than + // resetting it to something arbitrary. The sketch picker follows the same pick, so + // pointing at a line in a different sketch retargets both together. snaporca-3648. + if (m_active == Tool::Rib && entity >= 0) { + if (m_rib_sketch != nullptr) + for (unsigned i = 0; i < m_rib_sketch->GetCount(); ++i) + if (int(reinterpret_cast(m_rib_sketch->GetClientData(i))) == feat) { + m_rib_sketch->SetSelection(i); + break; + } + if (m_rib_entity != nullptr) m_rib_entity->SetValue(entity); + refresh_preview(); + } // Sweep card open: the sketch you point at becomes the PATH. The profile is already // settled selection-first — you pick a sketch and then invoke Sweep, which is the design // law's own canonical example — so the path is the input that was still trapped in a diff --git a/src/slic3r/GUI/DesignSketchTool.cpp b/src/slic3r/GUI/DesignSketchTool.cpp index 25d6a590ac..deee0841cf 100644 --- a/src/slic3r/GUI/DesignSketchTool.cpp +++ b/src/slic3r/GUI/DesignSketchTool.cpp @@ -2852,8 +2852,11 @@ void DesignSketchTool::hit_display_sketch(const DisplaySketch& d, const Vec2d& p if (h >= 0 && h < int(loops.size()) && point_in_poly(p, loops[h].poly)) { in_hole = true; break; } if (!in_hole) { face_feat = d.feature; face_reg = r; } } - dp_pick_trace("region hit -> feat=%d reg=%d (edge_feat=%d edge_reg=%d)", - face_feat, face_reg, edge_feat, edge_reg); + // edge_ent is printed because it is now DELIVERED (snaporca-3648) — a tool can ask for the + // line you pointed at, not just its loop, and "which entity did that click resolve to" is + // otherwise unanswerable from outside. + dp_pick_trace("region hit -> feat=%d reg=%d (edge_feat=%d edge_reg=%d edge_ent=%d)", + face_feat, face_reg, edge_feat, edge_reg, edge_ent); } std::vector DesignSketchTool::selected_loop_entities() const @@ -8947,7 +8950,7 @@ bool DesignSketchTool::on_mouse_impl(wxMouseEvent& evt, GLCanvas3D& canvas) // A precise hit on a loop outline wins over the solid face beneath it. if (edge_feat >= 0) { m_display_pick = edge_feat; m_display_pick_region = edge_reg; - if (on_display_sketch_selected) on_display_sketch_selected(edge_feat, edge_reg); + if (on_display_sketch_selected) on_display_sketch_selected(edge_feat, edge_reg, edge_ent); return true; } // No loop stroke under the cursor: the solid is the foreground (whole/face/edge cycle). @@ -8955,7 +8958,7 @@ bool DesignSketchTool::on_mouse_impl(wxMouseEvent& evt, GLCanvas3D& canvas) // Interior of a committed loop with no solid behind it. if (face_feat >= 0) { m_display_pick = face_feat; m_display_pick_region = face_reg; - if (on_display_sketch_selected) on_display_sketch_selected(face_feat, face_reg); + if (on_display_sketch_selected) on_display_sketch_selected(face_feat, face_reg, -1); return true; } m_display_pick = -1; m_display_pick_region = -1; // clicked bare plate -> drop highlight diff --git a/src/slic3r/GUI/DesignSketchTool.hpp b/src/slic3r/GUI/DesignSketchTool.hpp index c52429b9e4..982ed8a1cf 100644 --- a/src/slic3r/GUI/DesignSketchTool.hpp +++ b/src/slic3r/GUI/DesignSketchTool.hpp @@ -195,7 +195,10 @@ public: std::function on_solid_selection_changed; // Click a committed sketch overlay (no live session) -> select that loop: the Sketch // feature index + the clicked closed-region index within it (-1 = no specific loop). - std::function on_display_sketch_selected; + // entity = the sketch entity index under the cursor when the click landed on a loop + // STROKE, else -1 for an interior/region hit. Carried because a tool can legitimately + // want the LINE you pointed at, not just the loop it belongs to (Rib, snaporca-3648). + std::function on_display_sketch_selected; // Double-click on a committed sketch stroke: open THAT feature for editing. Selecting a line // and then hunting for an Edit button in a panel is the dependency this tab exists to remove. std::function on_display_sketch_activated;