1. 程式人生 > >Blender Python API中文介紹文件六

Blender Python API中文介紹文件六

提示和技巧

以下是各種建議,在你寫指令碼時候時有用,有些是python特點有些是blender特有的。

使用終端

當寫指令碼時,開啟終端很有用,不是指內嵌的python終端,俄式系統終端,有三種方式使用終端:

1.   你可以檢視指令碼執行print()的輸出,可以檢視debug訊息

2.   錯誤追蹤,列印在終端裡,但是在blender使用者介面不會產生

3.   如果指令碼執行太長時間,你有時候加入無限迴圈可以按ctrl-c來退出指令碼

注意:linux下終端直接執行blender,windows可以在help選單中開啟終端

介面終端

獲取操作命令

你可以在選單和按鈕的tips上ctrl-c複製命令道鍵盤

獲取資料路徑

查詢設定中的資料塊ID的路徑往往不是那麼簡單,在設定介面中按鈕右鍵選擇Copy Data Path,如果無法產生,只有屬性名字被複制

注意:使用同樣的方法可以獲取動畫路徑,通過:

顯示所有的操作

Blender日誌記錄所有的操作在info介面,這隻會顯示註冊的操作,避免在info資訊中出現:

bpy.ops.view3d.smoothview和bpy.ops.view3d.zoom

為了測試在終端中看到所有操作是有用的,啟動blender時加上--debug-wm引數,或者當Blender執行時設定bpy.app.debug_wm為True

使用外部編輯器

Blender文字編輯器對於小的修改和寫測試很好用,但是它全特徵和大的工程。你需要用單獨的編輯器或者使用Python-IDE

編輯外部文字,然後在Blender中開啟同樣的文字可以;但是最優的,以下是最優的兩種方式,你可以在blender中更方便的使用外部檔案

以下是一些例子,你仍需要在blender中文字塊,但是引用一個外部檔案而不是直接including

執行外部指令碼

相當於直接執行指令碼,從文字塊中引用一個指令碼路徑:

filename="/full/path/to/myscript.py"
exec(compile(open(filename).read(), filename, 'exec'))

你也許想引用和blender檔案相關的指令碼

importbpy
importos
filename
= os.path.join(os.path.dirname(bpy.data.filepath),"myscript.py")
exec(compile(open(filename).read(), filename, 'exec'))

執行模組

這個例子顯示以模組載入一個指令碼並執行模組

importmyscript
importimportlib
importlib.reload(myscript)
myscript.main()

注意指令碼每次都會重新載入,這會強制修改版本,而不是在sys.modules快取,快取只在重啟Blender軟體時使用

這和直接執行指令碼的區別是在模組中直接呼叫一個函式,這個例子中是main函式但是它可以是任意的函式,它有一個優勢是你可以從小的指令碼給函式中傳遞引數,這個在測試不同的設定中很快。

它的另一個問題是不得不在Python模組中搜索路徑,但這不是最好的方法,為了測試你可以擴充套件搜尋路徑,下面的例子,添加當前blend檔案路徑到搜尋路徑,然後再作為模組載入指令碼。

importsys
importos
importbpy
blend_dir= os.path.dirname(bpy.data.filepath)
if blend_dir notin sys.path:
   sys.path.append(blend_dir)
importmyscript
importimportlib
importlib.reload(myscript)
myscript.main()

不要使用Blender!

開發你自己的指令碼,通過介面手動載入執行指令碼,開啟檔案匯入等等

對於無法互動的指令碼,直接在命令列執行不通過命令列更高效:

blender --background --python myscript.py

你可以執行blend檔案來執行指令碼檔案(指令碼中有被操作的資料)

blender myscene.blend --background --python myscript.py

注意:你也許需要加入blender的執行檔案全路徑

一旦你以這種後臺方式執行指令碼,你會檢視指令碼的輸出,當然這完全依賴於你的任務,不過以下是一些建議:

1.   渲染圖片的輸出,使用圖片檢視,每次寫覆蓋同樣的圖片

2.   儲存一個新的blend檔案或者使用blender一個匯出器匯出檔案

3.   如果結果可以被作為文字顯示—列印或者將它寫到一個檔案中

然而這個需要費時來設定,測試更改,你甚至可以讓blender每隔幾秒執行指令碼,附帶結果的檢視更新

使用外部工具

當沒有快速的可獲取的python模組來執行明確的任務,最好記住你能夠讓python執行外部命令,來處理資料和讀取結果資料

使用外部程式新增外部依賴庫,也許會限制誰能使用指令碼,但是可以快速設定你自己的管道或寫一個一次性的指令碼,這很方便

例子包括:

1.   以批量模式執行Gimp執行使用者指令碼,用於高階圖片處理

2.   通過使用外部網格操作工具和讀入結果來輸出3D模型

3.   在讀取之前,轉化檔案格式為可識別的格式

捆綁Python和拓展

Blender在官網釋出的版本包括在各個平臺的完整的Python安裝,這會使blender無法找到系統安裝的各種擴充套件,有兩種方法處理:

1.   刪除Blender-python的子路徑,Blender會使用系統的Python,依賴於你的平臺,你需要明確引用python安裝路徑,使用PYTHONPATH環境變數

PYTHONPATH=/usr/lib/python3.5 ./blender

注意:Python版本必須和blender的版本

2.   把拓展工具複製和連線進Blender的Python子路徑,使得blender可以獲取這些子路徑,你也可以複製整個Python安裝路徑到Blender的子路徑,代替Blender中的。只要python版本匹配並且建立同樣的相對路徑。這樣有一個好處你可以限制捆綁其他的軟體和Blender以及遊戲玩家,包括你依賴的拓展外掛。

指令碼加入Python直譯器

在指令碼的中間,你需要檢查一些變數,執行一些函式,挖掘什麼在執行。

importcode
code.interact(local=locals())

如果你需要獲取全域性和區域性變數,這樣做:

importcode
namespace=globals().copy()
namespace.update(locals())
code.interact(local=namespace)

下面的例子,是一行程式碼,很容易直接貼進你的程式碼:

__import__('code').interact(local=dict(globals(), **locals()))

code.interact可以載入程式碼中的任意一行,暫停指令碼執行,啟動互動直譯器,解釋之後退出直譯器,指令碼繼續執行。

如果你安裝了IPython,你可以使用embed()函式,用在當前名稱空間,IPython,可以自動補全,它有一些標準python有用的功能。

importIPython

IPython.embed()

不得不承認,這個會導致python的debug支援,但是它仍舊很方便

注意:這在遊戲引擎上也有效,這使得檢查執行中的遊戲狀態更方便

高階特性

Blender作為一個模組

從python觀點來看,將所有的都看作外掛,使得Python指令碼和很多元件連線,這樣的優勢是:

1.   你可以使用外部文字編輯器或者IDE,用Blender Python API 並且在IDE執行指令碼,檢查指令碼執行時的變數

2.   編輯器或者IDE可以自動補全Blender模組和變數

3.   已經存在的指令碼可以匯入Blender API不需要在blender內部執行

將blender作為一個python模組執行需要特殊的設定方法

Python安全性

因為可以獲取已經移除的資料,很難跟蹤程式奔潰的原因。在獲取資料的過程中,來引發Python的異常,使得CMake生成WITH_PYTHON_SAFETY

新增資料跟蹤使得獲取資料慢了兩倍,這也是釋出版本沒有新增這個功能的原因。