
От STL к BREP: как AI-агент научился восстанавливать геометрию, а не просто сшивать треугольники
Открытый инструмент для FreeCAD MCP: восстановление плоскостей и цилиндрических поверхностей из STL, первые результаты и приглашение к тестированию.
В прошлой статье я рассказывал, как начал работать с FreeCAD через AI-агента. После публикации попросил знакомого, который профессионально занимается CAD, подсказать, чего ему не хватает в таком подходе.
Он назвал три задачи:
- Авто сшивку STL в BREP тела;
- Перевод чертежей в 3Д модели;
- Авто корректировку 3Д моделей типа reshape но с сохранением NURBS поверхностей и построенного на их основе тела.
Я решил начать с первой. Так в моём open-source форке FreeCAD MCP появился инструмент convert_mesh_to_brep.
Не просто сшивка треугольников
STL хранит треугольную сетку. Даже если сшить её в замкнутое BREP-тело, круглое отверстие может остаться набором плоских граней. Для дальнейшей работы с геометрией хотелось большего: распознавать в сетке плоскости и цилиндрические участки и заменять их настоящими аналитическими BREP-поверхностями.
Инструмент работает с самим STL — ему не нужны исходный OpenSCAD-проект, заранее известные радиусы или вручную выбранные грани. При этом он не восстанавливает историю построения детали и не обещает угадать исходные номинальные размеры.

Рис. 1. tiltservomount_std.stl, сшитый в BREP без распознавания поверхностей (recognize_surfaces=False): 808 граней, все плоские. Отверстия и проушина состоят из узких плоских полосок.

Рис. 2. Тот же STL после convert_mesh_to_brep(repair=true): 31 грань, из них 21 Plane и 10 Cylinder. Типы поверхностей прочитаны из BREP; цилиндрические грани окрашены оранжевым только для рисунка.
Многопроходный конвейер
Конвертация состоит из нескольких этапов:
STL / Mesh в FreeCAD
│
▼
Проверка сетки и опциональный ремонт мелких дефектов
│
▼
Сшивка в BREP-оболочку и создание solid
│
▼
Восстановление общих плоскостей
│
▼
Распознавание полных и частичных цилиндров, дуг
│
▼
Поиск оставшихся гранёных участков
│
├── есть подходящие участки и прогресс → ещё проход
▼
Контроль валидности, объёма и габаритов → отчёт
Алгоритм делает до четырёх проходов распознавания. Он пытается обработать оставшиеся поддерживаемые участки автоматически, вместо того чтобы останавливаться после первой найденной поверхности.
В отчёте отдельно отражаются валидность BREP и признаки остаточной гранёности (reconstruction_status). Это разные вещи: замкнутое тело ещё не означает, что цилиндры действительно восстановлены. И наоборот, отсутствие обнаруженных гранёных участков не доказывает идеальную реконструкцию всей геометрии.
Результат — отдельный объект Part::Feature. Поддерживаются аналитические плоскости, полные и некоторые частичные цилиндрические поверхности; произвольные NURBS-поверхности, конусы и сферы пока не реконструируются.
Результат на шести деталях
Для первых проверок я использовал шесть STL из Pan and Tilt for Standard Servo автора micromet (модели — CC BY-SA). На всём наборе использовался один инструмент с repair=true и стандартными допусками, без ручного выбора граней и размеров.
| Деталь | Граней BREP | Плоскостей | Цилиндрических граней | Изменение объёма |
|---|---|---|---|---|
PanTiltBase_std | 27 | 12 | 15 | 0,0397% |
PanMount7 | 45 | 34 | 11 | 0,0306% |
sideplateservo_std | 24 | 15 | 9 | 0,0227% |
sideplateshaft_std | 14 | 9 | 5 | 0,0109% |
tiltservomount_std | 31 | 21 | 10 | 0,0279% |
IRTmount_pantilt | 24 | 14 | 10 | 0,0253% |
Например, tiltservomount_std.stl содержал 2884 треугольника, а на выходе получился BREP из 31 грани: 21 плоскости и 10 цилиндрических участков. Это именно типы аналитических поверхностей, а не просто визуально сглаженная сетка. Число цилиндрических граней не равно числу отверстий: один цилиндр может состоять из нескольких участков.

Рис. 3. Исходная сетка tiltservomount_std.stl в том же ракурсе, что на рис. 1 и 2: 2884 треугольника → 31 BREP-грань (21 плоскость, 10 цилиндрических поверхностей, рис. 2).
Все шесть результатов — замкнутые валидные тела. Они прошли проверки геометрического ядра и тест сохранения с повторным открытием файла. Изменение объёма на каждой детали — менее 0,04%; сканер не обнаружил оставшихся цепочек граней, которые он умеет распознавать.
Но это только первый тест. Все шесть деталей — из одного комплекта, на них же велась разработка. Близость объёмов не гарантирует точность поверхностей: максимальное расстояние между исходной сеткой и результатом здесь отдельно не измерялось. Для произвольных STL надёжность ещё предстоит проверить.
Как попробовать
Код открыт: github.com/hram/freecad-mcp. Подробности установки, параметры, диагностические поля и ограничения — в документации convert_mesh_to_brep.
Когда FreeCAD запущен с обновлённым аддоном и работающим RPC, AI-агент может вызвать инструмент так:
convert_mesh_to_brep(
doc_name="Example",
source_file="/path/to/part.stl",
name="RecoveredPart",
repair=true
)
Путь к STL указывается на компьютере, где работает FreeCAD. Вместо файла можно передать существующий mesh-объект. Исходная сетка сохраняется, новый BREP создаётся отдельно; документ автоматически не записывается.
Конвертер возвращает JSON-отчёт (он также сохраняется в ConversionReport) с найденными поверхностями, отклонениями и причинами, по которым отдельные участки не удалось восстановить.
Мне нужны STL, на которых этот инструмент сломается
Я не CAD-профессионал, и шести тестовых деталей явно мало. Хочу проверить инструмент на настоящих задачах, а не продолжать подгонять его под один Pan–Tilt.
Если вы работаете с CAD, попробуйте конвертер на своём STL. Особенно интересны случаи, когда он оставляет цилиндры гранёными, неверно распознаёт поверхности, искажает отверстия, создаёт лишнюю геометрию или вообще не может обработать сетку.
Присылайте ошибки и идеи в GitHub Issues. Очень помогут проблемный STL, скриншот ожидаемого и фактического результата, версия FreeCAD и JSON-отчёт. Если модель коммерческая или конфиденциальная, не публикуйте её: достаточно обезличенного или специально упрощённого примера, на котором воспроизводится дефект.
Вторая и третья идеи моего знакомого тоже интересны. Но сначала хочется понять, насколько полезной можно сделать первую — с помощью тех, кто работает с такой геометрией каждый день.
Если ваш STL ломает мой конвертер — это именно то, что мне сейчас нужно.