Внутренняя кухня ZenCad
Геометрическое ядро и вычисления
Библиотека zencad базируется на геометрическом ядре OpenCascade. Доступ к API OpenCascade из Python предоставляет пакет cadquery-ocp-novtk (модули OCP). Геометрические типы и операции ZenCad находятся в zencad.geom; адаптеры к ядру — в zencad._native.
Объекты геометрии и значения сохраняют зависимости между операциями. Вычислитель EvalCache выполняет их в режиме deferred или immediate и управляет повторным использованием результатов. Context владеет вычислителем; обычному скрипту достаточно модульных функций и методов объектов. .value() получает вычисленное значение, .native() у формы — объект OCP. Подробнее: «Вычисления и кэш», «Точки и векторы».
Организация и взаимодействие потоков и процессов ZenCad.
Графический интерфейс ZenCad построен таким образом, чтобы по минимуму влиять на порядок вычислений в запускаемых скриптах. Для того, чтобы этого достичь, скрипты вызываются в отдельном процессе.
При запуске zencad model.py или python -m zencad model.py главный процесс владеет интерфейсом Qt, viewer OpenCascade и контекстом OpenGL. В этом же процессе находятся камера, выделение, маркеры и объекты отображения AIS.
RunnerSupervisor запускает исполнителя модели отдельным процессом через multiprocessing с методом spawn. Исполнитель строит геометрию и собирает сцену, но не создаёт окна Qt или OpenGL. Между процессами передаются данные сцены: сериализованная BREP-геометрия или меши, размещения, цвета, имена и видимость объектов. Окно viewer принадлежит главному процессу и сохраняется при пересчётах модели.
Связь организована через каналы multiprocessing.Pipe и версионированный протокол. По нему передаются снимки сцены, прогресс вычислений, вывод скрипта и ошибки; в обратном направлении — управляющие события и пользовательский ввод. stdout и stderr скрипта перехватываются исполнителем и доставляются интерфейсу как сообщения.
Пересчёт и обновление сцены
Каждый запуск получает номер поколения. Исполнитель накапливает описание объектов в SceneDraft; при публикации получается снимок SceneSnapshot. ScenePresenter в GUI проверяет и декодирует его, затем заменяет содержимое viewer. Применяется только результат актуального поколения: запоздавшее сообщение от предыдущего запуска не заменит текущую модель.
Во время расчёта, отмены или ошибки остаётся видимой последняя успешно построенная сцена. Камера при обновлении по умолчанию сохраняется. Исполнителя можно остановить и запустить заново, не пересоздавая главное окно и viewer.
Функция show.
В зависимости от контекста функция show может менять своё поведение (см. zencad/showapi.py).
- В скрипте, запущенном редактором или командами
inspect/check,display()добавляет данные вSceneDraft, аshow()публикует снимок сцены. Для статической сцены исполнение затем продолжается без запуска оконного цикла. - При прямом запуске
python model.pyвызовshow()открывает самостоятельный viewer в том же процессе и запускает цикл событий Qt. Полный редактор при этом не создаётся. Этот режим также доступен черезzencad --display model.py. zencad --no-show model.pyвыполняет скрипт с отключённым показом. Для получения отчёта о геометрии используются отдельные команды inspect и check.
Анимация и ввод
В редакторе анимированный исполнитель остаётся активным после публикации сцены. Callback получает время, ввод через state.input и управление камерой через state.camera. Изменения размещения, цвета и видимости передаются как обновления сцены; действия камеры — отдельными сообщениями. Обработка Qt и отображение выполняются в GUI-процессе.
Геометрию для такой анимации создают до начального show(). Callback не получает прямой доступ к виджету viewer и не заменяет геометрию после публикации. Контракт и примеры описаны в разделе «Анимация».
Описание протокола, владения объектами и жизненного цикла: Runtime architecture.