跳轉到內容

Blender 3D:菜鳥到高手/高階教程/Blender 指令碼/新增自定義屬性

來自華夏公益教科書,開放的書籍,開放的世界

外掛通常會做更多的事情,而不僅僅是無條件地執行單個操作;使用者可以透過多種方式控制它們的操作。我們可以為外掛面板新增用於調整設定的控制元件,並將這些控制元件與為當前場景定義的自定義屬性關聯起來;Blender 隨後會負責在使用者操作這些控制元件時更新屬性值,而我們的運算子的呼叫例程可以在執行時獲取這些屬性值。

定義屬性

[編輯 | 編輯原始碼]

屬性需要在自定義類註冊時同時定義。我們之前在頂層語句中完成此操作,但現在讓我們將所有內容一起收集到一個註冊方法中,如下所示

def register() :
    bpy.utils.register_class(MakeTetrahedron)
    bpy.utils.register_class(TetrahedronMakerPanel)
    bpy.types.Scene.make_tetrahedron_inverted = bpy.props.BoolProperty \
      (
        name = "Upside Down",
        description = "Generate the tetrahedron upside down",
        default = False
      )
#end register

在這裡,我們將屬性作為 Blender 的新屬性附加場景類;Python 允許我們將新屬性分配給幾乎任何物件,Blender 充分利用了這一點。請注意,必須使用bpy.props中提供的屬性定義例程之一來建立屬性;選擇與您要建立的屬性型別匹配的例程。在這裡,我們定義了一個簡單的真/假切換,使用者將透過複選框控制它。無論您為自定義類屬性使用什麼名稱,該類的例項都將具有相同名稱的屬性,該屬性儲存該屬性的實際值。

名稱將用作用於檢查或更改此屬性的控制元件的名稱,而描述將作為工具提示出現在使用者將滑鼠懸停在控制元件上時。這預設值用作屬性的初始值。

還要注意,我嘗試使用一個名稱,make_tetrahedron_inverted,該名稱不太可能與其他外掛或 Blender 部分定義的名稱衝突。

我們還將新增一個登出方法,它撤消註冊所做的一切。這目前不會真正使用,但當我們提取外掛以進行單獨安裝時,它將變得相關

def unregister() :
    bpy.utils.unregister_class(MakeTetrahedron)
    bpy.utils.unregister_class(TetrahedronMakerPanel)
    del bpy.types.Scene.make_tetrahedron_inverted
#end unregister

要使複選框顯示,請將以下行新增到面板的繪製例程

       TheColumn.prop(context.scene, "make_tetrahedron_inverted")

prop方法的第一個引數必須是我們在上面附加屬性定義的類的例項;在本例中,它是當前場景。

最後,我們需要用以下樣板程式碼完成我們的指令碼,該程式碼將在 Blender 不為我們呼叫註冊例程的情況下(例如在文字編輯器中)呼叫該例程

if __name__ == "__main__" :
    register()
#end if

使用屬性

[編輯 | 編輯原始碼]

現在,我們需要在運算子的執行例程中實際使用該屬性。我們將使用它來否定應用於四面體頂點 Z 座標的比例因子

        Scale = -1 if context.scene.make_tetrahedron_inverted else 1

但只有最後一個頂點具有非零 Z 座標,因此這是唯一需要更改其計算的頂點

        Vertices = \
          [
            mathutils.Vector((0, -1 / math.sqrt(3),0)),
            mathutils.Vector((0.5, 1 / (2 * math.sqrt(3)), 0)),
            mathutils.Vector((-0.5, 1 / (2 * math.sqrt(3)), 0)),
            mathutils.Vector((0, 0, Scale * math.sqrt(2 / 3))),
          ]

整合在一起

[編輯 | 編輯原始碼]

為了回顧我們所有更改,以下是完整的更新指令碼

import math
import bpy
import mathutils

class TetrahedronMakerPanel(bpy.types.Panel) :
    bl_space_type = "VIEW_3D"
    bl_region_type = "TOOLS"
    bl_context = "objectmode"
    bl_category = "Create"
    bl_label = "Add Tetrahedron"

    def draw(self, context) :
        TheColumn = self.layout.column(align = True)
        TheColumn.prop(context.scene, "make_tetrahedron_inverted")
        TheColumn.operator("mesh.make_tetrahedron", text = "Add Tetrahedron")
    #end draw

#end TetrahedronMakerPanel

class MakeTetrahedron(bpy.types.Operator) :
    bl_idname = "mesh.make_tetrahedron"
    bl_label = "Add Tetrahedron"
    bl_options = {"UNDO"}

    def invoke(self, context, event) :
        Scale = -1 if context.scene.make_tetrahedron_inverted else 1
        Vertices = \
          [
            mathutils.Vector((0, -1 / math.sqrt(3),0)),
            mathutils.Vector((0.5, 1 / (2 * math.sqrt(3)), 0)),
            mathutils.Vector((-0.5, 1 / (2 * math.sqrt(3)), 0)),
            mathutils.Vector((0, 0, Scale * math.sqrt(2 / 3))),
          ]
        NewMesh = bpy.data.meshes.new("Tetrahedron")
        NewMesh.from_pydata \
          (
            Vertices,
            [],
            [[0, 1, 2], [0, 1, 3], [1, 2, 3], [2, 0, 3]]
          )
        NewMesh.update()
        NewObj = bpy.data.objects.new("Tetrahedron", NewMesh)
        context.scene.objects.link(NewObj)
        return {"FINISHED"}
    #end invoke

#end MakeTetrahedron

def register() :
    bpy.utils.register_class(MakeTetrahedron)
    bpy.utils.register_class(TetrahedronMakerPanel)
    bpy.types.Scene.make_tetrahedron_inverted = bpy.props.BoolProperty \
      (
        name = "Upside Down",
        description = "Generate the tetrahedron upside down",
        default = False
      )
#end register

def unregister() :
    bpy.utils.unregister_class(MakeTetrahedron)
    bpy.utils.unregister_class(TetrahedronMakerPanel)
    del bpy.types.Scene.make_tetrahedron_inverted
#end unregister

if __name__ == "__main__" :
    register()
#end if

與之前一樣,使用  ALT + P  執行指令碼。檢查 3D 檢視中的工具架,您的面板現在應該看起來像這樣

嘗試在選中和未選中複選框的情況下執行它,您應該得到兩個朝相反方向指向的四面體。

華夏公益教科書