Дополнения (add-ons)#
Add-ons let you extend Blender’s functionality using Python. Most of the time you can get add-ons as part of the Extensions system.
Совет
If the Add-on does not activate when enabled, check the Console window for any errors that may have occurred.
Internet Access#
If the add-on needs to use internet, it must check for the (read-only) property bpy.app.online_access
.
This option is controlled by Preferences, which can be overriding via command-line
(--offline-mode
/ --online-mode
).
For better error messages, you can check also for bpy.app.online_access_overriden
,
to determine whether users can turn Allow Online Access
on the preferences, or not.
Примечание
Add-ons that follow this setting will only connect to the internet if enabled. However, Blender cannot prevent third-party add-ons from violating this rule.
Bundle Dependencies#
For add-ons to be bundled as extensions, they must be self-contained. That means they must come with all its dependencies. In particular 3rd party Python modules.
Для этого есть несколько вариантов:
- Bundle with Python Wheels.
This is the recommended way to bundle dependencies.
- Bundle other add-ons together.
This is recommended if an add-on depends on another add-on.
Make sure that both the individual and the combined add-on check for already registered types (Operators, Panels, …). This avoids duplication of operators and panels on the interface if the add-ons are installed as a bundle and individually.
- В комплекте с Vendorize
Это можно использовать как способ объединения зависимостей чистого Python в качестве подмодуля.
Преимущество этого подхода состоит в том, что он позволяет избежать конфликтов версий, хотя для настройки каждого пакета требуется определённая работа.
Local Storage#
Add-ons must not assume their own directory is user writable since this may not be the case for «System» repositories. Writing files into the add-on’s directory also has the down side that upgrading the extension will remove all files.
Add-ons which need their own user directory should use a utility function provided for this purpose:
extension_directory = bpy.utils.extension_path_user(__package__, path="", create=True)
If you wish create subdirectories, this can be done with the path
argument.
This directory will be kept between upgrades but will be removed if the extension is uninstalled.
Устаревшие (Legacy) аддоны против аддонов расширений (Extension)#
С появлением расширений в Blender 4.2, старый способ создания аддонов считается устаревшим. Хотя изменения довольно небольшие, они влияют на существующие аддоны.
In order to allow a smooth transition process, the so-called legacy add-ons will continue to be supported by Blender. They can be installed via Install legacy Add-on button in the User Preferences.
Всем разработчикам аддонов рекомендуется конвертировать дополнения, которыми они хотят поделиться, чтобы они были готовы к будущему и могли поддерживать такие функции, как обновление с платформы расширений.
Конвертация устаревшего аддона в расширение#
Create a manifest file.
Удалите информацию
bl_info
(теперь она находится в манифесте).Замените все ссылки на имя модуля на
__package__
.Сделайте все импорты модулей, чтобы использовать относительный импорт.
Используйте wheels для упаковки внешних зависимостей Python.
Remember to test it thoroughly.
Примечание
For testing it is import to install the extension from disk and check if everything is working well. This will get you as close to the final experience as possible.
Расширения и пространство имён (Namespace)#
Устаревшие аддоны будут использовать имя своего модуля для доступа к настройкам. Это может привести к конфликту имён при установке расширений с одинаковым именем (из разных репозиториев). Чтобы предотвратить этот конфликт, имя репозитория теперь является частью пространства имён.
Например, теперь вместо kitsu
имя модуля будет bl_ext.{repository_module_name}.kitsu
.
Это имеет некоторые последствия для настроек и импорта модулей.
Пользовательские настройки и упаковка __package__
#
Аддоны могут определять свои собственные настройки, которые используют имя пакета в качестве идентификатора. Доступ к нему можно получить с помощью __package__
.
Это уже поддерживалось в устаревших аддонах, но не было усилено. Таким образом, это может нарушить обратную совместимость.
До:
class KitsuPreferences(bpy.types.AddonPreferences): bl_idname = "kitsu" # ... snip ... # Access with: addon_prefs = bpy.context.preferences.addons["kitsu"]
Сейчас:
class KitsuPreferences(bpy.types.AddonPreferences): bl_idname = __package__ # ... snip ... # Access with: addon_prefs = bpy.context.preferences.addons[__package__]
- Подпакеты (Sub-packages)
Аддон, определяющий подпакеты (подкаталоги с собственным файлом
__init__.py
), которым необходимо использовать этот идентификатор, должен будет импортировать пакет верхнего уровня, используя относительный импорт.from .. import __package__ as base_package
Тогда вместо
__package__
можно использоватьbase_package
. «..
» импортируется относительно родительского пакета, субподпакеты (sub-sub-packages) должны использовать...
и так далее.
Примечание
Значение
__package__
будет различаться в зависимости от системы, поэтому его никогда не следует заменять буквенной строкой.Расширения не должны манипулировать значением
__package__
, поскольку это может привести к неожиданному поведению или ошибкам.
Относительный импорт#
- до:
from kitsu import utils
- сейчас:
from . import utils
Для импорта пакетов в модуль аддона необходимо использовать относительные пути. Это стандартная функция Python, применимая только для аддонов, имеющих несколько папок.
Это уже поддерживалось в устаревших аддонах, но не было усилено. Таким образом, это может нарушить обратную совместимость.