🐵
Blender Pythonでメッシュの各ポリゴンの各頂点の頂点座標値、Shapekeyごとの頂点座標値、UV座標値、頂点カラーを取得する
概要
メッシュの各ポリゴンの各頂点の
・頂点座標値
・各Shapekeyに登録されている頂点座標値
・UV座標値
・頂点カラー
を取得する方法を紹介します
今回は例としてデフォルトキューブを使って情報を取得してみます
環境
- Blender 3.3
Pythonスクリプトと実行方法
- Blenderを開き、デフォルトキューブを消さずに「ウィンドウ」タブの「システムコンソール切り替え」をクリックし、スクリプトの実行結果やエラーが見えるようにする
- 「Sclipting」タブの「+新規」ボタンをクリックして以下のPythonスクリプトを貼り付け、「▶」ボタンをクリックし、スクリプトを実行する
※
Shapekeyと頂点カラーはデフォルトキューブには最初から存在しないので、スクリプトで追加しています
import bpy
# メッシュを取得 (選択されているメッシュを取得する場合はbpy.context.view_layer.objects.active)
Mesh = bpy.data.objects["Cube"] # Cubeという名前のメッシュを取得
Mesh.select_set(state=True) # メッシュをアクティブに設定
# メッシュにShapekeyが2つ無かったら追加する
if not Mesh.data.shape_keys:
bpy.ops.object.shape_key_add()
Mesh.data.shape_keys.key_blocks[0].name = "Basis"
if 1 == len(Mesh.data.shape_keys.key_blocks):
bpy.ops.object.shape_key_add()
Mesh.data.shape_keys.key_blocks[1].name = "Key 1"
# メッシュに頂点カラーが無かったら追加する
if not Mesh.data.vertex_colors:
bpy.ops.mesh.vertex_color_add() # Blender3.4以降はMesh.data.vertex_colors.new()で動くはず
Mesh.data.vertex_colors[0].name = "Col"
# メッシュの各ポリゴンごとにループ
for Poly in Mesh.data.polygons:
# 現在のポリゴンのインデックス番号と辺の数を表示
print("----------------------------------------------------------------------")
print("Polygon index: %d, Number of sides: %d" % (Poly.index, Poly.loop_total))
# 現在のポリゴンの各頂点ごとにループ
for LoopIndex in range(Poly.loop_start, Poly.loop_start + Poly.loop_total):
# 現在の頂点のインデックス番号を取得
VertexIndex = Mesh.data.loops[LoopIndex].vertex_index
# 現在の頂点の座標値を取得
VertexPos = Mesh.data.vertices[VertexIndex].co
# 現在の頂点の各Shapekeyに登録されている座標値を取得 (BasisとKey 1)
Shapekey0_Pos = Mesh.data.shape_keys.key_blocks[0].data[VertexIndex].co
Shapekey1_Pos = Mesh.data.shape_keys.key_blocks[1].data[VertexIndex].co
# 現在の頂点のUV座標値を取得
UvPos = Mesh.data.uv_layers[0].data[LoopIndex].uv
# 現在の頂点の頂点カラーを取得
VertexColor = Mesh.data.vertex_colors[0].data[LoopIndex].color
# 取得した現在の頂点の情報を表示
print("")
print(" VertexIndex :", VertexIndex)
print(" VertexPos :", *VertexPos)
print("Shapekey0_Pos :", *Shapekey0_Pos)
print("Shapekey1_Pos :", *Shapekey1_Pos)
print(" UvPos :", *UvPos)
print(" VertexColor :", *VertexColor)
実行結果
デフォルトキューブは6個の四角面で構成されているので、Polygon indexが6回表示され、各Polygon index内でVertexIndexが4回表示されていれば成功です
Shapekey(Key 1)の頂点を移動させたり、UVをずらしたり、頂点ペイントを行ったりすると、スクリプトの実行結果も変わるはずです
つまづきやすいポイント
最初のうちは頭がこんがらがるのですが、頂点1個あたりにUV座標1個と頂点カラー1個が割り当てられているのではなく、「面と頂点の組み合わせ」ごとにUV座標と頂点カラーが割り当てられていることに注意してください
今回のデフォルトキューブでは頂点数が8個ですが、
UV座標と頂点カラーはそれぞれ 6(面の数) x 4(各面の頂点数) = 24個 存在します
各頂点の情報の変更例
今回のスクリプトでは各頂点の情報を表示しているだけですが、もちろん変更も行えます。
例えば頂点カラーの値を変更したければ、
VertexColor = Mesh.data.vertex_colors[0].data[LoopIndex].color
と書かれている右辺の部分を左辺に持ってきて
Mesh.data.vertex_colors[0].data[LoopIndex].color = [1, 0, 0, 1] # RGBAで赤色を指定
のように、リスト形式で値を直接指定できます
参考にさせていただいたサイト
Discussion