こんにちは、ヨセミテです。
スープカレー、最近はラマイにしか行ってません。割愛。
今回は何を取り扱うか、前日にAPI2.0のドキュメントを眺めてどれにしようか考えてました。当日にドキュメントを眺めだした前回とくらべると非常に大きな進歩ですね。
今回はポリゴンモデルを操作するために用いられる基本的な5つのAPIクラスと銘を打たれているクラスを扱ってみます。丁度前回ふれていない方のMIt~の方のクラスが多いです。
要はポリゴン、頂点、エッジ、UV、メッシュ全体などです。しょっちゅう使いますがあんまりしっかりまとめたことが無かったのでまとめてみます。
これらは同様の流れで使用する準備を整えることが出来ます。
前回同様に適当なメッシュを用意して、
前回同様にMGlobalクラスでメッシュのDagPathを取得します。
import maya.api.OpenMaya as om2 selList = om2.MGlobal.getActiveSelectionList() # 選択対象からSelectionListを取得 selDagPath = selList.getDagPath(0) # MSelectionListからindexを指定してDagPathの取得
で、DagPathを、引数にしてインスタンスを作成。全部同じ形です。
# メッシュ関連のライブラリは全てメッシュのDagPathを定義時に指定することで操作できる mitMeshPolygonIns = om2.MItMeshPolygon(selDagPath) mitMeshEdgeIns = om2.MItMeshEdge(selDagPath) mitMeshVertIns = om2.MItMeshVertex(selDagPath) mitMeshFaceVertIns = om2.MItMeshFaceVertex(selDagPath) mfnMeshIns = om2.MFnMesh(selDagPath)
これで上記の各クラスのリンク先にある処理を利用できるようになりました。
# 例えば割り当てているindexのエッジの隣接フェースを取得できます。 mitMeshEdgeIns.setIndex(6) # indexの指定 connectedFace = mitMeshEdgeIns.getConnectedFaces() print connectedFace
MIt~のクラスはイテレーターという連続処理に特化したクラスであり、.next()で順番に全ての要素にアクセスしていく、もしくは.setIndex()で指定のindexにアクセスするという処理を行います。
# イテレータをまわして全フェースのを面積調べる mitMeshPolygonIns.reset() # .resetで現在のindexを初期化できます。 print mitMeshPolygonIns.index() # .indexで現在のindexを調べられます。 for n in range(mitMeshPolygonIns.count()): # .countで全体の長さを調べられます。 faceSize = mitMeshPolygonIns.getArea() print faceSize # フェースの面積 mitMeshPolygonIns.next(1) # なぜかポリゴンだけnextに引数が必要…?ドキュメントに書いてないんで多分バグ
MItMeshPolygonの不審な挙動発見
イテレーター自体に関しては本来のPythonにある実装なので興味のある人はググって見てください。
もうちょっとAPI2.0での処理をかいてみましょう。
定義さえ済ませてしまえばcmdsやMELとさほど違いはありません。
# イテレータをまわして全頂点を -1 ~ 1 範囲でランダムに移動 import random mitMeshVertIns.reset() # .resetで現在のindexを初期化できます。 for n in range(mitMeshVertIns.count()): randPos = [random.uniform(-1,1),random.uniform(-1,1),random.uniform(-1,1) ] currentPos = mitMeshVertIns.position() PosData = om2.MPoint(currentPos[0] + randPos[0], currentPos[1] + randPos[1], currentPos[2] + randPos[2]) # 座標データはopenMayaの座標データ用のインスタンスで求められる場合も結構あります。 mitMeshVertIns.setPosition(PosData) mitMeshVertIns.next()
# イテレータをまわしてフェースの方向が下を向いているポリゴンを削除する mitMeshPolygonIns.reset() targetIndex = [] valueLambda = 0.00001 # 許容誤差 for n in range(mitMeshPolygonIns.count()): currentNormal = mitMeshPolygonIns.getNormal() xFlag = 0.0 - valueLambda < currentNormal[0] < 0.0 + valueLambda yFlag = -1.0 - valueLambda < currentNormal[1] < -1.0 + valueLambda zFlag = 0.0 - valueLambda < currentNormal[2] < 0.0 + valueLambda if xFlag and yFlag and zFlag: targetIndex.append(mitMeshPolygonIns.index()) mitMeshPolygonIns.next(1) for n in targetIndex[::-1]: mfnMeshIns.deleteFace(n) # MFnメッシュクラスはMIt~で取得したインデックスを指定して色々出来る
と、いうことでMeshのAPIはメッシュのDagPathを取得すればこのように大体利用できます。あとはリファレンスを見て何をしたいかに応じて試してみてください。
経験上、cmdsやMELを使っている人がAPIに移行する際に一番大きな障害になるのはAPIの利用方法です。使い方さえわかってしまえば色々なプロセスを効率化していきたい人たちもいるかなと思います。
Maya Python API 2.0 は非常に使いやすい仕組みに作られているので興味のある人が使ってみて、利用者が増えていってくれれば良いですね。
では。