Prefer edge snaps outside corner radius

This commit is contained in:
flash555588 2026-07-06 11:50:55 +08:00
parent 03fd845105
commit d20fffbba7
4 changed files with 262 additions and 225 deletions

View file

@ -5,7 +5,7 @@
- Stability: gate conversion-backed direct file views behind an explicit Load model action even when Obsidian restores them through `onLoadFile`, preventing STEP/STP workspace restore loops from freezing the vault.
- Stability: make the direct-view load gate settings-aware for preferred OBJ conversion and keep mobile direct-format reads on Obsidian vault APIs instead of desktop Node path helpers.
- UI: upgrade measurement calibration so users can scale the loaded model uniformly from the latest ruler distance, keep overlays anchored in model space, apply locked model-size scaling from one known axis, and verify the workflow through preview automation.
- UI: make distance measurement lock the selected object by default and snap endpoints to its mesh vertices or visible crease/perimeter triangle edges, filtering coplanar face diagonals, with first-click target selection when needed and Alt/Option-click preserving the older free surface pick as a backup.
- UI: make distance measurement lock the selected object by default and snap endpoints to mesh vertices or visible crease/perimeter triangle edges, filtering coplanar face diagonals and preferring edge projection outside the corner radius, with first-click target selection when needed and Alt/Option-click preserving the older free surface pick as a backup.
- UI: restyle distance measurements as orthographic drawing-style dimension callouts with extension lines, arrowheads, and compact drafting labels instead of thick freehand ruler lines.
- UI: remove the preview canvas native hover tooltip while preserving keyboard shortcut metadata for accessibility.
- UI: clarify render scale versus measurement scale by showing render resolution as percentages, syncing the toolbar to the active renderer budget, and applying the configured scale to `3dgrid`.

442
main.js

File diff suppressed because one or more lines are too long

View file

@ -139,6 +139,43 @@ describe("measurement helpers", () => {
expect(snapped?.point).toEqual({ x: 0, y: 0, z: 0 });
});
it("uses edge projection once the pointer is outside the corner radius", () => {
const snapped = snapMeasurementPointToGeometry(
{ x: -0.06, y: 0, z: 0 },
{
vertices: [
{ point: { x: 0, y: 0, z: 0 } },
{ point: { x: 1, y: 0, z: 0 } },
],
edges: [
{ start: { x: 0, y: 0, z: 0 }, end: { x: 1, y: 0, z: 0 } },
],
vertexRadius: 0.05,
},
);
expect(snapped?.kind).toBe("edge");
expect(snapped?.point).toEqual({ x: 0, y: 0, z: 0 });
});
it("rejects geometry snaps beyond the target snap distance", () => {
const snapped = snapMeasurementPointToGeometry(
{ x: 3, y: 3, z: 0 },
{
vertices: [
{ point: { x: 0, y: 0, z: 0 } },
],
edges: [
{ start: { x: 0, y: 0, z: 0 }, end: { x: 1, y: 0, z: 0 } },
],
vertexRadius: 0.05,
maxDistance: 0.5,
},
);
expect(snapped).toBeNull();
});
it("creates geometry snap edges from indexed and non-indexed triangles without face diagonals", () => {
const squareVertices = [
{ x: 0, y: 0, z: 0 },

View file

@ -192,10 +192,10 @@ export function snapMeasurementPointToGeometry(
});
}
const vertexRadius = input.vertexRadius ?? 0;
const candidate = nearestVertex && (nearestVertex.distance <= vertexRadius || !nearestEdge)
const vertexRadius = Math.max(input.vertexRadius ?? 0, 0);
const candidate = nearestVertex && nearestVertex.distance <= vertexRadius
? nearestVertex
: chooseNearestMeasurementSnapResult(nearestVertex, nearestEdge);
: nearestEdge ?? nearestVertex;
if (!candidate) {
return null;
}