Blenderで服を着せるのを自動化する
BlenderでVRCアバターに非対応の服を着せる の「メッシュを変更してだいたい服を着せる」の後の工程を自動化したい。
つまりボーンを移動させ、名前を正規化し、頂点グループを修正するあたりを自動化したい。
https://github.com/i544c-me/auto-wear
自動でやりたいことを整理する
✅服のメッシュを、アバターのオブジェクトに移動する
服のメッシュを選択し、Shift + Alt を押しながらアバターにドラッグアンドドロップする
✅服のボーンを、アバターのものに移動する
服のアーマチュアとアバターを選択し、結合する
服のボーンでアバターには無いものの parent をアバターのものに変更する
残った服のボーンは既にアバターにあるもので不要なので削除する
✅頂点グループを修正する
命名規則をアバターのものに修正する
✅服のメッシュのアーマチュアを修正する
服のメッシュのモディファイアにて、 Armature でオブジェクトを素体のものに選択する
期待するプラグインの利用方法
アバターと服をそれぞれ入力する
入力欄の候補は [obj for obj in bpy.data.objects if not obj.parent]
「着せる」ボタンを押すと、先に書いたやりたいことを全て自動でやってくれる
扱う変数たち
Object
https://docs.blender.org/api/main/bpy.types.Object.html#bpy.types.Object
親のオブジェクト
[obj for obj in bpy.data.objects if not obj.parent]
子のオブジェクト
children が生えているのでここから得られる
子のボーン
親のオブジェクトから取得できる
parent_object.data.bones
Bone
https://docs.blender.org/api/main/bpy.types.Bone.html
parent がある
parent が無ければトップのボーンと言える
VertexGroups
https://docs.blender.org/api/main/bpy.types.VertexGroups.html#bpy.types.VertexGroups
object.vertex_groups でアクセスできる
vertex_group.name = "hoge" で変更できる
扱うメソッドたち
トランスフォーム維持でペアレント
https://docs.blender.org/api/main/bpy.ops.object.html#bpy.ops.object.parent_set
ボーンの命名規則 を基に、正規化した名前でマッチングを行い、自動化に役立てる。
調べた情報を基に、コードを書いていく
code:parent.py
# TODO: いずれはアドオンとしてインタラクティブに変数を設定できるようにする
avatar = bpy.data.objects"Avatar"
cloth = bpy.data.objects"Cloth"
bpy.ops.object.select_all(action="DESELECT")
for obj in cloth.children:
obj.select = True
bpy.context.view_layer.objects.active = avatar
bpy.ops.object.parent_set(keep_transform=True)
code:move-bone.py
avatar_bones = bpy.data.objects"Avatar".data.bones
cloth_bones = bpy.data.objects"Cloth".data.bones
# TODO: 結合する
# TODO: それぞれボーン名を正規化して、比較できる状態に持っていく
# 正規化した名前をキー、元の名前を値として持つ辞書型が楽かも
# 例 { "upperleg.l": "Upper Leg.L" }
# TODO: 服のボーンでループを回し、その直下の子でアバターのボーンと一致しないものについて、その親のボーンを基にアバターのボーンを親に変更する
# この時、ルートボーンから順に実行する必要があることに注意
# TODO: 残った服のボーンは削除する
# アバターのボーンとしても存在するということなので
code:fix-vertex-group.py
# TODO: 服のオブジェクトでループを回す
# TODO: そのオブジェクトの頂点グループでループを回し、そのボーンを正規化してアバターのボーン名と一致した場合に、アバターのボーン名に名前を変更する
# 先の正規化したボーン情報を使用すること
code:change-armature.py
avatar = bpy.data.objects"Avatar"
cloth = bpy.data.objects"Cloth"
for obj in cloth.children:
obj.modifiers"Armature".object = avatar