🚀 Auto-deploy: melhoria no snap e medição AR em 22/05/2026 20:56:13

This commit is contained in:
2026-05-22 20:56:13 +00:00
parent d8ca2b2e6c
commit 8610ec67f7
2 changed files with 45 additions and 17 deletions
+41 -13
View File
@@ -252,8 +252,16 @@ export function findNearestEdgeSegment(
} }
}); });
// If no edge lines, generate from EdgesGeometry // If no edge lines, fetch from cache or generate and store in cache
const geo = edgeLines?.geometry ?? new THREE.EdgesGeometry(mesh.geometry, 15); let geo: THREE.BufferGeometry;
if (edgeLines) {
geo = edgeLines.geometry;
} else {
if (!mesh.userData.__cachedEdgesGeometry) {
mesh.userData.__cachedEdgesGeometry = new THREE.EdgesGeometry(mesh.geometry, 15);
}
geo = mesh.userData.__cachedEdgesGeometry;
}
const posAttr = geo.attributes.position; const posAttr = geo.attributes.position;
if (!posAttr) return null; if (!posAttr) return null;
@@ -298,8 +306,6 @@ export function findNearestEdgeSegment(
} }
} }
if (!edgeLines) geo.dispose();
if (bestDist <= thresholdPx && bestMid && bestA && bestB && bestLen > 0.5) { if (bestDist <= thresholdPx && bestMid && bestA && bestB && bestLen > 0.5) {
return { midpoint: bestMid, lengthMM: bestLen, a: bestA, b: bestB }; return { midpoint: bestMid, lengthMM: bestLen, a: bestA, b: bestB };
} }
@@ -321,7 +327,16 @@ export function detectCircularEdgeAtPoint(
mesh.children.forEach(c => { mesh.children.forEach(c => {
if (c.userData.__edgeLine && c instanceof THREE.LineSegments) edgeLines = c; if (c.userData.__edgeLine && c instanceof THREE.LineSegments) edgeLines = c;
}); });
const geo = edgeLines?.geometry ?? new THREE.EdgesGeometry(mesh.geometry, 15);
let geo: THREE.BufferGeometry;
if (edgeLines) {
geo = edgeLines.geometry;
} else {
if (!mesh.userData.__cachedEdgesGeometry) {
mesh.userData.__cachedEdgesGeometry = new THREE.EdgesGeometry(mesh.geometry, 15);
}
geo = mesh.userData.__cachedEdgesGeometry;
}
const posAttr = geo.attributes.position; const posAttr = geo.attributes.position;
if (!posAttr) return null; if (!posAttr) return null;
@@ -347,7 +362,6 @@ export function detectCircularEdgeAtPoint(
seen.add(key); seen.add(key);
verts.push(tmp.clone()); verts.push(tmp.clone());
} }
if (!edgeLines) geo.dispose();
if (verts.length < 6) return null; if (verts.length < 6) return null;
@@ -497,7 +511,15 @@ export function findNearestEdgeSegment3D(
} }
}); });
const geo = edgeLines?.geometry ?? new THREE.EdgesGeometry(mesh.geometry, 15); let geo: THREE.BufferGeometry;
if (edgeLines) {
geo = edgeLines.geometry;
} else {
if (!mesh.userData.__cachedEdgesGeometry) {
mesh.userData.__cachedEdgesGeometry = new THREE.EdgesGeometry(mesh.geometry, 15);
}
geo = mesh.userData.__cachedEdgesGeometry;
}
const posAttr = geo.attributes.position; const posAttr = geo.attributes.position;
if (!posAttr) return null; if (!posAttr) return null;
@@ -525,8 +547,6 @@ export function findNearestEdgeSegment3D(
} }
} }
if (!edgeLines) geo.dispose();
if (bestIndex !== -1 && bestDistSq <= thresholdSq) { if (bestIndex !== -1 && bestDistSq <= thresholdSq) {
const a = new THREE.Vector3().fromBufferAttribute(posAttr, bestIndex * 2).applyMatrix4(matrix); const a = new THREE.Vector3().fromBufferAttribute(posAttr, bestIndex * 2).applyMatrix4(matrix);
const b = new THREE.Vector3().fromBufferAttribute(posAttr, bestIndex * 2 + 1).applyMatrix4(matrix); const b = new THREE.Vector3().fromBufferAttribute(posAttr, bestIndex * 2 + 1).applyMatrix4(matrix);
@@ -546,7 +566,16 @@ export function detectCircularEdgeAtPoint3D(
mesh.children.forEach(c => { mesh.children.forEach(c => {
if (c.userData.__edgeLine && c instanceof THREE.LineSegments) edgeLines = c; if (c.userData.__edgeLine && c instanceof THREE.LineSegments) edgeLines = c;
}); });
const geo = edgeLines?.geometry ?? new THREE.EdgesGeometry(mesh.geometry, 15);
let geo: THREE.BufferGeometry;
if (edgeLines) {
geo = edgeLines.geometry;
} else {
if (!mesh.userData.__cachedEdgesGeometry) {
mesh.userData.__cachedEdgesGeometry = new THREE.EdgesGeometry(mesh.geometry, 15);
}
geo = mesh.userData.__cachedEdgesGeometry;
}
const posAttr = geo.attributes.position; const posAttr = geo.attributes.position;
if (!posAttr) return null; if (!posAttr) return null;
@@ -573,7 +602,6 @@ export function detectCircularEdgeAtPoint3D(
seen.add(key); seen.add(key);
verts.push(tmp.clone().applyMatrix4(matrix)); verts.push(tmp.clone().applyMatrix4(matrix));
} }
if (!edgeLines) geo.dispose();
if (verts.length < 6) return null; if (verts.length < 6) return null;
@@ -618,8 +646,8 @@ export function detectCircularEdgeAtPoint3D(
export function resolveSnap3D( export function resolveSnap3D(
mesh: THREE.Mesh, mesh: THREE.Mesh,
hitPoint: THREE.Vector3, hitPoint: THREE.Vector3,
vertexThresholdMeters: number = 0.035, vertexThresholdMeters: number = 0.07,
edgeThresholdMeters: number = 0.05 edgeThresholdMeters: number = 0.09
): { point: THREE.Vector3; type: 'vertex' | 'edge' | 'surface' } { ): { point: THREE.Vector3; type: 'vertex' | 'edge' | 'surface' } {
const v = findNearestVertex3D(mesh, hitPoint, vertexThresholdMeters); const v = findNearestVertex3D(mesh, hitPoint, vertexThresholdMeters);
if (v) return { point: v, type: 'vertex' }; if (v) return { point: v, type: 'vertex' };
+4 -4
View File
@@ -162,12 +162,12 @@ export function XRControllerMeasure() {
snapKind = 'hole'; snapKind = 'hole';
hoverDetected = { kind: 'hole', value: circle.diameterMM, position: circle.center }; hoverDetected = { kind: 'hole', value: circle.diameterMM, position: circle.center };
} else { } else {
// Snap 3D físico puro (3.5cm para vértices, 5cm para arestas) // Snap 3D físico puro (7cm para vértices, 9cm para arestas)
const snap = resolveSnap3D(hit.object, hit.point, 0.035, 0.05); const snap = resolveSnap3D(hit.object, hit.point, 0.07, 0.09);
snappedPoint = snap.point; snappedPoint = snap.point;
snapKind = snap.type; snapKind = snap.type;
if (snap.type === 'edge') { if (snap.type === 'edge') {
const seg = findNearestEdgeSegment3D(hit.object, hit.point, 0.05); const seg = findNearestEdgeSegment3D(hit.object, hit.point, 0.09);
if (seg) { if (seg) {
const lenMM = seg.a.distanceTo(seg.b) * 1000; const lenMM = seg.a.distanceTo(seg.b) * 1000;
hoverDetected = { kind: 'edge', value: lenMM, position: seg.midpoint, endpoints: { a: seg.a, b: seg.b } }; hoverDetected = { kind: 'edge', value: lenMM, position: seg.midpoint, endpoints: { a: seg.a, b: seg.b } };
@@ -259,7 +259,7 @@ export function XRControllerMeasure() {
const triggerHits = raycaster.current.intersectObjects(scene.children, true); const triggerHits = raycaster.current.intersectObjects(scene.children, true);
const triggerHit = triggerHits.find((h) => { const triggerHit = triggerHits.find((h) => {
const o = h.object; const o = h.object;
if (!(o instanceof THREE.Mesh)) return false; if (!isPickableModelMesh(o)) return false;
if (o.userData.__edgeLine) return false; if (o.userData.__edgeLine) return false;
if (o.geometry instanceof THREE.SphereGeometry) return false; if (o.geometry instanceof THREE.SphereGeometry) return false;
if (o.geometry instanceof THREE.RingGeometry) return false; if (o.geometry instanceof THREE.RingGeometry) return false;