rkaptur
September 28, 2026, 1:13am
1
Hi all,
Big shoutout to @CamilloMoschner and @rickwierenga for merging STAR’s 3D visualizer this weekend
main ← BioCam:visualizer3d
opened 04:31PM - 25 Sep 26 UTC
PyLabRobot could only draw a liquid handler's deck from above; nothing showed a … whole setup (devices, benches, what stands on them) in 3D.
- `Viewer3D(root)` serves any `Resource` tree to a browser in 3D and keeps it current from tracker state and `Resource.location`: volumes, tips, moving arms. Plain ES modules and vendored three.js, no build step, works offline. `python -m pylabrobot.visualizer3D.demo` shows a simulated STARlet beside a bench.
- `await viewer.wait_for_browser()` returns once a page says it is drawing, so a simulated run, over in milliseconds, starts in view. A page whose viewer stopped while it loaded says so.
- Each distinct model is sent once, and each instance as packed transforms.
- A resource is drawn from the `.glb` named after its `model`, else as a box. **59 model files (3.7 MB)** for STAR, Prep, Byonoy, Hamilton and Alpaqua parts ship as package data.
- Access: a per-run token, carried only in the printed link's `#token=` fragment. The websocket checks it and the `Origin`, and the file server checks the `Host`.
- **`websockets>=14`**. `make lint-js` and `make format-js` run Biome on the viewer's JavaScript and CSS, and `make lint-js` runs in the lint workflow.
- Builds on #1377: the viewer shows a rolled-back volume.
Tests: the scene split, the state channel, access, meshes, waiting for a browser, and the page in headless Chrome (WebGPU with a GPU, WebGL2 in software).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
<img width="1468" height="833" alt="Screenshot 2026-09-25 at 17 34 26" src="https://github.com/user-attachments/assets/2b52f351-0681-458d-96b0-27e9b7a59a6a" />
If you haven’t checked it out, I highly recommend it. This is something the community has long been waiting for.
I wanted to open a thread to start discussing features, fixes and general feelings about this excellent work.
While testing, the channel position did not update during CORE gripper movements. Did anyone else notice this issue? I submitted a PR just in case.
Also, wouldn’t it be great to have a playback feature? A way to step through the robot’s actions forward and backwards, adjust the playback speed, stop and resume, etc.
8 Likes
it’s all @CamilloMoschner ! I just had the pleasure of clicking merge on it
I just merged your PR, thanks for making it