feat: add production measurement tools#505
Conversation
- Smart measurement lens: registry-owned wall/slab/zone hover reports with a single top-center HUD, click-to-pin, latest-event back pressure, and no scene writes - Conservative derived zone quantities (footprint, perimeter, proven enclosure, gross wall/floor surface, flat-room volume) with the selected-zone blueprint panel - Direct editing of committed measurements via selected-only 2D/3D vertex affordances with midpoint insertion, cancellation, and one-write history - Shared measurement surface-query session; 2D tracing joins the slab/ceiling magnetic pipeline with registered-corner snapping - Angle arcs on the smaller angle, indigo active/black resting hierarchy, screen-sized normal-aligned contact rings Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Measurement drafting and committed-edit paths gated wall, semantic, and axis magnetism on isMagneticSnapActive(), which is only true in the 'lines' snapping mode — in the default 'grid' mode corners and wall intersections barely attracted (3D association fell to the 0.012 m verify tolerance, 2D wall radii to the 0.05 m connect stick). Measurement is an analysis tool whose anchors exist to bind real geometry, so its snapping no longer consults the construction snapping-mode chip: 2D/3D drafting and committed vertex edits are always magnetic, Alt is the temporary bypass in both views (releasing the axis pull, wall magnetism, and the 2D projected-geometry pull, and shrinking association to contact tolerance). A discrete 2D wall snap (endpoint / midpoint / crossing) now outranks the locked axis pull, and committed 2D edits route the fallback through the raw pointer so free drags no longer quantize to the construction grid. Volume extrusion height keeps its mode-driven grid quantize. Codex adversarial review confirmed the diagnosis and plumbing; its 2D Alt-depth and grid-quantize findings are applied. New surface-plan-snap tests pin the magnetic override seam. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
# Conflicts: # apps/editor/app/globals.css # packages/core/src/lib/space-detection.test.ts # packages/core/src/lib/space-detection.ts # packages/editor/src/components/editor-2d/renderers/floorplan-registry-layer.tsx # packages/editor/src/hooks/use-auto-save.ts # packages/editor/src/hooks/use-keyboard.ts # packages/editor/src/lib/plugin-panels.ts # packages/nodes/src/shared/polygon-vertex-affordance.ts # packages/nodes/src/slab/floorplan-affordances.ts # packages/plugin-trees/src/index.ts # packages/plugin-trees/src/instanced.tsx
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 3 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 64dc1e5. Configure here.
| snapshots.set( | ||
| levelId, | ||
| `${levelWallSnapshot(walls)}##${zones.map(zoneGeometrySignature).sort().join('||')}`, | ||
| ) |
There was a problem hiding this comment.
Zone edits rerun slab sync
Medium Severity
The levelStructureSnapshots now includes zone geometry, causing runSpaceDetection to trigger when only zone data changes. This leads to unnecessary re-reconciliation of auto slabs and ceilings, potentially recreating auto slabs a user had manually removed, a feedback loop the previous implementation aimed to prevent.
Reviewed by Cursor Bugbot for commit 64dc1e5. Configure here.
| zone.polygon, | ||
| polygon.map((point) => [point.x, point.y]), | ||
| ), | ||
| ) |
There was a problem hiding this comment.
Quantities ignore live zone polygon
Medium Severity
deriveZoneQuantityReport computes footprint, perimeter, and room matching from zone.polygon only. Procedural zones with autoFromWalls can have a stale stored polygon while resolveAutoZonePolygon already derives the live footprint from moved walls, so quantity reports can disagree with the scene.
Reviewed by Cursor Bugbot for commit 64dc1e5. Configure here.
| if (Array.isArray(anchor)) return anchor | ||
| const nodeId = idMap.get(anchor.reference.nodeId) | ||
| return nodeId ? { ...anchor, reference: { ...anchor.reference, nodeId } } : anchor | ||
| } |
There was a problem hiding this comment.
Clone keeps old anchor ids
Medium Severity
When remapping measurement feature anchors during clone, if idMap has no entry for a referenced host, the anchor keeps the original nodeId. The cloned measurement can keep pointing at nodes outside the clone (or the wrong instance in the target scene) instead of falling back to free anchors.
Reviewed by Cursor Bugbot for commit 64dc1e5. Configure here.


Summary
Verification
Note
High Risk
Large cross-cutting change to core schema, scene sync, clone graphs, and editor pointer handling; incorrect measurement or zone sync could corrupt saved scenes or misreport quantities.
Overview
Introduces a first-class
measurementscene node (distance, angle, area, perimeter, volume) with planar validation, optional semantic feature anchors that survive clone/paste via reference remapping, and geometry helpers exported from core.Extends the node registry with
measurementcontributions (features,match,quickMeasure) and richer floorplan labels;sceneRegistrynow exposes a revision counter when 3D object membership changes.Ships substantial 2D floorplan tooling: draft/commit flows with magnetic axis guides, registry-geometry snapping, vertex/midpoint editing, extrusion UI for volume, and a separate smart quick-measure HUD layer. Viewer Display menu gains a Measurements visibility toggle; dev react-scan / Agentation load only when
PASCAL_DEV_DIAGNOSTICS=1.Zones can
autoFromWallswithboundaryWallIds; space-detection sync plans polygon updates from detected rooms, andderiveZoneQuantityReportcomputes footprint vs enclosed-room quantities from matching walls/slabs/ceilings.Reviewed by Cursor Bugbot for commit 64dc1e5. Bugbot is set up for automated code reviews on this repo. Configure here.