145 подписчиков

Про нейросети: пишем аддон для Blender с помощью ChatGPT

228 прочитали

А вы полагали, мы тут обойдем эту тему стороной? Кто бы что ни думал или говорил по поводу нейросеток — это новые инструменты, многие из которых, пусть еще и находятся в зачаточном состоянии, уже оказывают огромное влияние на подход к работе и многие рабочие процессы.

Очередная обложка к статье, созданная с помощью нейросети Midjourney
Очередная обложка к статье, созданная с помощью нейросети Midjourney
Это очень техническая статья и здесь будет много конкретной узко-специализированной практики, но опыт, который я получил, разбираясь с ChatGPT для написания простых программ, может пригодиться при решении очень широкого спектра задач.

Вся информация, касательно особенностей ChatGPT и API Blender'а актуальна на момент написания статьи (начало февраля 2023 года, версия Blender — 3.3.3 LTS), так что, если вы читаете это из будущего, возможно, у вас уже все по-другому :)

По образованию я — программист, с некоторым опытом разработки ПО (в довольно далеком прошлом). Конечно же, работая в VFx, полностью уйти от программирования не удается (например, Houdini, по-сути, это инструмент визуального программирования компьютерной графики). Я знаком с языком Python, но вот API Blender'а, несмотря на более чем 12-летний стаж работы с ним, мне изучить толком так и не довелось: задачи по написанию каких-то специфических скриптов возникали редко, и решить их, как правило, помогали коллеги, лучше меня умеющие в blender-скрипты.

Задача 1: автоматизация преобразований

Но, как водится, когда-то приходится внять «зову к странствиям». В моем случае я оказался в ситуации, когда мне срочно надо было обрабоать простым, но очень специфическим образом около двух тысяч несложных объектов в Blender'е.

В этой главе рассматривается довольно специфическая задача, но ввиду ее простоты на примере решения удобно разобрать основные моменты работы с ChatGPT. Если вас интересует толоько аддон, который может быть полезен на практике, смело листайте вниз ко 2-й задаче.

Постановка задачи

Мой клиент заказал у неких 3D-моделеров, не работающих в Blender'е, порядка двадцати 3D-моделей, каждая из которых состояла из 50-200 отдельных объектов. Ко мне эти модели попали в виде fbx-файлов, а отдать их нужно было как blend-файлы, причем, принципиально важным моментом было то, что каждый элемент каждой модели (каждый отдельный mesh-объект сцены) в своем исходном масштабе (равном единице) должен иметь размеры 100х100х100 см, а его фактические размеры (например, 10х2500х1200 см) должны были достигаться за счет соответсвующего масштаба по осям (то есть, для приведенного примера, масштаб по 3 осям должен был составлять (0.1, 25, 12) единиц).

Если бы количество объектов для обработки всего было бы 10-20 штук, я не стал бы заморачиваться, и сделал всё вручную. Но объектов слишком много, а также модели еще могли быть скорректированы в будущем, значит, обработку для них пришлось бы повторить (возможно, не один раз). С такими вводными, единственный правильный подход — автоматизация процесса.

Midjourney так представил себе архитектурную сцену в Blender
Midjourney так представил себе архитектурную сцену в Blender

Подход к решению

Алгоритм преобразований максимально простой: необходимо запомнить размеры объекта, затем задать размеры по всем трем осям равным 100 см, применить трансформации масштаба и потом назначить запомненные размеры объекту (тем самым будет установлен нужный масштаб при фактическом размере объекта 100х100х100 см).

Geometry Nodes решить такую задачу не могут, поэтому мне нужен был Python-скрипт. Без знаний API написание нужной программы заняло бы больше времени, чем я был готов сам потратить на решение этой задачи. Современные проблемы требуют современных решений, так что в этот раз я решил не лезть в мануалы, а поставить задачу перед ChatGPT. Ранее я уже немного экспериментировал с написанием фрагментов кода в нем, поэтому настрой был довольно оптимистичный. Главное, что я уясил из предыдущих экспериментов — это два основных момента:

  • ChatGPT — это очень сырая штука, так что он часто не дописывает ответы, особенно, если они длинные; поэтому его ответы и фрагменты кода, которые я запрашиваю, должны быть максимально короткими;
  • сразу просить написать готовый скрипт — не лучшая идея: скорее всего, он будет содержать много функциональных неточностей, которые будет сложно исправлять; гораздо лучше писать программу постепенно, как если бы я разрабатывал ее сам, усложняя и добавляя возможности.
Зачем вообще нужен Blender, когда есть Midjourney? =)
Зачем вообще нужен Blender, когда есть Midjourney? =)

