Исследование геометрических ядер САПР: выбор и обоснование
Сравнение открытых и закрытых (с бесплатными лицензиями) ядер по пяти требованиям задачи плюс лицензионный риск шестым. Кандидаты проверены не только по документации: truck и OCCT через opencascade-rs собраны и прогнаны зондами на одной задаче. Ключевое из измеренного: - Fornjot архивирован в июне 2026, целей не достиг — из кандидатов выбывает; - opencascade-rs на Windows из коробки не собирается: три настройки окружения, непринятый PR #230 и четыре строки правки build.rs; - OCCT сохраняет CYLINDRICAL_SURFACE там, где truck пишет девять сплайновых заплаток, и считает булевы в 4-6 раз быстрее; - исключение к LGPL у OCCT покрывает только заголовки, не линковку; - бесплатного входа в промышленное ядро нет ни у C3D, ни у Parasolid, ни у ACIS. Рекомендация: OCCT через opencascade-rs, запасной вариант truck. #5 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,466 @@
|
||||
# Геометрические ядра САПР: что доступно и что брать
|
||||
|
||||
Документ по задаче #5. Цель — выбрать геометрическое ядро, поверх которого строится
|
||||
САПР-часть CFDManager, и обосновать выбор, а не объявить его.
|
||||
|
||||
Сейчас в дереве нет ничего, что можно было бы назвать ядром: `simv_mesh` читает `.obj`
|
||||
через tinyobjloader, сваривает вершины и считает AABB. Ни B-rep, ни NURBS, ни булевых
|
||||
операций, ни параметрических форматов. Всё это придётся взять снаружи — своё ядро
|
||||
пишется годами и не является предметом этого проекта.
|
||||
|
||||
## Требования и как они проверялись
|
||||
|
||||
Пять требований заданы в задаче, шестое добавлено здесь, потому что без него выбор
|
||||
некорректен.
|
||||
|
||||
| № | Требование | Как проверялось |
|
||||
|---|---|---|
|
||||
| 1 | Лёгкость и оптимизированность | сборка и запуск на этой машине, вес артефактов |
|
||||
| 2 | Rust-стек или доступное для Rust API | наличие крейта/биндингов, собрал и запустил |
|
||||
| 3 | Базовое редактирование 3D (аналог Plasticity) | наличие булевых, фасок, скруглений, выдавливания |
|
||||
| 4 | NURBS | какие поверхности представимы, что уходит в STEP |
|
||||
| 5 | Стандартные параметрические и полигональные форматы | STEP/IGES на запись **и чтение**, STL/OBJ/glTF |
|
||||
| 6 | **Лицензия** | текст лицензии и то, что она требует при поставке продукта |
|
||||
|
||||
Шестое требование добавлено по следующей причине. Ядро — не библиотека утилит, его
|
||||
нельзя заменить за неделю; лицензионное условие, замеченное после того, как на ядре
|
||||
написан год работы, стоит переписывания продукта. Поэтому GPL-ядра и ядра
|
||||
с некоммерческой лицензией разбираются здесь наравне с техникой, а не в сноске.
|
||||
|
||||
Измерения выполнены на машине разработки: Windows 11, MSVC 19.37.32825 (VS 2022
|
||||
Community), CMake 4.3.2, Ninja 1.13.2, Rust 1.97.1, сборки release. Числа, взятые
|
||||
из внешних источников, помечены явно.
|
||||
|
||||
---
|
||||
|
||||
## Группа 1. Открытый исходный код
|
||||
|
||||
### Open CASCADE Technology (OCCT)
|
||||
|
||||
Единственное зрелое открытое B-rep/NURBS ядро промышленного класса. Версия **8.0.1**
|
||||
от 30 июля 2026; семь модулей (Foundation Classes, Modeling Data, Modeling Algorithms,
|
||||
Visualization, Data Exchange, Application Framework, Mesh).
|
||||
|
||||
**Форматы:** STEP (AP203, AP214, AP242), IGES до 5.3, STL, OBJ, glTF 2.0, VRML 1.0 —
|
||||
на чтение и запись. ACIS, Parasolid, DXF, IFC, JT — **только через платные компоненты**
|
||||
Open Cascade, в открытую поставку не входят.
|
||||
|
||||
**Лицензия — LGPL 2.1 с исключением, и исключение не то, за которое его обычно
|
||||
принимают.** Полный текст `OCCT_LGPL_EXCEPTION.txt` разрешает ровно одно: включать
|
||||
в объектный код материал из заголовочных файлов библиотеки (инлайн-функции, шаблоны,
|
||||
CDL-классы) и распространять такой объектный код на своих условиях — при заметном
|
||||
уведомлении, что продукт использует OCCT. Про линковку исключение не говорит **ничего**.
|
||||
|
||||
Практический вывод: динамическая линковка — штатный путь, обязанности сводятся
|
||||
к уведомлению и к тому, что пользователь может подменить библиотеку. Статическая
|
||||
линковка остаётся под LGPL 2.1 §6 и требует выдать объектные файлы приложения, чтобы
|
||||
пользователь мог пересобрать его с изменённым OCCT. Это важно, потому что
|
||||
`opencascade-rs` со своим режимом `builtin` собирает OCCT **статически**
|
||||
(`BUILD_LIBRARY_TYPE=Static` в вызове CMake) — то есть самый удобный путь сборки
|
||||
оказывается как раз тем, который для проприетарной поставки неудобен.
|
||||
|
||||
Динамический путь существует: без `builtin` обвязка ищет **предустановленную** OCCT
|
||||
и, если та собрана с `BUILD_SHARED_LIBS=ON`, линкуется к ней как `dylib`
|
||||
(`crates/opencascade-sys/build.rs:43`). Но там же, строкой ниже, стоит жёсткая
|
||||
проверка версии: требуется мажор ровно **7** и минор не ниже 8, иначе сборка
|
||||
паникует. Поставить в системе свежую OCCT 8.0.1 и слинковаться с ней **не получится** —
|
||||
обвязка её отвергнет.
|
||||
|
||||
### opencascade-rs — путь к OCCT из Rust
|
||||
|
||||
Крейты `opencascade` / `opencascade-sys` версии 0.3.0 (обновлены 24 августа 2026),
|
||||
биндинги через `cxx`, лицензия LGPL-2.1. Форк `bschwind` живой, 263 звезды; форк
|
||||
`mkovaxx` последний раз трогали в октябре 2025 — его рассматривать не стоит.
|
||||
|
||||
API высокоуровневый и на вид приятный:
|
||||
|
||||
```rust
|
||||
let my_box = Shape::box_with_dimensions(10.0, 10.0, 1.0);
|
||||
let another = Shape::box_with_dimensions(1.0, 1.0, 0.8);
|
||||
my_box.subtract(&another).chamfer(0.07)
|
||||
```
|
||||
|
||||
Есть `write_step` / `write_iges` / `write_stl`, `read_step`, `mesh()`
|
||||
с настраиваемым допуском, фаски, скругления, выдавливание, заметание по траектории.
|
||||
|
||||
**Существенное отставание:** `occt-sys` зафиксирован на OCCT **7.8.1**, тогда как
|
||||
апстрим уже 8.0.1. Это не косметика — между ними мажорный релиз, и всё, что исправлено
|
||||
в 7.9 и 8.0, в этом пути недоступно, пока обвязку не обновят. Причём 8.0 заявлен
|
||||
командой OCCT3D (Capgemini Engineering) как релиз с ломающими изменениями API,
|
||||
чисткой интерфейсов и переработкой булевых операций, тесселяции и обработки допусков —
|
||||
то есть обновление обвязки будет не механическим, и ждать его быстро не стоит.
|
||||
|
||||
### truck — чистый Rust
|
||||
|
||||
Единственный живой чисто-растовый B-rep/NURBS кернел. Apache-2.0, 1559 звёзд,
|
||||
коммиты в репозитории вплоть до 7 сентября 2026 — **но крейты на crates.io не
|
||||
обновлялись с 20 сентября 2024** (`truck-modeling` 0.6.0). Два года git-активности
|
||||
без релиза — характерный признак: пользоваться придётся либо старым релизом,
|
||||
либо git-зависимостью.
|
||||
|
||||
Умеет: NURBS-геометрию, топологию (вершины/рёбра/грани/оболочки/тела), булевы операции
|
||||
(`truck-shapeops`), тесселяцию (`truck-meshalgo`), чтение и запись STEP
|
||||
(`truck-stepio`, есть и `in`, и `out`), полигональные форматы через `truck-polymesh`.
|
||||
|
||||
### Остальные открытые — отсев с причиной
|
||||
|
||||
| Проект | Состояние | Почему не подходит |
|
||||
|---|---|---|
|
||||
| **Fornjot** | архивирован 19 июня 2026 | Автор закрыл проект: «This project has been shut down. Its goals were never reached», код read-only, пригоден лишь для «very simple models» |
|
||||
| **SolveSpace** | живой, 4163★, GPL-3.0 | GPLv3 несовместим с проприетарной поставкой; NURBS-булевы, по признанию самих авторов, медленные, ограничены поверхностями выдавливания и вращения и «not too robust even then» |
|
||||
| **BRL-CAD** | живой, 1029★ | CSG-ориентированное ядро с Tcl-инфраструктурой, не про интерактивное NURBS-моделирование |
|
||||
| **openNURBS** | живой, 562★ | Чтение/запись `.3dm` и NURBS-геометрия, **но моделирования нет**: ни булевых, ни фасок |
|
||||
| **curvo** | живой, MIT, 0.1.91 | NURBS-кривые и поверхности как математика, не B-rep ядро |
|
||||
| **Manifold** | живой, Apache-2.0, есть крейт `manifold3d` 0.4.1 (обновлён 9 сентября 2026) | Быстрые и надёжные булевы, но по **полигональным сеткам**; NURBS и B-rep отсутствуют как понятие. Полезен позже — для подготовки геометрии к расчётной сетке, не как ядро |
|
||||
| **CGAL** | живой | Вычислительная геометрия, не САПР-ядро; ядро GPL с платной альтернативой |
|
||||
|
||||
Отдельно стоит отметить `libslvs` из SolveSpace: это **решатель геометрических
|
||||
ограничений**, то есть ровно та подсистема, которой нет ни у OCCT, ни у truck.
|
||||
К выбору ядра он отношения не имеет, но к параметрике — прямое (см. раздел о том,
|
||||
что придётся писать самим).
|
||||
|
||||
---
|
||||
|
||||
## Группа 2. Закрытый код, бесплатные и некоммерческие лицензии
|
||||
|
||||
Задача изначально говорила про открытые ядра; рамка расширена владельцем проекта.
|
||||
Результат этой группы отрезвляющий: **бесплатного входа в промышленное ядро нет ни
|
||||
у одного из четырёх.**
|
||||
|
||||
### C3D Modeler (C3D Labs)
|
||||
|
||||
Единственное коммерческое геометрическое ядро российской разработки, одно из пяти
|
||||
лицензируемых ядер в мире. B-rep с NURBS, обмен со STEP, IGES, Parasolid, ACIS,
|
||||
полигональными форматами. API — C++ с C-обёрткой; Rust-биндингов нет, их пришлось бы
|
||||
писать самим.
|
||||
|
||||
Публично доступна **только 90-дневная пробная версия** с техподдержкой. Бесплатной
|
||||
некоммерческой или академической лицензии в открытом доступе найти не удалось:
|
||||
у компании есть образовательные партнёрства с вузами, хакатоны и стажировки, но
|
||||
лицензия под них публично не описана и выдаётся по договорённости. Условия
|
||||
коммерческой лицензии компания называет гибкими и определяет индивидуально; цифра
|
||||
в 1 750 000 ₽ в год за лицензию разработчика плюс роялти встречается во вторичных
|
||||
источниках и **здесь не проверена** — уточнять её нужно у самой C3D Labs.
|
||||
|
||||
### Parasolid (Siemens)
|
||||
|
||||
Ядро, на котором построена названная в задаче Plasticity, а также SolidWorks, NX и
|
||||
десятки других систем. Эталон по надёжности булевых и качеству поверхностей.
|
||||
|
||||
Лицензируется коммерчески; публичных условий, прайса, бесплатного или академического
|
||||
тарифа в открытом доступе нет — вход только через переговоры с Siemens, и по отзывам
|
||||
разработчиков процесс и суммы для небольших проектов оказываются заградительными.
|
||||
Rust-биндингов нет.
|
||||
|
||||
### 3D ACIS Modeler и CGM Modeler (Spatial / Dassault Systèmes)
|
||||
|
||||
Второе историческое коммерческое ядро (ACIS, с конца 1980-х) и ядро CATIA (CGM).
|
||||
Технически полноценные B-rep/NURBS ядра. Ситуация с лицензией та же, что у Parasolid:
|
||||
публичных бесплатных или академических условий нет, пробный доступ и академические
|
||||
программы — по запросу. Rust-биндингов нет.
|
||||
|
||||
### Zoo Design API (бывш. KittyCAD)
|
||||
|
||||
Самый близкий к требованию 2 вариант: проприетарное ядро, **написанное на Rust**,
|
||||
GPU-native, выдаёт настоящий B-rep. Есть официальный Rust-клиент `kittycad.rs`,
|
||||
открытые Design Studio и язык KCL.
|
||||
|
||||
Но это **облачный сервис**, а не библиотека: геометрия считается на их серверах,
|
||||
тарификация поминутная, бесплатно даётся 20 минут API (баланс $10), дальше
|
||||
pay-as-you-go. Для настольного САПР с интерактивным редактированием это означает
|
||||
зависимость от сети, задержку на каждую операцию и оплату за использование, которая
|
||||
растёт вместе с числом пользователей. Для проекта, который сам по себе считает
|
||||
гидродинамику локально, такая схема противоречива.
|
||||
|
||||
### Обмен форматами отдельно
|
||||
|
||||
CAD Exchanger SDK, HOOPS Exchange, ODA — не ядра моделирования, а конвертеры.
|
||||
Они закрывают требование 5 там, где ядро не справляется (DWG, JT, CATIA, NX), и
|
||||
имеют смысл как **дополнение** к выбранному ядру, если такие форматы понадобятся.
|
||||
Все три коммерческие. Для OCCT, который сам читает STEP и IGES, необходимости
|
||||
в них на текущем этапе нет.
|
||||
|
||||
---
|
||||
|
||||
## Сводная таблица
|
||||
|
||||
Обозначения: ● полностью, ◐ частично, ○ нет.
|
||||
|
||||
| Кандидат | 1. Лёгкость | 2. Rust | 3. Редактирование | 4. NURBS | 5. Форматы | 6. Лицензия и её риск |
|
||||
|---|---|---|---|---|---|---|
|
||||
| **OCCT + opencascade-rs** | ○ 2,7 ГБ сборки, exe 19,4 МБ | ◐ биндинги есть, но на Windows не собираются без патчей | ● булевы, фаски, скругления | ● полноценно, аналитика сохраняется | ● STEP/IGES/STL/OBJ/glTF | LGPL-2.1+искл.: динамическая линковка — ок, статическая обязывает |
|
||||
| **truck** | ● 98 с сборки, exe 1,6 МБ | ● родной, собрался с первой попытки | ◐ булевы есть (в 4–6 раз медленнее), набор беднее | ◐ есть, но аналитика уходит в B-сплайны | ◐ STEP r/w, полигоны; IGES нет | Apache-2.0 — риска нет |
|
||||
| Fornjot | — | ● | ○ | ○ | ○ | архивирован |
|
||||
| SolveSpace | ● | ○ | ◐ | ◐ слабые булевы | ◐ | **GPL-3.0 — стоп для проприетарного** |
|
||||
| openNURBS | ● | ○ | ○ | ● | ◐ только 3dm | своя, свободная |
|
||||
| Manifold | ● | ● крейт `manifold3d` | ◐ только сетки | ○ | ◐ | Apache-2.0 — риска нет |
|
||||
| C3D Modeler | ◐ | ○ писать самим | ● | ● | ● | 90 дней, дальше платно |
|
||||
| Parasolid | ◐ | ○ | ● эталон | ● | ● | платно, условий публично нет |
|
||||
| ACIS / CGM | ◐ | ○ | ● | ● | ● | платно, условий публично нет |
|
||||
| Zoo Design API | ● клиент лёгкий | ● родной Rust | ● | ● | ● | облако, поминутная оплата |
|
||||
|
||||
---
|
||||
|
||||
## Измерения
|
||||
|
||||
Всё в этом разделе измерено здесь, а не переписано из чужих статей.
|
||||
|
||||
### truck
|
||||
|
||||
Зонд: два куба → булево объединение → тесселяция → экспорт OBJ и STEP. Написан
|
||||
по документации и **скомпилировался с первой попытки без правок** — показатель того,
|
||||
что API соответствует документации.
|
||||
|
||||
| Что | Значение |
|
||||
|---|---|
|
||||
| холодная сборка release | **98,6 с** |
|
||||
| пакетов в графе зависимостей | 103 |
|
||||
| исходники самих крейтов truck | 1,9 МБ, 233 файла, 10 крейтов |
|
||||
| размер `target/` | 446,8 МБ |
|
||||
| исполняемый файл зонда | 1,60 МБ |
|
||||
| построение двух кубов | 116 мкс |
|
||||
| булево объединение (плоскости) | 1,72 мс |
|
||||
| тесселяция результата | 340 мкс, 60 вершин / 36 граней |
|
||||
| экспорт STEP | 445 мкс, 17,6 КБ |
|
||||
| экспорт OBJ | 637 мкс, 8,8 КБ |
|
||||
|
||||
Второй зонд — на кривых поверхностях: цилиндр (через вращательное заметание) против
|
||||
куба, пересечение и объединение.
|
||||
|
||||
| Что | Значение |
|
||||
|---|---|
|
||||
| булево пересечение цилиндр ∩ куб | **32,6 мс** (в 19 раз дороже плоскостного) |
|
||||
| булево объединение цилиндр ∪ куб | 29,5 мс |
|
||||
| результат тесселируется | да, 84 вершины |
|
||||
|
||||
Третий зонд — чтение STEP обратно: файл, записанный первым зондом, разобран за
|
||||
**11,1 мс**, из него восстановлены 1 оболочка, 12 граней и 18 плоскостей. То есть
|
||||
круг «записал — прочитал» у truck замкнут. Мелочь, характеризующая зрелость API:
|
||||
`Table::from_step` возвращает `Option`, а не `Result`, поэтому причина неудачного
|
||||
разбора вызывающему не сообщается вовсе.
|
||||
|
||||
Обе булевы операции отработали — это лучше, чем можно было ожидать от ядра такой
|
||||
зрелости. Но экспорт цилиндра в STEP показал существенное: файл содержит `B_SPLINE_SURFACE` и
|
||||
`PLANE`, и **не содержит `CYLINDRICAL_SURFACE`**. То есть аналитические поверхности
|
||||
truck не сохраняет, всё сводится к сплайнам. Файл валиден, но принимающая система
|
||||
получает вместо цилиндра сплайновую аппроксимацию: хуже для распознавания элементов,
|
||||
хуже для точности, тяжелее.
|
||||
|
||||
### OCCT через opencascade-rs
|
||||
|
||||
Сборка этого пути оказалась мерой сама по себе — она упёрлась в три препятствия
|
||||
подряд, и каждое стоит знать заранее.
|
||||
|
||||
1. **CMake 4.x против OCCT 7.8.1.** `occt-sys` собирает OCCT 7.8.1, чей
|
||||
`cmake_minimum_required` объявляет совместимость ниже 3.5. В CMake 4.3.2 такая
|
||||
совместимость удалена, и конфигурация падает сразу:
|
||||
«Compatibility with CMake < 3.5 has been removed from CMake». Обходится
|
||||
переменной окружения `CMAKE_POLICY_VERSION_MINIMUM=3.5`. В OCCT 8.0.1 этой
|
||||
проблемы нет — но обвязка на него не переведена.
|
||||
2. **Генератор Visual Studio.** Крейт `cmake` по умолчанию берёт генератор
|
||||
«Visual Studio 17 2022», который на этой машине не отработал: установлены
|
||||
и Build Tools 2026, и VS 2022 Community. Лечится `CMAKE_GENERATOR=Ninja`
|
||||
из среды `vcvars64.bat`.
|
||||
3. **Длина пути Windows.** Дерево OCCT глубокое, и в каталоге с длинным путём
|
||||
сборка предупреждает про `CMAKE_OBJECT_PATH_MAX` (187 символов при пределе 250)
|
||||
и падает. Понадобился короткий путь вида `C:\occprobe`.
|
||||
|
||||
После того как все три обойдены, сборка идёт и **само ядро OCCT собирается успешно**.
|
||||
А потом падает компиляция cxx-мостов — тремя однотипными ошибками в собственных
|
||||
заголовках обвязки:
|
||||
|
||||
```
|
||||
b_rep.hxx(16): error C2440: невозможно преобразовать
|
||||
"opencascade::handle<Geom_Surface> *" в "std::unique_ptr<Handle_Geom_Surface, ...>"
|
||||
```
|
||||
|
||||
| Что | Значение |
|
||||
|---|---|
|
||||
| время до провала | **36 мин 09 с** (01:59:43 → 02:35:52) |
|
||||
| объём `target/` к этому моменту | ~1,0 ГБ |
|
||||
| исходники OCCT (`occt-sys` 7.8.1) | 87 МБ, 14 984 файла; скачиваемый архив 13,7 МБ |
|
||||
| ошибок компиляции | 3, все в `b_rep.hxx` |
|
||||
| собралось ли ядро OCCT | **да** |
|
||||
| собрались ли биндинги | **нет** |
|
||||
|
||||
Причина — коллизия имён: обвязка объявляет собственные типы `Handle_Geom_Surface`
|
||||
и им подобные, которые под MSVC сталкиваются с одноимёнными типами самого OCCT.
|
||||
Это **известная незакрытая проблема проекта**, а не особенность этой машины:
|
||||
PR #196 «Handle name conflict to fix Windows build» был влит ещё в январе 2025,
|
||||
PR #230 «Fix MSVC handle name collisions» от 19 августа 2026 — **закрыт, не влит**,
|
||||
а PR #216 «Fix Windows build» открыт с октября 2025 и всё ещё не принят.
|
||||
|
||||
Проверка обхода: патч из непринятого PR #230 (переименование `Handle_*` →
|
||||
`RustHandle_*`, 26 файлов) применяется к текущему master чисто — `git apply` проходит
|
||||
без конфликтов. После него мосты компилируются, **но сборка падает уже на линковке**:
|
||||
23 неразрешённых символа, среди них `InitializeAcl` и `InitializeSecurityDescriptor`,
|
||||
то есть не подключены системные библиотеки Windows. Это ровно предмет второго,
|
||||
до сих пор **открытого** PR #216 — и наложить его поверх первого не получается,
|
||||
два непринятых патча конфликтуют между собой в `build.rs`. Понадобилось дописать
|
||||
четыре строки вручную:
|
||||
|
||||
```rust
|
||||
println!("cargo:rustc-link-lib=dylib=advapi32");
|
||||
println!("cargo:rustc-link-lib=dylib=gdi32");
|
||||
println!("cargo:rustc-link-lib=dylib=shell32");
|
||||
println!("cargo:rustc-link-lib=dylib=comdlg32");
|
||||
```
|
||||
|
||||
**После этого всё собралось и заработало.** Итого, чтобы получить рабочий
|
||||
OCCT-из-Rust на Windows, потребовались: три настройки окружения, один непринятый
|
||||
PR и четыре строки своей правки.
|
||||
|
||||
| Что | Значение |
|
||||
|---|---|
|
||||
| холодная сборка до провала (без патчей) | 36 мин 09 с |
|
||||
| пересборка после патчей (ядро уже собрано) | 1 мин 45 с |
|
||||
| исходники OCCT (`occt-sys` 7.8.1) | 87 МБ, 14 984 файла; архив 13,7 МБ |
|
||||
| размер `target/` | ~2,7 ГБ |
|
||||
| исполняемый файл зонда | **19,4 МБ** (против 1,60 МБ у truck) |
|
||||
|
||||
Работа зонда: куб 10×10×10 минус куб 6×6×6, фаска 0,5, тесселяция, три экспорта
|
||||
и чтение STEP обратно.
|
||||
|
||||
| Операция | Время |
|
||||
|---|---|
|
||||
| два примитива | 503 мкс |
|
||||
| булево вычитание | 7,46 мс |
|
||||
| фаска по всем рёбрам | 20,2 мс |
|
||||
| тесселяция | 12,1 мс, 174 вершины / 86 треугольников |
|
||||
| экспорт STEP | 25,4 мс, 110,8 КБ, 2378 сущностей |
|
||||
| экспорт IGES | 14,6 мс, 87,3 КБ |
|
||||
| экспорт STL | 15,2 мс, 22,4 КБ |
|
||||
| чтение STEP обратно | 48,4 мс, те же 174 вершины |
|
||||
| всего | 145 мс |
|
||||
|
||||
### Прямое сравнение на одной задаче
|
||||
|
||||
Чтобы сравнение было честным, обоим ядрам дана одна и та же работа: цилиндр
|
||||
радиуса 2 высоты 4, пересечение и объединение с кубом 1,5, затем запись цилиндра
|
||||
в STEP.
|
||||
|
||||
| | truck | OCCT |
|
||||
|---|---|---|
|
||||
| цилиндр ∩ куб | 32,6 мс | **7,2 мс** |
|
||||
| цилиндр ∪ куб | 29,5 мс | **4,7 мс** |
|
||||
| тесселяция результата | 84 вершины | 38 вершин |
|
||||
| STEP цилиндра, размер | 13 281 байт | **5 652 байта** |
|
||||
| боковая поверхность в STEP | 9 × `B_SPLINE_SURFACE` | **1 × `CYLINDRICAL_SURFACE`** |
|
||||
|
||||
Последняя строка — самая содержательная во всём документе. Там, где OCCT пишет
|
||||
одну аналитическую цилиндрическую поверхность, truck пишет девять сплайновых
|
||||
заплаток: файл вдвое толще, а принимающая система видит не цилиндр, а его
|
||||
аппроксимацию. Булевы операции при этом у OCCT в 4–6 раз быстрее.
|
||||
|
||||
Мелкая, но заметная деталь эксплуатации: OCCT при записи STEP печатает в stdout
|
||||
собственную статистику трансфера («Statistics on Transfer», рамки из звёздочек).
|
||||
В библиотеке, встраиваемой в приложение с интерфейсом, этот вывод придётся глушить.
|
||||
|
||||
---
|
||||
|
||||
## Рекомендация
|
||||
|
||||
**Основной вариант — Open CASCADE Technology, из Rust через `opencascade-rs`.**
|
||||
|
||||
Причины, по порядку веса:
|
||||
|
||||
1. **Это единственное открытое ядро, которое закрывает требования 3, 4 и 5
|
||||
целиком.** Всё остальное открытое либо не умеет моделировать (openNURBS, curvo,
|
||||
Manifold), либо умеет плохо и под GPL (SolveSpace), либо закрыто (Fornjot).
|
||||
2. **Требование 2 выполняется без написания биндингов.** `opencascade-rs` даёт
|
||||
готовый Rust-API с булевыми, фасками, тесселяцией и обменом форматами.
|
||||
3. **Требование 5 закрывается из коробки:** STEP AP242 и IGES на чтение и запись —
|
||||
это то, чем САПР обменивается с внешним миром, и ни truck, ни полигональные
|
||||
библиотеки этого в таком объёме не дают.
|
||||
4. Зрелость: ядро развивается с 1990-х; на нём построены FreeCAD (его B-rep/NURBS
|
||||
слой — это OCCT), CadQuery и 3D-часть KiCad.
|
||||
|
||||
Цена решения, названная честно и **измеренная**: ядро тяжёлое (87 МБ исходников,
|
||||
2,7 ГБ сборочного каталога, 19,4 МБ исполняемый файл против 1,6 МБ у truck), это
|
||||
C++ с версией 7.8.1 в текущей обвязке, а сама обвязка **на Windows из коробки не
|
||||
собирается**: понадобились три настройки окружения, патч из непринятого PR #230 и
|
||||
четыре строки правки `build.rs`. Плюс лицензия, обязывающая к динамической линковке
|
||||
при проприетарной поставке — а динамический путь требует системной OCCT ветки 7.x.
|
||||
|
||||
Это не аргумент против выбора, но это работа, которую придётся сделать до того, как
|
||||
будет написана первая строка САПР-логики, и её лучше запланировать явно. Разумный
|
||||
первый шаг после утверждения — **форк `opencascade-rs`** с наложенными исправлениями:
|
||||
иначе каждый разработчик проекта будет проходить этот путь заново, а обновление
|
||||
апстрима будет ломать сборку.
|
||||
|
||||
**Запасной вариант — truck**, и он не запасной «на всякий случай», а по конкретному
|
||||
сценарию: если проект останется целиком на Rust и согласится на собственную
|
||||
реализацию недостающего. truck легче, собирается за полторы минуты, не тянет C++
|
||||
и не создаёт лицензионных обязанностей вовсе (Apache-2.0). Но за это придётся
|
||||
заплатить отсутствием IGES, потерей аналитических поверхностей при экспорте,
|
||||
более скудным набором операций и работой с крейтами двухлетней давности либо
|
||||
git-зависимостью.
|
||||
|
||||
**Отдельно про требование 3.** В задаче эталоном названа Plasticity — она построена
|
||||
на Parasolid, и это надо понимать буквально: уровня её прямого моделирования
|
||||
(push/pull по грани с мгновенной перестройкой тела) ни одно открытое ядро само по
|
||||
себе не даёт. OCCT предоставляет операции, из которых такой режим собирается, но
|
||||
собирать его придётся самим.
|
||||
|
||||
**Про закрытые ядра.** Ни одно из четырёх не даёт бесплатного пути в продукт:
|
||||
C3D — 90 дней, Parasolid и ACIS/CGM — только переговоры, Zoo — поминутная оплата
|
||||
и облако. Возвращаться к ним осмысленно тогда, когда у проекта появится бюджет
|
||||
и станет ясно, что именно в OCCT не устраивает: менять ядро на этапе прототипа
|
||||
дороже, чем позже, когда требования известны точно.
|
||||
|
||||
---
|
||||
|
||||
## Что придётся писать самим поверх любого ядра
|
||||
|
||||
Это не недостаток конкретного кандидата, а общее свойство: ядро даёт геометрию,
|
||||
а не САПР.
|
||||
|
||||
- **Решатель геометрических ограничений.** Ни OCCT, ни truck его не содержат.
|
||||
Без него нет параметрического эскиза. Кандидаты: `libslvs` из SolveSpace
|
||||
(GPL-3.0 — то же лицензионное ограничение, что и у самого SolveSpace),
|
||||
либо собственная реализация.
|
||||
- **Дерево построения и история операций.** Ядро выполняет операции, но не помнит,
|
||||
в каком порядке и от чего они зависели.
|
||||
- **Топологические имена.** Устойчивая идентификация граней и рёбер между
|
||||
перестроениями — классическая трудная задача, ядром не решается.
|
||||
- **Связь с расчётной частью.** Для CFD нужна сетка, а не B-rep: понадобится
|
||||
контролируемая тесселяция и, вероятно, воксельное или SDF-представление,
|
||||
согласованное с решателем KBC.
|
||||
|
||||
---
|
||||
|
||||
## Что нужно от владельца проекта
|
||||
|
||||
1. **Утвердить ядро** — критерий готовности задачи #5 сформулирован именно так.
|
||||
2. **Решить вопрос линковки**, если продукт будет проприетарным: удобный путь
|
||||
(`builtin`) даёт статическую сборку OCCT, а динамический требует предустановленной
|
||||
в системе OCCT ветки 7.8/7.9 — версию 8.x обвязка отвергает. Выбор: принять
|
||||
обязанности LGPL 2.1 §6, держать системную 7.x, либо править обвязку под себя.
|
||||
3. **Согласиться на форк `opencascade-rs`** (или явно отказаться): без него сборка
|
||||
на Windows воспроизводится только вручную, по шагам из раздела измерений.
|
||||
4. Если решено смотреть на закрытые ядра всерьёз — **запросить условия** у C3D Labs
|
||||
(90-дневная пробная плюс индивидуальные условия) и у Siemens по Parasolid.
|
||||
Регистрация и подписание — действия владельца, агентом они не выполняются.
|
||||
|
||||
---
|
||||
|
||||
## Источники
|
||||
|
||||
- [Open CASCADE Technology — обзор и форматы](https://occt3d.com/dev/doc/overview/html/index.html)
|
||||
- [FOSDEM 2026: OCCT3D 8.0 — ломающие изменения и развитие ядра](https://archive.fosdem.org/2026/schedule/event/QQRAAF-occt3d-8-kernel-evolution/)
|
||||
- [OCCT_LGPL_EXCEPTION.txt — текст исключения](https://raw.githubusercontent.com/Open-Cascade-SAS/OCCT/master/OCCT_LGPL_EXCEPTION.txt)
|
||||
- [Релизы OCCT (8.0.1, 30.07.2026)](https://github.com/Open-Cascade-SAS/OCCT/releases)
|
||||
- [opencascade-rs](https://github.com/bschwind/opencascade-rs)
|
||||
- [opencascade-rs PR #230 «Fix MSVC handle name collisions» — закрыт, не влит](https://github.com/bschwind/opencascade-rs/pull/230)
|
||||
- [opencascade-rs PR #216 «Fix Windows build: …missing system libraries» — открыт](https://github.com/bschwind/opencascade-rs/pull/216)
|
||||
- [truck — shape processing kernel by Rust](https://github.com/ricosjp/truck)
|
||||
- [Fornjot — архив, заявление о закрытии](https://github.com/hannobraun/fornjot)
|
||||
- [SolveSpace — использование как библиотеки](https://solvespace.com/library.pl)
|
||||
- [openNURBS](https://github.com/mcneel/opennurbs)
|
||||
- [Manifold](https://github.com/elalish/manifold)
|
||||
- [curvo](https://github.com/mattatz/curvo)
|
||||
- [C3D Toolkit — лицензирование](https://c3dlabs.ru/products/c3d-toolkit/licensing/)
|
||||
- [C3D Toolkit — тестовая версия](https://c3dlabs.ru/evaluation/)
|
||||
- [Zoo Design API](https://zoo.dev/design-api)
|
||||
- [Zoo — тарифы API](https://zoo.dev/api-pricing)
|
||||
- [kittycad.rs — Rust-клиент Zoo](https://github.com/KittyCAD/kittycad.rs)
|
||||
Reference in New Issue
Block a user