摘要:在交互式控制臺中運行此操作時,您將看到視口更新。鍵入或粘貼到交互式控制臺中。用戶首選項加載項列表使用顯示有關每個加載項的信息。最后兩行僅用于測試這允許腳本直接在文本編輯器中運行以測試更改。
Blender Python API概述
本文檔的目的是解釋Python和Blender如何組合在一起,涵蓋了一些在閱讀API參考和示例腳本時可能不明顯的功能。
Python in BlenderBlender有一個嵌入式Python解釋器,它在Blender啟動時加載,并在Blender運行時保持活動狀態。該解釋器運行腳本來繪制用戶界面,并用于Blender的一些內部工具。
Blender的嵌入式解釋器提供了典型的Python環境,因此關于如何編寫Python腳本的教程中的代碼也可以使用Blender的解釋器運行。Blender為嵌入式解釋器提供了Python模塊,例如bpy和mathutils,因此可以將它們導入到腳本中,并可以訪問Blender的數據,類和函數。處理Blender數據的腳本需要導入模塊才能工作。
這是一個簡單的示例,它移動附加到名為Cube的對象的頂點:
import bpy bpy.data.objects["Cube"].data.vertices[0].co.x += 1.0
這會直接修改Blender的內部數據。在交互式控制臺中運行此操作時,您將看到3D視口更新。
默認環境在開發自己的腳本時,了解Blender如何設置其Python環境可能會有所幫助。許多Python腳本與Blender捆綁在一起,可以用作參考,因為它們使用腳本作者編寫工具的相同API。腳本的典型用法包括:用戶界面,導入/導出,場景操作,自動化,定義自己的工具集和定制。
在啟動時,Blender會掃描scripts/startup/目錄中的Python模塊并導入它們。此目錄的確切位置取決于您的安裝。請參閱目錄布局文檔。
這看起來很明顯,但重要的是要注意直接執行腳本和將腳本作為模塊導入之間的區別。
通過直接執行腳本來擴展Blender意味著腳本完成執行后腳本定義的類在Blender中保持可用。與將腳本作為模塊導入相比,以這種方式使用腳本使得將來訪問其類(例如取消注冊它們)變得更加困難。將腳本作為模塊導入時,其類實例將保留在模塊中,稍后可以通過再次導入該模塊來訪問。
因此,最好避免直接執行通過注冊類來擴展Blender的腳本。
以下是在Blender中直接運行腳本的一些方法。
在文本編輯器中加載并按Run Script。
鍵入或粘貼到交互式控制臺中。
使用Blender從命令行執行Python文件,例如:
blender --python /home/me/my_script.py
要作為模塊運行:
顯而易見的方法,來自文本窗口或交互式控制臺的命令。import some_module
打開文本塊并勾選“注冊”選項,這將加載混合文件。
復制到其中一個目錄中scripts/startup,它們將在啟動時自動導入。
定義為加載項,啟用加載項將其加載為Python模塊。
附加組件一些Blenders功能最好保持可選,除了在啟動時加載的腳本我們有附加組件,這些附加組件保存在它們自己的目錄中scripts/addons,并且只有在從用戶首選項中選擇時才會在啟動時加載。
附加組件和內置Python模塊之間的唯一區別是附加組件必須包含bl_info Blender用于讀取元數據的變量,例如名稱,作者,類別和URL。
用戶首選項加載項列表使用bl_info顯示有關每個加載項的信息。
有關bl_info字典的 詳細信息,請參閱加載項。
在文本編輯器中運行Python腳本對于測試很有用,但是您需要擴展Blender以使工具可以像其他內置功能一樣訪問。
Blender Python api允許集成:
bpy.types.Panel
bpy.types.Menu
bpy.types.Operator
bpy.types.PropertyGroup
bpy.types.KeyingSet
bpy.types.RenderEngine
這是故意限制的。目前,對于更高級的功能,例如網格修改器,對象類型或著色器節點,必須使用C / C ++。
對于Python集成,Blender定義了所有類型共有的方法。這可以通過創建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集成并使用的所有類都是通用的,因此我們知道這是一個運算符而不是注冊時的Panel。
兩個類屬性都以bl_前綴開頭。這是一個用于區分Blender屬性和您自己添加的屬性的約定。
接下來看到execute函數,它接受運算符的實例和當前上下文。公共前綴不用于函數。
最后調用寄存器函數,這將獲取類并將其加載到Blender中。請參閱班級注冊。
關于繼承,Blender不對所使用的類繼承施加限制,注冊檢查將使用父類中定義的屬性和函數。
class mix-in示例:
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 ata中,以便在重新啟動Blender時可以恢復狀態。
注意
模態運算符是一個例外,它們的實例變量保持為Blender運行,請參見模態運算符模板。
因此,一旦類在Blender中注冊,實例化類并調用函數就由Blender完成。實際上,您無法像在大多數Python API中所期望的那樣從腳本中實例化這些類。
要運行運算符,可以通過運算符api調用它們,例如:
import bpy bpy.ops.object.simple_operator()
用戶界面類給出了繪制,按鈕窗口,文件頭,工具欄等的上下文,然后在顯示該區域時繪制它們,因此Python腳本不會直接調用它們。
注冊 模塊注冊啟動時加載的Blender模塊需要register()和unregister()功能。這些是Blender從您的代碼調用的唯一函數,否則它是常規的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()
這些函數通常出現在包含類注冊的腳本的底部,有時會添加菜單項。您也可以將它們用于內部目的,為您自己的工具設置數據,但要小心,因為加載新的混合文件時寄存器不會重新運行。
使用了注冊/取消注冊調用,因此可以在Blender運行時切換加載項和重新加載腳本。如果寄存器調用放在腳本的主體中,則會在導入時調用注冊,這意味著導入模塊或將其類加載到Blender之間沒有區別。
當腳本從另一個模塊導入類時,這會成為問題,因為很難管理正在加載哪些類以及何時加載。
最后兩行僅用于測試:
if __name__ == "__main__": register()
這允許腳本直接在文本編輯器中運行以測試更改。register()將腳本作為模塊導入時,此調用將不會運行,因為__main__保留用于直接執行。
類注冊使用Blender注冊類會導致類定義被加載到Blender中,并在現有功能的同時可用。
加載此類后,您可以bpy.types使用bl_idname而不是類原始名稱來訪問它。
加載類時,Blender執行完整性檢查,確保找到所有必需的屬性和函數,屬性具有正確的類型,并且函數具有正確數量的參數。
大多數情況下,你不需要擔心這個問題,但是如果類定義有問題,它將在注冊時引發:
使用函數參數,將引發異常:def execute(self, context, spam)
ValueError: expected Operator, SimpleOperator class "execute" function to have 2 args, found 3
使用將提高。bl_idname = 1
TypeError: validating class error: Operator.bl_idname expected a string type, not int
上面描述了將類加載到Blender中,對于簡單的情況,調用bpy.utils.register_class(SomeClass)就足夠了,但是當有很多類或子模塊子模塊有自己的類時,將它們全部列入注冊可能會很繁瑣。
為了更方便的加載/卸載bpy.utils.register_module(模塊)和bpy.utils.unregister_module(模塊)功能存在。
一個腳本,它定義了許多自己的操作符,面板菜單等,你只需要編寫:
def register(): bpy.utils.register_module(__name__) def unregister(): bpy.utils.unregister_module(__name__)
內部Blender在可注冊類型上收集子類,通過定義它們的模塊存儲它們。通過將模塊名稱傳遞給bpy.utils.register_module Blender,可以注冊該模塊及其子模塊創建的所有類。
類間依賴性在自定義Blender時,您可能希望將自己的設置組合在一起,畢竟,它們可能必須與其他腳本共存。要對這些屬性進行分組,需要定義類,對于組內的組或組內的集合,您可以發現自己必須處理注冊/取消注冊的順序。
自定義屬性組本身就是需要注冊的類。
假設您要存儲自定義引擎的材質設置。
# Create new property # bpy.data.materials[0].my_custom_props.my_float import bpy class MyMaterialProps(bpy.types.PropertyGroup): my_float = bpy.props.FloatProperty() def register(): bpy.utils.register_class(MyMaterialProps) bpy.types.Material.my_custom_props = bpy.props.PointerProperty(type=MyMaterialProps) def unregister(): del bpy.types.Material.my_custom_props bpy.utils.unregister_class(MyMaterialProps) if __name__ == "__main__": register()
注意
該類必須在用于屬性之前注冊,否則將引發錯誤: ValueError: bpy_struct "Material" registration error: my_custom_props could not register
# Create new property group with a sub property # bpy.data.materials[0].my_custom_props.sub_group.my_float import bpy class MyMaterialSubProps(bpy.types.PropertyGroup): my_float = bpy.props.FloatProperty() class MyMaterialGroupProps(bpy.types.PropertyGroup): sub_group = bpy.props.PointerProperty(type=MyMaterialSubProps) def register(): bpy.utils.register_class(MyMaterialSubProps) bpy.utils.register_class(MyMaterialGroupProps) bpy.types.Material.my_custom_props = bpy.props.PointerProperty(type=MyMaterialGroupProps) def unregister(): del bpy.types.Material.my_custom_props bpy.utils.unregister_class(MyMaterialGroupProps) bpy.utils.unregister_class(MyMaterialSubProps) if __name__ == "__main__": register()
注意
最低級別需要首先注冊,而unregister()是register()的鏡像操縱類
可以在Blender運行時添加和刪除屬性,通常在注冊或取消注冊時發生,但對于某些特殊情況,在腳本運行時修改類型可能很有用。
例如:
# add a new property to an existing type bpy.types.Object.my_float = bpy.props.FloatProperty() # remove del bpy.types.Object.my_float
這適用于您自己定義的PropertyGroup子類。
class MyPropGroup(bpy.types.PropertyGroup): pass MyPropGroup.my_float = bpy.props.FloatProperty()
......這相當于:
class MyPropGroup(bpy.types.PropertyGroup): my_float = bpy.props.FloatProperty()動態定義類(高級)
在某些情況下,數據的說明符可能不在Blender,renderman著色器定義中,例如,將它們定義為類型并在運行中刪除它們可能很有用。
for i in range(10):
idname = "object.operator_%d" % i def func(self, context): print("Hello World", self.bl_idname) return {"FINISHED"} opclass = type("DynOp%d" % i, (bpy.types.Operator, ), {"bl_idname": idname, "bl_label": "Test", "execute": func}, ) bpy.utils.register_class(opclass)
注意
type()被調用來定義類。這是Python中類創建的替代語法,更適合動態構造類。
要從上一個示例中調用運算符:
>>> bpy.ops.object.operator_1() Hello World OBJECT_OT_operator_1 {"FINISHED"}
>>> bpy.ops.object.operator_2() Hello World OBJECT_OT_operator_2 {"FINISHED"}
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/42160.html
摘要:在控制臺中輸入路徑。因此,下一步是通過參考文件檢查訪問畫筆的位置。上下文畫筆紋理對比度由于每個屬性都是按照我們在控制臺中組成數據路徑的方式給出的可以有多種方式來訪問相同的數據,您選擇的方法通常取決于任務。 Blender參考API用法 Blender有許多互連數據類型,它們具有自動生成的引用api,它通常具有編寫腳本所需的信息,但可能難以使用。 本文檔旨在幫助您了解如何使用參考API。...
摘要:插件教程什么是插件插件只是一個帶有一些附加要求的模塊,因此可以在包含有用信息的列表中顯示它。安裝附加組件時,將在控制臺中打印源和目標路徑。現在嘗試將此腳本復制到并在默認多維數據集上運行它。 Blender插件教程 什么是插件?插件只是一個帶有一些附加要求的Python模塊,因此Blender可以在包含有用信息的列表中顯示它。 舉個例子,這是最簡單的插件: bl_info = {name...
摘要:為了讓數值計算的結果能夠有更好的渲染效果,這段時間一直在用這個開源軟件來處理計算結果。 為了讓數值計算的結果能夠有更好的渲染效果,這段時間一直在用Blender這個開源軟件來處理計算結果。 因為是處理大量數據的計算結果,所以不得不考慮用Python編寫腳本來實現批量處理,編寫過程中,Google幫我解決了大部分實現過程中的障礙,下面是完整的實現過程: 將計算結果的mesh文件導入到...
摘要:源網頁說明文檔所有關于你應該且必須知道的。性能和優化概述的兼容性旨在兼容多種不同版本的支持的兼容性地理框架打算成為世界級的地理框架。其目標是盡可能簡單地構建應用程序并利用空間使能數據的功能。 源網頁:https://docs.djangoproject.co... django說明文檔 所有關于django你應該且必須知道的。 第一步 你是否django編程新手,那就從此開始!從零開始...
閱讀 3495·2023-04-26 02:44
閱讀 1632·2021-11-25 09:43
閱讀 1523·2021-11-08 13:27
閱讀 1888·2021-09-09 09:33
閱讀 906·2019-08-30 15:53
閱讀 1768·2019-08-30 15:53
閱讀 2780·2019-08-30 15:53
閱讀 3114·2019-08-30 15:44