LuaCAD — это скриптовый CAD: модели задаются на Lua и потом экспортируются в 3MF, STL, OBJ, PLY, OFF, AMF или SCAD, либо сразу рендерятся в PNG. Внутри движок написан на Rust и встраивает Lua 5.4. CSG-операции считаются напрямую через Manifold, или LuaCAD генерирует код OpenSCAD для внешнего рендеринга.
Синтаксис Lua похож на язык OpenSCAD, но Lua мощнее, быстрее и лучше подходит для встраивания. Есть перегрузка операторов, поэтому природно писать a + b, a - b, a * b. Например, куб и сферу в LuaCAD можно описать коротким кодом без объявления модулей, как в OpenSCAD. Lua уже используется в LibreCAD и Autodesk Netfabb.
Установка через cargo install luacad — это CLI для запуска и конвертации скриптов, и cargo install luacad-studio — GUI с живым 3D-превью. Можно собрать из исходников: git clone https://github.com/ad-si/LuaCAD.git, потом make install. Оба крейта тянут C/C++-зависимости с собой, системные библиотеки не нужны, но понадобятся компилятор C++ и CMake. luacad собирает Manifold и Clipper2, а luacad-studio дополнительно собирает OpenCSG, которому нужны OpenGL-заголовки: на Debian/Ubuntu это libgl1-mesa-dev, libx11-dev, libxcb1-dev, libxkbcommon-dev, libxrandr-dev, libwayland-dev.
CLI умеет конвертировать: luacad convert model.lua output.3mf, .stl, .scad. luacad watch пересобирает файл при изменениях, luacad render рисует PNG, luacad info печатает количество треугольников и bounding box, luacad lint проверяет код через selene, luacad run просто выполняет скрипт. Формат вывода определяется расширением, но его можно переопределить через --format. Флаг --via-openscad отдаёт экспорт установленному OpenSCAD вместо сборки сетки через Manifold.
В LuaCAD полная поддержка Belfry OpenSCAD Library v2, но она переписана внутри самой программы. Поэтому можно вызывать bosl.cuboid, bosl.regular_prism, bosl.spur_gear и получать рендер, превью и экспорт без установленного OpenSCAD. При экспорте в .scad вызов BOSL2 остаётся как есть, так что файл остаётся таким же коротким, как скрипт.
text() превращает системный шрифт в 2D-эскиз, а text3d() сразу выдавливает его в объём. import() читает все форматы, которые умеет записывать LuaCAD, и возвращает твёрдое тело; SVG и DXF дают 2D-эскиз для выдавливания. Каждое возвращаемое скриптом значение становится отдельным объектом 3MF, и слайсеры загружают их как отдельные детали. Их можно пометить через :name(…), чтобы управлять списком объектов. Остальные форматы не умеют раздельных объектов, поэтому схлопывают всё в одну сетку.