Skip to content

Commit 5e4e694

Browse files
committed
fix: stl export normalization
1 parent a724c36 commit 5e4e694

1 file changed

Lines changed: 21 additions & 2 deletions

File tree

src/lib/3d/stl.ts

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,29 @@ import { writeFloatLE, writeInt16LE, writeInt32LE } from '$lib/buffer';
22

33
const SOLID_NAME = 'THT-holder';
44

5+
const computeFaceNormal = (v: Float32Array, i: number): [number, number, number] => {
6+
const [x0, y0, z0, x1, y1, z1, x2, y2, z2] = [
7+
v[i]!, v[i + 1]!, v[i + 2]!,
8+
v[i + 3]!, v[i + 4]!, v[i + 5]!,
9+
v[i + 6]!, v[i + 7]!, v[i + 8]!,
10+
];
11+
const ex = x1 - x0, ey = y1 - y0, ez = z1 - z0;
12+
const fx = x2 - x0, fy = y2 - y0, fz = z2 - z0;
13+
const nx = ey * fz - ez * fy;
14+
const ny = ez * fx - ex * fz;
15+
const nz = ex * fy - ey * fx;
16+
const len = Math.sqrt(nx * nx + ny * ny + nz * nz);
17+
return len > 0 ? [nx / len, ny / len, nz / len] : [0, 0, 0];
18+
};
19+
520
export const generateStlFromVertices = (vertices: Float32Array): string[] => {
621
const lines: string[] = [`solid ${SOLID_NAME}`];
722

823
if (vertices.length % 9 === 0) {
924
let index = 0;
1025
while (index < vertices.length) {
11-
lines.push('facet normal 0 0 0', ' outer loop');
26+
const [nx, ny, nz] = computeFaceNormal(vertices, index);
27+
lines.push(`facet normal ${nx} ${ny} ${nz}`, ' outer loop');
1228
for (let pointIndex = 0; pointIndex < 3; pointIndex++)
1329
lines.push(` vertex ${vertices[index++]} ${vertices[index++]} ${vertices[index++]}`);
1430
lines.push(' endloop', 'endfacet');
@@ -28,7 +44,10 @@ export const generateBinaryStlFromVertices = (vertices: Float32Array): Uint8Arra
2844
if (vertices.length % 9 === 0) {
2945
let index = 0;
3046
while (index < vertices.length) {
31-
for (let pointIndex = 0; pointIndex < 3; pointIndex++) pos = writeFloatLE(buffer, 0, pos);
47+
const [nx, ny, nz] = computeFaceNormal(vertices, index);
48+
pos = writeFloatLE(buffer, nx, pos);
49+
pos = writeFloatLE(buffer, ny, pos);
50+
pos = writeFloatLE(buffer, nz, pos);
3251
for (let pointIndex = 0; pointIndex < 9; pointIndex++)
3352
pos = writeFloatLE(buffer, vertices[index++]!, pos);
3453
pos = writeInt16LE(buffer, 0, pos);

0 commit comments

Comments
 (0)