原文:https://docs.blender.org/api/blender_python_api_current/info_overview.html
- Python in Blender Blender中的Python
Blender嵌入了一个Python解释器,它由Blender启动并保持活跃。这个解释器运行脚本以绘制用户界面,并用于一些Blender的内部工具。
这是一个典型的Python环境,因此关于如何编写Python脚本的教程也将在Blender中运行脚本。Blender为Python解释器提供了bpy模块。可以将这个模块
导入一个脚本,并提供对Blender数据、类和函数的访问。处理Blender数据的脚本需要导入这个模块。
在开发自己的脚本时,它可能有助于理解Blender如何设置Python环境。许多Python脚本都是与Blender绑定的,可以作为参考,因为它们使用脚本作者编
写工具的相同API。脚本的典型用法包括:用户界面、导入/导出、场景操作、自动化、定义您自己的工具集和自定义。
在启动Blender时,扫描Python模块的scripts/startup/
目录并导入它们。这个目录的确切位置取决于您的安装。See the directory layout docs
- Script Loading 脚本加载
看起来很明显,但重要的是要注意直接执行脚本或将脚本导入模块的区别。
扩展Blender的脚本——定义在脚本执行之外的类,这使得将来对这些类的访问(例如取消注册)比导入模块更困难,因为在模块中保存类实例,之后可以通过导入该模块来访问这些类。
出于这个原因,最好只使用直接执行脚本,而不是通过注册类来扩展Blender。
下面是一些在Blender中直接运行脚本的方法
-
加载到文本编辑器中,然后 Run Script.
-
输入或粘贴到python控制台中.
-
在命令行中执行python文件:
blender --python /home/me/my_script.py
作为模块运行:
-
- 很明显的方法, 在文本编辑器或者Python终端中输入
import some_module
. - 打开一个文本块并标记 “注册”选项, 这将和blend文件一起加载.
- 复制到目录
scripts/startup中
, 那么他们将在启动时自动加载. - 定义为插件, 启用的插件将作为Python模块使用.
- 很明显的方法, 在文本编辑器或者Python终端中输入
- Addons 插件
一些Blender的功能最好是根据个人需要可选择的,他们保存在scripts/addons/目录中,只有在用户设置选择他们的时候才会自动启动。
插件和内置Python模块之间的唯一区别是,插件必须包含一个bl_info变量,该变量用于将名称、作者、类别和URL等元数据读取。
用户选项的插件清单使用bl_info来显示关于每个插件的信息。See Addons 有关更详细的bl_info
变量。
在文本编辑器中运行Python脚本对于测试非常有用,但是您需要扩展Blender,使工具与其他内置功能一样可访问。
Blender Python api允许集成:
这是故意有限。目前,对于更高级的特性,如网格修改器、对象类型或着色节点,必须使用C/C++。
对于Python 集成Blender,它定义了所有类型都通用的方法。这是通过创建一个包含由父类指定的变量和函数的一个Python子类来实现的,它被预
先定义为与Blender的接口。
例如:
import bpy class SimpleOperator(bpy.types.Operator): bl_idname = "object.simple_operator" bl_label = "Tool Name" def execute(self, context): print("Hello World") return {'FINISHED'} bpy.utils.register_class(SimpleOperator)
首先,我们定义了一个bpy.types的子类,这在所有可以与Blender结合使用的类中都很常见,所以我们知道如果这是一个操作符,而不是在注册一个面板。
两个类属性都以bl_前缀开头。这是一个惯例用来区分Blender定义的变量和你自己添加的。
接下来查看execute函数,它接受一个操作符和当前上下文的实例。常用的前缀不用于函数。
最后,注册函数被调用,它将类并载入到Blender。See Class Registration.
关于继承,Blender没有对使用的类继承施加限制,注册检查将使用父类中定义的属性和函数。
混合类实例: import bpy class BaseOperator: def execute(self, context): print("Hello World BaseClass") return {'FINISHED'} class SimpleOperator(bpy.types.Operator, BaseOperator): bl_idname = "object.simple_operator" bl_label = "Tool Name" bpy.utils.register_class(SimpleOperator)
注意,这些类没有定义__init__(self)函数。如果定义了__init__()和__del__(),那么类实例的生命周期只会跨越执行。例如,一个面板将为每次重绘提供
一个新实例,因此很少有理由在面板实例中存储变量。相反,应该将持久变量存储在Blenders data中,以便在重新启动Blender时恢复状态。
一旦这个类注册了Blender,就会将类实例化,并将函数调用为Blender。实际上,您不能像大多数Python API那样,从脚本中实例出这些类。
为了调用你定义的运算,你必须通过ops API来调用:
import bpy bpy.ops.object.simple_operator()
用户接口是在一个指定的上下文中,其中可以绘制、按钮窗口、文件头、工具栏等,然后在显示该区域时绘制它们,所以它们是不会直接被Python脚本调用的。
- Registration 注册
- Module Registration 模块注册
在启动时加载的Blender模块需要注册()和unregister()函数。这些都是您的代码中唯一可以调用的函数,否则就是一个常规的Python模块。
一个简单的Blender/Python 模块有这样的形式:
import bpy class SimpleOperator(bpy.types.Operator): """ See example above """ def register(): bpy.utils.register_class(SimpleOperator) def unregister(): bpy.utils.unregister_class(SimpleOperator) if __name__ == "__main__": register()
这些函数通常出现在包含类注册的脚本的底部,有时添加菜单项。您还可以在内部为您自己的工具设置数据时使用它们,但要注意,因为在加载新
的blend文件时,注册器不会重新运行。
因为有了register和unregister的调用,所以在Blender运行时可以切换插件和重载脚本。如果注册调用被放置在脚本的主体中,导入时就会调用注册,这意味着导
入模块或将其加载到Blender中是没有区别的。
当一个脚本从另一个模块导入类时,很难管理加载了哪些类并且是何时加载的,这就会产生问题。
最后两行仅仅是为了测试:
if __name__ == "__main__": register()
这允许在文本编辑器中直接运行脚本以测试更改。由于__main__是为直接执行保留的,所以这个register()导入时不会直接运行。
用Blender注册一个类,将类定义加载到Blender中,并与现有功能一起使用。
加载此类后,您可以从bpy.type访问它。类型,使用bl_idname而不是类原来的名称。
当加载一个类时,Blender对确保所有必需的属性和函数进行了完整性检查,这些属性具有正确的类型,并且函数的参数数量正确。
大多数情况下,你不需要关心这个问题,但是如果这个类定义有问题的话,它会在注册时提出:
使用函数参数时 def execute(self, context, spam)
, 会报错:
ValueError: expected Operator, SimpleOperator class "execute" function to have 2 args, found 3
使用类型 bl_idname = 1
将会提示.
TypeError: validating class error: Operator.bl_idname expected a string type, not int
Multiple-Classes 多重类
向Blender中加载简单的类,使用bpy.utils.register_class就可以完成,但是当你导入的模块中有很多类时,
可以使用
bpy.utils.register_module
(module) and bpy.utils.unregister_module
(module)
当一个脚本定义了很多自己的操作和菜单面板时:
def register(): bpy.utils.register_module(__name__) def unregister(): bpy.utils.unregister_module(__name__)
内部Blender在可注册类型上收集子类,将其存储在定义它们的模块中。通过将模块名传递给bpy. utils.register_module
Blender可以注册这个模块及其子模块创建的所有类。
Inter Classes Dependencies 类依赖
在定制Blender的时候,你可能想要把自己的设置组合在一起,毕竟,它们可能必须与其他脚本共存。为了将属性组合起来,你需要定义一些类,
对于一些组内组或组内集合,你发现你需要处理他们注册和取消注册的顺序。
自定义属性组本身是需要注册的类。
Blender运行时,属性可以添加和删除,这通常发生在类注册和取消注册时,但是在一些特殊的情况中,在脚本运行时修改属性类型是很有用的。
Dynamic Defined-Classes (Advanced) 动态定义类(高级)
在某些情况下,数据的指示符可能不属于Blender,例如renderman着色器的定义,它可能有助于定义类型并快速地删除它们。