# Polymodel

Polymodel (currently hosted intermittently at [polymodel.space](https://polymodel.space)) is an atproto-native 3D model sharing app: roughly “Thingiverse/Printables on atproto, but good.”

It's currently somewhere between "proof of concept" and "functional alpha". The core things work, including very basic social features, but there is a lot left to build and a lot of usability improvements needed and bugs to fix.

You can upload and share STL, STEP, OBJ, and 3MF files, as well as a couple of other incidental formats (GLTF, GLB), download them, preview them, add images, instructional text, tag them, and so on. You can follow other users, like or save their creations.

## Lexicons and data model

ALL lexicons currently in use should be expected to evolve in breaking ways in the near future, as I refine the desired semantics. They remain unpublished for this reason.

#### Core thing

A 'part' is a file with metadata; a name, dimensions, units, notes, format, preview images, attribution links, and so on. A 'model' is made up of multiple parts, and can represent a thing in itself, or something like a variant of something. A 'thing' is sort of the major project grouping, and includes more detailed text fields, instructions, multiple models, and so on. So for example, *Gridfinity* might be a 'thing', with all the different parts the maker designed as part of the system being 'parts', arranged into 'models'.

Currently 'thing' is the only real grouping exposed top-level, but this isn't the long-term intent. Loose 'parts' and 'models' and so on are intended to be surfacable, at least for the user that uploaded them.

#### Collaboration and Remixing

The current 'thing'-related types have a couple of reference fields, one for "derived from" relations, and the other for "indented to work with" relations. These are pretty preliminary and I'm still working out the semantics I want here. One goal of mine is to make it so that 'derived from' attribution in the interface is more or less automatic, even if the uploader didn't explcitly remix, likely via some form of perceptual hashing. I don't intend to include more than minimal in-browser editing.

Things like 'makes' or 'printer/slicer configs' and gcode are intended to be added as well. 'part' has a very preliminary take on print settings which *will* change, and the lexicons for "hey i made this `<link>`" straight up don't exist yet.

#### The rest

There are tags (currently exposed in the publish UI only, self-applied), intended to be user-supplied and/or community-applied. These are intended as curation and discoverability tools, not for moderation. Polymodel will have something more like moderation labels as well. Models and things have mandatory fields for license, so that copyright and use of original work is very clear. "All rights reserved" models or things will optionally be ineligible for remixing. The default is currently CC-BY-4.0.

There are lists (not currently exposed in the UI). There is the ability to save a model, bookmark it. Currently this is public, it will be made private. There are 'likes' and profiles with follows (currently using unidirectional follow semantics, this will likely evolve to an optional bidirectional request/accept pattern).

It has basic search and simple aggregated global and author feeds. 

> Larger text fields will in future support some subset of Weaver-style Markdown, once I port Weaver to Jacquard 0.12.X and fix some more bugs in its editor. I also intend to support other types of 3D content not intended for printing, including models for use in animation or video game production, or things like gaussian splats and point clouds.

## Architecture and Evolution

The current design is a monolithic Dioxus fullstck webapp+appview server, acting as an OAuth (potentially confidential) client. It backfills and tails the firehose via [hydrant](https://hydrant.klbr.net/) into its Fjall data store. That event stream is teed and written to an SQLite database for additional indexing, which is currently used as the primary read target and to support immediate readback of user writes. This is very likely to change, perhaps by sharding the SQLite database by DID and/or moving more into the Fjall store.

It also intends to support the draft spec for atproto permissioned data, for features such as drafts, private sharing, private lists, and so on. The core primitives will land upstream in Jacquard, and the concrete implementation will be a separate service binary from the main app server, ideally somewhat agnostic to the specifics of the app, acting as space host and permission broker.


## Development

Use Nix/direnv when available:

```sh
nix develop
# or
direnv allow
```

Common commands:

```sh
just fix       # format and apply safe clippy fixes
just check     # native, server, and wasm checks
just test      # unit tests via nextest
just test-all  # pre-review local validation
just serve     # Dioxus dev server
```

`just serve` starts against the current databases without seeding demo
content. For browser e2e or a local demo feed, opt in explicitly:
`POLYMODEL_SAMPLE_DATA=auto just serve`.

## Stack

- Dioxus 0.7
- Jacquard 0.12
- Hydrant for backfill (used as a library)
