Extensions Index

插件#

Important

This page is part of Extensions, and is only available experimentally in daily builds of Blender 4.2. Please enable "Extensions" on the Experimental Preferences to help testing it.

For the deprecated information about individual add-ons bundled with Blender visit 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.

Tip

如果启用后,没有激活插件功能,请打开 控制台窗口,检查是否有错误发生。

用户自定义插件路径#

用户还可以创建个人目录,存放新插件,然后在 偏好设置文件路径 标签页配置文件路径。创建个人脚本目录,请执行以下操作:

  1. 在选择的位置创建一个空文件夹 (如 my_scripts)。

  2. my_scripts 下创建子目录 addons (必须 使用这个名称,Blender才能识别)。

  3. 打开 偏好设置文件路径 标签页。

  4. 设置 脚本 目录指向新建的脚本目录 (如 my_scripts)。

  5. 保存用户设置,重启Blender,这样就可以识别新的插件目录了。

现在,安装插件时,可以在安装第三方脚本时选择 目标路径 。Blender会将新安装的插件复制到用户设置中的目标路径下。

旧版 vs 扩展插件#

With the introduction of Extensions in Blender 4.2, the old way of creating add-ons is considered deprecated. While the changes are rather small they impact existing add-ons.

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.

All add-on maintainers are urged to convert the add-ons they want to share, so they are future proof and can support features like updating from the extensions platform.

转换一个旧版插件到扩展#

  1. Create a manifest file.

  2. Remove the bl_info information (this is now in the manifest).

  3. Replace all references to the module name to __package__.

  4. Make all module imports to use relative import.

  5. Use wheels to pack your external Python dependencies.

  6. 记住要进行彻底的测试。

Note

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.

扩展与命名空间#

The legacy add-ons would use their module name to access the preferences. This could lead to a name clash when extensions with the same name (from different repositories) would be installed. To prevent this conflict, the repository name is now part of the namespace.

For example, now instead of kitsu the module name would be bl_ext.{repository_module_name}.kitsu instead.

This has a few implications for preferences and module imports.

用户设置与 __package__#

Add-ons can define their own preferences which use the package name as an identifier. This can be accessed using __package__.

This was already supported in the legacy add-ons, but not reinforced. As such this can break backward compatibility.

以前:

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

An add-on that defines sub-packages (sub-directories with their own __init__.py file) that needs to use this identifier will have to import the top-level package using a relative import.

from .. import __package__ as base_package

Then base_package can be used instead of __package__. The .. imports relative to the packages parent, sub-sub-packages must use ... and so on.

Note

  • The value of __package__ will vary between systems so it should never be replaced with a literal string.

  • Extensions must not manipulate the value of __package__ as this may cause unexpected behavior or errors.

Relative Imports#

以前:

from kitsu import utils

现在:

from . import utils

Importing packages within the add-on module need to use relative paths. This is a standard Python feature and only applicable for add-ons that have multiple folders.

This was already supported in the legacy add-ons, but not reinforced. As such this can break backward compatibility.

第三方 Python 模块#

Extensions must be self-contained, and as such must come with all its dependencies.

Currently there is no general solution for this although support is planned using Python wheels.

Some options are listed here:

Vendorize 捆绑

This can be used as a way to bundle a pure Python dependencies as a sub-module.

This has the advantage of avoiding version conflicts although it requires some work to setup each package.

Import Wheel's Directly

Wheels themselves can lead to version conflicts, since different add-ons could require different versions of the same library.

It is possible to load wheels that doesn't permanently affect sys.modules or sys.path. This way an add-on can load its own version of an external library from its bundled wheel file.

See Flamenco add-on for an implementation example.

Warning

While this method works in many cases, it can also fail for various reasons:

  • Access to files bundled with the module will fail.

  • Imports made by the module at runtime referencing it's own modules will fail.

  • Mis-match between the wheel and the module name aren't supported.

  • Wheels that depend on other wheels currently aren't supported.

  • Different system-architectures aren't supported.