Чтобы поэтапно подойти к итоговому решению, я набросал себе простой алгоритм «высокого уровня» подхода к разработке, который включал следующие этапы, позволяющие отслеживать правильность решения:

  1. Создать панель с кнопкой: при нажатии программа должна запомнить размеры выбранного объекта и затем задать размеры из сохраненных значений.
  2. Добавить применение трансформации масштаба между двумя операциями.
  3. Свести все операции в работу одной кнопки ”Retransform”.
  4. Поменять программу так, чтобы кнопка работала не для выделенного объекта, а для всех mesh-объектов сцены.

Пишем код с ChatGPT

Первый мой запрос выглядел следующим образом:

Write me a smibple blender script that creates 2 buttons: one remembers (stores) the object's dimensions and other applies that stored values to the selected object

«Напиши мне простой скрипт для блендера, который создает 2 кнопки: одна запоминает (хранит) размеры объекта, а другая — применяет эти сохраненные значения к выбранному объекту». Услужливый бот незамедлительно согласился:

Про нейросети: пишем аддон для Blender с помощью ChatGPT

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

Про нейросети: пишем аддон для Blender с помощью ChatGPT

Этот код я вставил в текстовый редактор Blender и запустил программу на выполнение. Соответствующая панелька появилась среди свойств объекта, но вот нажатие на “Remember Size” вызывало ошибку AttributeError: 'Object' object has no attribute 'remember_dimensions', о чем я и пообщался далее с ботом. Он ошибку признал и оперативно исправил:

Про нейросети: пишем аддон для Blender с помощью ChatGPT

Новый вариант (ссылка на код) заработал как положено: одна кнопка сохраняла размеры, вторая применяла эти размеры к выбранному объекту.

Далее я попросил добавить еще одну кнопку, которая задавала бы размер объекта по всем трем осям равным 10 (1 метр при масштабе единиц измерения сцены 0,1 м) и применяла бы масштаб.

Про нейросети: пишем аддон для Blender с помощью ChatGPT

Этот код почти работал как надо за исключением того, что, после изменения размерностей, применение масштаба (Apply Scale) к объекту не выполнялось. К этому моменту программа стала (внезапно) уже слишком длинная для стабильной работы ChatGPT (он уже начал грешить тем, что дописывал сообщения через раз), а мне нужно было добавить всего одну строчку (по моим соображениям). Так что я просто полез в стандартный поисковик за ответом и практически сразу нашел его:

bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)

Важно понимать, что эта конструкция работает с выделенным объектом. Три кнопки мне уже были ни к чему, так что я совместил весь код в одну функцию, почистил комментарии, добавил применение трансформаций и в итоге получил простейшую панель с одной «волшебной кнопкой», которая делала все операции с объектом, которые мне были нужны:

Про нейросети: пишем аддон для Blender с помощью ChatGPT

Здесь можно посмотреть итоговый код и скачать .py-файл.

Осталось решить одну задачу: как я уже упоминал, объектов в сцене было очень много, поэтому протыкивать вручную каждый мне не очень хотелось. Играть с ChatGPT — одно удовольствие, поэтому решение этого простого момента я также возложил на него. Чтобы нам с ним работать с одной и той же версией программы, я сначала сгрузил весь программный код ему в сообщении (бот отлично понял, что этот код делает), а потом попросил внести изменения:

Про нейросети: пишем аддон для Blender с помощью ChatGPT

Здесь можно посмотреть наше последнее общение с ChatGPT по этому вопросу. И всё работало почти хорошо за исключением того, что применение трансформаций (масштаба) перестало выполняться. Как я уже упоминал, в том виде конструкция работала только для выделенного объекта, а когда программа перебирает все объекты в сцене, они не выделяются.

Не став долго разбираться, как можно применить трансформации для не-выделенного объекта, я просто доработал код, найдя в сети, как программно выделить объект в сцене obj.select_set(True) и как это выделение снять после того, как нужная операция выполнена: obj.select_set(False). В итоге скрипт приобрел свой финальный вид.

Про нейросети: пишем аддон для Blender с помощью ChatGPT

Промежуточный итог

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

Этот успех подтолкнул меня к решению гораздо более распространенной задачи, которая также не давала мне покоя последние недели.

Задача 2: аддон для создания архива проекта Blender

У Blender есть удобная функция: упаковка-распаковка внешних файлов текстур в blend-файл, что позволяет переносить сцену между разными компьютерами, не теряя связанные файлы. Но как быть, если в проект прилинкованы еще и другие blend-файлы, плюс десяток alembic-ов с объектами и анимациями?

«Не влезает»
«Не влезает»

Постановка задачи

Я работаю над небольшой серией анимационных роликов с гуманоидными персонажами. Этот проект проходит через несколько студий, и на момент старта по техническим причинам мы не стали использовать USD-формат, который, возможно, мог бы отчасти решить проблемы, описываемые ниже. Вместо этого мы выстроили довольно линейный пайплайн, в конце которого нахожусь, собственно, я.

