2013-09-30 41 views
1

我正在編寫一個自定義導出腳本來解析攪拌器文件中的所有對象,按名稱對它們進行過濾,然後檢查以確保它們符合某些特定條件。使用Blender Python API的場景對象選擇性導出2.6

我使用Blender 2.68a。我用一些基本的2D和3D網格創建了一個攪拌器文件,還有一些應該會失敗我的測試標準。我正在Blender內部的Python控制檯中工作。這是使用blender python API的唯一方法,因爲它們的python環境是自定義的。

我整理如何通過對象使用for循環和D.objects迭代器遍歷,然後檢查名稱使用正則表達式匹配,然後用得到的對象網格:

mesh = obj.to_mesh(C.scene, True, 'RENDER') #where obj is an bpy.data.object[index] in the scene 
mesh.update(True, True) 
mesh.polygons[index].<long list of possible functions> 

讓我訪問一個多邊形數組來知道是否有一組邊形成一個多邊形的頂點,以及它們的關鍵值是什麼。

我無法理解的是如何從python控制檯確定poly是一個面還是一個poly。有沒有一個內置的函數,或者我可以通過編程來執行哪些測試來確定?例如,我可以有一個帶有4個邊的網格4頂點,它們沒有面,我不想導出它,但是如果我要編輯相同的4個頂點/邊並在其上面放上一個面,成爲一個理想的出口。

任何人都可以解釋bpy.data.object數據結構或解釋「面孔」的存儲位置?看起來它好像是npolys本身的屬性,但API並沒有讓它變得明顯。任何幫助澄清這將不勝感激。乾杯。

+0

網格模型由頂點,邊和麪組成。臉是多邊形的另一個名稱。 – sambler

回答

2

所以,我在blender.org論壇上問了這個問題,http://www.blender.org/forum/viewtopic.php?t=28286&postdays=0&postorder=asc&start=0,在過去幾天裏,一個非常有幫助的人幫助了我,每次我都陷入了自己的努力之中。

答案的短名單是:

1)所有多邊形面。如果不存儲爲多邊形,則不是一張臉。
2)在一個對象上使用to_mesh()函數會返回該函數的一個副本,因此對該副本執行的任何選擇都不會被上下文反映,因此我使用的方法有缺陷。訪問活動對象的唯一方法是通過使用:

bpy.data.objects[<index or object name>].data.vertices[<index>].co[<0,1,2> which correspond to x,y,z respectively] 
bpy.data.objects[<index or object name>].data.polygons[<index>].edge_keys 

第一個,您可以訪問所有頂點的有序索引中的對象(假設它的類型是「MESH」),以及其座標。
第二個可以訪問表示邊的有序對的二維數組。它包含在元組中的數字對應於第一個命令的頂點列表中的索引值,因此您可以獲取邊之間的座標。 也可以創建一個新的BMesh對象,並將您感興趣的對象複製到BMesh中。這爲您提供了許多無法在活動對象上訪問的功能。答案3中的代碼顯示了一個例子。 3)請參閱下面的回答我的問題有關檢查網格中的面孔。

事實證明,確定一個對象是否具有臉部並且所有邊緣都是臉部的一部分的一種方法是使用由以上線程上的有用用戶CoDEmanX編寫的以下代碼片段。

import bpy, bmesh 

for ob in bpy.context.scene.objects: 
    if ob.type != 'MESH': 
     continue 
    bm = bmesh.new() 
    bm.from_object(ob, bpy.context.scene) 

    if len(bm.faces) > 0 and 0 not in (len(e.link_faces) for e in bm.edges): 
     print(ob.name, "is valid") 
    else: 
     print(ob.name, "has errors") 

我這改變了一點點,因爲我不希望它遍歷所有的對象,而是我這有彷彿在傳遞的對象是有效的,否則爲假,返回true的功能。這使我可以序列化我的調用,以便我的插件只會嘗試驗證名稱與正則表達式匹配的對象。

def validate(obj): 
    import bpy, bmesh 

    if obj.type == 'MESH':     
     bm = bmesh.new() 
     bm.from_object(obj, bpy.context.scene) 

     if len(bm.faces) > 0 and 0 not in (len(e.link_faces) for e in bm.edges): 
      return True 
    return False