Maya で mesh のデーターを入力し、何らかの処理をして出力するノードを作成するとき、 すべての頂点・エッジ・フェース・UV などに変更を加えるには、 maya.OpenMaya クラスのイテレータクラスのメソッドを使用します。
イテレータとは、繰り返し処理を抽象化したものです。
イテレータを使うことによって、要素数を気にすることがなくなり、
スクリプトが簡単になります。
MEL における for( in ) もイテレータです。
maya.OpenMaya に属するクラスのイテレータは、
isDone() と next() メソッドを持ちます。
meshIter = maya.OpenMaya.MItメソッド名() while not meshIter.isDone(): # ここにメッシュに関する処理を書きます meshIter.next()
ポリゴンメッシュを読み込んで、頂点をランダムに移動するプラグインを作ってみましょう。
import sys import random import maya.OpenMaya import maya.OpenMayaMPx kPluginNodeName = 'randomPoly1' kPluginNodeId = maya.OpenMaya.MTypeId(0x87008) class randomPoly1(maya.OpenMayaMPx.MPxNode): rangeX = maya.OpenMaya.MObject() rangeY = maya.OpenMaya.MObject() inputMesh = maya.OpenMaya.MObject() outputMesh = maya.OpenMaya.MObject() def __init__(self): maya.OpenMayaMPx.MPxNode.__init__(self) def _randomMesh(self, rx, ry, outData): vertexIter = maya.OpenMaya.MItMeshVertex(outData) while not vertexIter.isDone(): v = maya.OpenMaya.MVector() v.x = random.uniform(rx, ry) v.y = random.uniform(rx, ry) v.z = random.uniform(rx, ry) vertexIter.translateBy(v, maya.OpenMaya.MSpace.kWorld) vertexIter.next() def compute(self, plug, data): if plug == randomPoly1.outputMesh: dataHandle = data.inputValue(randomPoly1.rangeX) rx = dataHandle.asFloat() dataHandle = data.inputValue(randomPoly1.rangeY) ry = dataHandle.asFloat() dataHandle = data.inputValue(randomPoly1.inputMesh) outputHandle = data.outputValue(randomPoly1.outputMesh) outputHandle.setMObject(dataHandle.asMesh()) self._randomMesh(rx, ry, outputHandle.asMesh()) data.setClean(plug) else: return maya.OpenMaya.kUnknownParameter def nodeCreator(): return maya.OpenMayaMPx.asMPxPtr(randomPoly1()) def nodeInitializer(): nAttr = maya.OpenMaya.MFnNumericAttribute() randomPoly1.rangeX = nAttr.create('rangeX', 'rx', maya.OpenMaya.MFnNumericData.kFloat, 0.0) nAttr.setStorable(True) randomPoly1.rangeY = nAttr.create('rangeY', 'ry', maya.OpenMaya.MFnNumericData.kFloat, 1.0) nAttr.setStorable(True) typedAttr = maya.OpenMaya.MFnTypedAttribute() randomPoly1.inputMesh = typedAttr.create('inputMesh', 'im', maya.OpenMaya.MFnData.kMesh) typedAttr.setStorable(True) randomPoly1.outputMesh = typedAttr.create('outputMesh', 'om', maya.OpenMaya.MFnData.kMesh) typedAttr.setStorable(False) typedAttr.setWritable(False) randomPoly1.addAttribute(randomPoly1.rangeX) randomPoly1.addAttribute(randomPoly1.rangeY) randomPoly1.addAttribute(randomPoly1.inputMesh) randomPoly1.addAttribute(randomPoly1.outputMesh) randomPoly1.attributeAffects(randomPoly1.rangeX, randomPoly1.outputMesh) randomPoly1.attributeAffects(randomPoly1.rangeY, randomPoly1.outputMesh) randomPoly1.attributeAffects(randomPoly1.inputMesh, randomPoly1.outputMesh) def initializePlugin(mobject): mplugin = maya.OpenMayaMPx.MFnPlugin(mobject) try: mplugin.registerNode(kPluginNodeName, kPluginNodeId, nodeCreator, nodeInitializer) except: sys.stderr.write('Failed to register node: %s' % kPluginNodeName) raise def uninitializePlugin(mobject): mplugin = maya.OpenMayaMPx.MFnPlugin(mobject) try: mplugin.deregisterNode( kPluginNodeId ) except: sys.stderr.write('Failed to deregister node: %s' % kPluginNodeName) raise
import maya.cmds obj = maya.cmds.polyPlane(w=10, h=10) dattr = maya.cmds.listConnections(obj[0] + '.i', p=True) maya.cmds.disconnectAttr(dattr[0], obj[0] + '.i') dc = maya.cmds.createNode('randomPoly1') maya.cmds.connectAttr(dattr[0], dc + '.im') maya.cmds.connectAttr(dc + '.om', obj[0] + '.i')
import sys
import random
import maya.OpenMaya
import maya.OpenMayaMPx
kPluginNodeName = 'randomPoly1'
kPluginNodeId = maya.OpenMaya.MTypeId(0x87008)
class randomPoly1(maya.OpenMayaMPx.MPxNode):
rangeX = maya.OpenMaya.MObject()
rangeY = maya.OpenMaya.MObject()
inputMesh = maya.OpenMaya.MObject()
outputMesh = maya.OpenMaya.MObject()
def __init__(self):
maya.OpenMayaMPx.MPxNode.__init__(self)
def _randomMesh(self, rx, ry, outData):
vertexIter = maya.OpenMaya.MItMeshVertex(outData)
while not vertexIter.isDone():
v = maya.OpenMaya.MVector()
v.x = random.uniform(rx, ry)
v.y = random.uniform(rx, ry)
v.z = random.uniform(rx, ry)
vertexIter.translateBy(v, maya.OpenMaya.MSpace.kWorld)
vertexIter.next()
def compute(self, plug, data):
if plug == randomPoly1.outputMesh:
dataHandle = data.inputValue(randomPoly1.rangeX)
rx = dataHandle.asFloat()
dataHandle = data.inputValue(randomPoly1.rangeY)
ry = dataHandle.asFloat()
dataHandle = data.inputValue(randomPoly1.inputMesh)
outputHandle = data.outputValue(randomPoly1.outputMesh)
outputHandle.setMObject(dataHandle.asMesh())
self._randomMesh(rx, ry, outputHandle.asMesh())
data.setClean(plug)
else:
return maya.OpenMaya.kUnknownParameter
def nodeCreator():
return maya.OpenMayaMPx.asMPxPtr(randomPoly1())
def nodeInitializer():
nAttr = maya.OpenMaya.MFnNumericAttribute()
randomPoly1.rangeX = nAttr.create('rangeX', 'rx', maya.OpenMaya.MFnNumericData.kFloat, 0.0)
nAttr.setStorable(True)
randomPoly1.rangeY = nAttr.create('rangeY', 'ry', maya.OpenMaya.MFnNumericData.kFloat, 1.0)
nAttr.setStorable(True)
typedAttr = maya.OpenMaya.MFnTypedAttribute()
randomPoly1.inputMesh = typedAttr.create('inputMesh', 'im', maya.OpenMaya.MFnData.kMesh)
typedAttr.setStorable(True)
randomPoly1.outputMesh = typedAttr.create('outputMesh', 'om', maya.OpenMaya.MFnData.kMesh)
typedAttr.setStorable(False)
typedAttr.setWritable(False)
randomPoly1.addAttribute(randomPoly1.rangeX)
randomPoly1.addAttribute(randomPoly1.rangeY)
randomPoly1.addAttribute(randomPoly1.inputMesh)
randomPoly1.addAttribute(randomPoly1.outputMesh)
randomPoly1.attributeAffects(randomPoly1.rangeX, randomPoly1.outputMesh)
randomPoly1.attributeAffects(randomPoly1.rangeY, randomPoly1.outputMesh)
randomPoly1.attributeAffects(randomPoly1.inputMesh, randomPoly1.outputMesh)
def initializePlugin(mobject):
mplugin = maya.OpenMayaMPx.MFnPlugin(mobject)
try:
mplugin.registerNode(kPluginNodeName, kPluginNodeId, nodeCreator, nodeInitializer)
except:
sys.stderr.write('Failed to register node: %s' % kPluginNodeName)
raise
def uninitializePlugin(mobject):
mplugin = maya.OpenMayaMPx.MFnPlugin(mobject)
try:
mplugin.deregisterNode(kPluginNodeId)
except:
sys.stderr.write('Failed to deregister node: %s' % kPluginNodeName)
raise
import maya.cmds obj = maya.cmds.polyPlane(w=10, h=10) dattr = maya.cmds.listConnections(obj[0] + '.i', p=True) maya.cmds.disconnectAttr(dattr[0], obj[0] + '.i') dc = maya.cmds.createNode('randomPoly2') maya.cmds.connectAttr(dattr[0], dc + '.im') maya.cmds.connectAttr(dc + '.om', obj[0] + '.i') maya.cmds.setAttr(dc + '.rx1', -0.5) maya.cmds.setAttr(dc + '.rx2', 0.5) maya.cmds.setAttr(dc + '.ry1', 0.0) maya.cmds.setAttr(dc + '.ry2', 0.5) maya.cmds.setAttr(dc + '.rz1', -0.5) maya.cmds.setAttr(dc + '.rz2', 0.0)