sand3d: 3D-моделирование на Python, созданное для LLM

· 5 мин чтения
python llm 3d-graphics blender cad
📂 Исходный код на GitHub

Python-библиотека для 3D-моделирования, построенная для работы с LLM: объекты описываются короткими читаемыми программами поверх Blender bpy, с экспортом в GLB, URDF, USD, OBJ и STL.

sand3d: 3D-моделирование на Python, созданное для LLM

sand3d — это Python-библиотека для 3D-моделирования, созданная специально для работы с LLM. Объект описывается короткой программой: профили, тела, правки, системы координат, джойнты и сборки. Под капотом — Blender и его Python-модуль bpy. Программа объясняет, как форма строится деталь за деталью, поэтому модель пишет её за несколько сотен токенов, а человек может её прочитать.

Зачем нужна ещё одна библиотека

Код для Blender многословен: чтобы достать нужную грань, приходится вручную считать координаты вершин. sand3d устроена иначе:

  • Коротко. Та же деталь занимает в 2–6 раз меньше токенов, чем в Blender Python, CadQuery или FeatureScript. Авторы открыли методику замеров — она расписана по каждой детали.
  • Весь API помещается в промпт — около 3600 токенов. Не нужно выискивать сигнатуры в документации: правила словаря и примеры влезают в системный промпт целиком.
  • По именам, а не по координатам. Детали, рёбра и грани достаются по имени, вручную ничего считать не нужно.
  • Воспроизводимость. Та же программа собирает тот же меш (полигональную сетку) — бит в бит.

Стиральная машина в 38 строк

Флагманский пример из README — фронтальная стиральная машина. Корпус, барабан, дверца со стеклом и ручкой, лоток для порошка и поворотная ручка: каждая деталь названа, а четыре джойнта описывают, как детали движутся друг относительно друга.

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)

Покрутить модель и прочитать весь код можно в галерее.

Экспорт в один вызов

Формат задаётся расширением файла, длины — в метрах:

s3d.export(machine, "washer.glb")    # or .urdf, .usda, .obj, .stl
Формат Что внутри Для чего
GLB меши, материалы, джойнты в extras каждого узла, в текущей позе веб, просмотрщики, игровые движки
URDF звено для каждой подвижной детали, её джойнты с лимитами, в состоянии покоя; рядом OBJ-меши ROS, PyBullet, MuJoCo, Isaac
USDA то же дерево в OpenUSD (UsdGeom, UsdPhysics), с материалами Omniverse, Isaac Sim, USD-пайплайны
OBJ, STL только меши в текущей позе: OBJ — ось Y вверх, бинарный STL — ось Z вверх любой 3D-инструмент, слайсеры

Файлы .usd, .usdc и .usdz получаются из .usda штатными инструментами USD (usdcat, usdzip). Сцена при этом остаётся обычной сценой Blender, так что годится всё, что Blender умеет экспортировать.

Установка

Нужен Python 3.13 (рекомендуется) или 3.11. Blender ставится вместе с библиотекой как модуль bpy: версия 5.2 LTS для Python 3.13, версия 4.5 LTS для Python 3.11; CI проверяет bpy 5.2.

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

Нюанс: для Python 3.12 у bpy нет готового пакета, как и для Intel-маков начиная с bpy 5.2. Там остаётся Python 3.11.

Первая программа

Кронштейн с двумя отверстиями и скруглением верхних рёбер:

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")

По умолчанию все размеры в миллиметрах. Каждый глагол с запускаемым кодом и рендером собран в квикстарте, все сигнатуры — в справочнике API. Готовые программы лежат в каталогах docs/examples/ и programs/ репозитория.

Как отдать библиотеку модели

Идея простая: положите docs/api.md в системный промпт. Это правила словаря, все сигнатуры и разобранные примеры — около 3600 токенов. Файл llms.txt указывает модели путь к этому описанию. Для объектов из нескольких деталей есть рекомендации по сборкам: восемь правил программы-сборки — сначала план, потом детали, потом части.

Что внутри

Весь API — одна плоская поверхность s3d.<глагол>, без вложенных пространств имён:

Семейство Глаголы
Профили rect circle slot polygon arc spline text offset … (16)
Тела и пути extrude revolve sweep loft helix box cylinder sphere torus … (15)
Правки cut join intersect hole pocket fillet chamfer shell … (15)
Системы координат и размещение Frame face edge bbox local at transform grid ring snap
Сочленения joint pose seat
Сборка group assembly attach export units fingerprint … (8)
Детали и материалы gear knurl thread material

В библиотеке нет глаголов-категорий вроде chair() или table(). Стул здесь — просто программа, написанная на самой sand3d.

Датасеты

Авторы выложили на Hugging Face пять датасетов sand3d-программ под лицензией CC BY 4.0:

  • sand3d-objaverse — бытовые объекты из Objaverse, каждый переписан как программа;
  • sand3d-cad — механические детали из открытых CAD-моделей;
  • sand3d-articraft — сочленённые объекты из Articraft с объявленными джойнтами;
  • sand3d-simready — ассеты NVIDIA SimReady, готовые к симуляции;
  • sand3d-automate — механические сборки из AutoMate, каждая деталь — функция своей программы.

Листать объекты удобно в эксплорере, все пять датасетов собраны в одну коллекцию.

Лицензия и участие

sand3d распространяется под Apache License 2.0. Как устроена сборка, тестирование и версии — в CONTRIBUTING.md, текст лицензии — в LICENSE.

Источник: https://github.com/Sandflow-ai/sand3d