3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【MAYA】マテリアルのフェイスアサイン時のノード構成を理解する#1

Posted at

MAYAのインスタンスの振る舞いに続いて、(世の中で嫌われていそうな)マテリアルのフェイスアサインについてPymelを使ったプログラム視点で調査したのでメモを残してみます。
以下は、MAYA2018 + MacOS Sierraで動作確認しています。ソース中pmとなっているのはimport pymel.core as pmという形でインポートされた PymelCoreオブジェクトです。ソース中、出力:と書いてある部分は、結果表示を自分がわかりやすくコメントの形で書き写した部分で、実際のMAYA上の画面とは異なります。

フィイスアサイン前後の差異

 2018-01-08 22.10.19.png マテリアルのフェイスアサイン前の状態です。shapeの`instObjGroups[0]`からShadingGroupの`dagSetMembers[0]`にコネクトされています。つまり、キューブのデフォルトインスタンスがマテリアル`phong1`に紐づいています。普通です。  2018-01-08 22.11.23.png フェイス1面に別のマテリアルである`phong2`をアサインしてみた状態がこれです。逆向きにコネクションができたり、コネクションの出力元が増えたり、急に複雑になりました。変更点をそれぞれ見てみます。

メンバーワイヤーフレームカラー

SGそれぞれからShapeに逆向きに伸びるコネクションです。見やすくビューのノードの左右位置を入れ替えて詳しく見てみます。
 2018-01-08 22.47.44.png
メンバーワイヤフィレームカラーからオブジェクトグループのカラーという所へコネクションが伸びています。詳しい値をscriptで表示してみます。

sg1 = pm.PyNode('phong1SG')
print(sg1.memberWireframeColor.get())
# 出力:-1

print(sg1.memberWireframeColor.listConnections(plugs=True))
# 出力:[Attribute(u'pCubeShape1.instObjGroups[0].objectGroups[0].objectGrpColor')]

sg2 = pm.PyNode('phong2SG')
print(sg2.memberWireframeColor.get())
# 出力:-1

print(sg2.memberWireframeColor.listConnections(plugs=True))
# 出力:[Attribute(u'pCubeShape1.instObjGroups[0].objectGroups[1].objectGrpColor')]

sg1、 sg2共にほぼ同じ状態で、異なるのはobjectGroupsのインデックス番号だけです。このobjectGroupsの番号がズバリ、フェイスのグループ番号を示すようです。青いフェイス部分がグループ0で、黄色い部分がグループ1という事ですね。

pCubeShape1.instObjGroups[0].objectGroups[0]は、つまり、pCubeShape1のデフォルトインスタンスのフェイスグループ0という意味でしょう。

そして、memberWireframeColorというのはどうも作業画面上のワイヤフレームのカラー表示設定のようで、ユーザーが自由にカスタマイズして使うことができるもののようです。値の-1というのはデフォルト値で設定なし、です。と、するとこのカラー番号を指定するUIがMAYAのSGのインスペクタ上に存在しそうなものですが見つかりません。。
見つからないのですが、重要そうなノード接続ではなさそうなので、深く考えずに先に進みます。

インスタンスオブジェクトグループのオブジェクトグループ

 2018-01-08 23.23.51.png フェイスアサイン前後を改めて確認します。
shape = pm.PyNode('pCubeShape1')
print(shape.instObjGroups[0].listConnections(plugs=True))
# 出力:[Attribute(u'phong1SG.dagSetMembers[0]')]

instObjGroups[0]からphong1SG.dagSetMembers[0]に接続が伸びています。

 2018-01-08 23.31.12.png フェイスアサイン後はこのようになりました。まず、選択されて黄色くなっているコネクションを確認します。
sg1 = pm.PyNode('phong1SG')
print(sg1.dagSetMembers[0].listConnections(plugs=True, source=True))
# 出力:[Attribute(u'pCubeShape1.instObjGroups[0].objectGroups[0]')]

sg2 = pm.PyNode('phong2SG')
print(sg2.dagSetMembers[0].listConnections(plugs=True, source=True))
# 出力:[Attribute(u'pCubeShape1.instObjGroups[0].objectGroups[1]')]

SGそれぞれ2つのdagSetMembers[0]から逆方向にコネクションを出力させてみましたが、フェイスアサイン前のinstObjGroups[0]ではなく、instObjGroups[0].objectGroups[0]instObjGroups[0].objectGroups[1]に接続先が変わりました。フェイスごとにSGに接続が伸びるようになったという事ですね。

さらに、objectGroup(=フェイスのグループ)について詳しく内容を表示してみます。

shape = pm.PyNode('pCubeShape1')
objectGroup = shape.instObjGroups[0].objectGroups[0]
attr_names = pm.listAttr(objectGroup)
for attr_name in attr_names:
    print('{}'.format(attr_name))
# 以下出力:
# instObjGroups[0].objectGroups[0]
# instObjGroups[0].objectGroups[0].objectGrpCompList
# instObjGroups[0].objectGroups[0].objectGroupId
# instObjGroups[0].objectGroups[0].objectGrpColor

どのような属性があるのか羅列してみました。
objectGroupsそのものと、objectGrpCompListobjectGroupIdobjectGrpColorが存在するようです。
それぞれの型と値を表示してみます。

objectGroup = shape.instObjGroups[0].objectGroups[0]
attrs = (objectGroup, objectGroup.objectGrpCompList,
  objectGroup.objectGroupId, objectGroup.objectGrpColor)
for a in attrs:
    print('{}({}) : {}'.format(a, a.type(), a.get()))
