摘要:在交互式控制臺中運(yùn)行此操作時,您將看到視口更新。鍵入或粘貼到交互式控制臺中。用戶首選項加載項列表使用顯示有關(guān)每個加載項的信息。最后兩行僅用于測試這允許腳本直接在文本編輯器中運(yùn)行以測試更改。
Blender Python API概述
本文檔的目的是解釋Python和Blender如何組合在一起,涵蓋了一些在閱讀API參考和示例腳本時可能不明顯的功能。
Python in BlenderBlender有一個嵌入式Python解釋器,它在Blender啟動時加載,并在Blender運(yùn)行時保持活動狀態(tài)。該解釋器運(yùn)行腳本來繪制用戶界面,并用于Blender的一些內(nèi)部工具。
Blender的嵌入式解釋器提供了典型的Python環(huán)境,因此關(guān)于如何編寫Python腳本的教程中的代碼也可以使用Blender的解釋器運(yùn)行。Blender為嵌入式解釋器提供了Python模塊,例如bpy和mathutils,因此可以將它們導(dǎo)入到腳本中,并可以訪問Blender的數(shù)據(jù),類和函數(shù)。處理Blender數(shù)據(jù)的腳本需要導(dǎo)入模塊才能工作。
這是一個簡單的示例,它移動附加到名為Cube的對象的頂點(diǎn):
import bpy bpy.data.objects["Cube"].data.vertices[0].co.x += 1.0
這會直接修改Blender的內(nèi)部數(shù)據(jù)。在交互式控制臺中運(yùn)行此操作時,您將看到3D視口更新。
默認(rèn)環(huán)境在開發(fā)自己的腳本時,了解Blender如何設(shè)置其Python環(huán)境可能會有所幫助。許多Python腳本與Blender捆綁在一起,可以用作參考,因?yàn)樗鼈兪褂媚_本作者編寫工具的相同API。腳本的典型用法包括:用戶界面,導(dǎo)入/導(dǎo)出,場景操作,自動化,定義自己的工具集和定制。
在啟動時,Blender會掃描scripts/startup/目錄中的Python模塊并導(dǎo)入它們。此目錄的確切位置取決于您的安裝。請參閱目錄布局文檔。
這看起來很明顯,但重要的是要注意直接執(zhí)行腳本和將腳本作為模塊導(dǎo)入之間的區(qū)別。
通過直接執(zhí)行腳本來擴(kuò)展Blender意味著腳本完成執(zhí)行后腳本定義的類在Blender中保持可用。與將腳本作為模塊導(dǎo)入相比,以這種方式使用腳本使得將來訪問其類(例如取消注冊它們)變得更加困難。將腳本作為模塊導(dǎo)入時,其類實(shí)例將保留在模塊中,稍后可以通過再次導(dǎo)入該模塊來訪問。
因此,最好避免直接執(zhí)行通過注冊類來擴(kuò)展Blender的腳本。
以下是在Blender中直接運(yùn)行腳本的一些方法。
在文本編輯器中加載并按Run Script。
鍵入或粘貼到交互式控制臺中。
使用Blender從命令行執(zhí)行Python文件,例如:
blender --python /home/me/my_script.py
要作為模塊運(yùn)行:
顯而易見的方法,來自文本窗口或交互式控制臺的命令。import some_module
打開文本塊并勾選“注冊”選項,這將加載混合文件。
復(fù)制到其中一個目錄中scripts/startup,它們將在啟動時自動導(dǎo)入。
定義為加載項,啟用加載項將其加載為Python模塊。
附加組件一些Blenders功能最好保持可選,除了在啟動時加載的腳本我們有附加組件,這些附加組件保存在它們自己的目錄中scripts/addons,并且只有在從用戶首選項中選擇時才會在啟動時加載。
附加組件和內(nèi)置Python模塊之間的唯一區(qū)別是附加組件必須包含bl_info Blender用于讀取元數(shù)據(jù)的變量,例如名稱,作者,類別和URL。
用戶首選項加載項列表使用bl_info顯示有關(guān)每個加載項的信息。
有關(guān)bl_info字典的 詳細(xì)信息,請參閱加載項。
在文本編輯器中運(yùn)行Python腳本對于測試很有用,但是您需要擴(kuò)展Blender以使工具可以像其他內(nèi)置功能一樣訪問。
Blender Python api允許集成:
bpy.types.Panel
bpy.types.Menu
bpy.types.Operator
bpy.types.PropertyGroup
bpy.types.KeyingSet
bpy.types.RenderEngine
這是故意限制的。目前,對于更高級的功能,例如網(wǎng)格修改器,對象類型或著色器節(jié)點(diǎn),必須使用C / C ++。
對于Python集成,Blender定義了所有類型共有的方法。這可以通過創(chuàng)建Blender類的Python子類來實(shí)現(xiàn),該類包含由父類指定的變量和函數(shù),這些變量和函數(shù)是預(yù)定義為與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集成并使用的所有類都是通用的,因此我們知道這是一個運(yùn)算符而不是注冊時的Panel。
兩個類屬性都以bl_前綴開頭。這是一個用于區(qū)分Blender屬性和您自己添加的屬性的約定。
接下來看到execute函數(shù),它接受運(yùn)算符的實(shí)例和當(dāng)前上下文。公共前綴不用于函數(shù)。
最后調(diào)用寄存器函數(shù),這將獲取類并將其加載到Blender中。請參閱班級注冊。
關(guān)于繼承,Blender不對所使用的類繼承施加限制,注冊檢查將使用父類中定義的屬性和函數(shù)。
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)函數(shù)。而__init__()和__del__()如果定義了將被調(diào)用,在類實(shí)例壽命僅跨越執(zhí)行。因此,例如一個面板將為每次重繪都有一個新實(shí)例,因此很少有理由在面板實(shí)例中存儲變量。相反,持久變量應(yīng)存儲在Blenders ata中,以便在重新啟動Blender時可以恢復(fù)狀態(tài)。
注意
模態(tài)運(yùn)算符是一個例外,它們的實(shí)例變量保持為Blender運(yùn)行,請參見模態(tài)運(yùn)算符模板。
因此,一旦類在Blender中注冊,實(shí)例化類并調(diào)用函數(shù)就由Blender完成。實(shí)際上,您無法像在大多數(shù)Python API中所期望的那樣從腳本中實(shí)例化這些類。
要運(yùn)行運(yùn)算符,可以通過運(yùn)算符api調(diào)用它們,例如:
import bpy bpy.ops.object.simple_operator()
用戶界面類給出了繪制,按鈕窗口,文件頭,工具欄等的上下文,然后在顯示該區(qū)域時繪制它們,因此Python腳本不會直接調(diào)用它們。
注冊 模塊注冊啟動時加載的Blender模塊需要register()和unregister()功能。這些是Blender從您的代碼調(diào)用的唯一函數(shù),否則它是常規(guī)的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()
這些函數(shù)通常出現(xiàn)在包含類注冊的腳本的底部,有時會添加菜單項。您也可以將它們用于內(nèi)部目的,為您自己的工具設(shè)置數(shù)據(jù),但要小心,因?yàn)榧虞d新的混合文件時寄存器不會重新運(yùn)行。
使用了注冊/取消注冊調(diào)用,因此可以在Blender運(yùn)行時切換加載項和重新加載腳本。如果寄存器調(diào)用放在腳本的主體中,則會在導(dǎo)入時調(diào)用注冊,這意味著導(dǎo)入模塊或?qū)⑵漕惣虞d到Blender之間沒有區(qū)別。
當(dāng)腳本從另一個模塊導(dǎo)入類時,這會成為問題,因?yàn)楹茈y管理正在加載哪些類以及何時加載。
最后兩行僅用于測試:
if __name__ == "__main__": register()
這允許腳本直接在文本編輯器中運(yùn)行以測試更改。register()將腳本作為模塊導(dǎo)入時,此調(diào)用將不會運(yùn)行,因?yàn)開_main__保留用于直接執(zhí)行。
類注冊使用Blender注冊類會導(dǎo)致類定義被加載到Blender中,并在現(xiàn)有功能的同時可用。
加載此類后,您可以bpy.types使用bl_idname而不是類原始名稱來訪問它。
加載類時,Blender執(zhí)行完整性檢查,確保找到所有必需的屬性和函數(shù),屬性具有正確的類型,并且函數(shù)具有正確數(shù)量的參數(shù)。
大多數(shù)情況下,你不需要擔(dān)心這個問題,但是如果類定義有問題,它將在注冊時引發(fā):
使用函數(shù)參數(shù),將引發(fā)異常: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中,對于簡單的情況,調(diào)用bpy.utils.register_class(SomeClass)就足夠了,但是當(dāng)有很多類或子模塊子模塊有自己的類時,將它們?nèi)苛腥胱钥赡軙芊爆崱?br>為了更方便的加載/卸載bpy.utils.register_module(模塊)和bpy.utils.unregister_module(模塊)功能存在。
一個腳本,它定義了許多自己的操作符,面板菜單等,你只需要編寫:
def register(): bpy.utils.register_module(__name__) def unregister(): bpy.utils.unregister_module(__name__)
內(nèi)部Blender在可注冊類型上收集子類,通過定義它們的模塊存儲它們。通過將模塊名稱傳遞給bpy.utils.register_module Blender,可以注冊該模塊及其子模塊創(chuàng)建的所有類。
類間依賴性在自定義Blender時,您可能希望將自己的設(shè)置組合在一起,畢竟,它們可能必須與其他腳本共存。要對這些屬性進(jìn)行分組,需要定義類,對于組內(nèi)的組或組內(nèi)的集合,您可以發(fā)現(xiàn)自己必須處理注冊/取消注冊的順序。
自定義屬性組本身就是需要注冊的類。
假設(shè)您要存儲自定義引擎的材質(zhì)設(shè)置。
# 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()
注意
該類必須在用于屬性之前注冊,否則將引發(fā)錯誤: 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運(yùn)行時添加和刪除屬性,通常在注冊或取消注冊時發(fā)生,但對于某些特殊情況,在腳本運(yùn)行時修改類型可能很有用。
例如:
# 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()
......這相當(dāng)于:
class MyPropGroup(bpy.types.PropertyGroup): my_float = bpy.props.FloatProperty()動態(tài)定義類(高級)
在某些情況下,數(shù)據(jù)的說明符可能不在Blender,renderman著色器定義中,例如,將它們定義為類型并在運(yùn)行中刪除它們可能很有用。
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()被調(diào)用來定義類。這是Python中類創(chuàng)建的替代語法,更適合動態(tài)構(gòu)造類。
要從上一個示例中調(diào)用運(yùn)算符:
>>> bpy.ops.object.operator_1() Hello World OBJECT_OT_operator_1 {"FINISHED"}
>>> bpy.ops.object.operator_2() Hello World OBJECT_OT_operator_2 {"FINISHED"}
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/42160.html
摘要:在控制臺中輸入路徑。因此,下一步是通過參考文件檢查訪問畫筆的位置。上下文畫筆紋理對比度由于每個屬性都是按照我們在控制臺中組成數(shù)據(jù)路徑的方式給出的可以有多種方式來訪問相同的數(shù)據(jù),您選擇的方法通常取決于任務(wù)。 Blender參考API用法 Blender有許多互連數(shù)據(jù)類型,它們具有自動生成的引用api,它通常具有編寫腳本所需的信息,但可能難以使用。 本文檔旨在幫助您了解如何使用參考API。...
摘要:插件教程什么是插件插件只是一個帶有一些附加要求的模塊,因此可以在包含有用信息的列表中顯示它。安裝附加組件時,將在控制臺中打印源和目標(biāo)路徑。現(xiàn)在嘗試將此腳本復(fù)制到并在默認(rèn)多維數(shù)據(jù)集上運(yùn)行它。 Blender插件教程 什么是插件?插件只是一個帶有一些附加要求的Python模塊,因此Blender可以在包含有用信息的列表中顯示它。 舉個例子,這是最簡單的插件: bl_info = {name...
摘要:為了讓數(shù)值計算的結(jié)果能夠有更好的渲染效果,這段時間一直在用這個開源軟件來處理計算結(jié)果。 為了讓數(shù)值計算的結(jié)果能夠有更好的渲染效果,這段時間一直在用Blender這個開源軟件來處理計算結(jié)果。 因?yàn)槭翘幚泶罅繑?shù)據(jù)的計算結(jié)果,所以不得不考慮用Python編寫腳本來實(shí)現(xiàn)批量處理,編寫過程中,Google幫我解決了大部分實(shí)現(xiàn)過程中的障礙,下面是完整的實(shí)現(xiàn)過程: 將計算結(jié)果的mesh文件導(dǎo)入到...
摘要:源網(wǎng)頁說明文檔所有關(guān)于你應(yīng)該且必須知道的。性能和優(yōu)化概述的兼容性旨在兼容多種不同版本的支持的兼容性地理框架打算成為世界級的地理框架。其目標(biāo)是盡可能簡單地構(gòu)建應(yīng)用程序并利用空間使能數(shù)據(jù)的功能。 源網(wǎng)頁:https://docs.djangoproject.co... django說明文檔 所有關(guān)于django你應(yīng)該且必須知道的。 第一步 你是否django編程新手,那就從此開始!從零開始...
閱讀 3480·2023-04-26 02:44
閱讀 1622·2021-11-25 09:43
閱讀 1510·2021-11-08 13:27
閱讀 1881·2021-09-09 09:33
閱讀 899·2019-08-30 15:53
閱讀 1762·2019-08-30 15:53
閱讀 2771·2019-08-30 15:53
閱讀 3106·2019-08-30 15:44