Design: kill the pick cycle — one click selects what is under the cursor

Tommaso, correctly: fix selection before building on it. I had taken the
whole→face→edge click cycle as terrain and hung the tool offer off it, when §10
of the charter already listed that cycle as an L5 violation. An offer can only
ever be as truthful as the selection beneath it, so this is the foundation and
it should have come first.

NOW: one click selects the SMALLEST thing under the pointer — the edge if the
cursor is within tolerance of one, otherwise the face. No repeat clicks, no
state, no memory of what was picked before. Verified by sweeping a column of
single clicks down a plate on :11: y=800..915 all report "face 5 selected", and
y=925/935 — within a few pixels of the front edge — report "edge 3 selected".
One gesture, one deterministic result, which is what L5 asks for.

TOLERANCE IS IN SCREEN PIXELS. The old edge step compared a ray-to-segment
distance in millimetres, so the same gesture meant different things at
different zoom levels. The pointer is a screen object; its tolerance has to be
one too. 8 px, measured against the edge polyline projected through the camera.

WHAT IS NOT HERE, AND WHY IT IS NOT FAKED. Whole-body selection has no viewport
gesture in this commit. Double-click is ALREADY zoom-to-fit, bound earlier in
the same on_mouse, and this pick runs on LeftUp where LeftDClick() can never be
true — so a double-click branch here would have been dead code that reads like
a working feature. I wrote one, found it unreachable, and deleted it rather
than leave it. The body gesture is the rubber band, which is its own piece of
work; until it lands bodies are selected from the Bodies list, and the hole is
named in a comment at the site instead of being left for someone to trip over.

Six status strings that promised the cycle ("click again for a face", "click
again for an edge", "click again to reset") are gone — they described a
behaviour that no longer exists, and a hint that lies is worse than none.

Both forks build. Parity: DesignSketchTool.cpp byte-identical, DesignPanel.cpp
30 divergent lines — the invariant exactly.

snaporca-6vs.
This commit is contained in:
Tommaso Bianchi
2026-07-31 12:37:21 +02:00
parent 7114e316ea
commit b003d20e37
2 changed files with 65 additions and 28 deletions
+6 -6
View File
@@ -3138,9 +3138,9 @@ DesignPanel::DesignPanel(wxWindow* parent)
if (level <= 0)
m_status->SetLabel(_L("Selection cleared"));
else if (level == 1)
m_status->SetLabel(wxString::Format(_L("Body %d selected — click again for a face"), body + 1));
m_status->SetLabel(wxString::Format(_L("Body %d selected"), body + 1));
else if (level == 2)
m_status->SetLabel(wxString::Format(_L("Body %d, face %d — click again for an edge"), body + 1, face));
m_status->SetLabel(wxString::Format(_L("Body %d, face %d"), body + 1, face));
else
m_status->SetLabel(wxString::Format(_L("Body %d, edge %d selected"), body + 1, edge));
m_status->Refresh();
@@ -3240,9 +3240,9 @@ DesignPanel::DesignPanel(wxWindow* parent)
m_status->SetForegroundColour(wxNullColour);
const int nb = int(m_doc.bodies.size());
const wxString bodytag = (nb > 1) ? wxString::Format(_L("Body %d "), body + 1) : wxString();
m_status->SetLabel(level == 1 ? bodytag + _L("selected (whole) — click again for a face")
: level == 2 ? bodytag + wxString::Format(_L("face %d selected — Extrude to push/pull it, or click again for an edge"), face)
: level == 3 ? bodytag + wxString::Format(_L("edge %d selected — open Fillet/Chamfer to dress it, or click again to reset"), edge)
m_status->SetLabel(level == 1 ? bodytag + _L("selected (whole body)")
: level == 2 ? bodytag + wxString::Format(_L("face %d selected — Extrude to push/pull it"), face)
: level == 3 ? bodytag + wxString::Format(_L("edge %d selected — Fillet/Chamfer to dress it"), edge)
: _L("Nothing selected"));
m_status->Refresh();
});
@@ -5600,7 +5600,7 @@ bool DesignPanel::place_on_face()
if (b < 0 || b >= int(m_doc.bodies.size()) || m_sel_solid_face < 0
|| b >= int(m_doc.display_body_meshes.size())) {
m_status->SetForegroundColour(wxColour(235, 110, 110));
m_status->SetLabel(_L("Pick a body face first (click a solid, then click again to a face), then press F"));
m_status->SetLabel(_L("Click a face on the solid, then press F"));
m_status->Refresh();
return false;
}