# 以下出力:
# pCubeShape1.instObjGroups[0].objectGroups[0](TdataCompound) : [[u'f[1:5]'], 20, -1]
# pCubeShape1.instObjGroups[0].objectGroups[0].objectGrpCompList(componentList) : [u'f[1:5]']
# pCubeShape1.instObjGroups[0].objectGroups[0].objectGroupId(long) : 20
# pCubeShape1.instObjGroups[0].objectGroups[0].objectGrpColor(short) : -1
  • objectGroups[0]TdataCompoundという型で、この場合は他の情報をひとまとめにした型という事のようです。値の表示も他の3つのデータがそのままリストで並んでいます。
  • objectGrpCompListcomponentListという型で、uf[1:5]という文字列の内容から察するにフェイス番号1から5の集合という意味ではないでしょうか。
  • objectGroupIdlongの数値型でフェイスグループのID番号のようです。
  • objectGrpColorshortの数値型で前述したように枠線表示などに利用される色番号のようです。

別フェイスグループの方も見てみます。

objectGroup = shape.instObjGroups[0].objectGroups[1]
attrs = (objectGroup, objectGroup.objectGrpCompList,
  objectGroup.objectGroupId, objectGroup.objectGrpColor)
for a in attrs:
    print('{}({}) : {}'.format(a, a.type(), a.get()))
# 以下出力:
# pCubeShape1.instObjGroups[0].objectGroups[1](TdataCompound) : [[u'f[0]'], 22, -1]
# pCubeShape1.instObjGroups[0].objectGroups[1].objectGrpCompList(componentList) : [u'f[0]']
# pCubeShape1.instObjGroups[0].objectGroups[1].objectGroupId(long) : 22
# pCubeShape1.instObjGroups[0].objectGroups[1].objectGrpColor(short) : -1

おおよそ予想通りの内容が表示されました。フェイス番号0が一つ設定されています。キューブの場合全フェース数は6個なので、辻褄が合います。

なお、このようなフェイスアサインにした場合、
 2018-01-09 0.04.48.png
objectGroups[0].objectGrpCompListの値は、[u'f[0]', u'f[2:3]', u'f[5]']と、なりました。飛び飛びのフェイス番号が登録されています。

ここまでは、問題なく理解できました。

コンポーネントのインスタンスオブジェクトグループ

マテリアルのフェイスアサインにすると変化するコネクションの最後の1つ、一番厄介そうな奴を見ていきます。

 2018-01-09 0.09.40.png コネクションで黄色くなっている部分に注目します。フェイスアサイン前には伸びていなかったコネクションで、片方のマテリアルにだけ伸びています。最初にオブジェクト全体に適用されていたマテリアル側に伸びるようです。  2018-01-09 0.14.25.png 元々の青いマテリアル(SG1)を赤いマテリアル(SG3)をフェイスアサインする事で無くしてみましたが、まだコンポーネントのインスタンスオブジェクトグループからSG1へのコネクションは維持されています。  2018-01-09 0.14.48.png オブジェクト自体にSG3をアサインし直してみました。コンポーネントのインスタンスオブジェクトグループからSG1へのコネクションがなくなりました。  2018-01-09 0.15.14.png 改めて黄色いSG2をフェイスアサインしてみました。今度はインスタンスオブジェクトグループからSG3へコネクションが貼られています。

フェイスアサインがなかった場合のデフォルトのマテリアル設定を保持している、と考えれば良いでしょうか。よくわからないので、詳細の調査に進みます。

shape = pm.PyNode('pCubeShape1')
compInstObjGroups = shape.compInstObjGroups[0]
attr_names = pm.listAttr(compInstObjGroups)
for attr_name in attr_names:
    print('{}'.format(attr_name))
# 以下出力:
# compInstObjGroups[0]
# compInstObjGroups[0].compObjectGroups
# compInstObjGroups[0].compObjectGroups.compObjectGrpCompList
# compInstObjGroups[0].compObjectGroups.compObjectGroupId

compObjectGroups = compInstObjGroups.compObjectGroups[0] # ここで[0]にしないとMAYAが落ちる
attrs = (compInstObjGroups,
    compObjectGroups,
    compObjectGroups.compObjectGrpCompList,
    compObjectGroups.compObjectGroupId
)
for attr in attrs:
    print('{}({}) {}'.format(attr, attr.type(), attr.get()))
# 以下出力:
# pCubeShape1.compInstObjGroups[0](TdataCompound) (0.0,)
# pCubeShape1.compInstObjGroups[0].compObjectGroups[0](TdataCompound) [None, 2]
# pCubeShape1.compInstObjGroups[0].compObjectGroups[0].compObjectGrpCompList(None) None
# pCubeShape1.compInstObjGroups[0].compObjectGroups[0].compObjectGroupId(long) 2

ここで、compInstObjGroups[0]compObjectGroupsTdataCompound型で、compObjectGrpCompListにはNoneが、compObjectGroupIdには2が設定されています。
さて、値がNoneとは。。?

ちなみにこの値はマテリアルのフェイスアサイン前にも存在はしていて、

# pCubeShape1.compInstObjGroups[0](TdataCompound) (0.0,)
# pCubeShape1.compInstObjGroups[0].compObjectGroups[0](TdataCompound) [None, 0]
# pCubeShape1.compInstObjGroups[0].compObjectGroups[0].compObjectGrpCompList(None) None
# pCubeShape1.compInstObjGroups[0].compObjectGroups[0].compObjectGroupId(long) 0

のような状態になりました。
さらによくわかりませんが、#2に続きます。#2ではシェイプのインスタンスを作成して異なるフェイスアサインをしてみます。

3
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?