2018年7月16日 星期一

從Blender裡萃取模組資料(1)

從Blender裡萃取模組資料(1)

前言

  從Blender裡匯出模型的完整範例很難搜尋到,都只能搜尋到片段的資料會出範例,所以這裡做個紀錄,由於目前並未研究透徹,只會萃取"位址"、"Normal"與"Index"的部分。

內容

  在之前的那一篇初探Blender的script裡有一個輸出的範例,那個範例輸出的資料恐怕是有問題的,如果用該範例輸出一個Cube的話,會得到36個vertex與36個index,這個和一般在Direcct3D與OpenGL的範例不一樣,Direcct3D與OpenGL的範例是24個vertex與36個index,其中的vertex是有Face的概念的,而不是將全部的Triangle一個一個輸出。
  這裡說一下輸出格式的問題,由於每個引擎有自己的格式,所以範例的用法並會包含輸出的格式,而是著重在從Blender裡將資料萃取出來,至於輸出格式的部分,相信並不困難,這裡就不記錄了。
  接著,就來看萃取的範例
import bpy
import bmesh

tagMesh = bpy.data.meshes["Cube"]
#Create bmesh from mesh
tagBMesh = bmesh.new()
tagBMesh.from_mesh(tagMesh)

#Start extract
baseIndex = 0
for face in tagBMesh.faces:
  for i in range(len(face.loops) ):
    print("Position:",face.loops[i].vert.co," ",end="")
    print("Normal:",face.normal," ",end="")
  print("Loop vertex end")
  loopLen = len(face.loops)
  for i in range( len(face.loops) - 2):
    print("index0:",baseIndex," ",end="")
    print("index1:",baseIndex + i + 1," ",end="")
    print("index2:",baseIndex + i + 2," ",end="")
  print("Loop index end")
  
#Free bmesh...
tagBMesh.free()

範例會去取"Cube"這個Mesh,如果取其它的Mesh的話,更換名稱即可。接著,會去從每個face裡取出loop的資料,這裡如果以"Cube"來說的話,loop就代表了"Cube"的面,如果用len(face.loops)取得的數值會是4,再依據每個loop的索引取得vertex的位址。Normal的部分可以直接從face拿到。接著會依據loop來輸出Index,每個面要輸出的Index應該有6個(兩個Triangle),輸出的過程如下圖
Index的輸出順序
至於BaseIndex是作為目前已第幾個Index為基準輸出Index,這樣就可以輸出6個Index了。
  輸出資料的時候要注意一些事,像是vertex的數值如果要取值時要經過round(),具體的範例如下
tagX = round(vert.co.x,3)
tagY = round(vert.co.y,3)
tagZ = round(vert.co.z,3)

取完後,才會是float的數值,原本的數值是double的。還有要注意Blender的坐標系是"右手坐標系",Index的順序是"順時針",如果需要轉換的話請自行轉換。

參考資料

Blender Documentation Contents

相關文章

從Blender裡萃取模組資料(2)

沒有留言:

張貼留言