MAYAのインスタンスという機能について、プログラムで扱ってみたら、予想と違う挙動を取ったりしたので混乱しないようにまとめておく。なお、MAYA2018 + MacOS Sierra という環境で調査を進めています。 OSをSierraにいつあげたんだっけ。。
#インスタンスとは
基本的には、Flashのシンボル:インスタンスやフォトショのスマートオブジェクトのように、実態を共有したコピーのようなもの。個別の存在がメッシュ形状をいじると全てに変形が適用されたりする。なのだが。
#インスタンスの作り方と基本的な挙動
ノードを選択して 特殊な複製
のオプションからジオメトリタイプをインスタンスにして適用。グループ化のパラメータの違いはよくわからず。作成されたノードの名前は連番で自動で作られる。
プログラムの場合、選択状態を作らなくてもインスタンスが作れる。
pm.instance('node名')


メッシュは同じなので片方を変形すると両方の形状が変わる。アウトライナで確認すると同じメッシュノードがぶら下がっているのがわかる。ここまでよし。違和感ない。
#作成時の挙動
一度グループ化したものをインスタンスにした場合、トランスフォームもインスタンスとなった。

グループもトランスフォームなので、選択しているトランスフォームはコピーされて中身のツリーがインスタンスとなる挙動に見える。ライトやカメラでも同じ挙動となった。(カメラ2台として動くかどうかは未確認)
ただし、メッシュを直接選択している場合は親トランスフォームがコピーされてメッシュがインスタンス化される模様。トランスフォームがない場合どうなるのか?その辺をオプションパラメータで調整できるのか?要調査。
#インスタンスの細かい挙動詳細
マテリアルを変更した場合、両方のマテリアルが変更されそうなもんだが、そうではなく、片方だけ変わる。マテリアルの紐付けがトランスフォーム側にある訳でもない。これは一体?
ノードグラフで確認してみる。




#ノードのパス
メッシュそれぞれを選択した時のスクリプトログを確認すると、ノード名がフルパス(ロングネーム)で表されるように変化している事に気づく。同じ名前が2つあるので区別するために必要になると言うことはわかる。
meshes = pm.ls(type='mesh')
for m in meshes:
print(m.longName())
# 出力: |pCube1|pCubeShape1
しかしlsコマンドで一覧を得ると1つしかヒットしない。まあ実態は1つなのでこれもわかる。
t1 = pm.PyNode('pCube1')
s1 = t1.getShape()
t2 = pm.PyNode('pCube2')
s2 = t2.getShape()
print(s1.longName())
print(s2.longName())
print(s1 == s2)
# 出力: |pCube1|pCubeShape1
# 出力: |pCube2|pCubeShape1
# 出力: False
トランスフォームを別々に取得して子供のメッシュを確認すると、この場合は別物が取得できている。PyNodeオブジェクトとしては別物となる。この時、あるPyNodeオブジェクトがどのインスタンスグループ番号所属なのか知るにはどうすればいいんだろう?
s = pm.PyNode('pCube2|pCubeShape1')
info = dir(s)
for mem in info:
if 'instance' in str(mem).lower():
print (mem)
# 以下、出力
#_getAssociatedColorSetInstances
#_getAssociatedUVSetInstances
#getInstances
#getOtherInstances
#instanceCount
#instanceNumber
#isColorSetPerInstance
#isInstanceOf
#isInstanceable
#isInstanced
#isInstancedAttribute
#isUVSetPerInstance
#setInstanceable
インスタンスぽい名前のメンバーを抜き出してみたら結構あった。これを調べてみよう。
#疑問点・TODO
- インスタンス作成オプションのグループ化の設定の違いについて調べる
- トランスフォームを介さないインスタンス化ができるのか?
- カメラ・ライトのインスタンスはちゃんとした挙動をするのか?
- プログラムでインスタンスの扱い
全部対応とは言わないが、宿題は以上。