Blender 3D:融入 Python/自定義資料塊屬性
草案,提議新增使用者定義的每個資料塊屬性。
這意味著任何具有 ID 的 Blender 資料型別都可以為其分配屬性。
物件/網格/相機/超球/燈/格柵/文字/IPO/螢幕/場景/世界/波浪 - 目前不包括面或頂點。這可能會在稍後新增,但需要進一步的工作,並且超出了本提案的範圍。
有一些領域我不夠了解,並要求其他人擴充套件。
我鼓勵那些可能從這項工作中受益的人閱讀此頁面,並檢視是否有可以改進的地方(編輯,提供示例並討論 :) ) - Ideasman
來自 Ton 的訊息
關於屬性系統,需要解決的問題是;
- 它如何影響 UI
- 層次結構如何精確地工作?(也用於 UI 訪問)
- 是否有一種方法可以預設設定為屬性集?意思是;
您可以設定自定義屬性,以便預設情況下為 yafray、crystalspace 等新增。
這將節省大量麻煩,並會以這種方式建立良好的可訪問 UI。
- 我很忙,現在沒有時間做這些, - Ideasman
Reed Hedges 說
為了回答 Ton 上面的問題,以下是我認為的:在 UI 中,您需要在某個窗格中新增一些東西,該窗格與現有的遊戲邏輯屬性完全一樣(名稱、值、型別 {字串、布林值、整數、浮點數、向量等})。這可以是新的視窗型別,而不是遊戲邏輯視窗,也可以是在按鈕視窗中與物件級操作一起,也可以是概述檢視的一部分。從我在下面讀到的內容來看,層次結構命名主要是一種命名約定。這可以被 UI 用於顯示為樹,或者它們可以只是一個標準列表,其中“層次結構”僅在名稱格式中。對我來說,預設屬性沒有用。但是,它們可以是用於單個物件的相同 gui 的另一種模式。
+-CUSTOM PROPERTIES -------------------------------------+ | | | Selected Object: ME:Suzanne01 (Defauts) | <-- (Defaults) is a two-state toggle button | | to show default props instead of sel. object | Name: Type: Value: Del: | | [Example.Prop....] (String) [This is my stri...] (X) | <-- Name is text field. Type is multivalue | [Another.example.] (Bool ) (true) (X) | dropdown. Value depends on type. | (New) | <-- (New) creates a new empty property above it. +--------------------------------------------------------+
我還要求所有物件型別能夠具有屬性,包括場景/世界。(是的,場景和世界將具有,因為它們具有 ID - Ideasman42)
- 註釋關於網格、物件或材料的註釋可以儲存為指向文字塊的連結或字串。其他元資料也可以新增到不同的專案中。
- 渲染設定外部渲染引擎的額外屬性,其中許多可以新增到材質資料,全域性渲染設定可以分配給場景資料塊。這可能是邁向更好的 Renderman 整合的第一步!
- 遊戲引擎許多遊戲引擎特定的設定,例如物件的細節級別。人物的不同姿勢狀態。可以儲存在這些設定中。
- Blender CAD許多屬性可以新增到 BlenderCAD 專案中。(請擴充套件)
- 模擬模擬行業需要填補一個空白,許多人已經在使用 Blender 進行模擬,但是沒有簡單的方法新增模擬輸出設定(主要是 OpenFlight 屬性)
- 擴充套件資料一些內部功能可能需要儲存值,同時又不想對所有資料塊施加額外的權重,即使那些不需要它的人也是如此
- 評論:允許使用者使用內部功能訪問的資料也是一個不好的主意。如果它對內部有用(我想不出我會更喜歡其他實現的情況),使用者資料和 Blender 資料應該分開或訪問受限(Blender 內容只讀)。-- tbleicher
- 對評論的回答 : 並不是因為你使用了屬性機制,它就必須是使用者可編輯的,甚至可以檢視。這種情況下,當你需要在極少數情況下(比如整個網格上只有很小一部分邊)新增大量資料時,它很有用。
- (由 Ideasman 提出) 大家,我想解決這個問題,請隨意不同意,但必須劃定一個界限來確定該專案涵蓋的功能。
- 1)使用者必須能夠直接編輯屬性,將有一個為此目的的介面。Blender 的內部工具也可以管理屬性,但將有一個專門用於資料塊屬性的面板。
您可能會爭辯說,讓使用者接觸它們會導致資料中出現可能的錯誤,但允許使用者編輯屬性的優勢遠遠超過讓 Python 指令碼/Blender 正確處理各種資料的努力。 - 2)屬性不會分配給邊、貝塞爾點、面、單獨的骨骼等。這超出了本專案的範圍。如果需要預網格面屬性,例如,我們可以將其作為單獨的新增來解決。現在,只有具有 ID 結構的資料將具有自定義屬性。
- 1)使用者必須能夠直接編輯屬性,將有一個為此目的的介面。Blender 的內部工具也可以管理屬性,但將有一個專門用於資料塊屬性的面板。
- Blender BVH 運動捕捉關節名稱可以分配為屬性,以便不同運動捕捉裝置之間的重複物件名稱不會衝突。目前,我將所有關節名稱設定為唯一,因為沒有很好的方法來設定物件的關節名稱。(Ideasman)
對於預設設定,可以使用主目錄中的文字檔案,名為.Bprops
現有檔案是.B.blend用於預設新檔案,以及.Bfs用於檔案選擇器中的預設目錄列表。
.Bprops文字檔案將儲存預設情況下顯示的屬性(無需手動新增到資料塊)
DataBlockType:PropertyType:PropertyName=DefaultValue - 將使用以下格式。
Object:bool:CrystalSpace.staticObject=1 Material:Text:RenderMan.Shader="" Scene:int:RenderMan.Quality=5 Lamp:bool:OpenFlight.LightString=0
注意從 b2cs (crystalspace 匯出器) 的角度來看,不僅預設值有用,最小值、最大值以及可能每個屬性的描述也很有用。
以下是一些可能直接受益於屬性的專案,感謝作者的輸入以及如何擴充套件這些專案可能帶來的益處。這個提議是否滿足您的需求?
- Blight(OpenFlight 相容性 - 儲存 OpenFlight 特定的註釋)
- Make Human(Make Human,每個網格的 Human 設定...)
- Brad Blender/Radiance 匯出器(材質設定...)
- 材質:將描述儲存為文字字串;儲存對其他定義的依賴項(“修飾符”)
- 網格:使用道具作為“特殊”匯出物件,而不是 meshobj 名稱
- 燈光:儲存對燈具資料和使用的資料來源的引用(db、fs)
- 場景:渲染選項和後期處理資訊(濾鏡、影像轉換)
- CrystalSpace 開源遊戲引擎。
- RenderMan 將 RenderMan 支援新增到 Blender 中。
- 著色器:為 RenderMan 著色器指定著色器名稱和引數(表面、位移...)
- 圖元:為 RenderMan 匯出器提供處理特定圖元的提示。
- 場景:為 RenderMan 匯出器提供場景級渲染控制的提示。
在此處新增您的專案
屬性將儲存在層次結構中。每個資料塊可以擁有任意數量的屬性資料夾
(我建議不要使用根級別屬性,以強制執行更好的設計)
使用屬性的外掛將在根目錄中有一個資料夾,用於存放其所有設定 - 這將阻止它在 UI 中變得雜亂,併為每個外掛保持名稱空間分離。
示例結構。python 可以包裝 C 資料,並作為字典或類進行訪問,我們可以允許兩者共存 ob.prop.foo 或 ob.prop['foo'] - Ideasman42),
object.prop.metadata.annotation = 'This is a building' # string object.prop.metadata.timestamp = sys.time() # float object.prop.crystalSpace.lod = Mathutils.Vector(0,50) # vec object.prop.crystalSpace.shadowMap.used = True # bool object.prop.crystalSpace.shadowMap.size = 512 # int
以下是外掛可以使用的一些屬性型別。
- 布林值
- 整數
- 浮點數
- 字串 大小可能有限制,對於大型多行文字,可以連結文字塊。
- 向量 (2D, 3D, 4D)
- 資料塊連結 允許您連結到另一個數據塊 - 文字/物件/網格/曲線等。
- 陣列 所有先前值(不是必需的,因為可以使用屬性資料夾,可能有用)
OOps 檢視可以擴充套件為包含一個面板,允許編輯每個資料塊的屬性。這也可以在大綱檢視中檢視,但 OOps 檢視更適合,因為它只顯示每個資料塊一次,並且同時顯示所有資料塊。
- 註釋 1:對於指令碼來說,比訪問和編輯整個屬性集更重要的是按名稱/層次結構訪問單個屬性。對於 BPy,我希望有一個 __getitem__/__setitem__ 的實現(就像在字典中一樣)。示例
- amesh.prop["Radiance"]["export"]["smooth"] = True # 設定屬性,布林值
- var= amesh.prop["Radiance"]["export"]["smooth"] # 獲取屬性
- amesh.prop["Radiance"]["export"].keys() # 獲取子屬性列表。
["smooth", "emit_light"] - del amesh.prop["Radiance"]["export"]["smooth"]
KeyError 應該在指定不存在的鍵(或將現有鍵轉換為“容器”)時引發。如何檢查並做出反應是指令碼的任務。
- 註釋 2:為了匯入/匯出屬性集,一個通用的資料序列化方法將非常受歡迎。目前,我們必須使用 Python 標準庫從登錄檔/文字物件/文字檔案中儲存/讀取執行時資料。一種從 Python 物件建立/解析文字字串的內建方法可以幫助指令碼編寫者載入和儲存持久資料。這樣,整個屬性集就可以作為物件的字串屬性儲存。
-- tbleicher
(註釋:Python 的 pickle 模組提供了這個功能,但我不知道它將如何與 Blender 物件等互動。 -- sapir)
任何具有 ID 的 Blender 資料都可以擁有一個屬性。(請擴充套件並新增如何實現 - 在 Blenders DNA 中)
抱歉,我剛剛在網上搜索時看到了這個頁面,試圖弄清楚如何在 Blender 中向物件新增使用者資料。在搜尋中沒有找到任何內容,但最終從 API 文件中弄明白了某些東西。
在 Blender 的 Python 互動式控制檯中嘗試以下操作
cube = bpy.data.objects["Cube"]
cube.addProperty("myUserDataName", 1, 'INT')
dir(cube.getProperty("myUserDataName"))
var = cube.getProperty("myUserDataName").data
cube.getProperty("myUserDataName").setData(2)
cube.getAllProperties()
cube.removeProperty("myUserDataName")