fix(overlay): Photos-ready dims follow tape, not wood MAR
After rotateCalibration, map tape tick A→B through bakeTiltTransform into baked cal coords, orient overlay bbox with orientedRect(..., tapeAngle), and pass optional axis into buildOverlayPlan so length || tape and widths ⊥ tape.
This commit is contained in:
@@ -10,7 +10,7 @@ import { measure } from '../measure/measure';
|
||||
import { orientedRect } from '../geometry/rect';
|
||||
import { encodeInventoryPng, type InventoryInput } from '../png/inventory';
|
||||
import { encodeOverlayPng, type EncodeOverlayInput } from '../png/overlay';
|
||||
import { rotateCalibration } from '../png/rotateCal';
|
||||
import { bakeTiltTransform, rotateCalibration } from '../png/rotateCal';
|
||||
import { decodeOrientedBitmap } from '../decodeOrientedBitmap';
|
||||
import { clampTiltDeg, defaultTape, tapeEndpoints, type TapeTransform } from './tapeGeometry';
|
||||
import { getCropFill } from '../settings/cropFill';
|
||||
@@ -636,19 +636,37 @@ export function createCaptureSession(opts: SessionOpts = {}): CaptureSession {
|
||||
// #63: second copy of the calibration inventory PNG with dimension overlays.
|
||||
// Keep clean inventoryPng untouched; never stash overlay into batchApply[cal].
|
||||
// Overlay uses the same baked orientation as the clean cal PNG (#99 scope).
|
||||
// Length / width directions follow the tape (not wood MAR): map tick A→B
|
||||
// through the same bake as rotateCal, then orient the overlay bbox to that.
|
||||
let overlayBlob: Blob;
|
||||
try {
|
||||
const preEp = axis.tape.spanPx > 0
|
||||
? tapeEndpoints(axis.tape, source.widthPx, source.heightPx)
|
||||
: null;
|
||||
const bakeXform = bakeTiltTransform(source.widthPx, source.heightPx, axis.tape.tiltDeg);
|
||||
let overlayBbox = calMask.bbox;
|
||||
let overlayAxis: { start: [number, number]; end: [number, number] } | undefined;
|
||||
if (preEp && preEp.spanPx > 0) {
|
||||
const start = bakeXform.mapPoint(preEp.start[0], preEp.start[1]);
|
||||
const end = bakeXform.mapPoint(preEp.end[0], preEp.end[1]);
|
||||
const dx = end[0] - start[0];
|
||||
const dy = end[1] - start[1];
|
||||
const angleDeg = ((Math.atan2(dy, dx) * 180) / Math.PI + 180) % 180;
|
||||
overlayBbox = orientedRect(calMask.bbox, angleDeg);
|
||||
overlayAxis = { start, end };
|
||||
}
|
||||
overlayBlob = await encodeOverlay({
|
||||
inventoryPng: pngBlob,
|
||||
bitset: calMask.bitset,
|
||||
widthPx: calSource.widthPx,
|
||||
heightPx: calSource.heightPx,
|
||||
bbox: calMask.bbox,
|
||||
bbox: overlayBbox,
|
||||
scale: base.scale,
|
||||
lengthIn: eighthsToIn(lengthEighths),
|
||||
lengthLabel: fmtEighths(lengthEighths),
|
||||
slabBounds: calMask.slabBounds,
|
||||
source: calSource,
|
||||
axis: overlayAxis,
|
||||
});
|
||||
} catch {
|
||||
// Deterministic tests may inject a non-decodable inventory blob; still
|
||||
|
||||
Reference in New Issue
Block a user