どうも、COYOTEスタジオTAチームのMです。
さて早速今回の記事のネタですがタイトル通り、「SIWeightEditor改修記!」です。
Maya使いのモデラーやセットアッパーのかなりの割合の人がお世話になっている
SIWeightEditor(以下SIWE)というツールがあります。
簡単に紹介しますと、
こちらのGithubページで無料で配布されているツールで、作者はysさん。
https://github.com/ShikouYamaue/SIWeightEditor
Mayaの標準の数値入力でのウェイト編集機能は、コンポーネントエディターで無理やり編集する以外に方法がありません・・・。
他DCCツールですと使いやすいものが標準で搭載されていることがあり、かつてSoftImageに搭載されていたウェイト編集機能オマージュし、Maya用ツールとして制作されたのがこのSIWEなのです。
そんな素晴らしいSIWEなのですが直近のMayaのバージョンアップで大きな変化の影響を受けてしまいました。
それはMayaで動作しているPythonのバージョンが2系→3系への切り替えです。
(Maya2020まではPython2.7.11 Maya2022でPython3.7.7 Maya2023でPython3.9.7になりました。
なおMaya2022時点ではWindows版 Linux版のみ2系&起動3系起動の切り替えが可能、MacOS版は3系のみでした。)
実はPython3系で動かなかった時期に弊社内でSIWEのPython3系対応をやろう!ということを私が提言していたこともあったのですが案件のアサイン的に時間が確保できず歯がゆい思いをしていたら・・・な、なんと他の方が3系対応してくださっていました。
かくして、改修作業がバッティングせずに済み、3系MayaでもSIWEが使えるようになりましためでたしめでたし・・・・
と思いきや3系特有の別問題が発生していたこと、弊社内で上がっていた機能追加要望もあったため、弊社TAチームのパイプライン系TAの天埜くんと二人三脚で改修作業を行いました。(筆者は主に調査と監修を担当。実装は天埜くん。)
(ここまで前フリ!長い!)
さてさて、改修作業の要点としては以下となります。
★作業効率やデータ破損につながるクリティカル部門
・3系Mayaで使用時、インフルエンス名(Joint名)をクリックした際の対象インフルエンスのハイライト機能が動いていない。
・Issueに来ている通り、3系で使用した際に発生するRound処理の不正ウェイト修正。
★挙動として修正がほしいと思っていた部門
・SIWE上のハンマー機能2種を使った際、対象SkinClusterの「最大インフルエンス数の保持」アトリビュートがOFFになっている場合強制的にONになる。
・1メッシュ数万頂点級のメッシュでSIWEのリスト書き換え処理が走る際にMayaが 一瞬~数秒 フリーズする。
他にも細かい要望はありますが、大きな問題ではないので一旦以上の4項目に絞って優先的に対応致しました。
なおIssueにある高DPI環境対応に関してはやや一筋縄で行かない類のモノなため一旦対応を先送りと致しました。
4項目の詳細と、対応リストを作った際の不調の原因の予想
・インフルエンスハイライトの動作不良
ウェイト調整時、名前だけ見ていてもどのJointに対してなのかが分かりづらいため、よく使う機能としてSIWE上のインフルエンス名をクリックした時にJointが白く変わるハイライト機能があります。しかしMaya2022以降で動作させた時に表示が切り替わりません。(2022のPython2モードでも動作しない)
予想:
Python2系モードで動作しない以上これは
2022で何らかの描画系の仕様変更?もしくはアトリビュートの仕様変更?(調べたらこのハイライト機能は対象ノードの描画オーバーライドを使っていたのでその関連?)
・Round処理の動作不良
Round機能を使うと桁が飛ばされないばかりか不正なウェイト値になってしまう(正常にNormalizeされていない?)
予想:
Python2系起動のMaya2022では正常に動作しているのでPython3系のなにかしらが原因?
・ハンマー系機能使用時の挙動
ハンマー系機能を使った際に動作対象のSkinClusterの最大インフルエンス数の保持フラグが強制的にONになってしまう
予想:
このアトリビュートをOFFにした状態で使うことを想定しておらず、計算の途中でいかなる場合でもここをONにし、計算前がOFFだった場合に
継承しない設計になっている?
・ハイポリメッシュでの動作フリーズ
ハイポリゴンなメッシュでSIWEを使いウェイト作業をしていると数秒フリーズする。
予想:
ウェイト取得をcmdsのSkinpercentコマンド等で行っているせい?もしくは表示するためのリストを生成しているPythonの処理やQtの処理の問題?
もしcmdsを使っているとしたら取得をAPI2.0で取得すればもっと早くなる・・・はず?
このように仮説をそれぞれ立てて調査+改修していきました。
結果は
・インフルエンスハイライト
まさかのQtのバージョンに依存した問題。
2022ではQtのバージョンが5.15.2に。そのため2系でも3系モードでも同じ問題が起きていた。(QtはPythonのバージョンとは独立したモジュールなので2系3系で共通のものを読んでいるようだ。)
Maya2020(QT 5.12.5)より前まではQItemSelectionModel.currentIndex()をparentに指定していたが、デフォルトの引数が空で動くようになった影響なのか指定することで逆に動かなくなってしまっていたのでMaya2022以降では空のQModelIndexを指定するようにしました。
https://doc.qt.io/qt-5/qitemselectionmodel.html#columnIntersectsSelection
・Round処理
直接的な原因はPython3系ではmapがオブジェクトとして返ってくるため.count関数が使えなくなっていた。
そのためlistに変換して.countを使用できるように変更。
また付随したものとしてround関数の挙動が
Python2系:四捨五入
Python3系:偶数丸め
と、同じ数字をround関数に渡しても返ってくる値が違います。
そのため3系稼動のときも四捨五入動作するようにしました。
https://github.com/ShikouYamaue/SIWeightEditor/pull/14/commits/750201358dbee0efcab8f1a71d1ce63a40fb2b33#diff-7e14f101ed9b5cb575664724b346abe966a8aa15059965626f4615c90f979bf1
・ハンマー系機能でのアトリビュート保持
原因は、SkinClusterノードのmaintainMaxInfluencesフラグの直接的な変更ではなく、SkinClusterコマンドのobeyMaxInfluencesフラグによるものだった。
https://help.autodesk.com/cloudhelp/2022/JPN/Maya-Tech-Docs/CommandsPython/skinCluster.html#flagobeyMaxInfluences
このフラグを使用しないように改修することも出来るが、他機能へ何らかの悪影響が出る可能性も捨てきれないので、mMIアトリビュートがFalseの場合は処理後にFalseにセットし直すように機能追加とした。
(筆者はウェイト作業中はMaxインフルエンス制限をかけずに作業し、最後に制限をかけて仕上げる派なのでこの改修は地味にありがたい・・・!)
・ハイポリメッシュでの動作フリーズ
調査の結果、判明した原因は読み込み部分。しかし、既にAPI2.0で実装済。なお計測したところUIは足を引っ張ってなさそう。
これ以上は最早C++で実装しないと高速化不可能なため一旦これ以上の改修は断念し、ScriptJobを強制的に停止するボタンの実装。
(これだけでも意図しないフリーズが発生しなくなるので作業のストレスはだいぶ軽減される。なおSIWEの既存の機能であるロック機能もにた状態を作れるが挙動が少し違うことと、ロック機能自体に改修を入れた場合に波及する部分の調査等のタスクが肥大化するおそれがあったため別機能として実装しました。)
ちなみにC++実装が必要であるという結論の理由に関しては、
・コンポーネントエディタでの同一メッシュウェイト読み込みがおおよそ倍~4倍ほど読み込み速度が違ったこと
・Python自体は他言語とくらべて多機能な反面処理負荷が重いこと
・C言語で実装されているPython(いわゆるCPython)はGILという制限のためマルチスレッドが行えず単コアの処理としては最早限界と思われる
以上の3点からMaya上のPythonからのAPIアクセスではC++で実装されているであろうコンポーネントエディタには追いつけないなと判断したためです。
以上、このように4つの問題に関して改修作業を行いました。
○改修作業を終えて
普段から業務で使うことの多いSIWEを色々と改修したい、Mayaの最新バージョンでも正常に動作するようにしたい。そういう思いから社外ツールではありますがSIWEの改修をさせていただきました。
予想と結果をご覧の通り、実際の不具合ポイントが予想と割と違っていて自分のデバッカー能力もまだまだだなぁと痛感しました。
また今回の改修については別の意味合い 思惑もあり、弊社内で今まで作ってきたツール郡は今後どんどんPython3系対応改修していかなければならない過渡期にあるため 、知見の習得機会にもなり、コレはチームとしても収穫が大きいであろうということで本改修作業は全て業務時間扱いで行いました。そういう取り組みにもOKを出してくれてありがたい会社だなぁ・・・と思いましたね!(決してヨイショしているわけじゃないですよ!純粋にありがたい!)
まだ色々と手を加えたい部分は少しありますし、C++で超高速化も行いたい所ではありますが今回は一旦ここまで!
SIWEはGithubで全ソースコード見られますし、今回の改修内容も全てGithub上でプルリクを送ったのでご興味ある方はどう改修したのか?の差分を見てみるとすこし勉強になるかもしれません。
それではまた次の機会で~。
執筆:M
技術:天埜零士
協力:COYOTEスタジオスタッフ、TAチーム各位
Special Thanks:ys様