From 7071366ce823bbfbc51eadd3dff30427d4778c06 Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Thu, 21 May 2026 13:45:39 +0000 Subject: [PATCH] Changes Co-authored-by: Reifonas <211114984+Reifonas@users.noreply.github.com> --- src/components/three/ModelViewer.tsx | 41 ++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/src/components/three/ModelViewer.tsx b/src/components/three/ModelViewer.tsx index 445c733..68c308b 100644 --- a/src/components/three/ModelViewer.tsx +++ b/src/components/three/ModelViewer.tsx @@ -362,6 +362,15 @@ function SmartSnapHandler() { return; } + const st = useModelStore.getState(); + + // Highest priority: a live hover label pointing at a hole → snap to its center + if (st.hoverInfo?.type === 'hole') { + const [hx, hy, hz] = st.hoverInfo.position; + setSnapPoint({ x: hx, y: hy, z: hz }); + return; + } + raycaster.setFromCamera(mouse, camera); const intersects = raycaster.intersectObjects(scene.children, true); const hit = intersects.find(i => { @@ -373,11 +382,39 @@ function SmartSnapHandler() { return obj instanceof THREE.Mesh; }); + const canvas = gl.domElement; + const canvasW = canvas.clientWidth; + const canvasH = canvas.clientHeight; + + // Cursor in screen px (mouse is in NDC [-1, 1]) + const cursorX = (mouse.x * 0.5 + 0.5) * canvasW; + const cursorY = (-mouse.y * 0.5 + 0.5) * canvasH; + + // Snap to centers of saved hole measurements within 20 px on screen + const holeSnapPxThreshold = 20; + let bestHoleDist = Infinity; + let bestHole: { x: number; y: number; z: number } | null = null; + const proj = new THREE.Vector3(); + for (const m of st.measurements) { + if (m.kind !== 'hole') continue; + proj.set(m.pointA.x, m.pointA.y, m.pointA.z).project(camera); + const sx = (proj.x * 0.5 + 0.5) * canvasW; + const sy = (-proj.y * 0.5 + 0.5) * canvasH; + const d = Math.hypot(sx - cursorX, sy - cursorY); + if (d < bestHoleDist && d <= holeSnapPxThreshold) { + bestHoleDist = d; + bestHole = { x: m.pointA.x, y: m.pointA.y, z: m.pointA.z }; + } + } + if (bestHole) { + setSnapPoint(bestHole); + return; + } + if (hit && hit.object instanceof THREE.Mesh) { - const canvas = gl.domElement; const snap = findNearestVertex( hit.object, hit.point, camera, - { width: canvas.clientWidth, height: canvas.clientHeight }, + { width: canvasW, height: canvasH }, 10 ); if (snap) {