Персонажи и анимированные элементы локации присылают мне в виде alembic-файлов. Для сохранения единообразия материалов и внешнего вида деталей сцен, я использую линковку к blend-файлам с материалами и группами объектов, вроде расстановки предметов в интерьере. Моя задача — собрать все объекты в финальные сцены, сделать материалы, настроить освещение, высчитать (отрендерить) всё и сделать композитинг (этой теме будет посвящена отдельная статья, когда мы сей проект закончим).

Гуманоидные персонажи тануцуют и поют, пока идет рендер.
Гуманоидные персонажи тануцуют и поют, пока идет рендер.

Поначалу я не думал об использовании рендер-ферм (или обращаться за помощью с рендером к коллегам), но со временем сроки начали сокращаться, поэтому моих собственных мощностей стало нехватать. И все острее становился вопрос: как мне просто и быстро передать сцену на другую машину, не потеряв все эти связи с файлами? А в более широкой перспективе — как вообще делать архивы подобных проектов, чтобы не собирать вручную файлы по всему компьютеру, и не раздувать blend-файлы, встраивая в них изображения?

Нужен был аддон. И теперь, уже успешно сделав нечто подобное, я чувствовал, что готов попытаться сделать его самостоятельно (используя ChatGPT).

Пишем код в ChatGPT. Часть первая

Начал опять с самого простого, чтобы потом постепенно усложнять: попросил написать скрипт, который выводил быв консоль список всех внешних файлов:

Про нейросети: пишем аддон для Blender с помощью ChatGPT

А после попросил добавить к ним также внешние алембики и файлы сцен блендера:

Про нейросети: пишем аддон для Blender с помощью ChatGPT

Код заработал не сразу — возникло несколько ошибок, которые я сообщил боту, и он (в итоге успешно) попытался их исправить:

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

Следующий шаг — скопировать все найденные файлы в одну папку: я написал запрос боту, чтобы новая версия программы создавала папку “assets”, в которую копировала бы все найденные внешние файлы. Скрипт, вроде бы, заработал, но для контроля выполнения программы я попросил добавить вывод отчета в консоль:

Листинг переписки доступен здесь.

Дальше стали возникать сложности (подозреваю, что во многом потому, что я даже не пытался особо углубляться в суть разработки и просто решал задачу в лоб — но в том был и смыл: я старался максимально отстраниться от разработки и минимизировать время, которое я сам трачу на решение). Их все я без зазрения совести адресовал нейросетке, попутно отмечая, как бот из контекста хорошо понимает мои запросы в моменты, когда мой английский сбоил, выдавая опечатки и грамматические ошибки. Переписку можно посмотреть тут.

Под конец до меня дошло то, что надо было сделать одним из первых шагов — исключить дубликаты файлов. Правда, на этом ошибки не закончились, и я предположил, что дело в относительных путях к файлам, формат которых в Blender может быть не совместим с моей операционной системой... но тут ChatGPT сломался.

Про нейросети: пишем аддон для Blender с помощью ChatGPT

На момент описываемых событий это означало, что надо начинать новый чат, чтобы продолжить работу. Хорошо, что бот может вспомнить любой ваш с ним диалог.

Пишем код в ChatGPT. Часть вторая

Правда в этот раз напоминать пришлось максимально конкретно: самым простым способом оказался просто отправить ему предыдущий программный код.

Про нейросети: пишем аддон для Blender с помощью ChatGPT

В итоге оно вспомнило: «Да, я помню, что помогал вам написать этот скрипт. Предоставленный вами скрипт является скриптом Python Blender, который экспортирует все связанные файлы (текстуры, связанные библиотеки и файлы кэша Alembic) используемые в текущей сцене Blender в каталог «assets» в том же каталоге, что и файл blend. Скрипт использует модуль bpy, который является Python API Blender, для доступа к данным Blender и выполнения операций».

И я повторил свой запрос по поводу путей файлов:

Про нейросети: пишем аддон для Blender с помощью ChatGPT

Бот внес изменения, но ошибки по-прежнему возникали — глядя на консольный вывод, я пытался направить нейросеть на правильное решение:

Про нейросети: пишем аддон для Blender с помощью ChatGPT

Код выглядел корректно, но, похоже, сканирование всех прилинкованных файлов, включало также и файлы аддонов, что вызывало дополнительные ошибки работы с путями и доступом к файлам. Я это понял чуть позже, но на момент работы с кодом, я решил подойти к вопросу в более общем ключе, попросив включить в код обработчики ситуаций, когда обрабатываемый файл не существует, и когда есть проблемы с доступом — это решило проблему (в конце-концов все мои рабочие файлы вряд ли располагались по путям с закрытым доступом, а те, которые попадали, меня не интересовали).

Про нейросети: пишем аддон для Blender с помощью ChatGPT

