跳轉至內容

Blender 3D:從新手到專業/高階教程/Blender 指令碼/外掛剖析

來自 Wikibooks,為開放世界提供開放書籍

一個外掛是一個 Python 指令碼,它可以以多種方式擴充套件 Blender 的功能。它可以位於 Blender 使用者偏好目錄中的一個檔案中,也可以儲存在 Blender 文件中的一個文字塊中。在前一種情況下,外掛需要在要使用它的每個 Blender 文件中啟用,方法是在該文件的“使用者偏好設定”視窗中的“外掛”列表中,勾選其條目中的複選框。在後一種情況下,指令碼可以透過在“文字編輯器”視窗中按下  ALT + P  來執行;或者你可以在“文字編輯器”中勾選該指令碼的“註冊”複選框,以便在文件載入到 Blender 中後自動啟用該外掛。

外掛指令碼通常要做的事情是定義一個或多個新的運算子。Blender 中的所有使用者介面功能都是由運算子執行的;它們透過與選單項、按鈕或熱鍵相關聯來呼叫。每個運算子都是bpy.types.Operator類的子類。你在 Python 中給你的類取的名字在定義它的指令碼之外並不重要;它將透過它的運算子名稱從 Blender 的其他地方引用,這個名稱在文件中必須是唯一的。同樣,你的指令碼可以透過 Blender API 函式來呼叫其他地方定義的運算子,這些函式需要運算子名稱作為引數。

文字塊

[編輯 | 編輯原始碼]

一個 Blender 文件可以包含文字塊,它們與 3D 場景中的文字物件不同(儘管前者可以轉換為後者)。除了生成文字物件之外,文字塊還可以用作任何你喜歡的目的;例如,用它將工作流程說明與文件一起傳遞給同事;在使用者開啟文件時看到的初始佈局中顯示版權或幫助資訊;或者儲存一個 Python 指令碼,使用者可以執行它來執行與文件相關的某些有用操作。

你的第一個運算子

[編輯 | 編輯原始碼]

開啟一個新的、空的 Blender 文件。在任何方便的視窗中調出“文字編輯器” ;你會看到一個空灰色矩形。在你可以輸入文字之前,你需要建立一個文字塊;透過點選視窗標題中標記為“新建”的大按鈕來建立它。一旦你這樣做,你應該會看到一個彈出選單出現,列出文件中的所有文字塊,當前(唯一)的條目名為“文字”。你應該還會看到一個紅色插入光標出現在左上角,表示你可以開始輸入。

與“控制檯視窗”不同,不會自動為你匯入任何內容。因此,與任何其他 Python 指令碼一樣,你需要提及你想要訪問的每個模組。

你將運算子定義為bpy.types.Operator的子類。它必須有一個bl_idname類屬性,它給出運算子名稱,而bl_label給出在空格鍵選單中顯示的使用者可見名稱。前者必須具有有效的 Python 語法,用於命名,包括一個點;點左邊的部分必須是有效運算子類別之一的名稱,你可以在“控制檯視窗”中輸入

dir(bpy.ops)

來找到它。

讓我們定義一個運算子,它將在文件中新增一個新的四面體物件。類定義應該以類似這樣的形式開始

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

它必須定義一個invoke方法,它以類似這樣的形式開始

    def invoke(self, context, event) :

invoke方法執行運算子的實際功能;在它完成後,它必須返回一個值,該值是一組字串,告訴 Blender 一些事情,比如運算子是否仍處於模態狀態,或者操作是否已完成,如果是,那麼它是成功完成還是失敗完成。要指示成功完成:在invoke方法的結尾新增以下程式碼

        return {"FINISHED"}

無論如何,讓我們計算四面體頂點的座標:邊長為 1 Blender 單位,合適的數值為 。或者在 Python 中

        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, math.sqrt(2 / 3))),
          ]

然後我們建立網格資料塊,並將其命名為“四面體”

        NewMesh = bpy.data.meshes.new("Tetrahedron")

用上面的頂點定義和相關聯的面來填充它

        NewMesh.from_pydata \
          (
            Vertices,
            [],
            [[0, 2, 1], [0, 1, 3], [1, 2, 3], [2, 0, 3]]
          )

