久しぶりの3Dネタです。
仕事で、シーンファイルの合成をすると必ず落ちる不具合が発生しました。不具合が発生したシーンのオブジェクトを、正常なファイルに1つでも合成すると、正常なファイルでも不具合が起きて直らなくなるという。まさにウイルスの様なバグ。
原因と対処法を探しましたので、メモしておきます。
不具合内容
3dsMAXで、「合成」をすると極端に重くなる。
不具合が起きたファイルから全オブジェクトノードを削除し、ボックスを1個置いたシーンがこちら。
頂点数8でポリゴン数12ってのが謎ですが…。まぁいいか。
【2015/10/18追記】壮大な勘違いでした。頂点数8のボックスのメッシュオブジェクトのポリゴン数は12で合っています。3dsMAXは「面」「メッシュ」「ポリゴン」を混同しがちなので、気をつけないとダメですね。非平面は3D空間に描画できないので、面は必ず3頂点で構成されます。ボックスのポリゴンは6つで、4頂点で構成されるポリゴンは2つの面でできています。なので、12面。メッシュオブジェクトではポリゴンと面を同じものとして扱うので、シーン情報のメッシュ総数は頂点8、ポリゴン数12で合っている訳です。【追記ここまで】
ファイル名のつづりが間違ってるのも気にせんといてください。
中身は頂点数8のボックス1個なのに、ファイルサイズを見ると9MB近くもあるで…!
原因
ワールド直下のトラックビューノードにゴミがたまっているのが原
ちなみに、ワールド直下にくっついてるトラックビューノードはシーン内の全オブジェクトを削除しても消えません。しかも、見えません。
対策方法
スクリプトを使って、
3dsMAX 2008以降でAutodeskに類似の不具合報告があります。
このバグではモーションクリップを削除していますが、リタイマーやアニメーションレイヤーでも動揺の症状が発生する様です。
http://tech.autodesk.jp/faq/faq/adsk_result_dd.asp?QA_ID=6445
スクリプト 「リタイムクリーナーさん」
=========================
RTC_Cleaner3.ms_.zip
=========================
※ MITライセンス(動作無保証です)
※Macで圧縮してるので、widnowsで解答すると文字化けするかもしれません。
スクリプト起動して、ゴミを削除するとファイルサイズが正常に戻ります。
スクリプトの内容について
このスクリプトは、3dsMAX 2014以降に対応しています。
下記スクリプトを実行すると、3段階の確認ダイアログが表示されます。
削除処理が始まるとフリーズした様に見えるかもしれませんが、10分ほど待つと完了画面が表示されます。
/* ================================ RTC Cleaner v1.0 License is MIT. (c)DENSHIs / yuki ================================ */ if querybox "[1/3] 不自然に生成されたリタイマーのゴミを削除します" title:"RTC_Cleaner" do( tv = trackviewnodes rtm = tv[#Retimer_Manager] if rtm != undefined do ( deleteTrackViewController tv rtm.controller gc() ) ) if querybox "[2/3] 不自然に生成されたアニメーションレイヤーのゴミを削除します" title:"RTC_Cleaner" do( tv = trackviewnodes alc = tv[#Anim_Layer_Control_Manager] if alc != undefined do ( deleteTrackViewController tv alc.controller gc() ) ) count = RetimerMan.numRetimers if querybox ("[3/3] " + count as string + "個のリタイムコントローラーが見つかりました。¥n使用されていないコントローラーを削除します。¥nこの処理に5分〜15分ほど掛かる場合があります" title:"RTC_Cleaner") do( progressstart "リタイムコントローラーを掃除中" /* reference method */ get_rt = RetimerMan.GetNthRetimer del_rt = RetimerMan.DeleteRetimer undo off /* remove roop*/ for i = 1 to count where (rtc = get_rt (count-i+1); rtc != undefined and rtc.nummarkers==0) do( progressupdate (i/count ) del_rt (count-i+1) ) /* end */ gc() progressend() undo on /* repot message */ new_count = count - RetimerMan.numRetimers messagebox ("シーンから未使用の " + new_count as string + "個のコントローラーを削除しました。" title:"正常に終了しました") )