2019-08-25に投稿

MDagPathの掘り下げ

ゲーム系でTAしてます。

スクラップボックスから引っ越し中
引っ越し前の記事から新しい情報はありません。
スクラップボックスはコードコピペするとインデント崩れるので止めましたが、入力周りでもcrieitは使いやすいですね。


MDagPathの掘り下げ

今の会社で、家でMayaを利用できる環境を提供いただけたのでAPI2.0の情報をまとめていこうと思います。
テスト環境はMaya2019。

MDagPath

## Maya Python API2.0 2019 Reference

MDagPathはMayaAPIのMFn、MItなどのノードに対するクラス群を利用する際に利用するクラス。
APIを利用する際には絶対使うと考えてもよいと思う。

MDagPath インスタンスの取得と利用

ノード単位でインスタンスを定義して利用するもので、自分だと以下の名前で取得する書き方でよく取得する。
コードを試す場合はCubeを一つ作成してください。

``` python46fa376e0744bbd562f9b24d9265417e-png.png
from maya.api import OpenMaya as om2

ノード名からDagPathを取得

node_name = "pCubeShape1"
sel_list = om2.MGlobal.getSelectionListByName(node_name) # MGlobalにSelectionListを名前から取得する関数がある
dag = sel_list.getDagPath(0) # Selectionリストのindexを指定してDagPathを取得


もしくは他のAPIクラスからMObjectを取得した場合はMFnDagNodeクラスからDagPathは取得できる。 ``` python # MObjectからDagPathを取得 node_name = "pCubeShape1" sel_list = om2.MGlobal.getSelectionListByName(node_name) dag = sel_list.getDagPath(0) transform = om2.MDagPath(dag).transform() # TransformのMObjectを取得(この時点だとDagPathではない) mfndag = om2.MFnDagNode(transform) # MObjectからMFnインスタンスを定義 dag = mfndag.getPath() # DagPathを取得 om2.MFnTransform(dag) # MFnTransformにクラスに利用できればDagPath

取得したDagPathをMFnMeshなどのクラス定義に利用すればそのノードに対する関数を利用できるようになります。
また、DagPathは階層構造を取得するためのクラスでマテリアルなどの階層構造に依存しないノードは持っていません。

node_name = "pCubeShape1"
sel_list = om2.MGlobal.getSelectionListByName(node_name)
dag = sel_list.getDagPath(0)
mfnmesh = om2.MFnMesh(dag)
print mfnmesh.numPolygons       # MFnMeshクラスの関数でポリゴン数を取得

node_name = "lambert1"
sel_list = om2.MGlobal.getSelectionListByName(node_name)
dag = sel_list.getDagPath(0)    # LambertマテリアルにDagPathは無い
# エラー: TypeError: file <maya console> line 10: item is not a DAG path # 

MDagPathの機能

DagPathはノードの位置情報を持っているのでMFn,MItなどのインスタンスに入れなくてもそれ単体で階層構造を取得する機能を持っています。以下のシーンで実行。コードを試す場合ボックスと多面体を作ってグループ化してください

dag_path_testpng.png

from maya.api import OpenMaya as om2
node_name = "group1"
sel_list = om2.MGlobal.getSelectionListByName(node_name)
dag = sel_list.getDagPath(0)

# cmds.lsでいうlongNameも取得できる
print dag.fullPathName()

# 子階層のMObjectを取得できる。indexは何個目の子ノードかの指定
print "num_child".format(dag.childCount())
child_obj = dag.child(0)
print "child_dag_1: {}".format(om2.MFnDagNode(child_obj).getPath())
child_obj = dag.child(1)
print "child_dag_2: {}".format(om2.MFnDagNode(child_obj).getPath())

# 親ノードの数も取得できる
num_hierarchy = dag.length()
print u"num_hierarchy : {}".format(num_hierarchy)

# 一つ上の階層のDagPathを取得できる
for index in xrange(num_hierarchy):
    upper_dag = dag.pop()
    print "path : {} - type: {}".format(upper_dag.node, type(upper_dag))

他にも覚えておくと便利そうなことだと、現在の階層までのTransformのMatrixを取れたりもする。

# group2のスケール(1.0,0.8,1.0)
#  ∟ group1のスケール(1.0,0.4,1.0)
print dag.exclusiveMatrix()    # 該当ノードのMatrix
print dag.inclusiveMatrix()    # 該当ノードまでのMatrix
# (((1, 0, 0, 0), (0, 0.8, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)))
# (((1, 0, 0, 0), (0, 0.32, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)))

DagPathはAPI使う場合はめっちゃ使うのでいろいろ試してみることをお勧めします。


ヨセミテ

ゲームの会社でテクニカルアーティストしてます

Crieitは個人で開発中です。 興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!

ボードとは?

関連記事

コメント