The viewer scaffold is live at /viewer. Drop a .step file on it
and it renders. Nothing gets uploaded — the entire parse happens in your
browser tab.
The pipeline
file drop → ArrayBuffer → web worker → OCCT (WASM) → triangle soup → Three.js
Three pieces, each deliberately boring:
Parsing:
occt-import-js— OpenCascade compiled to WASM. We hand it the file as aUint8Array, it hands back tessellated meshes: positions, normals, indices per body. The tessellation tolerances are the interesting knob —linearDeflectioncontrols how far the triangle soup can deviate from the real surface. We're using a bounding-box-ratio deflection so small parts don't get over-tessellated. We'll write a whole post on this once we have screenshots worth looking at.The worker: parsing a 50 MB STEP file freezes the main thread for seconds. The OCCT call lives in a web worker from day one — results come back as transferred
Float32Array/Uint32Arraybuffers, so there's no structured-clone copying cost either:
for (const mesh of result.meshes) {
const position = new Float32Array(mesh.attributes.position.array);
const index = new Uint32Array(mesh.index.array);
meshes.push({ name: mesh.name, position, index, faces: mesh.brep_faces });
transfer.push(position.buffer, index.buffer);
}
self.postMessage({ ok: true, meshes }, transfer);
- Rendering: plain
WebGLRenderer+OrbitControlsfor now. Yes, we said WebGPU last week — still the plan, but "load a file and see it spin" was the milestone worth shipping first. WebGL2 covers it today.
What's deliberately missing
Face picking, exploded view, section cuts, measurements, progressive tessellation. All post-v1. Right now it does exactly one thing: prove the parse-to-pixels path works on real files.
If you have a STEP file lying around, try it — if it fails to render your file, that's exactly the kind of bug report we want (Contact link, bottom right).