Sandflow-ai/sand3d is an open-source project on GitHub, mainly written in HTML. 3D modeling in Python, built for LLMs. It currently holds 729 stars and 84 forks with 5 open issues, and was last pushed on 2026-11-06 (repository created 2026-11-03).
Project Overview
AI Homed tracks it on the Today's Trending board, currently at rank #81 with 0 new stars today.
GitHub Repository Details
Repository Sandflow-ai/sand3d · default branch main · size 24254 KB · watchers 3 · source: GitHub REST API and repository README
README
sand3d
3D modeling in Python, built for LLMs.
sand3d is a Python library for writing 3D objects as short programs: profiles, solids,
edits, frames, joints and assemblies, over Blender's bpy. A program says how a shape
is made, part by part and in its own words, so a model writes it in a few hundred tokens
and a person can read it.
Short. A part takes 2 to 6× fewer tokens than the same part in Blender Python, CadQuery or FeatureScript (details).
The whole API fits in a prompt, about 3,600 tokens (the API).
Named, not computed. Parts, edges and faces are reached by name, never by hand-computed coordinates.
Deterministic. The same program builds the same mesh, bit for bit.
A whole object, part by part
A front-loading washing machine in 38 lines of code (play it and read it):
the cabinet, the drum, the door with its glass and handle, the detergent drawer and the dial,
each a named part, and four joints that say how they move.
door = s3d.group("door", ring, glass, handle) # the handle and the glass move with it
s3d.joint("door_hinge", door, hinge, axis="-Z", range=(0, 143))
s3d.joint("drum_spin", drum, front.move(0, 400), kind="continuous")
s3d.joint("drawer_slide", drawer, top_band.move(150), kind="prismatic", axis="+X", range=(0, 200))
s3d.joint("dial_turn", dial, top_band.move(-150), kind="continuous")
return s3d.assembly("washing_machine", cab, drum, door, drawer, dial, front=front)
Export: GLB, URDF, USD, OBJ, STL
One call; the file's extension names the format; lengths in metres.
s3d.export(machine, "washer.glb") # or .urdf, .usda, .obj, .stl
| format | what it carries | for |
|---|---|---|
| GLB | meshes, materials, the joints in each node's extras, at the current pose | the web, viewers, game engines |
| URDF | a link per moving part, its joints and their limits, at rest; OBJ meshes beside it | ROS, PyBullet, MuJoCo, Isaac |
| USDA | the same tree in OpenUSD (UsdGeom, UsdPhysics), with the materials | Omniverse, Isaac Sim, USD pipelines |
| OBJ, STL | the meshes alone, at the current pose: OBJ Y up, binary STL Z up | any 3D tool, slicers |
.usd, .usdc and .usdz come from the .usda through USD's own tools (usdcat,
usdzip). The scene is also an ordinary Blender scene, for anything else Blender writes.
Install
Python 3.13 (recommended) or 3.11. Blender comes with it, as the bpy module: 5.2 LTS on
Python 3.13, 4.5 LTS on Python 3.11; CI runs bpy 5.2.
pip install sand3d # or, in a uv project: uv add sand3d
bpy has no wheel for Python 3.12, nor for Intel Macs from 5.2 on: there, use Python 3.11.
Put docs/api.md in the system prompt: the rules of the vocabulary, every
signature, and worked examples, in about 3 600 tokens; llms.txt points a
model at it. For objects of several parts, the guidelines give
the eight rules of an assembly program: the plan first, then the details, then the parts.