Brickheart

LFrame WebGL Rendering

: Written by a human with AI assistance.

Goal

A web-based LEGO model viewer built on the open-source brick-viewer component. It will be combined with a parts database, a searchable model gallery, user uploads, and an installable offline editor.

Current state

  • Hosting: the fork (thekitchenscientist/LFrame) is deployed as static assets from the docs/ folder, with the custom domain attached.
  • Viewer: the component is a Lit and three.js wrapper that takes an .mpd URL. It reads self-contained MPDs and has no parts library. Camera controls (three.js OrbitControls) are private, so customising them means editing the fork's source and rebuilding the bundle.

Planned architecture

Browser (HTML/JS, installable PWA)
  ├─ <brick-viewer>  ← models, flattened MPDs
  └─ /api/*  →  Worker  →  D1 (parts data) + R2 (models, LDraw library)
  • R2 holds the roughly 5,000 small model files and the stripped LDraw library, outside Git.
  • D1 (SQLite-compatible) holds the trimmed Rebrickable data.

Data

  • The Rebrickable database is being trimmed to small sets (the viewer struggles past a couple of hundred parts) with no minifigures.
  • Clean up orphaned rows, vacuum, index, then load in chunks.

LDraw parts library

  • Why it's needed: thin .ldr files reference parts the viewer can't find. A flatten step collects every referenced file and writes a self-contained MPD.
  • Stripping: build a seed list from your kept sets, exclude prints, minifigures, flexible and rare parts, then compute the dependency closure so sub-parts and primitives aren't orphaned. Delete the textures, and map the 8/ and 48/ primitive variants down.
  • Aliasing: replace unwanted parts with tiny stub files that reference a simpler part (mould variants to the canonical part, prints to plain, etc). Real part IDs are preserved in user files.
  • Size: current library is about 550 MB across 24k files, aiming for under 10k files. The 308 largest files total 85 MB. The metric that matters is the compressed pack size. Reduce it by minifying, dropping edge lines if the look allows, removing duplicates, and packing into a few gzipped files.

Uploads and offline editor

  • Uploads: .ldr files load locally in the browser (file input to Blob URL), so the server isn't involved. The upload should go through the flatten step to resolve parts. .pbg (LCAD parts bin) files need converting to .ldr first.
  • Offline PWA: a manifest plus service worker for caching, IndexedDB for saved models, and file download or open as a backup. The flatten logic moves into the browser, with parts fetched and cached as they're used.
  • Live MPD editor: a textarea feeds the viewer through Blob URLs. Saving is not built yet.

Licensing

The LDraw library is under CC BY 2.0/4.0. The working plan is:

  • Keep Name, Author and !LICENSE lines in every file, so they carry through into flattened MPDs.
  • Exclude any part marked "Not redistributable".
  • Mark modified files (aliases, minified or simplified geometry).
  • Add a credits page naming LDraw.org, the licence and what you changed, and keep the LDraw and LEGO trademark notices.

Unverified assumptions to test

  • The viewer reloads when src changes (the fallback is to recreate the element).
  • The loader accepts Blob URLs without a file extension and finds embedded sub-files by the names written.
  • Aliased parts line up in position and size with their substitutes.

Suggested order

  1. Finish trimming and cleaning the Rebrickable DB and test loading a few models.
  2. Run the size report on the parts library, cut the largest files, and build the closure and alias pipeline.
  3. Add R2 and the model-serving Worker, then bulk-upload the models.
  4. Build the gallery page and the first D1-backed endpoint.
  5. Add upload plus flatten, then the editor and PWA, and port the Streamlit features one at a time.
  6. Add the credits page.