D日記

フルリモートで働くモーションアーティストの技術ブログだよ。日常も書くよ。

MENU

【Maya】スキニング後のメッシュを綺麗にしたり分割したりするぞ2019!

f:id:ponta565:20191207040945p:plain

2019年アドベントカレンダー13日目の金曜日です!
初めてアドベントカレンダーに参加してみましたー
といってもそんなにすごい記事は書けないので軽い気持ちで読んで頂ければ嬉しいです。

皆さんこんな経験ありませんか?
①スキニング後のメッシュ(スキンドメッシュ)の頂点を消したりしてゲームエンジンにデータを出力したら見た目が壊れた。
②スキンドメッシュを複数のメッシュに分割する必要が出てきた。でもスキンはそのままにしたい。
今日はこれらを私がやってみた方法で直していきます!

①スキンドメッシュを綺麗にする

解決策1(簡単)

スキンドメッシュを選択して、
編集>種類ごとに削除>デフォーマ以外のヒストリ
f:id:ponta565:20191205224644g:plain

これで解決できる場合もあります!
しかしこの修正方法だと、ヒストリーの削除後に頂点のウェイトが飛んだりする場合があり私は困ってしまいました。

解決策2(ちょっと手間)

メッシュを複製クリーンナップしたあとにウェイトを移すというアプローチで直します。

バインドジョイントを保持

スキンドメッシュに関連するジョイントを覚えておくのも大変なので、選択セットとして保持しておきましょう。下記MELをどうぞ!
f:id:ponta565:20191205224232g:plain

// スキニングされたメッシュ(transform)を選択して実行すると、バインドジョイントの選択セットを作成する
{
    $sel = `ls -sl`;
    $skinC = findRelatedSkinCluster($sel[0]); // SkinCluster取得
    string $bindJnts[] = `listConnections -type joint $skinC`; // joint 取得
    sets -n ("set_bind_joints_"+$sel[0]) $bindJnts; // セット作成
}

スキンドメッシュを複製

複製したメッシュをメッシュAとします。
あとは、ヒストリーの削除やトランスフォームのフリーズ(要ロック解除)などを行ってメッシュを綺麗にします。
f:id:ponta565:20191205230217p:plain

おまけ

// トランスフォームのフリーズ&ピボットのリセット
FreezeTransformations;
ResetTransformations;


ジョイントとメッシュAを選択してスキニング

スキンドメッシュBとします。

f:id:ponta565:20191205231243g:plain

③ウェイトのコピー

スキンドメッシュA と スキンドメッシュB を選択して、
スキン>スキンウェイトのコピー オプションを開き下記の設定をしてウェイトをコピーします。
f:id:ponta565:20191126221139p:plain

f:id:ponta565:20191205232905g:plain
これでメッシュのヒストリーはきれいな状態でウェイトを転送することができました。
ただ、たまに一部の頂点が飛んでいることがあるので、そこは今の所手動で直しています・・・・
分かる人誰かコメントください~
また、もっと簡単なスキンウェイトのクリーンナップ方法あったらおせ~て・・

②スキンドメッシュを分割する

手動でやってみる

モデリング設定を少し変更

プリファレンス>モデリング>フェースの一体性を維持 のチェックを入れます。
これでフェースを抽出した際に、ポリゴン単位でバラバラにならずに済むのです!
f:id:ponta565:20191207025946p:plain

バインドジョイントを保持

解決策2と同じ手順でバインドジョイントを保持してくせい!へいへい!

スキンドメッシュを複製して分割

今回は、「頭」と「体」を分割する想定でいきましょ!
Ctrl + D で複製し、Ctrl + 1 で複製メッシュだけを表示して、フェース選択モードで頭のみを選択。
f:id:ponta565:20191207033419p:plain

そして、Shift + RMB >フェースの抽出・・・
頭と体が見事に分かれるので、そのままの選択状態でAlt + Shift + D でヒストリーを削除
名前は「head」「body」で分けておきましょ:)
f:id:ponta565:20191207033908g:plain

複製モデルにスキニング

ジョイント→頭メッシュ→体メッシュ の順に選択してスキニング。
f:id:ponta565:20191207034401p:plain

ウェイトのコピー

旧モデル→頭メッシュ の順に選択して、
スキン>スキンウェイトのコピー を実行。設定などは前述したものと同じです!
f:id:ponta565:20191207034451p:plain

体メッシュにも同様にウェイトのコピーを!

不要なインフルエンスの削除

現状、使われていないジョイントまでインフルエンスとして登録してしまっています!
なので、使われていないジョイントはインフルエンスから除外しましょう(^^)

スキン>影響を編集>使われていないインフルエンスの除去
f:id:ponta565:20191207034601p:plain

これで頭メッシュには headジョイントしか影響しないようになりました。無駄が無くて最高ですね!
f:id:ponta565:20191207034703p:plain


見事スキンドメッシュを分割することができましたぁぁぁ!!
f:id:ponta565:20191207034855p:plain

スクリプトで自動化する

上で手順をやっておいてなんですが、こちら似たようなことが下記サイトのスクリプトでできます(笑)
しかもこっちの方が普通に早いと思います!
mayamelscript.blogspot.com

ただリンク先のMELだと不足している関数がいくつかありますので、単独動作させたい方はS_TOOLから関数を見つけ出して入れこんで使用するなどしてください(笑)

yjp_DuplicateMeshSkin
yjp_doImitateBind
yjp_meshUnlook


基本的にはS_TOOLを導入していただき下記手順で実行して頂ければ!
メニュー[S_TOOL]->[Modeling]->[SeparateMeshSkin]を実行
mayamelscript.blogspot.com

ツールを導入するのが面倒くさい方は、今回のブログの手順でメッシュを分割しまくりましょう!良いお年を~

おまけメッシュを結合する

分割したメッシュをスキニングを維持したまま結合したい場合は・・
Mesh > Combineのオプションで下記のチェックを入れることで可能です。
f:id:ponta565:20200408115145p:plain