首頁  >  文章  >  後端開發  >  Blender Python程式設計入門實例分析

Blender Python程式設計入門實例分析

王林
王林轉載
2023-05-12 10:55:051770瀏覽

    Blender Python 程式設計

    支援的特性:

    • 編輯使用者介面可以編輯的任何資料(場景,網格,粒子等)。

    • 修改使用者首選項、鍵映射和主題。

    • 使用自己的設定運行工具。

    • 建立使用者介面元素,如選單、標題和麵板。

    • 建立新的工具。

    • 建立互動式工具。

    • 建立與 Blender 整合的新渲染引擎。

    • 訂閱對資料及其屬性的變更。

    • 在現有的 Blender 資料中定義新設定。

    • 使用 Python 繪製3D視圖。

    (仍然)缺少的特性:

    • #建立新的空間類型。

    • 為每個類型指派自訂屬性。

    資料存取

    Python 以與動畫系統和使用者介面相同的方式存取 Blender 的資料。這意味著可以透過按鈕更改的任何設定也可以從 Python 更改。

    使用模組可以完成從目前載入的 Blender 檔案存取資料的操作 bpy.data 。這樣就可以存取庫資料。例如:

    >>> bpy.data.objects
    <bpy_collection[3], BlendDataObjects>
    >>> bpy.data.scenes
    <bpy_collection[1], BlendDataScenes>
    >>> bpy.data.materials
    <bpy_collection[1], BlendDataMaterials>

    存取集合

    您會注意到索引和字串都可以用來存取集合的成員。與 Python 字典不同,這兩種方法都是可用的; 但是,在運行 Blender 時,成員的索引可能會改變。

    list(bpy.data.objects)
    [bpy.data.objects["Cube"], bpy.data.objects["Plane"]]
    >>> bpy.data.objects[&#39;Cube&#39;]
    bpy.data.objects["Cube"]
    >>> bpy.data.objects[0]
    bpy.data.objects["Cube"]

    存取屬性

    一旦你有了資料塊,例如一個材質、物件、集合等,它的屬性就可以被訪問,就像使用圖形介面更改設定一樣。事實上,每個按鈕的工具提示也顯示了 Python 屬性,它可以幫助尋找在腳本中更改哪些設定。

    bpy.data.objects[0].name
    &#39;Camera&#39;
    >>> bpy.data.scenes["Scene"]
    bpy.data.scenes[&#39;Scene&#39;]
    >>> bpy.data.materials.new("MyMaterial")
    bpy.data.materials[&#39;MyMaterial&#39;]

    對於測試要存取哪些數據,使用 Python Console 是很有用的,它是自己的空間類型。這支援自動完成,為您提供了一種快速探索文件中的資料的方法。

    可以透過控制台快速找到的資料路徑範例:

    bpy.data.scenes[0].render.resolution_percentage
    100
    >>> bpy.data.scenes[0].objects["Torus"].data.vertices[0].co.x
    1.0

    資料建立/刪除

    當你熟悉其他Python API 時,你可能會驚訝於bpy API 中新的資料塊不能透過呼叫類別來建立:

    bpy.types.Mesh()
    Traceback (most recent call last):
      File "<blender_console>", line 1, in <module>
    TypeError: bpy_struct.__new__(type): expected a single argument

    使用者不能在Blender 資料庫(bpy.data存取的那個)外的任何地方新數據,因為這些資料是由Blender管理的(保存、載入、撤銷、追加等)。

    而只能使用下列方法進行資料增刪:

    mesh = bpy.data.meshes.new(name="MyMesh")
    >>> print(mesh)
    <bpy_struct, Mesh("MyMesh.001")>
    bpy.data.meshes.remove(mesh)

    自訂屬性

    Python 可以存取具有ID 的任何資料區塊上的屬性。當分配屬性時候,如果該屬性本來就不存在,就會新建該屬性。

    這些屬性同樣保存在 Blender 檔案中,並隨著物件一同繼承或複製。

    bpy.context.object["MyOwnProperty"] = 42
    if "SomeProp" in bpy.context.object:
        print("Property found")
    # Use the get function like a Python dictionary
    # which can have a fallback value.
    value = bpy.data.scenes["Scene"].get("test_prop", "fallback value")
    # dictionaries can be assigned as long as they only use basic types.
    collection = bpy.data.collections.new("MyTestCollection")
    collection["MySettings"] = {"foo": 10, "bar": "spam", "baz": {}}
    del collection["MySettings"]

    但是,這些自訂屬性的值必須是基本的 Python 資料類型。如:

    • int/float/string

    • ##int/ float 的陣列

    • #字典(僅支援字串鍵,值也必須是基本型別)

    自訂屬性在Python 外部同樣有效。它們可以透過曲線設定動畫或在驅動路徑中使用。

    上下文 Context

    能夠直接透過名稱或清單存取資料非常有用,但更常見的是根據使用者的選擇進行操作。這些上下文資訊始終可從

    bpy.context 中取得。

    常用案例:

    >>> bpy.context.object
    >>> bpy.context.selected_objects
    >>> bpy.context.visible_bones

    請注意,上下文是唯讀的。這些值不能直接修改,儘管可以透過執行 API 函數或使用資料 API 進行更改。

    因此這樣會

    引發錯誤bpy.context.object = obj

    但是這樣會正常運作:

    bpy.context. scene.objects.active = obj

    運算子Operators (Tools)

    Operators 通常是使用者從按鈕、選單項目或快速鍵存取的工具。從使用者的角度來看,它們是一個工具,但是 Python 可以透過

    bpy.ops 模組來存取、設定並運行他們。

    範例:

    bpy.ops.mesh.flip_normals()
    {&#39;FINISHED&#39;}
    >>> bpy.ops.mesh.hide(unselected=False)
    {&#39;FINISHED&#39;}
    >>> bpy.ops.object.transform_apply()
    {&#39;FINISHED&#39;}

    Operator Cheat Sheet 給出了 Python 語法中所有操作符及其預設值的列表,以及產生的文件。這是一個了解 Blender 所有操作符的好方法。

    Operator Poll()

    許多的 Operators 都有自己的

    Poll() 方法,該方法可以檢查現在的 Blender 上下文是否滿足該 Operator 運行的條件。不滿足時,直接呼叫該 Operator 將會產生錯誤。所以在操作一個Operators 的時候,建議先用一下方式檢查context

    if bpy.ops.view3d.render_border.poll():
        bpy.ops.view3d.render_border()

    將Python 整合到Blender 的方式

    #Python 腳本可以透過以下方式與Blender 整合:

    • 透過定義渲染引擎。

    • 透過定義運算子。

    • 通过定义菜单,标题和面板。

    • 通过将新按钮插入现有菜单,标题和面板

    在 Python 中,这是通过定义一个类来完成的,该类是现有类型的子类。

    Blender 官方文档中提供了实例的类模板。如:

    示例运算符

    import bpy
    def main(context):
        for ob in context.scene.objects:
            print(ob)
    class SimpleOperator(bpy.types.Operator):
        """Tooltip"""
        bl_idname = "object.simple_operator"
        bl_label = "Simple Object Operator"
        @classmethod
        def poll(cls, context):
            return context.active_object is not None
        def execute(self, context):
            main(context)
            return {&#39;FINISHED&#39;}
    def register():
        bpy.utils.register_class(SimpleOperator)
    def unregister():
        bpy.utils.unregister_class(SimpleOperator)
    if __name__ == "__main__":
        register()
    # test call
    bpy.ops.object.simple_operator()

    一旦这个脚本运行,SimpleOperator 在 Blender 中注册,可以从 Operator Search 中调用或添加到工具栏中。

    运行脚本:

    • 启动 Blender 并切换到脚本工作区。

    • 单击文本编辑器中的 New 按钮以创建新的文本数据块。

    • 从上面并将其粘贴到文本编辑器中。

    • 单击 Run Script 按钮。

    • 将光标移至 3D 视口,打开运算符搜索菜单,输入 “Simple”。

    • 点击搜索中找到的 “SimpleOperator” 项目。

    示例面板

    面板注册为一个类,就像操作符一样。请注意用于设置它们所显示的上下文的额外 bl_ 变量。

    import bpy
    class HelloWorldPanel(bpy.types.Panel):
        """Creates a Panel in the Object properties window"""
        bl_label = "Hello World Panel"
        bl_idname = "OBJECT_PT_hello"
        bl_space_type = &#39;PROPERTIES&#39;
        bl_region_type = &#39;WINDOW&#39;
        bl_context = "object"
        def draw(self, context):
            layout = self.layout
            obj = context.object
            row = layout.row()
            row.label(text="Hello world!", icon=&#39;WORLD_DATA&#39;)
            row = layout.row()
            row.label(text="Active object is: " + obj.name)
            row = layout.row()
            row.prop(obj, "name")
            row = layout.row()
            row.operator("mesh.primitive_cube_add")
    def register():
        bpy.utils.register_class(HelloWorldPanel)
    def unregister():
        bpy.utils.unregister_class(HelloWorldPanel)
    if __name__ == "__main__":
        register()

    运行脚本:

    • 启动 Blender 并切换到脚本工作区。

    • 单击文本编辑器中的 New 按钮以创建新的文本数据块。

    • 从上面并将其粘贴到文本编辑器中。

    • 单击 Run Script 按钮。

    要查看结果:

    • 选择默认立方体。

    • 点击按钮面板中的对象属性图标(最右边;出现为一个小立方体)。

    • 向下滚动查看名为 “Hello World Panel” 的面板。

    • 更改对象名称也会更新 Hello World Panel 的 name:字段。

    请注意通过代码定义的行分布以及标签和属性。

    数据类型

    Blender 定义了许多 Python 类型,但也使用 Python 本机类型。

    原生类型

    在简单的情况下,将数字或字符串作为自定义类型会很麻烦,因此可以将它们作为普通的 Python 类型进行访问。

    • Blender float / int / boolean-> float / int / boolean

    • Blender 枚举器->字符串

    >>> C.object.rotation_mode = &#39;AXIS_ANGLE&#39;
    • Blender枚举器(多个)->字符串集

    # setting multiple camera overlay guides
    bpy.context.scene.camera.data.show_guide = {&#39;GOLDEN&#39;, &#39;CENTER&#39;}
    # passing as an operator argument for report types
    self.report({&#39;WARNING&#39;, &#39;INFO&#39;}, "Some message!")

    内部类型

    用于 Blender 数据块和 Blender 集合: bpy.types.bpy_struct

    用于包含 collections/meshes/bones/scenes 等属性的数据。

    包装 Blenders 数据的主要类型有 2 种,

    • 一种用于数据块(内部称为 bpy_struct

    >>> bpy.context.object
    bpy.data.objects[&#39;Cube&#39;]
    • 另一种用于属性。

    >>> C.scene.objects
    bpy.data.scenes[&#39;Scene&#39;].objects

    Mathutils 类型

    用于表示向量,四元数,euler,矩阵和颜色类型等,可从 mathutils 模块访问它们。

    一些属性,如 bpy.types.Object.location, bpy.types.PoseBone.rotation_eulerbpy.types.Scene.Cursor_location 可以作为特殊的数学类型访问,这些类型可以一起使用并以各种有用的方式进行操作。

    例如,矩阵向量的乘法

    bpy.context.object.matrix_world @ bpy.context.object.data.verts[0].co

    注意:mathutils 类型保留对 Blender 内部数据的引用,这样更改就可以应用回来。

    举个例子

    # modifies the Z axis in place.
    bpy.context.object.location.z += 2.0
    # location variable holds a reference to the object too.
    location = bpy.context.object.location
    location *= 2.0
    # Copying the value drops the reference so the value can be passed to
    # functions and modified without unwanted side effects.
    location = bpy.context.object.location.copy()

    动画

    有两种方法可以通过 Python 添加关键帧。

    • 第一种是直接通过键属性,这类似于用户从按钮插入关键帧。

    • 您也可以手动创建曲线和关键帧数据,然后将路径设置为属性。

    这是这两种方法的示例。这两个示例都在活动对象的 Z 轴上插入关键帧。

    简单的例子:

    obj = bpy.context.object
    obj.location[2] = 0.0
    obj.keyframe_insert(data_path="location", frame=10.0, index=2)
    obj.location[2] = 1.0
    obj.keyframe_insert(data_path="location", frame=20.0, index=2)

    使用低级功能:

    obj = bpy.context.object
    obj.animation_data_create()
    obj.animation_data.action = bpy.data.actions.new(name="MyAction")
    fcu_z = obj.animation_data.action.fcurves.new(data_path="location", index=2)
    fcu_z.keyframe_points.add(2)
    fcu_z.keyframe_points[0].co = 10.0, 0.0
    fcu_z.keyframe_points[1].co = 20.0, 1.0

    以上是Blender Python程式設計入門實例分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

    陳述:
    本文轉載於:yisu.com。如有侵權,請聯絡admin@php.cn刪除