見出し画像

頂点カラーを調べる

頂点には色をつけることができる。頂点についた色のことを頂点カラーと呼ぶ。頂点カラーは個々の頂点に紐づいている情報なので、bpy.data.meshes["Cube"].verticesプロパティからアクセスすることができる…と思いきや、bpy.data.meshes["Cube"].vertex_colorsプロパティからアクセスする。

Vertex Colorsは、メッシュ・データのプロパティ画面から設定することができる。追加する際のデフォルト名は「Col」となる。

Vertex Colorsは頂点カラーのセットみたいなので、シェーダーで切り替えることができるようになっている。『ドラゴンクエスト』で言えば、スライムと色違いのスライム・ベスをパレット・チェンジで表現するようなものに近い。

Vertex Paintモード

頂点カラーは、Vertex Paintモードで塗ることができる。デフォルトでは頂点に色をつけると、共有しているフェイスすべてに色がつく。

Paint Maskを使うと、色を塗りたいフェイスを選択して、対象となっているフェイスにだけ色を塗ることができるようになる。

フェイスごとに塗り分けると『ルービック・キューブ』のようにすることもできる。

スクリプトでフェイスを塗りたい

このVertex Paintの処理をPythonのスクリプトでどのように書けばいいのか?というのを、今回は調べてみた。

今回はフェイス0番だけを赤く塗るPythonスクリプトを書くことにする。

フェイス0番を塗りたいのだから、bpy.data.meshes["Cube"].polygons[0]からアクセスした情報がキーになるということは、容易に推測できる。

では、そのプロパティから頂点カラーを指定するための情報をどのように紐づけたらよいのだろうか?というところが、今回の調査の肝となる。

bpy.data.meshes["Cube"].polygons[0].verticesには、頂点のサブスクリプトが入るけど、頂点カラーの情報はフェイスごとに持っているのだから、おそらく頂点のサブスクリプトではアクセスできない。

試しに、すべてのフェイスに紐づく頂点のサブスクリプトを表示させてみた。予想通り、頂点のサブスクリプトは0~7の範囲に収まっていることが確認できた。

>>> for polygon in bpy.data.meshes["Cube"].polygons:
...     print(f"{polygon.index}:", end="") 
...     for vertex in polygon.vertices:
...         print(f" {vertex}", end="")
...     print("")
...     
00 4 6 2
13 2 6 7
27 6 4 5
35 1 3 7
41 0 2 3
55 4 0 1

Cubeメッシュは四角いフェイスが6枚あるのだから、24個の頂点情報を持っているプロパティがどこかにあるはずだ。

メッシュ・ループ

フェイスは頂点を結んでいって作られるものだから、「頂点をどのような順番で結んでいるのか?」という情報を持っていて、Blenderではメッシュ・ループという構造で表現している。

polygonsプロパティの要素にアクセスすると、loop_indicesプロパティを見つけることができる。中身を表示させてみると、rangeオブジェクトで連番を保持させていることがわかる。

>>> bpy.data.meshes["Cube"].polygons[0].loop_indices
range(0, 4)

すべてのフェイスについて、loop_indexプロパティの内容を表示させてみて、loop_indicesプロパティから頂点カラーへのアクセスに必要な24個のサブスクリプトを得られるのかを調べてみた。

>>> for polygon in bpy.data.meshes["Cube"].polygons:
...     print(polygon.loop_indices)
...     
range(04)
range(48)
range(812)
range(1216)
range(1620)
range(2024)

頂点カラーへのアクセスに必要な24個のサブスクリプトは得ることができたので、次はカラー情報が格納されている

頂点カラーの情報

頂点カラーの情報は、bpy.data.meshes["Cube"].vertex_colorsプロパティに格納されている。

>>> bpy.data.meshes["Cube"].vertex_colors[0].name
'Col'

インタラクティブ・コンソール上で、実際のカラー情報を探してもそれらしいプロパティが見つからないのだけど、プロパティの顔ぶれを見ると、dataプロパティ一択となる。

dataプロパティは、自分自身の由来を示すデータを参照していることが多いけど、頂点カラーに関しては、頂点カラー・データのコレクションとなっている。

コレクション・データの数を調べてみると24個あるので、ここに頂点カラーの情報があるのは間違いなさそうだ。

>>> type(bpy.data.meshes["Cube"].vertex_colors["Col"].data)
<class 'bpy_prop_collection'>

>>> print(len(bpy.data.meshes["Cube"].vertex_colors["Col"].data))
24

実際のカラー情報がどこにあるのかを調べてみると、colorプロパティに格納されていることがわかった。colorプロパティは4個の要素から構成されていて、RGBA形式の値が格納できるようになっている。

各カラーの要素は、値0.0~1.0の範囲で設定できる。Blenderの場合、合成係数αは不透明度を表していて1.0が完全な不透明で、0.0に近づくほど透明になっていく。

スクリプトで塗る

ここまでの調査結果をイメージにまとめると、次のようになる。

この情報を元に、フェイス0番だけ赤く塗るスクリプトを作成し、実行させてみる。

>>> for index in bpy.data.meshes["Cube"].polygons[0].loop_indices:
...     bpy.data.meshes["Cube"].vertex_colors["Col"].data[index].color = ( 1.00.00.01.0 )

Vertex Paintモードに切り替えて、1面だけ赤くなることが確認できた。




この記事が気に入ったらサポートをしてみませんか?