Python + MaxScriptのツール開発入門(Max2020版)その14

 前回までで当初予定していたものは完成しました。Python を使った3dsmax の開発では、やはり実行部分はMaxScript で作り、UIをPython で作るというのがとっかかりとしては楽だと思います。

 しかし、これPython で開発していると言えるのだろうか、と思いますよね。なにしろPython なのはUI だけですから。そこで、今回はチュートリアルとしては番外編として、これまで作ってきたGridCopy を全部Pythonで、MaxScript を一切使わずに実装してみましょう。

実行部分をPython で実装する

 実際の動作部分をPython で作るわけですが、今回はすでに求める機能をMaxScript で実装済ですので、そのコードを参考にしましょう。gridCopy.ms を見ると、実行はlineCopy という関数と、gridCopy という関数に分かれています。

 動きを確認すると、lineCopy という関数は元になるノードのリストを受け取り、それを一方向へコピーして並べる、という動作です。そしてでき上った状態をリストにして返しています。

 ここで、MaxScript では複数のオフジェクトを格納するデータ型は配列(Array) しかなかったので特に何も考える必要はありませんでしたが、3dsmax のPythonAPI にはこういう場合に使える型がいくつかあります。何を使うのが良いかはケースバイケースで、Python のリストも使えるのですが、ここではせっかくなので3dsmax のPythonAPI のINodeTab を使いましょう。

 一気に書いてしまいましたがこんな感じです。MaxScriptのCloneNodes みたいにオフセット地を入れて実行したり、生成されたノードを回収したりということを一発でやるものは用意されていません。そのため、それぞれの処理は自前で実装する必要があります。

 あとはこれをx、y、zそれぞれの方向に実行するgridCopy を実装するだけです。

 このような感じですね。あとはこのgridCopy を実行ボタンのシグナルに接続したスロットの中で呼ぶようにします。ここではdoGridCopy がそれに当たるので、その中身を書き換えましょう。

 ポイントは最後のビューの更新で、Python から操作を行うと、画面更新がかかるまでビューポートに反映されない(シーン内は変更されているのに画面が変わらない)という現象が起きます。そのため、画面更新の必要な処理(ここでは存在しなかったオブジェクトが増えるという操作)をした場合は、操作完了時にビューポートの再描画処理を入れましょう。

ついでに

 ここで完成したものをテストしていたら、入力欄のタブストップは横方向、つまりX個数→X間隔、Y個数→Y間隔、となっているほうが便利な気がしてきたので、そのように変更しました。

images/ss28.png

完成!

 ついに完成しました。これで初めてのPython による3dsmax のツール開発がまがりなりにも完成しました。お付き合いいただいた皆様、ありがとうございました。

 最後にGridCopy クラスの全体を置いておきますね。

images/gridcopy11.gif

 このチュートリアルは本当に初めて3dsmax でPython を使ったツール開発をしてみたいという人に向けて書いたものなので、これでなんでもできる! というようなことはありません。でも入口部分で躓きやすいところはなるべく解説したつもりです。

 一旦これでチュートリアルは終了となりますが、3dsmax のPython 周りについても継続して記事を書いていこうと思っています。なにか要望などもあればぜひ聞かせてください。

まとめ

  • 3dsmax のPythonAPI には複数のノードを格納するデータ型がいくつもある
  • 3dsmax でPython からビューポートの変化を伴い処理をしたら明示的に再描画した方が良い
  • 3dsmax でPython を使ったツール開発をするのは楽しい!(これが一番重要!)