Создание аддона для Blender

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

Пользовательский аддон в Blender
Пользовательский аддон в Blender

Возьмем простой скрипт создания трубы:

Дополним его функционал до полноценного аддона.

Для превращения скрипта в аддон Blender нужно выполнить 4 обязательных требования Blender API:

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

    Так же API требует, чтобы все пользовательские классы были статическими, поэтому в них не требуется определять конструктор __init__ и деструктор __del__.

    В нашем примере от аддона требуется выполнить действие по созданию меша. В классе bpy.types.Operator определена функцию execute, которая выполняется в момент обращения к классу через API Blender — как раз то, что нужно для выполнения какого-то определенного действия. Поэтому оборачиваем код скрипта в класс и наследуем его от bpy.types.Operator. Переопределяем функцию execute и заносим в нее весь исполняемый код нашего скрипта. Функция execute должна возвращать указание о успешном выполнении {‘FINISHED’}:

    Класс, наследующий bpy.types.Operator становится полноправным оператором Blender API.

    Кроме функции execute операторы имеют следующие предопределенные переопределяемые функции:

    1. poll — выполняется перед выполнением самого оператора, и если в ходе ее выполнения произошла ошибка — сам оператор далее не выполняется
    2. invoke — используется для интерактивных операций, таких как перетаскивание элементов
    3. draw — вызывается для создания графических элементов, панелей
    4. modal — используется в операторах, которые требуют периодического вызова, например при разрезании нескольких ребер. Не прерывают работу после возвращения {‘FINISH’}
    5. cancel — вызывается при отмене выполнения оператора
  1. Для того, чтобы созданный класс подключился к Blender API, нужно его зарегистрировать, вызвав функцию bpy.utils.register_class(), указав в ее параметрах имя регистрируемого класса:

При завершении работы зарегистрированный класс требуется разрегистрировать:

Так как мы оформляем наш класс в виде аддона, операцию регистрации класса нужно выполнить в момент инициализации аддона, а операцию разрегистрации класса — в момент его отключения. Для этого в API предусмотрено следующее условие: если в коде аддона определены функции register и unregister, они будут вызваны: первая при подключении аддона, вторая — при его отключении.

Добавим в конец кода нашего аддона эти две функции и проведем в них соответственно регистрацию и разрегистрацию нашего класса:

  1. Любой класс, зарегистрированный в Blender API, должен иметь уникальный идентификатор, чтобы можно было к нему обращаться по этому идентификатору.

В качестве идентификатора необходимо использовать строковую константу с предопределенным именем bl_idname. Такая константа обязана присутствовать в любом подключаемом к API Blender классе. Кроме обязательного предопределенного имени константы к ней есть еще одно требование — в ее значении должна присутствовать точка. Скорее всего это сделано для более удобной группировки идентификаторов классов внутри API.

Для определения идентификатора нашего класса создадим такую переменную и присвоим ей значение ‘mesh.create_tube’:

После чего функционал (функция execute) нашего класса, который после регистрации в API становится оператором, может быть вызван через:

Так же в области видимости класса должна быть объявлена текстовая константа bl_label, содержащая в значении текст. Этот текст будет использоваться при отображении панелей или меню с участием нашего класса.

Определим необходимые константы в классе нашего аддона:

Если в области видимости класса определяются другие константы, рекомендуется снабжать их все префиксом bl_.

  1. Для окончательного оформления аддона нужно сделать его описание. Это требование не является в полной мере обязательным, но его все равно стоит выполнять. Написав несколько аддонов без описаний, даже их автору очень сложно разобраться в их назначении. Для составления описания аддона служит словарь с предопределенным именем bl_info, который имеет следующие предопределенные пункты:
    1. name — название аддона
    2. author — ФИО автора
    3. version — версия аддона
    4. blender — версия Blender под которую разрабатывался аддон
    5. category — категория, в которую аддон будет помещен
    6. location — указание на то, где искать панель аддона
    7. url — указание на исходный код аддона (откуда он распространяется)
    8. description — строка с более подробным описанием аддона

По минимуму стоит заполнять пункты name, category и blender.

Добавим в начало кода нашего аддона описание для него:

Полный текст аддона теперь выглядит так:

Аддон готов в минимальном исполнении. Можно подключить его в Blender, открыть окно Python Console и вызвать оператор командой bpy.ops.mesh.create_tube().

Установленный аддон и вызов его функционала из Python Console
Установленный аддон и вызов его функционала из Python Console

Вызывать созданный функционал через Python Console очень неудобно. Доработаем немного функционал аддона — добавим в меню создания мешей (Shift+a — Mesh) пункт для вызова нашего оператора — создания трубы.

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

Объект layout содержит в себе структуру определяемого меню, в которую мы добавили один пункт, связав его с нашим оператором через его bl_idname.

Для того, чтобы этот пункт добавлялся в меню в момент регистрации аддона и удалялся при его разрегистрации, добавим в функции register и unregister нужные команды:

Полный код аддона:

Если вы установили аддон, его нужно переустановить — удалить нажатием на кнопку Remove в окне User Preferences — Add-ons — Add Mesh: Create Tube Addon и установить заново из дополненного файла.

После установки и активации аддона в меню добавления меша появится новый пункт Create Tube.

Добавление пункта в меню Add Mesh для вызова функционала аддона
Добавление пункта в меню Add Mesh для вызова функционала аддона

При добавлении объектов в сцену, в N-панели обычно выводится панель, в которой указываются параметры создаваемого объекта для присваивания им начальных значений. Добавим такую же панель для установки начальных параметров трубы в наш аддон.

Для того, чтобы при создании трубы в N-панели выводилась панель создаваемого объекта, в описание класса нужно добавить переменную с предопределенным именем bl_options. Эта переменная — нумерованное множество, от содержания которого зависит, какие опции будут доступны оператору. Обязательным значением является «REGISTER» — собственно регистрация опций (это значение используется по умолчанию, когда переменная явно не определена). Добавим в bl_options опцию «UNDO» для того, чтобы оператор был включен в стек отмены — возврата операций (undo — redo) и ему была доступна отдельная панель в N-панели.

Если просто добавить эту константу в класс createTube панель будет создаваться, он она останется пустой.

Начальные параметры создаваемой трубы заданы в описании функции execute:

  • n — количество ребер
  • r1 — внешний радиус трубы
  • r2 — внутренний радиус трубы
  • h — высота трубы

Превратим их из простых переменных в настоящие свойства оператора. Свойства оператора задаются через bpy.props._тип_свойства следующим образом:

Таким образом задано свойство property целочисленного типа со значением по умолчанию равным 0. Обращаться к нему внутри функций класса-оператора нужно через указатель self:

Зададим начальные параметры нашего оператора в виде свойств:

Непосредственное задание этих параметров в начале функции execute нужно удалить. Внутри функции execute обращение к этим свойствам осуществлять через self.

Так как входные параметры нашего оператора заданы через bpy.props, при создании меша они автоматически добавляются в панель свойств меша в N-панели и ими можно управлять.

Полный и окончательный код аддона выглядит так:

Панель с установкой начальных параметров меша
Панель с установкой начальных параметров меша

Аддон полностью готов. Можно проводить его установку и активацию. И использовать для быстрого создания трубообразных объектов.

Мини-бонус:

Во многих аддонах в конце кода встречается конструкция:

Этот код нужен исключительно в процессе разработки аддона. Если код аддона или ссылка на него в IDE набраны в окне Text Editor — при наличии этого участка кода по нажатию на кнопку Run Script будет выполняться активация аддона в Blender, что позволяет сразу же протестировать его работу. В завершенном аддоне этот код совершенно не нужен.