.Tooトップへ
デジタルメディアシステム部 03-6757-3145 お問い合わせ

report

Maya + Python でインハウスツールを作ろう!(後編)

2017.12.08
 

レイアウトが完了したところで、Maya上での表示デモが行なわれた。
ここで紹介されたのが、PySide2とPyQt5の違いを吸収してくれるPyQtUtil。PyQtUtilは、MayaのMMessageイベントをQtのシグナルとして扱うことも可能だ。

ここで、富田氏はQtの特徴である、シグナル・スロットとModel/Viewについて解説した。
〝シグナル〟はボタンが押される、数値が入力される、などウィジェットの状態が変更されたときに発生するイベントで、これにより〝スロット〟が実行される。
Model/Viewは、データを管理するModelとデータを表示するViewを組み合わせたもの。QtにはModel/ViewベースとItemベースのWidgetがあるが、富田氏は「Model/Viewがおすすめ」とした。これはModel/Viewには、 同じデータ(Model)のままViewを差し替えるだけで、ListやTree、Tableなど表示方法の変更が容易というメリットがあるためだ。

必要な解説が終了したところで、富田氏は各機能の実装に移った。

 

アセット登録のフロー

アセット登録のフロー

アセット検索のフロー

アセット検索のフロー

 

DBエンジンに選択したのはsqlite3だが、サーバー機能は搭載されていない。このため、スタンドアローンのPythonでサーバーを構築。標準モジュールのSimpleXMLRPC Serverを使用し、Mayaのアセット管理ツール内で、XMLRPCクライアントを起動してサーバーと通信するという構成を採用している。

アセットの登録に必要なサムネイルは、自動生成を行なっている。
富田氏が最初に考えたのは、Widgetの中身をキャプチャする

QPixmap Widget::grab(const QRect &rectangle)

だった。しかし、Mayaのビューポートを含むWidgetでgrab関数を呼び出しても真っ黒になり上手くいかなかった。

何通りかある解決方法の中で、富田氏が採用したのはglReadPixelsでOpenGLのフレームバッファを直接読み出すという手法だった。ctypesを使ってOpenGL32.dllにあるglReadPixelsのエントリポイントを取得し、PythonからglReadPixelsを呼び出している。コードでは、Viewをリフレッシュしたのち取得するという流れも解説された。
なお、この方法を選んだ理由のひとつに「ctypesが便利だから紹介したかった」ということがあるそうだ。

 

他の言語と比べて遅いPythonの高速化Tips

富田氏は完成したツールのデモ実行後、Python高速化Tipsについて解説した。
具体例として挙げられたのは、頂点カラー平均化ツール。基本的なアルゴリズムの説明後、

  • 再帰を使った実装
  • 再帰をループに変更した実装
  • ループをリスト内包表記に変更した実装
  • ローカル変数化に変更した実装

について、それぞれソースコードが提示された。

 

ローカル変数化に変更した実装

ローカル変数化に変更した実装

 

「Pythonの関数呼び出しのコストが高い」ため、再帰処理をループに置き換えると高速化される。ループのうち、内ループをリストト内包表記に変更した場合は、生成されるバイトコードが減るため高速化されるとした。
さらに、頻繁にアクセスされるメンバ変数、メンバ関数はローカルに定義し直すことで高速化できるとのことだ。

 

実際に実行時間を計測するデモも行なわれた

実際に実行時間を計測するデモも行なわれた

 

富田氏はまとめで〝cythonを使ったネイティブコードへの変換〟といった、今回は紹介しなかった高速化テクニックがあることに触れ、「ツール、パイプライン開発に興味を持つ開発者がたくさん増えると嬉しい」と締めくくった。
なお、本講演で使用したソースコードはGitHub(https://github.com/takeno1027/cedec2017)からダウンロードすることが可能になっている。