Текст переписки можно посмотреть по этой ссылке. Этот скрипт уже выполнялся без критических ошибок, копируя задействованные в сцене файлы в папку “assets”.

Осталась последняя задача: заменить пути для всех скопированных файлов с оригинальных на новые, в папке ”assets”. И в момент ее реализации ChatGPT опять начал неприятно глючить — в этот раз стало слетать форматирование, и вместо программного кода я стал получать markdown-форматированный текст:

Пропали отступы (а в Python они важны), комментарии стали заголовками... в общем, тихий ужас, если не хочется лезть и ручками перебивать код.
Пропали отступы (а в Python они важны), комментарии стали заголовками... в общем, тихий ужас, если не хочется лезть и ручками перебивать код.

Следующие 10-15 минут прошли забавно: я пытался привести нейросеть в чувства, направляя ее в сторону корректного результата (я очень не хотел вручную править и перепроверять код — слишком много ошибок можно было совершить, потом исправлять, а я не хотел тратить столько времени) — все «веселье» в галерее — листайте:

В итоге я решил пойти на крайние меры. Обновил страницу и начал новый чат, скормив в первом сообщении боту последнюю полную версию скрипта. Хорошо, что он ее признал!

Про нейросети: пишем аддон для Blender с помощью ChatGPT

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

Про нейросети: пишем аддон для Blender с помощью ChatGPT

Бот починился и даже выдал целиком программный код, который работал! Да, в консоли выскакивали ошибки и предупреждения для некоторых файлов, но программа выполнилась полностью, и все материалы, текстуры и связанные алембики были на месте с новыми путями к каталогу “assets” — ссылка на результат.

Последнее, что нужно было сделать — чтобы пути были не абсолютными, а относительными (ведь на другой машине проект может находиться совсем по другому пути). Самый простой способ — в конце программы снова пройтись по всем путям и преобразовать их в относительные.

Про нейросети: пишем аддон для Blender с помощью ChatGPT

Форматирование опять сломалось, но мне не хотелось еще раз пытаться заставить его писать правильно, поэтому я просто скопировал код в редактор и поправил отступы. В результате я получил не самый оптимизированный, но готовый рабочий скрипт, решающий мою задачу! Ура!

Превращаем скрипт в аддон

Оставался еще нюанс: скрипт — это не аддон. А я хотел получить именно постоянно висящую панельку, которая торчала бы у меня в Blender под рукой, готовая выполнить сбор файлов в любое время дня и ночи по моей первой прихоти! Поэтому, мы продолжили («мы пахали: я и трактор», — да-да).

Этот сеанс с ChatGPT также уже забаговался, поэтому я просто запустил новый, и начал с простых вещей: попросил сделать панель с кнопкой. Функционал кнопки должен был быть максимально простой, чтобы я позже подставил туда свой код, сгенерированный ранее:

Напиши мне простой аддон для Blender, который создаст панель с заголовком “Asset Collector”, одним полем ввода с меткой “Assets folder name” и значением по умолчанию “assets”, и кнопкой “Collect”. Кнопка должна просто выводить “Collected!” в консоль.

Конечно, панель — это еще не аддон, но полученного кода мне хватало для реализации всего оставшегося функционала. Это был тот момент, когда дописать самому стало быстрее, чем просить кого-нибудь это сделать (даже такую исполнительную штуку как ChatGPT).

Про нейросети: пишем аддон для Blender с помощью ChatGPT

Я добавил в текст этой программы сгенерированный ранее код: дописал нужные инструкции import, вставил в тело функции execute() кнопки весь функционал предыдущего скрипта. А чтобы скрипт был именно аддоном, добавил соответствующий заголовок bl_info (как он пишется, я просто нашел в интернете):

Про нейросети: пишем аддон для Blender с помощью ChatGPT

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

Замечания (вместо послесловия)

Конечно, этот скрипт не идеален. Он генерирует большое количество ошибок и предупреждений, а сам код может быть еще оптимизирован (например, в части замены абсолютных путей на относительные).

Но всего за пару часов я смог получить рабочий инструмент, который решил мою проблему (при том, что самостоятельно я бы это делал гораздо дольше, разбираясь в API и особенностях разработки). На данный момент уже два ролика были успешно «упакованы» этим аддоном и отправлены для рендера на другие машины, так что «оно работает» — пользуйтесь, если нужно! :)

Если кто-то решит допилить этот аддон до «более правильного» состояния — милости прошу: весь код открыт, берите, пользуйтесь, развивайте, делитесь в комментариях! Ну и, как обычно, если у вас остались вопросы, появились замечания или предложения, пишите — прочитаю, учту, отреагирую. Подписывайтесь на этот журнал, канал в Телеграме и/или мой личный канал в Телеге, где не только про VFx, рассказывайте вашим знакомым — вдруг подобный материал будет кому-нибудь еще интересен и/или полезен.

Всего хорошего!