# model_3d

## Что делает

Компилирует существующий OpenSCAD-скрипт (`.scad`) в binary STL-файл.

**Требует:** OpenSCAD установлен в системе (`openscad` в PATH).

## Предпосылки

1. **Файл `.scad` уже должен существовать.** Напишите его заранее через `filesystem write`.
2. **OpenSCAD должен быть установлен.** Если нет — инструмент вернёт ошибку `openscad_not_found`.

## Формат вызова

```python
model_3d(
    scad_path="session_files/{session_id}/handle.scad",
    output_path="session_files/{session_id}/handle.stl"
)
```

## Параметры

| Параметр | Обязательно | Описание |
|---|---|---|
| `scad_path` | Да | Путь к существующему `.scad`-файлу |
| `output_path` | Да | Путь, куда записать сгенерированный `.stl`. Родительские директории создаются автоматически. |

## Workflow

### 1. Написать OpenSCAD-скрипт

```
filesystem write session_files/sess-abc/bracket.scad '
difference() {
    cube([40, 20, 5], center=true);
    translate([15, 0, 0]) cylinder(h=6, d=4, center=true);
    translate([-15, 0, 0]) cylinder(h=6, d=4, center=true);
}
'
```

### 2. Скомпилировать в STL

```
model_3d(
    scad_path="session_files/sess-abc/bracket.scad",
    output_path="session_files/sess-abc/bracket.stl"
)
```

### 3. Показать пользователю

```
content_publish(filename="bracket.stl", title="Bracket")
```

## Что возвращает

При успехе:
```
Generated: bracket.stl
Path: /home/.../session_files/sess-abc/bracket.stl
Size: 12.4 KB
```

При ошибке:
- `openscad_not_found` — OpenSCAD не установлен
- `scad_not_found` — исходный файл не найден
- `openscad_compile_error` — ошибка компиляции (невалидный CSG, деление на ноль и т.д.)
- `no_output` — OpenSCAD завершился без ошибок, но файл не создался

## Важные правила

1. **Всегда binary STL** — нет параметра ASCII/binary, всегда используется `--export-format binstl`.
2. **Скрипт должен существовать до вызова** — `model_3d` не пишет `.scad`, только компилирует.
3. **Ошибки OpenSCAD** читаемы: строка, символ, тип ошибки — всё в stderr.
