Внутренняя кухня ZenCad


Геометрическое ядро.

Библиотека zencad базируется на геометрическом ядре OpenCascade. Для работы с OpenCascade используется тонкая прослойка servoce, определяющая небольшое количество базовых объектов, операций над ними и использующая pybind11 для создания API на стороне python. Практически все функции питоновского API библиотеки servoce отпускают GIL интерпретатора, что позволяет осуществлять работу с состоянием python в момент просчета геометрии.


Организация и взаимодействие потоков и процессов ZenCad.

Графический интерфейс ZenCad построен таким образом, чтобы по минимуму влиять на порядок вычислений в запускаемых скриптах. Для того, чтобы этого достичь, скрипты вызываются в отдельном процессе, пораждаемом путём вызова командной строки операционной системы (см. zencad/gui/application.md, zencad.gui.__main__.py). Общение между процессами осуществляется через каналы posix (или их аналоги). Зависимые процессы читают сообщения из stdin и отправляют сообщения через stdout. Консольный вывод зависимых процессов перехватывается системой пайпов и отправляется управляющему процессу со специальным маркером, чтобы тот в свою очередь вывел это сообщение на консоль. Поскольку система консольного вывода в результате получается довольно сложной и сама по себе требует отладки, отладочная информация отправляется в stderr, а не в stdout. Активация отладочного вывода выполняется ключём --debug.

Существует две схемы запуска графического интерфейса пользователя.

В первом случае графический интерфейс запускается непосредственно, путём применения команд (zencad, python3 -m zencad). Здесь графический интерфейс является корневым процессом.

Во втором случае графический интерфейс пользователя создаётся функцией show(), из процесса интерпретатора python скрипта. В этом случае графический интерфейс пользователя является порожденным корневым процессом и, например, для работы с консольным выводом, перенаправляет вывод всех порожденных им скриптов в корневой процесс. Корневой процесс не уничтожается до окончания работы графического интерфейса, даже если в интерфейсе был открыт другой файл.


Спящая оптимизация.

Интерперетатор языка python, увы, имеет свойство загружаться довольно продолжительное время (вплоть до нескольких секунд), что несколько ухудшает отзывчивость системы, поскольку каждый перерасчет модели выполняется в ZenCad выполняется в новом процессе.

Чтобы несколько сгладить этот фактор, введена спящая оптимизация. Система заранее загружает и держит в спящем состоянии python процесс, который в дальнейшем может быть оперативно использован для выполнения следующего скрипта. Как только предыдущий спящий процесс использован, создаётся новый на его место.

Отключение спящей оптимизации выполняется ключём --no-sleeped


Оконное встраивание.

ZenCad использует механизм встраиваемых окон для отображения графического вывода процессов в интерфейсе главного окна.

Отключение оконного встраивания выполняется ключём --no-embed


Запуск процесса из графического интерфейса.

При запуске процесса из графического интерфейса zencad производит некоторые предварительные операции.

Вот неполный список: - Изменяет поведение функции show (см. ниже) - Перехватывает вывод в stdout, перенаправляет его в процесс-родитель. - Подписывается на уведомления от библиотеки кеширования для отображения прогресса вычисления.


Функция show.

В зависимости от контекста функция show может менять своё поведение (см. zencad/showapi.py).

Если процесс запущен пользователем из консоли, функция show порождает процесс приложения, после чего конструирует окно визуализации, о чем уведомляет процесс приложения.

Если процесс порождён приложением zencad, функция show конструирует окно визуализации, после чего уведомляет процесс приложения.