• 二、Blender/Python API总览


    原文: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着色器的定义,它可能有助于定义类型并快速地删除它们。

  • 相关阅读:
    @黎耀天 , 你的 论文 里 是不是 说 电场 磁场 对 光 有 作用 ?
    《如何彻底搞懂狭义相对论里的“光速不变”?》 回复
    宇宙际理论该如何理解?
    无工质 飞行装置
    《李秉泉的心里话》 回复
    《与K歌之王的交流》 回复
    我对 李炳铁 和 李秉泉 两位老师 的 学术成果 的 评价
    知乎 : 为什么美国中小学生学的数学比我们简单,美国人却还能做出超级牛的东西?
    @bnllm 快把 0, 1, 1, 无穷, 无穷, 阶乘, 指数 玩坏了
    让 我们 来 测量 普朗克常数 和 万有引力常数
  • 原文地址:https://www.cnblogs.com/wildbloom/p/7732067.html
Copyright © 2020-2023  润新知