MaxScriptTip: Maxオブジェクトを一意に特定する

3月 26, 2016
MaxはMaya等と違って、オブジェクト名がシーン内で一意であることを保証していません。

当然全くの同名(同パス)オブジェクトが複数シーン内に存在する事になり、オブジェクト名では特定のオブジェクトを必ずしもハンドルする事が出来ません。
MaxScript内で常にオブジェクトのインスタンスを保持出来れば良いのですが、それが出来ないケースもあります。
例えば、.NETと連携させる時やクリップボードに転送する時等…。

そこで今回は、MaxScript内で、インスタンス保持以外の方法で、オブジェクトをハンドルする方法を2つ紹介します。


inode.handleを使う方法

ノードオブジェクト(シーン内に座標系を持って存在しているオブジェクト)はinodeインタフェースのhandleプロパティが使えます。
local handle = $box001.inode.handle
これにより、シーン内のノードを一意に特定出来るハンドルを取得出来ます。
ハンドルからノードを取得するには以下のようにします。
local node = maxOps.getNodeByHandle handle
リファレンスによると、$box001.handleとするよりは$box001.inode.handle等とする方が良いらしいです。
inodeを省略した場合、元々「handle」プロパティを持っているオブジェクト(Teapot等)はうまくハンドルを取得出来ない可能性があるからだそうです。


AnimHandleを使う方法

ノード以外のオブジェクト(マテリアル、モディファイヤ、コントローラ等)をハンドルするにはAnimHandleという仕組みが使えます。
AnimHandleは、文字通りAnimatableオブジェクトに設定出来るハンドルシステムで、シーン内のほぼ全てのオブジェクトのハンドルを取得する事が出来ます。
local mtlHandle = GetHandleByAnim $box001.material
ハンドルからマテリアルを取得するには以下のようにします。
local mtl = GetAnimByHandle mtlHandle
この方法は、うまく使うと.NET APIにオブジェクトを転送する時等にも使えます。
(.NET API内でもGetAnimByHandleは使える為)

ただし、こちらのハンドルはMaxのセッションが終了するとリセットされてしまうみたいなので、外部ファイルに保存しておいて使うような使い方には向きませんね。

どちらを使うかはケースバイケースだと思いますが、知っておくと便利かもしれません。

Related Articles