[feat] 15-E selection & gizmo rework (+ weld-wireframe fix) - #94
Merged
Conversation
…frame gone User report: the edit wireframe overlay stayed unchanged after a weld. Weld (and create-face) still did a pre-D1 exit->enter dance to regroup handles, so the overlay rebuild depended on re-entry succeeding; any early-out left the old wireframe on screen. Since D1, applyMeshGeo refreshes a live vertex session in place (handles + overlay + selection) - weld and create-face now ride that same path, one refresh route shared with undo and remote commits. - also fixes a latent size-cap bug the trace surfaced: a too-large weld mutated the position attribute in place, then failed the commit WITHOUT reverting (and never set needsUpdate) - mesh, wire and peers silently diverged; the raw attribute is now restored on a failed commit - e2e: mesh-ops +2 (overlay fingerprint tracks the welded geometry; the session survives the weld with no exit/enter); regressions green (mesh-edit-popup, vertices-create-face, vr-face-weld, vr-face-edit, vr-mesh-undo, faces-toolbar); build green; 419/62 held Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… cap + selection-aware move, gizmo re-seat, face-basis local/world gizmo, per-axis face scale Roadmap 15-E (E10 -> E6 -> E7 -> E9 -> E8), the unifying rule: the selection IS the op target whenever non-empty; hover/highlight is the fallback. - E10: ctrl/shift-click ADDS to the face selection everywhere (desktop had no ctrl path at all); the Multi toolbar button is retired (the store + toggleFaceMulti stay - VR drives them); pickFaceUnit = plain click replaces the selection with the granularity-aware unit; stale-selection auto-heal in highlightFaceByTriangle (aiming outside the selection dissolves it; additive clicks skip the heal or it would wipe what they add to); live counts segment #mesh-sel-counts (N faces . M tris + the boundary-edge counts of exactly-2 faces, mismatch tinted red - bridge mismatches visible BEFORE clicking) - E6: inset/extrude/move KEEP the cap selected (indices survive: cloneTris keeps order, ring/walls append) + highlight re-derived - groupFaces re-merges a coplanar inset cap with its ring, so "inset then Move the cap" was impossible; the gizmo drag path reads the same selection-first target (the CL-B stash) - E7: the gizmo comes back seated on the new cap after an inset/extrude/ move commit; NEVER on arm (the B1 fix holds - mesh-ops B1 assertions stay green); Scene's tail only re-seats armed Move on non-commit clicks - E9: face-basis gizmo - Z = the face WORLD normal, X/Y deterministic tangents (least-aligned world axis seed); persisted faceGizmoSpace pref + [Local|World] toolbar segment; setSpace LEAK fixed (detach/exit restore 'world' - it used to stick to the shared TransformControls); rotation deltas conjugated through R = objQuat^-1 * proxyStartQuat (identity pre-E9, so the old path is a special case) - E8: per-axis face scale - applyFaceGrab takes scale: Vector3|number + scaleQuat, diagonal scale sandwiched in the proxy frame (R*S*R^-1); a number stays uniform so every VR caller is untouched - attachFaceGizmo never seats in VR (isVRMode guard - commitFaceOp now calls it, and VR commits ride the same code) - e2e: NEW mesh-inset-move (6); desktop-face-gizmo +7 (proxy Z = normal, space toggle + leak fix, tangential (2,1,1) scale w/ normal extent unchanged, rotate-about-normal coplanar, committed rotation watertight); faces-toolbar +5 (Multi gone, counts, equal/mismatch edge tints); regressions green: mesh-ops, mesh-edit-popup, novr-inset, vr-face-edit, vr-face-polygon, vr-face-live-adjust. Build green; svelte-check 419/62. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Roadmap #15 mesh lane, batch E (plan: cloud plans-core/pending/15-e-selection-gizmo.md). Second of D → E → F. Two commits:
Commit 1 — [fix] weld/create-face refresh the session in place (user report)
The edit wireframe stayed stale after a weld: weld/create-face still did a pre-D1 exit→enter dance, so the overlay rebuild depended on re-entry succeeding. They now ride
applyMeshGeo's D1 session refresher — ONE refresh path shared with undo and remote commits. Also fixes a latent size-cap bug: a too-large weld mutated the position attribute, then failed the commit without reverting (mesh/wire/peers silently diverged); the raw attribute is now restored.Commit 2 — [feat] 15-E (E10 → E6 → E7 → E9 → E8)
Unifying rule: the selection IS the op target whenever non-empty; hover/highlight is the fallback.
toggleFaceMultikept for VR); plain click =pickFaceUnit(granularity-aware replace); stale-selection auto-heal inhighlightFaceByTriangle(VR-per-frame safe; additive clicks skip it); live counts segment —N faces · M tris, plus boundary-edge counts when exactly 2 faces are selected (mismatch tinted red, so a bridge mismatch is visible before clicking).groupFaces, so "inset, then Move just the cap" was impossible. Move (commit or gizmo) is selection-aware; welded ring verts follow, the rest of the plane stays.#mesh-gizmo-space); setSpace leak fixed —'local'used to stick to the shared TransformControls after any face session; rotation deltas conjugated throughR = objQuat⁻¹·proxyStartQuat(rotate-about-normal keeps the cap coplanar).applyFaceGrabtakesscale: Vector3|number+scaleQuat(R·S·R⁻¹sandwich); numbers stay uniform so all VR callers are untouched.attachFaceGizmonever seats in VR (isVRModeguard — VR commits sharecommitFaceOpnow).Verification
mesh-inset-move6/6 (cap selected, gizmo re-seat, selection-aware move w/ outer plane fixed, gizmo grab parity)desktop-face-gizmo14/14 (+7: proxy Z = normal, live space toggle, exit restores world, (2,1,1) tangential scale with normal extent unchanged, 90°-about-normal coplanar, committed 25° rotation watertight)faces-toolbar11/11 (+5: Multi gone, counts, equal vs mismatched edge tints)mesh-ops(35, incl. the B1 inset-interception block),mesh-edit-popup(22),novr-inset,vr-face-edit,vr-face-polygon,vr-face-live-adjust, plus commit 1'svertices-create-face,vr-face-weld,vr-mesh-undonpm run buildgreen; svelte-check 419/62 (gate, unchanged)🤖 Generated with Claude Code