sand3d 1.6.2

3D modeling in Python, built for LLMs

sand3d is a 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.

Quickstart Articulated galleryAPI for LLMs GitHub
Objects written in sand3d

Why sand3d

4.0×fewer tokens than Blender Python, for the same CAD part (median)
3 643tokens: the whole API, ready for a prompt
70public names on one flat s3d.<verb> surface
2fresh processes, the same mesh to the bit, for every verb

Fewer tokens for the same object

Blender Python · written by an LLM 30 CAD parts
4.0×
9 of 30 build the right part
CadQuery · the dataset's own programs (Zero-To-CAD) 17 CAD parts
2.3×
synthetic programs, generated for the dataset
FeatureScript (Onshape) · the dataset's own programs (CADFS) 13 CAD parts
6.0×
real designs from public Onshape documents
Articraft's Python SDK · the dataset's own programs 12 articulated objects
2.0×
5 of 12 also use CadQuery; they also declare masses and inertias

median of the other program's tokens over sand3d's · o200k_base, code only · per part: the table

The same part or object, written in sand3d and in another language: the Blender Python an LLM writes for 30 parts from public CAD models (9 of 30 build the right part; all 30 in sand3d), the CAD datasets' own CadQuery and FeatureScript programs, and Articraft's own programs for 12 articulated objects. The sand3d programs are written for this repo, each matching its reference mesh. Objects that come as meshes are not compared: no program exists to set beside sand3d's.

A whole object, part by part

A washing machine: its part tree, its joints, its three export files

A front-loading washing machine: the cabinet, the drum, the door with its glass and handle, the 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)

6 lines · 153 tokens (o200k_base)

Twelve articulated objects, a lamp, a refrigerator, a gate, a tripod head, binoculars and more, each one program, to turn in 3D and play joint by joint: the gallery.

Play the articulated gallery

Export: GLB, URDF, USD, OBJ, STL

One call; the file's extension names the format; lengths in metres.

formatwhat it carriesfor
GLBmeshes, materials, the joints in each node's extras, at the current posethe web, viewers, game engines
URDFa link per moving part, its joints and their limits, at rest; OBJ meshes beside itROS, PyBullet, MuJoCo, Isaac
USDAthe same tree in OpenUSD (UsdGeom, UsdPhysics), with the materialsOmniverse, Isaac Sim, USD pipelines
OBJ, STLthe meshes alone, at the current pose: OBJ Y up, binary STL Z upany 3D tool, slicers

.usd, .usdc and .usdz come from the .usda through USD's own tools.

Install, and a first program

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, the two versions the tests run on.

pip install sand3d        # or, in a uv project: uv add sand3d
import sand3d as s3d


def bracket(w=80, d=40, t=6, hole_d=6.6, pitch=50):
    plate = s3d.extrude("plate", s3d.rect(w, d, r=4), t)
    s3d.hole(plate, hole_d, on=s3d.grid(2, 1, pitch, 0))
    s3d.fillet(plate, 1, edges="top")
    return plate

s3d.export(bracket(), "bracket.glb")

10 lines · 121 tokens (o200k_base)

The bracket

Every verb, with code that runs and its render: the quickstart.

Give it to your LLM

Put the API in the system prompt: the rules of the vocabulary, every signature, and worked examples, in 3 643 tokens. It is served raw at api.md, and 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.

Read the APIapi.md, raw

Datasets

sand3d programs for four sources of 3D objects, on Hugging Face under CC BY 4.0. The programs come from Sandflow's iterative agentic reconstruction pipeline, which will be described in upcoming releases.

sand3d-objaversesand3d-objaverse · Objaverse Everyday objects from Objaverse, each rebuilt as a program. sand3d-cadsand3d-cad · CAD Mechanical parts from public CAD models. sand3d-articraftsand3d-articraft · Articraft Articulated objects from Articraft, their joints declared. sand3d-simreadysand3d-simready · SimReady Simulation-ready assets from NVIDIA SimReady.

Citation

@misc{sand3d2026,
  author = {Neveu, Thibault and Loy, Andr{\'e}a},
  title  = {sand3d},
  year   = {2026},
  note   = {Version 1.6.2},
  url    = {https://github.com/Sandflow-ai/sand3d}
}
sand3d 1.6.2 · Apache-2.0 · source Sandflow