Annotated Output: The dotted arrows in the image below point to the rear and bottom polygons of the cube, while the full arrows point to its forward and top polygons. The table which accompanies this image illustrates the various array parameters used in MFnMesh.create().
Program Summary: The plug-in code below is an adaptation of the animCubeNode.py example provided with the Maya API documentation. Some variable names were refactored to be more closely aligned with the class documentation and annotated output above. This MPxNode plug-in defines a typed input attribute which accepts Maya's time to determine the scale of the generated output cube mesh. Once this command is run, slide the timeline in the Maya user interface to view the animation.
# pyAnimCubeNode.py import sys import maya.api.OpenMaya as OpenMaya def maya_useNewAPI(): """ The presence of this function tells Maya that the plugin produces, and expects to be passed, objects created using the Maya Python API 2.0. """ pass kPluginNodeName = "spAnimCube" kPluginNodeId = OpenMaya.MTypeId(0x8700B) ########################################################## # Plug-in ########################################################## class animCube(OpenMaya.MPxNode): time = OpenMaya.MObject() outputMesh = OpenMaya.MObject() def __init__(self): ''' Constructor. ''' OpenMaya.MPxNode.__init__(self) def createMesh(self, tempTime, outData): ''' Create a cube mesh, and scale it given the current frame number. The resulting mesh data is stored within outData. ''' frame = int(tempTime.asUnits(OpenMaya.MTime.kFilm)) if frame is 0: frame = 1 cubeSize = 0.5 * float(frame % 10) numPolygons = 6 numVertices = 8 numPolygonConnects = 4 * numPolygons # four vertices are needed per polygon. (i.e. 24 numPolygonConnects) vertexArray = OpenMaya.MFloatPointArray() vertexArray.setLength( numVertices ) vertexArray[0] = OpenMaya.MFloatPoint(-cubeSize, -cubeSize, -cubeSize) vertexArray[1] = OpenMaya.MFloatPoint( cubeSize, -cubeSize, -cubeSize) vertexArray[2] = OpenMaya.MFloatPoint( cubeSize, -cubeSize, cubeSize) vertexArray[3] = OpenMaya.MFloatPoint(-cubeSize, -cubeSize, cubeSize) vertexArray[4] = OpenMaya.MFloatPoint(-cubeSize, cubeSize, -cubeSize) vertexArray[5] = OpenMaya.MFloatPoint(-cubeSize, cubeSize, cubeSize) vertexArray[6] = OpenMaya.MFloatPoint( cubeSize, cubeSize, cubeSize) vertexArray[7] = OpenMaya.MFloatPoint( cubeSize, cubeSize, -cubeSize) polygonCounts = OpenMaya.MIntArray() polygonCounts.setLength( numPolygons ) for i in range (0,numPolygons): polygonCounts[i] = 4 polygonConnects = OpenMaya.MIntArray() polygonConnects.setLength( numPolygonConnects ) polygonConnects[0] = 0 polygonConnects[1] = 1 polygonConnects[2] = 2 polygonConnects[3] = 3 polygonConnects[4] = 4 polygonConnects[5] = 5 polygonConnects[6] = 6 polygonConnects[7] = 7 polygonConnects[8] = 3 polygonConnects[9] = 2 polygonConnects[10] = 6 polygonConnects[11] = 5 polygonConnects[12] = 0 polygonConnects[13] = 3 polygonConnects[14] = 5 polygonConnects[15] = 4 polygonConnects[16] = 0 polygonConnects[17] = 4 polygonConnects[18] = 7 polygonConnects[19] = 1 polygonConnects[20] = 1 polygonConnects[21] = 7 polygonConnects[22] = 6 polygonConnects[23] = 2 meshFn = OpenMaya.MFnMesh() newMesh = meshFn.create(vertexArray, polygonCounts, polygonConnects, parent=outData) def compute(self, plug, data): if plug == animCube.outputMesh: timeData = data.inputValue(animCube.time) tempTime = timeData.asTime() outputHandle = data.outputValue(animCube.outputMesh) dataCreator = OpenMaya.MFnMeshData() newOutputData = dataCreator.create() self.createMesh(tempTime, newOutputData) outputHandle.setMObject(newOutputData) data.setClean(plug) else: return OpenMaya.kUnknownParameter ########################################################## # Plug-in initialization. ########################################################## def nodeCreator(): ''' Creates an instance of our node class and delivers it to Maya as a pointer. ''' return animCube() def nodeInitializer(): ''' Defines the input and output attributes as static variables in our plug-in class. ''' unitAttr = OpenMaya.MFnUnitAttribute() typedAttr = OpenMaya.MFnTypedAttribute() animCube.time = unitAttr.create("time", "tm", OpenMaya.MFnUnitAttribute.kTime, 0.0) animCube.outputMesh = typedAttr.create("outputMesh", "out", OpenMaya.MFnData.kMesh) animCube.addAttribute(animCube.time) animCube.addAttribute(animCube.outputMesh) animCube.attributeAffects(animCube.time, animCube.outputMesh) def initializePlugin(mobject): ''' Initialize the plug-in ''' mplugin = OpenMaya.MFnPlugin(mobject) try: mplugin.registerNode( kPluginNodeName, kPluginNodeId, nodeCreator, nodeInitializer) except: sys.stderr.write( "Failed to register node: " + kPluginNodeName ) raise def uninitializePlugin(mobject): ''' Uninitializes the plug-in ''' mplugin = OpenMaya.MFnPlugin(mobject) try: mplugin.deregisterNode( kPluginNodeId ) except: sys.stderr.write( "Failed to deregister node: " + kPluginNodeName ) raise ########################################################## # Sample usage. ########################################################## ''' # Copy the following lines and run them in Maya's Python Script Editor: import maya.cmds as cmds cmds.loadPlugin( "pyAnimCubeNode.py" ) cmds.createNode( "transform", name="animCube1" ) cmds.createNode( "mesh", name="animCubeShape1", parent="animCube1" ) cmds.sets( "animCubeShape1", add="initialShadingGroup" ) cmds.createNode( "spAnimCube", name="animCubeNode1" ) cmds.connectAttr( "time1.outTime", "animCubeNode1.time" ) cmds.connectAttr( "animCubeNode1.outputMesh", "animCubeShape1.inMesh" ) '''
# animCubeNode.py import sys import maya.OpenMaya as OpenMaya import maya.OpenMayaMPx as OpenMayaMPx kPluginNodeName = "spAnimCube" kPluginNodeId = OpenMaya.MTypeId(0x8700B) ########################################################## # Plug-in ########################################################## class animCube(OpenMayaMPx.MPxNode): time = OpenMaya.MObject() outputMesh = OpenMaya.MObject() def __init__(self): ''' Constructor. ''' OpenMayaMPx.MPxNode.__init__(self) def createMesh(self, tempTime, outData): ''' Create a cube mesh, and scale it given the current frame number. The resulting mesh data is stored within outData. ''' frame = int(tempTime.asUnits(OpenMaya.MTime.kFilm)) if frame is 0: frame = 1 cubeSize = 0.5 * float(frame % 10) numPolygons = 6 numVertices = 8 numPolygonConnects = 4 * numPolygons # four vertices are needed per polygon. (i.e. 24 numPolygonConnects) vertexArray = OpenMaya.MFloatPointArray() vertexArray.setLength( numVertices ) vertexArray.set( OpenMaya.MFloatPoint(-cubeSize, -cubeSize, -cubeSize), 0) vertexArray.set( OpenMaya.MFloatPoint( cubeSize, -cubeSize, -cubeSize), 1) vertexArray.set( OpenMaya.MFloatPoint( cubeSize, -cubeSize, cubeSize), 2) vertexArray.set( OpenMaya.MFloatPoint(-cubeSize, -cubeSize, cubeSize), 3) vertexArray.set( OpenMaya.MFloatPoint(-cubeSize, cubeSize, -cubeSize), 4) vertexArray.set( OpenMaya.MFloatPoint(-cubeSize, cubeSize, cubeSize), 5) vertexArray.set( OpenMaya.MFloatPoint( cubeSize, cubeSize, cubeSize), 6) vertexArray.set( OpenMaya.MFloatPoint( cubeSize, cubeSize, -cubeSize), 7) polygonCounts = OpenMaya.MIntArray() polygonCounts.setLength( numPolygons ) polygonCounts.set(4, 0) polygonCounts.set(4, 1) polygonCounts.set(4, 2) polygonCounts.set(4, 3) polygonCounts.set(4, 4) polygonCounts.set(4, 5) polygonConnects = OpenMaya.MIntArray() polygonConnects.setLength( numPolygonConnects ) polygonConnects.set(0, 0) polygonConnects.set(1, 1) polygonConnects.set(2, 2) polygonConnects.set(3, 3) polygonConnects.set(4, 4) polygonConnects.set(5, 5) polygonConnects.set(6, 6) polygonConnects.set(7, 7) polygonConnects.set(3, 8) polygonConnects.set(2, 9) polygonConnects.set(6, 10) polygonConnects.set(5, 11) polygonConnects.set(0, 12) polygonConnects.set(3, 13) polygonConnects.set(5, 14) polygonConnects.set(4, 15) polygonConnects.set(0, 16) polygonConnects.set(4, 17) polygonConnects.set(7, 18) polygonConnects.set(1, 19) polygonConnects.set(1, 20) polygonConnects.set(7, 21) polygonConnects.set(6, 22) polygonConnects.set(2, 23) meshFn = OpenMaya.MFnMesh() newMesh = meshFn.create(numVertices, numPolygons, vertexArray, polygonCounts, polygonConnects, outData) def compute(self, plug, data): if plug == animCube.outputMesh: timeData = data.inputValue(animCube.time) tempTime = timeData.asTime() outputHandle = data.outputValue(animCube.outputMesh) dataCreator = OpenMaya.MFnMeshData() newOutputData = dataCreator.create() self.createMesh(tempTime, newOutputData) outputHandle.setMObject(newOutputData) data.setClean(plug) else: return OpenMaya.kUnknownParameter ########################################################## # Plug-in initialization. ########################################################## def nodeCreator(): ''' Creates an instance of our node class and delivers it to Maya as a pointer. ''' return OpenMayaMPx.asMPxPtr( animCube() ) def nodeInitializer(): ''' Defines the input and output attributes as static variables in our plug-in class. ''' unitAttr = OpenMaya.MFnUnitAttribute() typedAttr = OpenMaya.MFnTypedAttribute() animCube.time = unitAttr.create("time", "tm", OpenMaya.MFnUnitAttribute.kTime, 0.0) animCube.outputMesh = typedAttr.create("outputMesh", "out", OpenMaya.MFnData.kMesh) animCube.addAttribute(animCube.time) animCube.addAttribute(animCube.outputMesh) animCube.attributeAffects(animCube.time, animCube.outputMesh) def initializePlugin(mobject): ''' Initialize the plug-in ''' mplugin = OpenMayaMPx.MFnPlugin(mobject) try: mplugin.registerNode( kPluginNodeName, kPluginNodeId, nodeCreator, nodeInitializer) except: sys.stderr.write( "Failed to register node: " + kPluginNodeName ) raise def uninitializePlugin(mobject): ''' Uninitializes the plug-in ''' mplugin = OpenMayaMPx.MFnPlugin(mobject) try: mplugin.deregisterNode( kPluginNodeId ) except: sys.stderr.write( "Failed to deregister node: " + kPluginNodeName ) raise ########################################################## # Sample usage. ########################################################## ''' # Copy the following lines and run them in Maya's Python Script Editor: import maya.cmds as cmds cmds.loadPlugin( "animCubeNode.py" ) cmds.createNode( "transform", name="animCube1" ) cmds.createNode( "mesh", name="animCubeShape1", parent="animCube1" ) cmds.sets( "animCubeShape1", add="initialShadingGroup" ) cmds.createNode( "spAnimCube", name="animCubeNode1" ) cmds.connectAttr( "time1.outTime", "animCubeNode1.time" ) cmds.connectAttr( "animCubeNode1.outputMesh", "animCubeShape1.inMesh" ) '''