kovakmedya 9e78d506ae feat(jobs): in-browser STL / PLY / OBJ scan viewer
Clinics upload intraoral scans as raw STL/PLY/OBJ and labs need to see
what was captured before accepting the case. Built a tooth-level 3D
preview that runs entirely in the browser — no server-side rendering,
no extra service, just three.js + react-three-fiber driven off the
existing download proxy.

Component (src/components/stl-viewer.tsx)
  - Detects format from the filename (.stl / .ply / .obj).
  - fetch() → ArrayBuffer → STLLoader / PLYLoader / OBJLoader.parse.
  - OBJ comes back as a Group; merge the child meshes into a single
    BufferGeometry (positions concat) so all three formats render
    through the same mesh path.
  - Scene: dark background, ambient + two directional lights, a
    light-grey standard material, drei <Bounds> for auto-fit framing,
    OrbitControls with damping. A 'Sığdır' button in the corner re-fits
    the camera by remounting Bounds.
  - Cleanup: geometry.dispose() on unmount, fetch cancellation guard,
    inline error/loading states.

Wiring (job-files-panel.tsx)
  - VIEWABLE_RE = /\.(stl|ply|obj)$/i. Only those rows get the new
    eye-icon button.
  - STLViewer is loaded via next/dynamic with ssr:false so three.js
    (~500KB minified) only enters the bundle when the dialog actually
    opens. Mounting is also gated on viewerOpen, so closing the dialog
    frees the WebGL context.
  - Dialog is a tall (85vh) wide (max-w-5xl) shell with the filename
    + size in the header and the canvas filling the rest.

Deps added: three, @react-three/fiber, @react-three/drei (+ types).
2026-05-22 01:51:05 +03:00
S
Description
No description provided
5.8 MiB
Languages
TypeScript 99.2%
CSS 0.7%