BlenderからHoudiniのbgeoファイルを出力

この記事は[Houdini Advent Calendar 2024](https://qiita.com/advent-calendar/2024/houdini)の17日目の記事です。

# 初めに
Houdiniのbgeoフォーマットについては[前に書いてある](https://qiita.com/towazumi/items/2b5a6c5bd13e3656a895)ので今回はこんなの作ったよという共有となります。

作ったものは以下にあります。

https://github.com/towazumi/blender_bgeo_script

BlenderからHoudiniにbgeoでデータを受け渡すことで多くの情報を持たせることが出来ます。
記事の内容はほとんどはBlenderとHoudiniのデータの対応表みたいな感じです。

# Houdini側でやっていること

今回の内容に直接関わるのはPython SOP１つだけです。それ以降のノードは読み込んだデータの加工処理です。

Python SOPの内容は

 * Blenderにスクリプトを実行させてbgeoを出力する
 * 出力されたbgeoを読み込む

の２つです。実行にはBlenderのexeを指定する必要があります。

![python_sop.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/92401aeb-7ff8-eab8-36f6-70e98d64c553.png)


# Blenderから持ってこれるデータ

## Mesh

BlenderはZ-up、HoudiniはY-upの座標系なのでその変換が入ります。
それ以外は出来る限りそのままの情報を受け渡すのを基本方針としています。

### 法線
VertexアトリビュートのNで出力されます。

![normal.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/6b13c7e5-b3fe-7266-adb0-04a453f9d4b7.png)


### UV
Blenderは複数UVを持つことが出来て名前を付けられます。
Vertexアトリビュートでその名前のまま出力されます。

![blender_uv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/e8078e58-192f-d6e9-36f6-a8eb3223e474.png)

![houdini_uv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/53c37944-748a-8ff4-14df-560efd66d3ca.png)


### 色
Blenderは複数のカラーアトリビュートを持つことが出来ます。
BlenderのVertexカラーはHoudiniのPointのカラーに
FaceCornerカラーはHoudiniのVertexのカラーに対応してその名前のまま出力されます。

![blender_color.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/56a923fb-e3eb-9028-0cb3-d179a7d0f00c.png)

![houdini_color.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/a6ea5649-f6fd-fd27-3e21-ce81f597e381.png)



### 頂点グループ
0～1の数値でボーンウェイトやマスクデータなどに使われるものです。
Pointアトリビュートとしてその名前のまま出力されます。

![blender_vertexgroup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/30d44fad-831d-76ef-6030-3797332e9084.png)

![houdini_vertexgroup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/0d0efcdc-644b-e432-93c3-6fb1f97d263a.png)


### マテリアル名
マテリアルをHoudini側で再現するのが難しいため名前だけ持っていきます。
Primitiveアトリビュートとしてmaterial_nameで出力されます。

![blender_material.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/97fa8ff6-4836-7fa6-9b03-54769e20712f.png)


### エッジグループ
シャープエッジとUVシームをエッジグループとして出力します。
シームだけBlenderで入れておいてその後のUV展開はHoudiniでといったワークフローが作れるようになります。

![blender_edgegroup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/13fc5bac-c78b-5cc4-440d-327d7f17b51f.png)


![houdini_edgegroup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/b7c8f9c4-d606-0e5a-23da-24b4c10cacfa.png)


### シェイプキー
ブレンドシェイプのデータです。
ポイントの位置(P)とVertexの法線(N)だけのメッシュデータとして出力されます。

![blender_shapekeys.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/10294c9f-8530-17b5-a420-c2628b7aac05.png)

![houdini_shapekeys.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/6a98f97d-5e59-b50a-28dd-677996373d55.png)


## Armature
スケルトンのデータです。kinefxのスケルトンとして扱えるポリラインの形式で以下のPointアトリビュートを持ちます。

 * 位置(P)
 * 3x3の行列(transform)
 * ボーン名(name)
 * ボーンの長さ(length)

ボーンの長さはHoudiniのスケルトンとしては必要ないデータですがHoudini側でボーンウェイトを設定するのにあったら使うかもということで入れてあります。

![blender_armature.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/a049417d-edf5-7f67-2e60-3716d217bb60.png)

![houdini_armature.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/3e84ecf6-9f12-0830-a1fa-3cbf5013577e.png)



## カーブ
Houdiniもカープを扱えるので基本的にカーブのデータとして出力されますが再現しきれていないところがあるといった状態です。Path(Nurbsカーブ)は良い感じに再現出来ていて良い感じです。

またBlenderでHoudiniのSweep SOPのように断面形状を指定してメッシュを生成する機能があるのですがそちらが使われていた場合は追加でそのメッシュも出力されます。

![blender_curve.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/dd348212-b9af-84bf-d0e7-752bb80ce14e.png)

![houdini_curve.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/da3d1aad-a526-b34c-7b75-a2f4f771faac.png)



# Packed Geometry

ここまで多くのアトリビュートを扱いましたがそれをそのままの形で扱うと数が多くて見通しが悪くなります。
本来スケルトン(Armature)にしか必要のないtransformの情報がポリゴンメッシュのポイントに入ってきたり管理が煩わしくなります。

![unpack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/70fbbeb8-a6c3-ca47-16b1-cfa1ea96b0d2.png)

HoudiniにはPackedGeometryという便利な仕組みがありPack化することで一つのプリミティブとして扱えるようになります。
そこでBlenderの一つのオブジェクトを一つのPackedGeometryとすることでHoudiniで読み込んだ時にとてもすっきりとします。

![houdin_pack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/bc34fdf0-a8b7-6c3e-2c03-3013fe92d548.png)

![houdini_pack_geometryspreadsheet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/694c6d33-e833-2509-972f-8da53943c678.png)

このnameはBlenderのView Layerと対応しています。
シェイプキーを持つものは.に続けてシェイプキー名がつけられています。

![blender_viewlayer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/d6ce5f33-2eca-1914-f16a-d563d641711a.png)

BlastノードやSplitノードで必要なものを選択してUnpackすることで各オブジェクトの情報にアクセス出来るようになります。


![houdini_unpack.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/70df4261-87a1-e70c-b2cd-1a808a901cb6.png)


# Blenderのアドオンにするのかしないのか

BlenderのアドオンにするとBlenderのGUIからbgeoを出力出来るようになります。しかしHoudiniのボタン一つで出力と読み込みが出来る現状で便利なので個人的にはアドオン化する必要がないかなと思っています。

Blenderでオブジェクトを選んでbgeoを出力していくフローを組みたい場合にはアドオン化した方が都合が良くなると思います。





# まとめ

個人的に作成したツールの紹介でした。Houdiniのアトリビュートが他のソフトだとどのデータに相当するか等を考えるのも面白いですね。

Houdiniで自動化しやすいようにBlenderでデータ作成するということを意識するようになったので結構おもしろいツールになったんじゃないかと思います。

ではではこの記事が誰かの役に立てば幸いです。

![matome.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223831/ff7c2694-133f-ba5f-6039-8c4838986409.png)