Mesh.from_pydata方法目前在 Blender API 中沒有很好的文件,但它的第一個引數是Vector陣列,用於定義頂點,第二個引數是邊定義陣列,第三個引數是面定義陣列。每個邊或面都被定義為頂點索引列表(每列表中包含 2 個元素,邊為 2 個,面為 3 個或 4 個),以通常的 Python 方式從 0 開始,是傳遞給你的頂點定義陣列的索引。請注意,你傳遞的是邊定義或面定義,但不能同時傳遞兩者:另一個應該傳遞為空列表。如果此函式使用不當,會導致 Blender 崩潰。

我們還需要新增以下內容,告訴 Blender 網格已更改,需要更新(就好像它無法自己弄清楚一樣)

        NewMesh.update()

(省略此操作會導致一個小問題:右鍵單擊新建立的四面體不會像其他物件那樣以橙色突出顯示其輪廓,但如果你進入物件的編輯模式並退出,問題就會消失。)

現在建立物件資料塊(我也將其命名為“四面體”),並將其連結到網格

        NewObj = bpy.data.objects.new("Tetrahedron", NewMesh)

但物件只有在連結到場景後才會顯示給使用者

        context.scene.objects.link(NewObj)

回顧一下,這是完整的指令碼

import math
import bpy
import mathutils

class MakeTetrahedron(bpy.types.Operator) :
    bl_idname = "mesh.make_tetrahedron"
    bl_label = "Add Tetrahedron"
    def invoke(self, context, event) :
        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, math.sqrt(2 / 3))),
          ]
        NewMesh = bpy.data.meshes.new("Tetrahedron")
        NewMesh.from_pydata \
          (
            Vertices,
            [],
            [[0, 2, 1], [0, 1, 3], [1, 2, 3], [2, 0, 3]]
          )
        NewMesh.update()
        NewObj = bpy.data.objects.new("Tetrahedron", NewMesh)
        # Blender 2.79: context.scene.objects.link(NewObj)
        context.collection.objects.link(NewObj)
        return {"FINISHED"}
    #end invoke
#end MakeTetrahedron

bpy.utils.register_class(MakeTetrahedron)

請注意添加了 register_class 呼叫,讓 Blender 將你的運算子新增到其內建集合中。

現在透過輸入  ALT + P  來執行你的指令碼。如果一切順利,不應該有任何明顯的變化發生;Blender 將定義類並將它註冊為一個新的運算子,如你所要求的那樣,隨時可以使用。

如果你遇到任何語法錯誤,Blender 應該會在一個彈出視窗中顯示這些錯誤;返回並更正它們,並使用  ALT + P  重新執行指令碼。

呼叫你的運算子

[編輯 | 編輯原始碼]

我們還沒有(現在)為這個運算子定義任何使用者介面;那麼我們如何呼叫它呢?很簡單。

進入 3D 檢視視窗。刪除預設的立方體以避免它遮擋其他物體,然後按下  空格鍵  (Blender 2.8 和 Blender 3 中為 F3)。這將彈出一個可搜尋的選單,包含當前文件中定義的所有運算子。在搜尋框中,輸入你為該bl_label屬性定義的字串的一部分或全部(輸入“tetra”應該足夠)。這將限制菜單隻顯示包含該字串的專案,其中應該包括你的運算子名稱;用  滑鼠左鍵  點選它,或選中它並按下  回車鍵 。如果一切順利,你應該會看到你的四面體物件出現!如果它沒有出現,請確保在偏好設定編輯器中,介面/顯示的“開發者額外功能”複選框被選中。

如果遇到錯誤

[編輯 | 編輯原始碼]

如果在編譯或執行指令碼時遇到任何錯誤,Blender 會在彈框中顯示它。例如,以下簡單的單行指令碼

raise RuntimeError("Uh-oh")

將顯示此彈框

完整的 Python 追溯訊息將寫入標準錯誤,看起來像這樣

Traceback (most recent call last):
  File "/Text", line 1, in <module>
RuntimeError: Uh-Oh!

在 Linux/Unix 系統上,如果你從命令列啟動 Blender,則訊息將出現在終端會話中;否則,如果你是從 GUI 啟動 Blender,則訊息將被追加到你的~/.xsessionerrors檔案。在 Windows 上,訊息會出現在控制檯視窗中。

華夏公益教科書