fabriks
A level-of-detail (LOD) wire format for 3D meshes. fabriks partitions surface collections into an octree of Parquet files, allowing viewers to fetch only the required spatial detail per frame without running a dedicated server.
It is strictly a serializer: zero network dependencies, client code, or storage opinions. Hand it an abstract store, and it writes the same layout to disk, S3, GCS, or memory.
Key Properties
- Octree Partitioning: Level 0 is full detail. Each coarser level combines 8 finer cells into 1 cell with a quarter of the face count.
- Dual Catalogs:
catalog/cells.parquet(spatial index read once at mount) andcatalog/objects.parquet(inverted index mapping object IDs to cell keys). - Seamless Boundaries: Vertices on cell faces stay pinned during decimation—fine cells meet coarse neighbors without visual cracks.
- Range-Query Optimized: Cells map to individual Parquet row groups sorted in Morton order for efficient byte-span fetches.
Layout & Partitioning
my-collection/
fabriks.json <- Root manifest (written last; atomic completion signal & checksums)
catalog/cells.parquet <- Spatial index (maps level & cell_key to row group byte locators)
catalog/objects.parquet <- Identity index (maps object IDs to cell keys for isolation/extraction)
level=0/part-00000.parquet <- Level 0 full-detail geometry
level=1/part-00000.parquet <- Decimated coarse-level geometry (L=1, L=2, ...)
- Spatial Octree: Space is partitioned into uniform 3D cells (
cell_size). Each parent cell at levelL >= 1merges 8 child cells (2×2×2) from levelL - 1. - Seam Locking: Vertices on cell boundary planes stay pinned during decimation so fine and coarse cells tile seamlessly without visual gaps.
- Morton Ordering: Geometry row groups are sorted along a Z-order curve (Morton space) for spatially compact, range-query-friendly byte fetches.
Install
pip install fabriks # Core writer/reader (trimesh, fast-simplification, scipy, shapely)
pip install 'fabriks[obstore]' # + S3 / GCS / Azure support via obstore
pip install 'fabriks[meshopt]' # + MESHOPT blob decoding
Sizing & Writing
import trimesh
from obstore.store import LocalStore
import fabriks
objects = {
7: trimesh.creation.icosphere(radius=18.0).apply_translation([200, 160, 60]),
3: trimesh.creation.box(extents=[40, 24, 16]).apply_translation([90, 70, 40]),
}
# Derive grid dimensions from byte targets (optional)
grid_plan = fabriks.plan_grid(objects, cell_bytes=16 * 1024, layer_bytes=128 * 1024)
# Write meshes directly to a store
manifest = fabriks.write_meshes(
objects,
store=LocalStore("/data"),
prefix="my-collection",
**grid_plan.as_kwargs(),
)
Reading & Planning
import fabriks
from obstore.store import LocalStore
collection = fabriks.open_collection(LocalStore("/data"), "my-collection")
# Camera or voxel error budget planning
camera = fabriks.Camera.perspective((0, 0, 500), fov_y=0.8, viewport_height=1080)
plan = collection.plan(camera=camera, pixel_budget=1.0)
# Synchronous batch fetch
for cell in collection.read_cells([(e.level, e.cell) for e in plan]):
draw(cell.vertices, cell.faces)
# Reassemble single object across cells
mesh = collection.object_mesh(7)
collection.release()
Async Reading
collection = await fabriks.aopen_collection(S3Store(...), "my-collection")
plan = collection.plan(camera=camera)
cells = await collection.aread_cells([(e.level, e.cell) for e in plan], concurrency=16)
Configuration
| Protocol | Options | Notes |
|---|---|---|
| Stores | LocalStore, S3Store, DirectoryStore, MemoryStore |
Implements put, get, list, and optional get_range. |
| Simplifiers | "QUADRIC" (default), "GREEDY" |
QUADRIC uses fast-simplification with preserve_border=True. Custom simplifiers implement fabriks.Simplifier. |
| Codecs | codec: NONE, MESHOPT |
compression: NONE, ZSTD | Default is NONE/NONE (raw little-endian arrays for zero-copy GPU upload). |
Verification
report = fabriks.verify(collection, tier="geometry") # "structure" | "blobs" | "geometry"
if not report:
print(report)
Coordinates & Conventions
fabriks addresses dimensions strictly by array slot (0, 1, 2). Inputs from (z, y, x) volumes pass directly via cell_size=(z_size, y_size, x_size) without transposition. Axis labels in column names are slot identifiers, not physical coordinate claims.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file fabriks-1.1.0.tar.gz.
File metadata
- Download URL: fabriks-1.1.0.tar.gz
- Upload date:
- Size: 91.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9879d7bfe2ef9fe860d6a783e089414272a5d1d7fd504d7b8daba562976197f9
|
|
| MD5 |
6b63e2cd3be025e92094fc4b5ef1cc55
|
|
| BLAKE2b-256 |
352986f8f49676d1474d088b20b5163c33bc76b58c29aaa2f7a419b82e0424fd
|
File details
Details for the file fabriks-1.1.0-py3-none-any.whl.
File metadata
- Download URL: fabriks-1.1.0-py3-none-any.whl
- Upload date:
- Size: 109.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0c08690fb8e08d0a9bbe244bc06e5fef8e697365e11fb093f36529958f72191b
|
|
| MD5 |
f2103dde1c8d06f8d2fc87d11f2455f3
|
|
| BLAKE2b-256 |
9d0c398928521e0bacc10a76b62f0fc2bd3dd03b68ba31cb6df4b4d2069c0f13
|