チュートリアル / 読んで触ってよくわかる!Mayaを使いこなす為のAtoZ
第88回:妙に巨大なシーンファイルをどうにかする方法
- Maya
- ゲーム
- コラム
- チュートリアル
- データ
- 上級者
- 中級者
- 学生・初心者
Mayaでデータを作っていると、シーンの中身からすると大した容量ではなさそうなのに、妙にファイルサイズが大きいことってありませんか?
ファイルサイズが不要に大きいとシーンの読み書きの時間がかかってしまうことも。読み書きに時間がかかると、シーンを保存することを避けてしまい、保存する回数が減ったり、ちょっとした作業するのにシーンを開くのも億劫になったりして、ストレス増長、品質低下、気分悪い…色々と問題になります。
Mayaの仕組み上、ユーザが好きにノードを追加したりできるため、どうしてもデータが大きくなることがあります。例えば後で使おうと思って非表示にしたメッシュは必要なものですが、ファイルサイズに影響します。この手のデータは機械的に不要かどうか判断できないため、削除することが難しく、結局シーンに残っていくことになります。特に誰かからもらったシーンだと、果たして必要なデータかどうかわかりにくいですし、そもそも存在に気付かないことも…。
今回はファイルサイズが大きくなる原因でよくあるパターンと解決方法についてみていきましょう。
パターンとしては大きく分けて2パターンあります。
・少ないノードで大きな容量を占める(見えないジオメトリのデータ)
・大量の小さなノードで大きな容量を占める
少ないノードで大きな容量を占める(見えないジオメトリのデータ)
長い時間作業しているシーンでは、作業途中のオブジェクトを複製して取って置くことがあります。作成したオブジェクトの数も増えていきます。その分ファイルサイズが大きくなりますが、これ自体は普通のことですので大丈夫です。
履歴が複雑なメッシュでは、履歴を削除すると「隠れたメッシュ」がシーンに残ったり、他にもノードがたくさん残ったりすることがあります。(大抵この問題を再現しようとしてもなかなか再現出来ないのですが…)
この問題が特に顕著になるのが、モデリングやデフォーマの履歴を削除する時です。これらは履歴の一番始めに「編集する前の形状」があります。次の図の様に「中間オブジェクト(Intermediate Object)」と呼ばれる、見る必要はないけどデータとして必要な形状として扱われます。
履歴を削除すると中間オブジェクトは一緒に削除されます。上の履歴はMultiCut(polyCut)のもので、履歴を削除するとpCubeShape1だけが残ります。中間オブジェクトは削除されます。
でも複雑な履歴が組み合わさっている時、中間オブジェクトが残ることもあります。残ると、ビューで見えない形状である分、いつの間にかシーンに残るということになります。この形状は、元のオブジェクトと同じTransformを親とした階層になりますので、複製すると一緒に複製されます。
中間オブジェクトは Hypergraph(Hierarchy) のOption > Display > Shape nodesとHidden nodesをオンにすると、薄い文字色のノードで表示されます。
以前あったケースをご紹介します。
ある問題のシーンでは、作業すればするほどファイルサイズが数十MBずつ大きくなっていました。シーン同士で差分を見てみると、この中間オブジェクトが大量にぶら下がったメッシュがありました。そのため作業中にメッシュを複製する毎にファイルサイズが大きくなっていたのです。十個ぶら下がっていれば、複製する毎に十倍メッシュのデータを使います!
そう、この手の問題の場合「複製すると極端にファイルサイズが大きくなる」(数MB~数百MB)傾向があります。
複製した分倍々にファイルサイズが大きくなるので、そういった傾向がみられた場合、中間オブジェクトが怪しいです。
中間オブジェクトは普通のメッシュなどのシェイプノードです。ただIntermediate Objectがオンになっているだけなので、選択して削除すればOKです。
Intermediate Objectをオフにするとワイヤーフレームで形をみられますので、不要かどうか見て削除することも出来ます。
不要かどうか…この中間オブジェクトをデフォーマで使っている等、本当に不要かどうかわからないこともあります。中間オブジェクトを選択してHypergraphやNode Editorで前後の履歴を確認して、特に履歴がなければ使われていませんので、削除しても大丈夫です!
この中間オブジェクトの下流の履歴として、groupParts、groupId、tweak等のノードがある可能性もあります。それらのつながりが最終的にビューに見えているノードに繋がっている場合は、その中間オブジェクトが使われていることになります。もし見えているノードに繋がってなければシーンに影響はありませんので削除してみてください。
背景や小物を作っている場合で、デフォーマも履歴もすべて削除しているからとりあえずシーン内の全ての中間オブジェクトを削除しても大丈夫!という場合には次のコマンドを実行します。すべての中間オブジェクトを削除します。
delete `ls -io -type mesh`;
大量の小さなノードで大きな容量を占める
シーン内に巨大なメッシュもないし、中間オブジェクトもない時、小さなノードが沢山含まれている可能性があります。
例えば履歴を削除したときに、とある部分の履歴が独立して残っていることもあります。普通は不要なので削除されるのですが。
あとは何かの加減でノード間の接続を削除したとか、意図的に後で利用するために接続を切っている場合もそれらのノードはシーンに残ります。こういうノードは、そう、「後で使う」ということで意図的にとってあるのかどうか、本人にしかわからないため扱いがちょっと難しいです。
他にもこの手のノードが発生するパターンとして、例えばリグを削除した後、リグのコントロールは削除されているけれどロジック部分のノードが残っていると、数百個のノードがシーンに残り続ける可能性があります。
履歴の中にビューで描画されるものや、Outlinerの階層で表示されるようなトランスフォームノードが関わっていれば、この履歴の存在に気づけます。でも純粋なディペンデンシーグラフのノードであると、見た目で確認できないため、気づきにくいです。しかも見えないため選択もしづらく、削除もしにくいです。
いずれにせよ、ノードの種類ごとに数を確認してみて、極端に多い(1000個以上ある)と容量を占めている可能性があります。例えば次のPythonコードを実行すると、シーン内のノードを種類ごとに集計してウインドウに表示します。
import maya.cmds as cmds
allNodes = cmds.ls()
nodeTypes = {}
for i in range(len(allNodes)):
nodeType = cmds.nodeType(allNodes[i])
if not nodeType in list(nodeTypes.keys()):
nodeTypes[nodeType] = 0
nodeTypes[nodeType] = nodeTypes[nodeType] + 1
print(nodeTypes)
cmds.window()
cmds.paneLayout()
tsl = cmds.textScrollList()
for key in list(nodeTypes.keys()):
text = str(nodeTypes[key]) + '\t' + str(key)
cmds.textScrollList(tsl, e=1, append=text)
cmds.showWindow()
このパターンの場合、不要なものすべて見つけ出して削除することが難しいため、「必要なノードを選択して書き出す」という方法が良いです。必要なものと関連したものだけ書き出されますので、サイズが小さくなります。選択したもの以外がファイルサイズを大きくしていた原因ですので、それぞれのシーンの違いを比べることで、容量を占めていた原因部分も確認しやすくなります。
適切なファイルサイズかどうか見抜く
ファイルをインポートすることを繰り返すと、中間オブジェクトや不要なノードがどんどんインポートされ、それをまた他のシーンにインポートして…と繰り返すごとで倍々にファイルサイズが増えていくことがあります。
どこかの時点で「シーンの見た目以上に保存やロードに時間がかかりすぎているかも…」と気づけるといいですよね。そうでないと妙にファイルサイズの大きなシーンを作ってしまい、それを他の人に渡してしまい、といった連鎖が発生します。この辺り、何かツールで検査することも出来るかもしれませんね。
とりあえずツールに頼らずとも適切なファイルサイズかどうか肌間隔で見抜けるようになることが大切です。まずはMayaの中のノードの種類に応じたファイルサイズを考えてみましょう。
・普通のノード
ジョイント、トランスフォーム、plusMinusAverage等やシェーダー、テクスチャといったノードは、単純に文字列や数値のアトリビュートを持っているだけです。これらはそれほど大きなファイルサイズになりません。もちろん数が数万になれば無視できないサイズになります。
・ちょっと大きめのノード
NURBSカーブはCVごとに位置の情報などを持っているため、普通のノードよりはファイルサイズが大きくなります。
沢山のデータを持つものはシェイプとは限りません。アニメーションカーブのノードも同じです。キーフレームごとに時間、値、接線といった情報を持つため、ちょっと大きめです。数分のモキャプデータであれば、数十MB以上になることも普通にあります。キャラクタの数やジョイント、リグのコントロールの数分増えていくことに注意します。
どちらも頂点やキーフレームがとても多い場合、ファイルサイズに影響を与える可能性があります。例えばアニメーションであれば、モキャプのデータ、ベイクしたキーフレームがTRS値にある場合、それなりに大きなファイルサイズになることが予想されます。
skinClusterも各頂点xインフルエンス数分のスキンウェイトを記録しているため、ちょっと大きめです。頂点数が多く、ジョイント数も多いシーンではちょっと注意が必要です。
・シェイプノード
NURBSサーフェスは元々それほど頂点数を必要としないため、思ったほどサイズは大きくなりません。問題はメッシュです。
メッシュは頂点毎に「位置」が必ず保存されます。必要に応じて「UV」「頂点カラー」「法線」が増えますし、UVとカラーについてはセットが増えるごとに倍々です。面を構成する頂点の情報、エッジのハードソフトなど、とにかく大量の数値が登場するため、どうしてもサイズが大きくなります。
さて、こうなると特に注意が必要なのはシェイプということになります。
ところで…東京で寿司の味の相場を知るには、東京で一番安い寿司と、一番高い寿司を食べると良いらしいですよ。あとは何を食べてもその両方と比べれば妥当かどうかわかるというわけです。肌間隔としてファイルサイズが妥当かどうかとらえるにも同じことが言えます。普通の場合と極端な場合で比べてみましょう。
まずは普通の場合。トーラス(履歴なし)やサンプルで含まれている人型では次のようなサイズです。
これに作業しているシーンが何個UVやカラーセットを持っているかを加味すると、おおよそのファイルサイズが想像できます。
あとはデフォーマやスキニングをすると、中間オブジェクトが作られるため、形状のサイズは最大で二倍になります。
で、数百MBのシーンではどうなるか。
これぐらいのデータ量になるはずです。基本的に頂点やポリゴン数が増えればファイルサイズが増えます。一つのメッシュになっている方が効率が良いのでファイルサイズを小さくできます。メッシュがばらけているほどにより追加の情報が必要になるため、サイズが大きくなります。
Maya Binaryファイルであれば、大体50MB以上の時は百万ポリゴンぐらいになっています。
ということは、ファイルサイズが数百MBなのに、これよりもシーンが随分簡素であれば何か不要なものが含まれているかもしれません。
ちなみにアスキーファイルを開いて確認すると、キャラクタ一体でもこんな感じで、大量のデータが必要です。
シンプルなノードだとどうなるかということで、setRangeノードを百万個作ってみました。Maya ASCIIで90MB、バイナリで65MBでした。
ファイルの中身はこんな感じです。
一つ一つは小さなデータです。特に値を設定していなければノード名とUID以外保存する物もないので、とても小さいです。アスキーでもバイナリでも、名前は文字列扱いであるため、基本的にファイルサイズは近い傾向になります。
一つ100バイトでも百万だと100MB近くなります。これは頂点も同じですね。一つの頂点で位置やUV、頂点カラーを持てば数十バイト*要素数ですから、頂点数が多いとファイルサイズも大きくなります。
ちなみに、テクスチャを沢山使っていても、それはテクスチャへのパス(文字列)しかファイルに保存しませんので、ファイルサイズにはほとんど影響ないです。FBXはテクスチャも含んで保存できますけれど。
シーンを開くとテクスチャを読み込むためメモリを使いますが、消費したメモリとファイルサイズは関連しないことも多々ありますので、実際に何が書き出されているか、Maya ASCIIで確認することをお勧めします。
いつでもExport Selectionが確実?
File > Optimize Scene Sizeは一番手っ取り早いです。が、すべての不要なノードを削除するわけではありません。削除できなかったノードはNode Editor等でノードを確認しながら削除したり、時にはツールを作って削除することになります。
後は本当に不明なものとして、UIのレイアウトノードが増えてファイルサイズを大きくしていたというケースもありました。これを解決するにはExport Selectionするのが効果的です。UIのスクリプトやノードは書き出しませんので。
というわけで、ツールを作るのはちょっと…という場合、大抵最後はExport Selectionで書き出すという手段になります。
ただし中間オブジェクトは選択したオブジェクトの下に隠れてくっついているため、Export Selectionしても一緒に書き出されてしまいます。そのため事前に削除しておく必要があります。もしExport Selectionして、シーンの形状の数や複雑さと比べてファイルのサイズが妙に大きいようでしたら、中間オブジェクトも確認してみてください。
まとめ
ここで紹介した以外にもファイルの肥大化を起こす原因があったりしますが、おおよそ様子をつかめていただけたのではないでしょうか。肥大化の原因や概要をつかめれば、後は個別の問題を確認するだけですので、今日からはもう謎に巨大なファイルに悩まされないはず!
傾向がつかめてきたなら、プロジェクトごとに残りがちなデータの特徴が見つかるかもしれません。そんな時はシーンをチェックするツールを作成してみると面白いですよ。