BMesh 簡介
BMesh 是 Blender 中用于表示和操作網格數據的底層數據結構系統,它是傳統網格數據結構的高級替代品。
主要特點
-
靈活拓撲支持:
- 支持 n-gons(任意邊數的多邊形),而不僅僅是三角形和四邊形
- 允許邊和頂點不屬于任何面
-
高效操作:
- 設計用于支持復雜的網格編輯操作
- 提供豐富的 API 用于網格操作
-
數據結構:
- 基于半邊數據結構(Half-Edge)
- 包含三種基本元素:頂點(verts)、邊(edges)和面(faces)
使用場景
BMesh 主要用于:
- 編寫 Blender 的網格編輯工具
- 開發復雜的網格處理插件
- 執行高級網格操作如布爾運算、細分等
基本元素
- BMVert:表示頂點
- BMEdge:表示邊
- BMFace:表示面
BMesh 提供了比傳統網格更強大的功能,特別是在處理復雜拓撲和非流形幾何時表現優異。
訪問方式
在 Python API 中,可以通過 bmesh
模塊訪問 BMesh 功能,通常用于編寫網格處理腳本和插件。
創建一個bmesh后,可以貼圖不同的材質嗎?
是的,在一個 bmesh
對象中創建的多個面,完全可以賦予不同的材質,只要你后續把 bmesh
寫入 mesh,并對 mesh.polygons[i].material_index
設置正確即可。
? 關鍵點總結
操作目標 | 是否可行 | 方法 |
---|---|---|
一個對象中多個面貼不同材質 | ? 支持 | 設置 face.material_index |
bmesh 創建時直接貼材質 | ? 不直接支持 | 需要在 bmesh.to_mesh() 之后,通過 mesh.polygons[...] 設置 |
一個 Object 支持多個材質 | ? 支持 | obj.data.materials.append(...) 添加多個材質槽 |
? 正確做法:一個 Object
、多個材質、不同面貼圖
1. 創建 bmesh
添加多個面
import bpy
import bmesh# 新建 mesh 和 object
mesh = bpy.data.meshes.new("MyMesh")
obj = bpy.data.objects.new("MyObject", mesh)
bpy.context.collection.objects.link(obj)bm = bmesh.new()# 頂點
v1 = bm.verts.new((0, 0, 0))
v2 = bm.verts.new((2, 0, 0))
v3 = bm.verts.new((2, 2, 0))
v4 = bm.verts.new((0, 2, 0))v5 = bm.verts.new((3, 0, 0))
v6 = bm.verts.new((5, 0, 0))
v7 = bm.verts.new((5, 2, 0))
v8 = bm.verts.new((3, 2, 0))# 兩個面
face1 = bm.faces.new([v1, v2, v3, v4])
face2 = bm.faces.new([v5, v6, v7, v8])
2. 寫入 mesh
bm.to_mesh(mesh)
bm.free()
mesh.update()
3. 添加兩個材質到 obj
mat1 = bpy.data.materials.new("Red")
mat2 = bpy.data.materials.new("Green")mat1.diffuse_color = (1, 0, 0, 1) # RGBA
mat2.diffuse_color = (0, 1, 0, 1)obj.data.materials.append(mat1)
obj.data.materials.append(mat2)
4. 給 mesh.polygons[i]
設置材質索引
# 給第一個面用第一個材質
obj.data.polygons[0].material_index = 0# 給第二個面用第二個材質
obj.data.polygons[1].material_index = 1
結果
🔁 所以流程是:
- 在
bmesh
中構建所有頂點和面; bm.to_mesh(mesh)
把面數據寫到mesh.polygons
;- 添加所有材質到
obj.data.materials
; - 遍歷
mesh.polygons[i]
,設置對應的material_index = X
。
?注意事項
- 必須保證
obj.data.materials
中的材質數量 >= 所有material_index
的最大值 + 1; material_index
是一個整數索引(指向材質槽的位置),不是材質本身;- 所有
material_index
設置必須在bm.to_mesh()
后進行,因為bmesh
階段沒有material_index
概念。
撰寫該博文的原因是有一個需要用腳本來控制一個立方體不同面的貼圖,其實現的基本原理和上述代碼是一致的。