全球簡(jiǎn)訊:實(shí)驗(yàn)筆記:基礎(chǔ)的Blender Python腳本編寫
用輪子→改輪子→造輪子,而Blender Python API使得GUI里進(jìn)行的操作十有八九都能用命令行敲出來。雖然相關(guān)的教程已經(jīng)夠多了,不過這次的目的還是“將(折騰MMD時(shí)的)部分操作替代為腳本,從而提升工作效率”。
(相關(guān)資料圖)
自己的代碼基本功不怎么扎實(shí),讀起來或許會(huì)有些費(fèi)勁,如果有什么issue也還請(qǐng)各位同好加以糾正。
特別鳴謝
春日未來with?星元素 擔(dān)當(dāng)P @Eleanor
之前研究星耀的改模時(shí)提供了腳本支援,這次則帶著自己入門了bpy模塊;
如果在“某個(gè)游戲”里見到了土豆的模組,十有八九得拜這位佬做過的研究所賜。
此外,本次依然受了@LC_ilmlp的腳本指導(dǎo)&修正,感謝。
目錄
1. 環(huán)境/工具提示配置
2. bpy.context - 獲取信息
3. bpy.data - 物體處理
4. 控制臺(tái)→腳本注意事項(xiàng)
5. 簡(jiǎn)單的實(shí)戰(zhàn)案例
寫在前面
先放一篇知乎上的參考文章,雖然作者還在坑,但現(xiàn)有的部分已經(jīng)很不錯(cuò)了:
《Blender Python 簡(jiǎn)易參考》
https://zhuanlan.zhihu.com/p/525475118
首先想談一下如何“學(xué)習(xí)”Blender + Python。
最高效的方法是我要做什么我就學(xué)什么。
如果你去看API文檔,然后上來“bpy包含幾大模塊,bpy.ops, bpy.data, bpy.mesh, bpy.context“云云,看了半天還不知道該干嘛,記也沒記住,十分低效。那不如你在這篇博客里找找常見操作的代碼,直接就可以用了,用了幾個(gè)差不多就知道bpy是怎樣一個(gè)設(shè)計(jì)的邏輯了,一個(gè)下午就能完成任務(wù)是最好的。
就像Python本身一樣,各種庫與函數(shù)都是隨找隨用,甚至可以在獲取需要的信息后立刻打開ChatGPT照葫蘆畫瓢。因此比起背語法,更重要的是將腳本要達(dá)成的目標(biāo)進(jìn)行分解,并在浩如煙海的API文檔中為每個(gè)步驟都找到相關(guān)的定義/寫法。用到的代碼或許并不復(fù)雜,但如果缺乏邏輯就開工的話,腳本沒寫完,大腦先Out of memory了。
本次使用的blender版本為3.4.1,以及對(duì)應(yīng)的官網(wǎng)Python API文檔:
https://docs.blender.org/api/3.4/
1. 環(huán)境/工具提示配置
點(diǎn)擊最上面一行中的“Scripting”,或是在GUI里調(diào)出“腳本”相關(guān)窗口:
文本編輯器(中間):編輯/運(yùn)行整段腳本
Python控制臺(tái)(左側(cè)):運(yùn)行單個(gè)命令行
信息欄(左下):顯示部分GUI操作所對(duì)應(yīng)的函數(shù)/變量轉(zhuǎn)換
接著,在blender最上面的“窗口”項(xiàng)里調(diào)出系統(tǒng)控制臺(tái)(cmd窗口):
需要區(qū)分的是,Python控制臺(tái)只負(fù)責(zé)顯示控制臺(tái)內(nèi)輸入的指令/操作:
而腳本運(yùn)行的輸出內(nèi)容則會(huì)顯示在cmd窗口里:
在blender本體由于腳本或GUI操作卡死時(shí),也可以通過在cmd窗口按下Ctrl+C組合鍵來強(qiáng)制停止腳本運(yùn)行,因此建議在測(cè)試腳本時(shí)保持cmd窗口的常時(shí)開啟。
還有一個(gè)blender自帶的,寫腳本所需的重要功能:
設(shè)置-界面-勾選“使用工具提示”與“Python工具提示”,在鼠標(biāo)懸停到對(duì)應(yīng)按鈕/物體時(shí)可以看到API中對(duì)應(yīng)的python變量/調(diào)用函數(shù)。
舉個(gè)小例子,用GUI的按鈕添加一個(gè)柱體:
左下角的信息欄里就出現(xiàn)了:
把這行敲進(jìn)控制臺(tái)就有了相同的效果:
隨便套個(gè)for循環(huán)進(jìn)去:
效果顯而易見:
也就是說,有些批量化的功能(匹配/重復(fù)生成/狀態(tài)應(yīng)用&賦值等)只能通過腳本而不能通過GUI來實(shí)現(xiàn)。
雖然已經(jīng)有了星月佬的現(xiàn)成工具miritore,但由于模型格式相對(duì)規(guī)范且方便講解,所以還請(qǐng)?jiān)试S自己這次繼續(xù)用土豆的模型作為數(shù)據(jù)范例。
隨機(jī)請(qǐng)上一位小偶像——
.rd?1d52 = 24 =?杏奈。
在接下來的內(nèi)容里不會(huì)出現(xiàn)其他圖示,還請(qǐng)各位兔子P們安心。
如果想仿照著接下來的步驟進(jìn)行操作的話,任意導(dǎo)入一個(gè)其他的fbx/pmx就行。
重新排一下GUI視圖,環(huán)境設(shè)置完畢。
2. bpy.context - 獲取信息模型的物體屬性和信息都包含在bpy.context里:
https://docs.blender.org/api/current/bpy.context.html
通過讀取bpy.context以及其子變量,可以獲得“當(dāng)前GUI窗口中選擇的物體(或者說,當(dāng)前狀態(tài)為active的物體)”的屬性,這些都可以在API文檔中查詢到:
比如最基礎(chǔ)的,獲得當(dāng)前選擇物體的名稱列表:
實(shí)操一下,先確認(rèn)當(dāng)前的GUI大綱視圖狀態(tài):
進(jìn)控制臺(tái)起命令,得到了包含一個(gè)名為“Armature”的object的list:
需要注意的是,輸出的變量類型不是string而是list(只有一項(xiàng)的list也是list),在指定了具體某一項(xiàng)后才能輸出string:
當(dāng)然,bpy.context可以get到的內(nèi)容遠(yuǎn)遠(yuǎn)不止selected_objects,又比如:
另一方面,通過向bpy.context中的一些變量賦值,也可以改變GUI中的顯示,包括但不限于選中物體,或是設(shè)定某個(gè)狀態(tài)的開關(guān)。
而作為腳本的基礎(chǔ)規(guī)則之一,只有將物體指定為active_object之后才能對(duì)該物體進(jìn)行操作,平常在GUI中所進(jìn)行的點(diǎn)擊也可以視作將物體設(shè)為active。
因此,大部分腳本的起手式都是“選擇需要編輯的物體”——set object as active:
回到GUI,可以看到位于eyes名稱左側(cè)位置出現(xiàn)了小框:
此時(shí),eyes就成為了active_object,可以進(jìn)行后續(xù)操作了。
3. bpy.data的處理在從GUI或bpy.context選中物體后,接著就是通過bpy.data對(duì)物體進(jìn)行處理。
https://docs.blender.org/api/current/bpy.data.html
點(diǎn)開data type,可以看到bpy.data下同樣包含了眾多子變量:
關(guān)鍵的是,可以通過bpy.context.active_object.data,或是bpy.context.selected_objects.data的形式,將上文中bpy.context的內(nèi)容作為data使用:
而對(duì)于這部分,最需要理解的就是“到底該調(diào)用哪個(gè)變量”。
受篇幅所限,這次的專欄就以“獲取骨骼”為例:
bpy.context.active_object.data.bones
bpy庫功能.在GUI中顯示出內(nèi)容的.當(dāng)前選中的物體的.數(shù)據(jù)中的.骨骼合集?
稍微改一下,改為顯示指定物體而非當(dāng)前物體:
bpy.data.objects["Armature"].data.bones
bpy庫功能.在GUI中顯示出內(nèi)容的.名為“Armature”的物體的.數(shù)據(jù)中的.骨骼合集?
再改一下,又可以變成:
bpy.context.selected_objects[0].data.bones
bpy庫功能.在GUI中顯示出內(nèi)容的.所有可選物體[最頂層]的.數(shù)據(jù)中的.骨骼合集?
并且顯然,獲取object內(nèi)容的方式并不唯一:
而正如第一節(jié)中所提到的,腳本中主要采用active_object來指定物體名稱:
并配合著其對(duì)應(yīng)的bpy.data進(jìn)行操作:
諸如此類,相關(guān)類型和列表都記載在API文檔里,動(dòng)畫(actions),形態(tài)鍵(keys/shape_keys),材質(zhì)(material),翻翻type和子變量,print()或者list()幾下,總是能找到的。
確定對(duì)象之后,就是對(duì)object進(jìn)行賦值來改變物體屬性了。這步想必不用多作解釋,保證等號(hào)左右兩邊變量類型一致就行。
賦值,改名:
最終,改名操作只用到了一行代碼。
4. 控制臺(tái)/腳本中命令行的區(qū)別大多數(shù)控制臺(tái)的內(nèi)容放到腳本里都能用,但寫腳本時(shí)還是有一些注意事項(xiàng):
1. (廢話)控制臺(tái)可以直接輸入命令,而使用腳本則需要引入bpy庫:
2. 同理,控制臺(tái)不能使用其他py庫,但腳本則不受限制——
比如打時(shí)間戳:
或是通過正則匹配遍歷列表,直接將set_active_object的對(duì)象設(shè)定到符合條件的物體上,可以進(jìn)行批量操作,或是避免在選擇不合適的物體時(shí)腳本報(bào)錯(cuò):
注意:如果在腳本在運(yùn)行過程報(bào)錯(cuò),會(huì)直接跳出而非繼續(xù)運(yùn)行,因此需要使用合適的判斷語句來避免在可能報(bào)錯(cuò)(比如input為空,或是input變量類型錯(cuò)誤)的情況下執(zhí)行命令。
3. 如果要給blender裝額外的py庫,則需要去blender自帶的Python目錄(blender文件夾\python\bin\python.exe)下起shell開pip install,詳細(xì)方法在開頭引用的參考文章里“[Blender Python] 安裝Python包”一節(jié)中可以找到。
4. 對(duì)于blender的外部插件同樣可以用“python工具提示”來查看對(duì)應(yīng)命令,比如改模時(shí)常用的mmd_tools插件的“轉(zhuǎn)換模型”按鈕:
5. 快速實(shí)戰(zhàn)環(huán)節(jié)你已經(jīng)學(xué)會(huì)了Blender腳本的基礎(chǔ)編寫方式,現(xiàn)在嘗試在改模時(shí)把改名插件送進(jìn)回收站吧!
給定一個(gè)頭部fbx模型,將其作為Armature導(dǎo)入blender并選中后:
1. 列出該Armature的名字與其包含的總骨骼數(shù)量
2. 找到位于頸部和頭部的兩個(gè)骨骼,分別改名為“首/頭”,且返回賦值結(jié)果
將任務(wù)拆分一下:
-模型名稱和骨骼信息都可以從bpy.context里找到
-通過自定義字典來建立映射關(guān)系
-如果骨骼名稱包括在字典內(nèi),就對(duì)骨骼進(jìn)行改名
開碼:
然后跑下腳本:
一個(gè)可掛載自定義字典的骨骼重命名工具——有效代碼不到20行。
思考題
-能改名的可以是模型的骨骼,也可以是動(dòng)作的骨骼,還可以是鏡頭動(dòng)畫。
-賦值能實(shí)現(xiàn)的遠(yuǎn)遠(yuǎn)不只是“改名”,更是包括了”對(duì)物體應(yīng)用骨骼動(dòng)畫“,“開啟/關(guān)閉形態(tài)鍵”,“給材質(zhì)上貼圖”等應(yīng)用類操作,一些強(qiáng)大的插件甚至可以實(shí)現(xiàn)對(duì)材質(zhì)與紋理的快速切割/分層。
-除了bpy.context和bpy.data外,還有輸入輸出文件的bpy.path句柄,原則上來說可以實(shí)現(xiàn)從文件輸入到輸出的一條龍操作。
題外話
其一
Steam上的blender可以通過設(shè)置來自選版本(并且每個(gè)版本都有各自的獨(dú)立維護(hù)與更新),使用體驗(yàn)更好點(diǎn),還可以讓好友看到自己開著blender敬業(yè),不過有個(gè)小缺點(diǎn)是每次更新大版本需要重新手動(dòng)開啟插件。
其二
雖然說的晚了點(diǎn),之前專欄里使用過的部分操作也可以被腳本代替掉——有時(shí)間的話或許會(huì)回去補(bǔ)充點(diǎn)內(nèi)容,也可以作為不錯(cuò)的習(xí)題來練手。
其三
雖然百10th活動(dòng)結(jié)束了,還是挺好奇活動(dòng)每日播片里的高精度模型以后是否有機(jī)會(huì)實(shí)裝進(jìn)游戲...回頭再看著現(xiàn)行的紙板裙反而略顯奇怪了。
不過往好了想,除了比較消耗事務(wù)員以外,正是簡(jiǎn)單而標(biāo)準(zhǔn)化的模型,才能讓土豆在衣服上有著那么高的產(chǎn)能。
本期專欄頭圖
既然隨機(jī)到了,那就斗膽借杏奈和今天過生日的百合子發(fā)揮一下,紅桃賽季沒把這組安排到一起對(duì)我來說還是挺遺憾的。
Copyright?
BANDAI NAMCO
看著閃5Day1和某位作曲家的庭審記錄給這篇專欄做了最后的校對(duì),東西寫完,血壓也爆了。
另外,如果覺得封面構(gòu)圖在哪見過的話,可以再去刷幾個(gè)太晶坑回味回味。
這次的課題不完全是MMD相關(guān),但還是那句話,要做什么就學(xué)什么。
2023/3/18岸田夏海標(biāo)簽: