Если вы когда-либо сидели перед Blender и думали: «Как бы было здорово, если бы этот рабочий процесс был другим» или «Было бы классно, если бы…», то у меня для вас новости — вам не нужно ждать, пока команда Blender прочитает ваши мысли. Вы можете создать это сами. Да, прямо сейчас. С помощью Python. И я говорю не о змее; я говорю о языке программирования, который тихо работает за кулисами красивого пользовательского интерфейса Blender.
Позвольте быть с вами откровенным: когда я впервые попытался создать расширение для Blender, я думал, что мне понадобится докторская степень по вычислительной геометрии и доступ к какой-то секретной пещере разработчиков, спрятанной под офисами Blender. Оказалось, я слишком усложнял. Если вы умеете писать на Python (даже на базовом уровне), вы можете расширять Blender. Точка.
Эта статья — ваш путеводитель по становлению разработчиком расширений для Blender. Мы пройдёмся по всему — от вашего первого оператора «hello world» до упаковки вашего расширения для использования во всём мире. Никаких мистических заклинаний не требуется.
Почему расширения Blender не так страшны
Вот в чём дело с Blender: почти всё, что вы видите в пользовательском интерфейсе — каждая кнопка, каждый ползунок, каждый пункт меню — доступно через Python. Разработчики Blender буквально вручили вам главный ключ и сказали: «давай, веселись». Они не обязаны были это делать, но сделали. Уважение.
Однако различие между надстройками и расширениями имеет значение. Расширения — это более новая и усовершенствованная версия надстроек, представленная в последних версиях Blender. Они распространяются через официальную платформу расширений Blender и следуют более строгим правилам. Но механически? Они работают по тем же принципам Python.
Прежде чем мы углубимся в код, позвольте показать вам, как Blender буквально кричит своим API на вас каждую секунду.
Секретное оружие: подсказки Python
Это первое, что я хочу, чтобы вы сделали, и я серьёзно. Это сэкономит вам часы разочарований.
Откройте Blender и перейдите в:
- Правка → Настройки
- Перейдите в Интерфейс (левая панель)
- В разделе Отображение установите флажок Подсказки Python
Теперь наведите курсор на что угодно в Blender — кнопку, поле ввода, выпадающее меню. Вы увидите код Python, который управляет этим. Навели курсор на значение местоположения X объекта? Вуаля — появляется bpy.context.object.location.x. Это буквально Blender подсказывает вам, как получить доступ ко всему программно. Это как иметь лист с читами, постоянно вытатуированный на интерфейсе.
Вы также можете щёлкнуть правой кнопкой мыши по многим элементам интерфейса и выбрать «Копировать полный путь к данным», чтобы скопировать точную команду Python. Это ваш секретный туннель для понимания API без чтения тысячи страниц документации.
Настройка среды разработки
Знаю, знаю — «ещё один шаг настройки перед написанием реального кода». Но поверьте мне, хорошая среда сделает вас значительно быстрее и менее разочарованным.
Что вам нужно
- Python 3.10+: Blender работает на Python, и вам понадобится такая же версия локально
- VS Code: редактор, в котором происходит реальная разработка
- Расширение Blender Development: расширение VS Code, которое связывает всё воедино
Шаги установки
Сначала скачайте Python с python.org и VS Code. Как только VS Code будет открыт, нажмите Ctrl+Shift+X, чтобы открыть панель «Расширения» и найти «Blender Development» от Jacques Lucke. Установите его.
Затем установите fake-bpy-module. Это золото. Откройте терминал и запустите:
pip install fake-bpy-module
Этот модуль позволяет вам писать код Blender Python без необходимости запуска Blender. Ваша IDE будет предоставлять автозаполнение и проверку ошибок ещё до того, как вы откроете Blender. Это определение опыта разработчика на высшем уровне.
Теперь создайте папку для вашего первого расширения. Назовём её my_first_extension. Откройте её в VS Code. Нажмите Ctrl+Shift+P, введите «Blender» и выберите опцию для создания нового дополнения. Заполните название вашего расширения и имя автора. VS Code создаст базовую структуру файлов для вас.
Понимание архитектуры расширения
Прежде чем писать код, давайте разберёмся, что мы на самом деле создаём. Вот основной поток:
Каждому расширению нужны:
- Файл манифеста: метаданные о вашем расширении
- Файл
__init__.py: место, где происходит волшебство - Классы операторов: отдельные инструменты/функции
- Функции регистрации/отмены регистрации: хуки жизненного цикла Blender
Ваше первое реальное расширение: перемещение объектов
Давайте создадим что-то, что действительно делает что-то. Вот простой оператор, который перемещает все выбранные объекты по оси X:
import bpy
bl_info = {
"name": "Move X Axis",
"author": "Ваше имя",
"version": (1, 0, 0),
"blender": (4, 0, 0),
"location": "View3D > Object Menu",
"description": "Перемещает выбранные объекты вдоль оси X",
"category": "Object",
}
class OBJECT_OT_move_x(bpy.types.Operator):
"""Перемещает выбранные объекты на 1 единицу вдоль оси X"""
bl_idname = "object.move_x"
bl_label = "Move X by One"
bl_options = {'REGISTER', 'UNDO'}
def execute(self, context):
scene = context.scene
for obj in scene.objects:
if obj.select_get():
obj.location.x += 1.0
self.report({'INFO'}, "Objects moved!")
return {'FINISHED'}
def menu_func(self, context):
self.layout.operator(OBJECT_OT_move_x.bl_idname)
def register():
bpy.utils.register_class(OBJECT_OT_move_x)
bpy.types.VIEW3D_MT_object.append(menu_func)
def unregister():
bpy.utils.unregister_class(OBJECT_OT_move_x)
bpy.types.VIEW3D_MT_object.remove(menu_func)
if __name__ == "__main__":
register()
Позвольте разбить, что здесь происходит, потому что это важно:
Словарь bl_info — это как резюме вашего расширения. Blender читает это, чтобы понять, что делает ваше расширение и с какой версией оно совместимо.
Класс OBJECT_OT_move_x наследуется от bpy.types.Operator. Это оператор — фактическое действие. bl_idname должен быть уникальным и следовать шаблону категория.действие. bl_label — это то, что пользователи видят в меню.
Функция execute() — это место, где происходит реальная работа. Когда пользователь вызывает ваш оператор, эта функция выполняется. Мы перебираем выбранные объекты и увеличиваем их местоположение X на 1,0 единицу. Возвращение {'FINISHED'} сообщает Blender, что операция прошла успешно.
Функция menu_func() добавляет наш оператор в меню «Объект». Так пользователи получают к нему доступ.
register() и unregister() — это хуки жизненного цикла. Когда Blender загружает ваше расширение, он вызывает register(). Когда он выгружает, он вызывает unregister().
Для локального тестирования в Blender:
- Скопируйте код в текстовый редактор Blender (рабочий пространство Scripting)
- Запустите его
- Выберите объект
- Откройте меню «Объект» и найдите «Move X by One»
- Нажмите на него и наблюдайте за телепортацией вашего объекта
Выход за рамки кнопок: свойства и панели
Теперь становится интересно. Давайте добавим некоторые элементы управления. Что, если вы хотите, чтобы пользователь указал, насколько сильно переместить объект?
import bpy
from bpy.props import FloatProperty
class OBJECT_OT_move_custom(bpy.types.Operator):
"""Перемещает объекты вдоль оси X на заданное расстояние"""
bl_idname = "object.move_custom"
bl_label = "Move X by Amount"
bl_options = {'REGISTER', 'UNDO'}
amount: FloatProperty(
name="Amount",
description="How far to move",
default=1.0,
min=-100.0,
max=100.0
)
def execute(self, context):
for obj in context.selected_objects:
obj.location.x += self.amount
self.report({'INFO'}, f"Moved {len(context.selected_objects)} objects by {self.amount}")
return {'FINISHED'}
def invoke(self, context, event):
return context.window_manager.invoke_props_dialog(self)
Обратите внимание на FloatProperty? Он создаёт всплывающее диалоговое окно, где пользователи могут ввести значение. Метод invoke() показывает диалоговое окно перед выполнением. Именно так работают профессиональные инструменты — они запраши
