From dd6363f536151db7d5f01dda66dc5ab3ee6f1349 Mon Sep 17 00:00:00 2001 From: Tommaso Bianchi Date: Fri, 14 Aug 2026 21:50:27 +0200 Subject: [PATCH] CAD: clicking a reference plane's label selects THAT plane (snaporca-uw3c) Ported from snaporca 373ef325d8. See that commit for the full rationale. Co-Authored-By: Claude Opus 5 (1M context) --- src/slic3r/GUI/DesignSketchTool.cpp | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/slic3r/GUI/DesignSketchTool.cpp b/src/slic3r/GUI/DesignSketchTool.cpp index aeb70dfb79..25d6a590ac 100644 --- a/src/slic3r/GUI/DesignSketchTool.cpp +++ b/src/slic3r/GUI/DesignSketchTool.cpp @@ -4319,6 +4319,34 @@ int DesignSketchTool::hit_test_base_pick(GLCanvas3D& canvas, const wxMouseEvent& { if (!m_dbp_active) return -1; const double H = dbp_half_extent(); + + // THE LABEL WINS, and it has to. Each plane's name is a screen-space chip centred on its + // own in-plane anchor, and it is the one part of a base plane a user aims at deliberately — + // the quads are near-transparent and overlap everywhere. Ray-casting the quads alone made + // the labels pure decoration: on a fresh document at 1920x1060, clicking "XY" reported + // "XZ plane selected", because the XZ quad happens to sit in front at that pixel. Nothing + // about the click was ambiguous to the user; they clicked the word XY. + // Anchor and text height must track render_base_pick's, which is where they are drawn. + const Camera& cam = wxGetApp().plater()->get_camera(); + const double th = H * 0.10; + const Vec2d anchor(-H + th * 2.0, H - th * 1.6); + int lbest = -1; double lbest_d = 1e30; + for (size_t i = 0; i < m_dbp_planes.size(); ++i) { + if (i >= m_dbp_labels.size() || m_dbp_labels[i].empty()) continue; + const wxPoint sp = world_to_screen_px(cam, m_dbp_planes[i].to_world(anchor)); + if (sp.x < 0 && sp.y < 0) continue; // behind the camera + const double dx = std::abs(double(evt.GetX() - sp.x)); + const double dy = std::abs(double(evt.GetY() - sp.y)); + // Chip half-extents in px, scaled like the label itself. Generous rather than tight: + // missing the text and silently selecting a different plane is the failure being fixed. + const double hw = (9.0 + 5.0 * double(m_dbp_labels[i].size())) * double(m_render_scale); + const double hh = 11.0 * double(m_render_scale); + if (dx > hw || dy > hh) continue; + const double d = dx * dx + dy * dy; // nearest label if chips overlap + if (d < lbest_d) { lbest_d = d; lbest = int(i); } + } + if (lbest >= 0) return lbest; + const Linef3 r = canvas.mouse_ray(Point(evt.GetX(), evt.GetY())); const Vec3d ro = r.a, rd = r.b - r.a; int best = -1; double best_t = 1e30;