«Больше никаких 1000 кликов»: Как я заставил C4D рендерить сотни конфигураций без человека
Скрипт на Python для Cinema 4D, заменяющий ручной перебор десятков комбинаций «профиль × наполнитель × поддон × угол × материал» единым GUI-инструментом с автоматическим сопоставлением файлов и пакетным рендером.
Контекст и задача
Проект выполнен для компании «Техностиль», занимающейся изготовлением стеновых и кровельных сэндвич-панелей (профилированный металлический лист + утеплитель). Отдел визуализации использует Cinema 4D для генерации PNG-иконок каждого профиля панели, наполнителя (утеплителя — минвата/пенополистирол/PIR-PUR) и поддона — эти изображения затем используются в веб-конфигураторе продукции на сайте компании, где клиент собирает панель нужной комплектации «по кубикам».
До автоматизации 3D-художнику приходилось вручную для каждой единицы номенклатуры: подгружать нужный .ai-файл контура профиля панели, переключать видимость слоёв в сцене, выставлять углы стыковки (90°/135°), задавать материал утеплителя (вата/пенополистирол/PIR-PUR), запускать рендер и раскладывать PNG по правильным папкам. При десятках профилей и наполнителей это часы монотонной ручной работы и источник ошибок в путях сохранения.
Задача скрипта — свести всю эту работу к нескольким кликам: пользователь один раз выбирает угол, материал и режим, отмечает нужные профили/наполнители в чек-листе, и скрипт сам рендерит и раскладывает результат по дисковой структуре.
Технологический стек
— Python (Cinema 4D Python API — модуль c4d)
— c4d.gui.GeDialog — кастомные модальные GUI-диалоги (чекбоксы, группы, кнопки)
— c4d.documents.RenderDocument + MultipassBitmap — программный рендер и сохранение PNG с альфа-каналом
— User Data сцены (ID_USERDATA) — как «пульт управления» видимостью объектов и назначением текстур из скрипта
— os / файловая система — сканирование, парсинг имён файлов, построение путей сохранения
Архитектура решения
Скрипт построен вокруг одного управляющего объекта сцены RENDER_CONTROL, чьи User Data-параметры выступают интерфейсом между Python-кодом и содержимым 3D-сцены: путь к .ai-файлу контура, путь к файлу наполнителя, путь к поддону, набор булевых «выключателей видимости» (профиль/вата/поддон, замки LZ/PR/PZ, matte-параметры торцов lw/pw) и переключатели угла. Это классический паттерн «оживления» статичной сцены данными снаружи — сцена не меняется, меняются только входные параметры перед каждым рендером.
Логика выполнения делится на пять последовательных этапов:
— Выбор угла раскроя (90° / 135° / без угла) — через нативный c4d.gui.ShowPopupDialog.
— Выбор материала наполнителя (VATA / POLY / PIR) — с автоматическим подбором материала сцены по имени и donастройкой UV-тайлинга текстуры под конкретный материал.
— Выбор логического режима рендера (всё вместе, весь профиль, LZ/PR/PZ по отдельности, только наполнитель, только поддон).
— Сканирование каталога источника, разбор имён .ai-файлов и группировка через собственные GUI-диалоги (ProfileSelectDialog, NapolnitelSelectDialog).
— Цикл рендера: для каждой выбранной позиции скрипт выставляет нужную комбинацию «переключателей» через set_all_switches(), инициирует пересчёт сцены и рендерит кадр в вычисленную по правилам папку.
Ключевые инженерные решения
Самодокументируемый диспетчер состояний сцены
Функция set_all_switches() — сердце скрипта. Вместо разбросанных по коду присвоений она собирает все восемь переключателей сцены (видимость профиля/ваты/поддона, три типа замков, два matte-флага торцов) в одну именованную сигнатуру с понятными умолчаниями и докстрингом, объясняющим смысл каждого флага. Любой следующий разработчик может понять логику состояния сцены за 10 секунд, не читая C4D-документацию.
Эвристический парсер и «спаривание» файлов
Файлы поставляются с говорящими, но не строго стандартизированными именами (profil_lz.ai, napolnitel_lz pirpur.ai и т.п.). Функция find_paired_file() очищает префикс и расширение, нормализует регистр и пробелы/подчёркивания и ищет по «чистому» имени соответствующий файл наполнителя или поддона для текущего профиля — с поддержкой суффикса материала (например, pirpur), который отличает, скажем, наполнитель под PIR-PUR от такого же наполнителя под вату.
Собственные GUI-диалоги с группировкой по смыслу
Вместо стандартного системного диалога «выбери файлы» реализованы два кастомных c4d.gui.GeDialog:
— ProfileSelectDialog — список профилей, автоматически разделённый на «обычные» и «замковые» (по суффиксу _z), с кнопками «Выбрать все» / «Снять все».
— NapolnitelSelectDialog — трёхколоночный диалог наполнителей (без префикса / группа Z / группа VENT) с быстрыми фильтрами «только Z», «только VENT» и т. д., чтобы не листать десятки чекбоксов вручную.
Оба диалога используют единый приём: диапазон ID чекбоксов (CHECK_BASE) плюс индекс в объединённом списке, что позволяет одной строкой восстановить, какие позиции пользователь отметил, без хранения отдельного состояния на каждый чекбокс.
Предсказуемая структура сохранения результатов
Путь сохранения PNG собирается динамически из нескольких независимых переменных: базовая папка → флаг «замки» → тип объекта (profil/napolnitel/poddon) → материал наполнителя → подпапка угла (90°/135°). Такой подход гарантирует, что структура папок веб-конфигуратора всегда предсказуема и не зависит от порядка выбора пользователем — а для повторяющегося поддона (одинакового для группы профилей) отдельный флаг poddon_rendered_once исключает лишние дубли рендера.
Защита от «пустого» рендера
Перед каждым фактическим рендером сцена дважды прогоняется через wait_for_scene() (ExecutePasses + GeSyncMessage), чтобы Cinema 4D успела пересчитать зависимые генераторы и текстуры после смены User Data — иначе первый кадр в серии рискует захватить ещё не обновлённое состояние сцены. Это распространённая, но неочевидная проблема программного рендера в C4D, решённая явным ожиданием синхронизации.
Пример потока выполнения
— находит парный файл наполнителя под PIR-PUR и рендерит его отдельным проходом с другим набором переключателей видимости;
— рендерит поддон один раз на группу профилей без замков;
— сохраняет все PNG по маршруту вида .../zamki/profil/uglovie/135°/... и по завершении открывает соответствующие папки в проводнике.
Итог
Скрипт превращает многочасовую рутинную задачу подготовки графики для конфигуратора в управляемый процесс из нескольких кликов: 3D-художник задаёт только высокоуровневые параметры (угол, материал, что рендерить), а сопоставление файлов, переключение состояний сцены, построение путей и пакетный рендер выполняются автоматически и воспроизводимо.
С инженерной точки зрения работа демонстрирует практическое владение Python-интеграцией со сторонним DCC-приложением (Cinema 4D SDK), проектирование пользовательских GUI поверх непривычного тулкита, устойчивый к вариативности входных данных парсинг имён файлов и аккуратную декомпозицию сложной ветвящейся логики (шесть режимов рендера) на переиспользуемые функции.