dimaforcepush

PROJECT

Unflat

You can't rotate a screenshot of a 3D model. So Unflat it.

WHAT IT IS
A static, read-only 3D review surface for fixed revisions of print models.
WHAT IT IS NOT
Not CAD, not a slicer, not a check that a print will fit.
STATUS
Running privately for my own models. Polish is ongoing; no public release yet.
01

Always just out of frame

I was working through iterations of a 3D-printed iPhone charging stand with Hermes. Each revision came back to me in chat: a description of what changed, maybe an image, another description when I asked about the other side. The part I needed to inspect was always just out of frame. Is that wall thick enough? Where does the cable go? What does the tray look like underneath?

I could keep asking the agent to take more screenshots. Or I could give us both a better place to look.

THE LOOP · ILLUSTRATIVE DRAWING, NOT A CAPTURE From a picture of the model to the model itself.
  1. 01 · WHAT I GOT A screenshot

    One angle, chosen for me. The part I need is always just out of frame.

  2. 02 · WHAT I NEEDED The actual model

    Orbit it, pinch it, hide a part, pull the assembly apart, clip it to look inside.

  3. 03 · WHAT HERMES SENDS One fixed version

    A link to that exact revision. Old ones stay put; the hash is an integrity check, not a key.

  4. 04 · WHAT I SEND BACK Feedback on the shape

    I point at the object we both see, not at a paragraph we both imagine.

then the next revision, with its own fixed link — and around again

02

The missing object

A printable model is not a paragraph, and one render is not the model. I wanted to orbit it on my laptop, pinch and turn it on my phone, hide a part, pull an assembly apart, and open a specific revision again tomorrow. Most importantly, when Hermes changed the design, I wanted a link to that exact version in the conversation — not another round of “can you show it from the other side?”

Three.js was the useful piece of the puzzle: it renders the geometry in a browser, where I can actually move around it. Unflat grew around it. A small publisher takes STL parts and their placement metadata, turns them into browser-friendly GLB files, and exports a read-only gallery and viewer. That private review surface is a static site; it does not need an application server to show a model.

  1. 01Hermesmakes a revision
  2. 02Publisherexports it as an immutable version
  3. 03Hermessends me that version’s URL
  4. 04Meinspect it on desktop or mobile
  5. 05Megive feedback on the actual shape

The URL identifies a project and version; a content-hash prefix lets the viewer warn me if the content behind a link does not match what I was sent. Old revisions remain available for comparison rather than silently changing under the same name. The viewer lets me orbit, pan and zoom, select exact views with an orientation cube, show and hide parts, spread an assembly apart, and visually clip it along an axis to see inside.

03

Sharing one version, not the whole workshop

The private gallery is behind Basic Auth. Giving someone that login would let them browse the entire catalog, which is a terrible way to say “can you look at this revision?” So Unflat now has a separate share action: it makes a short link to one fixed version, without a gallery or access to future iterations. I can set its lifetime (30 days by default) and revoke it. Hermes can create a link through a CLI, and a person can use Share… in the private viewer. The recipient doesn’t need my Basic Auth login.

WHAT A LINK REACHES · SCHEMATIC, NOT A CAPTURE One version, for a while — not the whole workshop.

A SHARE LINKShare… or the CLI

  1. rev n-1 not reachable
  2. rev n this one, fixed
  3. rev n+1 not reachable
LIFETIME · 30 DAYS BY DEFAULT, MY CHOICE · REVOKE ANY TIME

No gallery, no future iterations, and the recipient doesn't need my login.

THE HASH
On an ordinary version URL it is an integrity check, not an access key.
THE GEOMETRY
Whoever can open an interactive model can get it. A link limits which model, not what they can do with it.

That share link isn’t a magic DRM spell.

Removing a download button does not change that. I only share models I’m comfortable handing over as files. And the content hash on an ordinary version URL is an integrity check, not an access key. The private static viewer and the narrow sharing gate are intentionally separate jobs.

04

Why it isn't “a Hermes feature”

I built it while working with Hermes, but Unflat does not require Hermes to render anything. The static exporter takes files and metadata; any agent, script, or human that can run the publisher can make a version and send its link. Hermes is my current collaborator, not a dependency baked into the viewing surface. Harness-agnostic by design.

WHO PUBLISHES, WHO GETS IN · SCHEMATIC The harness is replaceable. The protection is not optional.
  1. 01 · ANYONE WHO CAN RUN IT
    • Hermes today's collaborator
    • another agent
    • a script
    • a human
  2. 02 · THE PUBLISHER Files + metadata → a static version

    No Hermes in the viewing surface. No user database, no mandatory login provider.

  3. 03 · TWO SEPARATE DOORS
    Private viewer & gallery

    MY DEPLOYMENT HTTPS + Basic Auth at the edge

    Share route

    ITS OWN GATE version-scoped, separate from the login

ANY INSTALLATION picks its own hosting and auth — as long as all private HTML, metadata, model files and downloads stay protected.

The viewer also has no built-in user database or mandatory login provider. My private deployment uses HTTPS + Basic Auth at the edge; the sharing route uses a separate, version-scoped access gate. Another installation can choose its own hosting and authentication policy, as long as all private HTML, metadata, model files and downloads remain protected. Auth-agnostic does not mean unprotected.

05

What changed in practice

The first useful test was a real multi-part charging-stand revision, not a demo cube. Instead of arguing over which side a render showed, I could isolate the holder and tray, look at assembled and exploded positions, and give feedback against a fixed version. When I actually need to print, the selected version offers an STL download for each part. The model became the shared reference; the chat became the place to decide what to change next.

The UI took its own iterations. A technically working viewer can still be bad at showing the object: too much version metadata on desktop, controls that eat the mobile screen, or a view cube that only looks interactive. The model now gets the canvas. Controls stay in one movable window on desktop and a compact bottom panel on mobile. Browser and emulator checks cover desktop and touch layouts; a real iPhone’s in-app browser still needs its own final check. That distinction matters more than a big green test count.

This is not a CAD editor, a slicer, or an autonomous design validator. It will not tell me whether a print fits. It does something narrower and more useful for this loop: