Binary STL
32-bit in partWrites each triangle's unit normal and three corners.
normal = n ÷ |n| from the winding; every number written with setFloat32
Normals and corners are converted to 32-bit as they are written, at their absolute coordinates. A 32-bit number between 128 and 256 has a spacing of about 1.5 × 10⁻⁵, so a coordinate of that size in millimeters is written to the nearest 15 nm or so. A triangle without area gets the normal [0, 0, 0] (its length is replaced by 1).
export function stlBinary(mesh, header = 'binary STL, millimeters') {
const P = mesh.positions, I = mesh.indices, nt = I.length / 3;
const out = new Uint8Array(84 + nt * 50), dv = new DataView(out.buffer);
const h = String(header).slice(0, 79);
for (let i = 0; i < h.length; i++) out[i] = h.charCodeAt(i) & 0x7f;
dv.setUint32(80, nt, true);
let o = 84;
for (let t = 0; t < nt; t++) {
const a = I[t * 3], b = I[t * 3 + 1], c = I[t * 3 + 2];
const n = triNormal(P, a, b, c), l = Math.hypot(n[0], n[1], n[2]) || 1;
for (const v of [n[0] / l, n[1] / l, n[2] / l]) { dv.setFloat32(o, v, true); o += 4; }
for (const v of [a, b, c]) for (let k = 0; k < 3; k++) { dv.setFloat32(o, P[v * 3 + k], true); o += 4; }
o += 2;
}
return out;
}