WildBloom

导航

 

原文:https://docs.blender.org/api/blender_python_api_current/info_overview.html

 


 

    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

    看起来很明显,但重要的是要注意直接执行脚本或将脚本导入模块的区别。

    扩展Blender的脚本——定义在脚本执行之外的类,这使得将来对这些类的访问(例如取消注册)比导入模块更困难,因为在模块中保存类实例,之后可以通过导入该模块来访问这些类。

    出于这个原因,最好只使用直接执行脚本,而不是通过注册类来扩展Blender。

    下面是一些在Blender中直接运行脚本的方法

    •   加载到文本编辑器中,然后 Run Script.

    •   输入或粘贴到python控制台中.

    •   在命令行中执行python文件:

        blender --python /home/me/my_script.py

    作为模块运行:

    •   很明显的方法, 在文本编辑器或者Python终端中输入 import some_module .
    •   打开一个文本块并标记 “注册”选项, 这将和blend文件一起加载.
    •   复制到目录 scripts/startup中, 那么他们将在启动时自动加载.
    •   定义为插件, 启用的插件将作为Python模块使用.

    一些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脚本调用的。

        在启动时加载的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 args, found 3

        使用类型 bl_idname 1 将会提示.

        TypeError: validating class error: Operator.bl_idname expected 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的时候,你可能想要把自己的设置组合在一起,毕竟,它们可能必须与其他脚本共存。为了将属性组合起来,你需要定义一些类,

          对于一些组内组或组内集合,你发现你需要处理他们注册和取消注册的顺序。

            自定义属性组本身是需要注册的类。

                                   Manipulating Classes  操作类

            Blender运行时,属性可以添加和删除,这通常发生在类注册和取消注册时,但是在一些特殊的情况中,在脚本运行时修改属性类型是很有用的。

                                   Dynamic Defined-Classes (Advanced)  动态定义类(高级)

            在某些情况下,数据的指示符可能不属于Blender,例如renderman着色器的定义,它可能有助于定义类型并快速地删除它们。

posted on 2017-10-26 20:28  WildBloom  阅读(4981)  评论(0编辑  收藏  举报