animCubeNode.py

一个节点例子。该节点有一个time输入属性用来连接时间或设置关键帧动画,有一个outputMesh属性来根据time属性而得出的Cube(多边形方块),这个Cube的大小是由time来控制的。

animCubeNode.py
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
#
# import maya.cmds as cmds
# 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")

import sys
import maya.OpenMaya as om
import maya.OpenMayaMPx as ompx

kPluginNodeTypeName = "spAnimCube"
animCubeId = om.MTypeId( 0x8700B )

# Node definition
class animCube( ompx.MPxNode ):
    """ animCubeNode """
    # class variables
    time = om.MObject()
    outputMesh = om.MObject()
    
    def __init__( self ):
        super( animCube, self ).__init__()
        
    def createMesh( self, tempTime, outData ):
        # 将时间单位转为24(Film)
        frame = int( tempTime.as( om.MTime.kFilm ) )
        if frame is 0:
            frame = 1
            
        # cube的大小,由时间控制
        cubeSize = 0.5 * float( frame % 10 )
        
        # cube的面、顶点数,
        # FaceConnects是6个面的点的总和
        # 即6 * 4 = 24
        numFaces = 6
        numVertices = 8
        numFaceConnects = 24
        
        # 落实顶点
        vtx_1 = om.MFloatPoint( -cubeSize, -cubeSize, -cubeSize )
        vtx_2 = om.MFloatPoint( cubeSize, -cubeSize, -cubeSize )
        vtx_3 = om.MFloatPoint( cubeSize, -cubeSize, cubeSize )
        vtx_4 = om.MFloatPoint( -cubeSize, -cubeSize, cubeSize )
        vtx_5 = om.MFloatPoint( -cubeSize, cubeSize, -cubeSize )
        vtx_6 = om.MFloatPoint( -cubeSize, cubeSize, cubeSize )
        vtx_7 = om.MFloatPoint( cubeSize, cubeSize, cubeSize )
        vtx_8 = om.MFloatPoint( cubeSize, cubeSize, -cubeSize )
        
        # vertexArray
        # 顶点数组,包括所有的顶点
        points = om.MFloatPointArray()
        # 设置数组长度
        points.setLength( 8 )
        points.set( vtx_1, 0 )
        points.set( vtx_2, 1 )
        points.set( vtx_3, 2 )
        points.set( vtx_4, 3 )
        points.set( vtx_5, 4 )
        points.set( vtx_6, 5 )
        points.set( vtx_7, 6 )
        points.set( vtx_8, 7 )
        
        # 顶点数组
        # 顶点与顶点的连接
        faceConnects = om.MIntArray()
        faceConnects.setLength( numFaceConnects )
        faceConnects.set( 0, 0 )
        faceConnects.set( 1, 1 )
        faceConnects.set( 2, 2 )
        faceConnects.set( 3, 3 )
        faceConnects.set( 4, 4 )
        faceConnects.set( 5, 5 )
        faceConnects.set( 6, 6 )
        faceConnects.set( 7, 7 )
        faceConnects.set( 3, 8 )
        faceConnects.set( 2, 9 )
        faceConnects.set( 6, 10 )
        faceConnects.set( 5, 11 )
        faceConnects.set( 0, 12 )
        faceConnects.set( 3, 13 )
        faceConnects.set( 5, 14 )
        faceConnects.set( 4, 15 )
        faceConnects.set( 0, 16 )
        faceConnects.set( 4, 17 )
        faceConnects.set( 7, 18 )
        faceConnects.set( 1, 19 )
        faceConnects.set( 1, 20 )
        faceConnects.set( 7, 21 )
        faceConnects.set( 6, 22 )
        faceConnects.set( 2, 23 )
        
        # 面数(6个),每个面由4个顶点组成
        # 也是一个顶点数组
        faceCounts = om.MIntArray()
        faceCounts.setLength( 6 )
        faceCounts.set( 4, 0 )
        faceCounts.set( 4, 1 )
        faceCounts.set( 4, 2 )
        faceCounts.set( 4, 3 )
        faceCounts.set( 4, 4 )
        faceCounts.set( 4, 5 )
        
        # 创建cube
        meshFS = om.MFnMesh()
        newMesh = meshFS.create( numVertices, numFaces, points,
                                faceCounts, faceConnects, outData )
        return newMesh
        
    def compute( self, plug, data ):
        # 需要更新(重新计算)的属性
        if plug == animCube.outputMesh:
            timeData = data.inputValue( animCube.time )
            tempTime = timeData.asTime()
            
            outputHandle = data.outputValue( animCube.outputMesh )
            
            # 创建MeshData
            dataCreator = om.MFnMeshData()
            newOutputData = dataCreator.create()
            
            self.createMesh( tempTime, newOutputData )
            
            outputHandle.setMObject( newOutputData )
            data.setClean( plug )
        else:
            return om.kUnknownParameter
        
# creator
def nodeCreator():
    return ompx.asMPxPtr( animCube() )
    
# initializer
def nodeInitializer():
    unitAttr = om.MFnUnitAttribute()
    typedAttr = om.MFnTypedAttribute()
    # time
    animCube.time = unitAttr.create( 'time', 'tm',
                                    om.MFnUnitAttribute.kTime, 0.0 )
    # outputMesh
    animCube.outputMesh = typedAttr.create( 'outputMesh', 'out',
                                           om.MFnData.kMesh )
    # add attributes
    animCube.addAttribute( animCube.time )
    animCube.addAttribute( animCube.outputMesh )
    animCube.attributeAffects( animCube.time, animCube.outputMesh )
# initialize the script plug-in
def initializePlugin( mobject ):
    mplugin = ompx.MFnPlugin( mobject )
    try:
        mplugin.registerNode( kPluginNodeTypeName, animCubeId, nodeCreator, nodeInitializer )
    except:
        sys.stderr.write( "Failed to register node: %s" % kPluginNodeTypeName )
        raise
        
# uninitialize the script plug-in
def uninitializePlugin( mobject ):
    mplugin = ompx.MFnPlugin( mobject )
    try:
        mplugin.deregisterNode( animCubeId )
    except:
        sys.stderr.write( "Failed to deregister node: %s" % kPluginNodeTypeName )
        raise

类方法createMesh展示了如何创建一个Cube
创建一个多边形需要使用MFnMesh类的create方法
# 创建cube
meshFS = om.MFnMesh()
newMesh = meshFS.create( numVertices, numFaces, points, faceCounts, faceConnects, outData )

numVertices 是这个多边形的顶点总数
numFaces(numPolygons) 是这个多边形的面的总数
points(vertexArray) 是顶点的一个数组。包括所有的顶点。例如一个默认的cube的vertexArray是{ (-1,-1,-1), (1,-1,-1), (1,-1,1), (-1,-1,1), (-1,1,-1), (-1,1,1), (1,1,1), (1,1,-1) }
faceCounts(polygonCounts) 是每个多边形的面的顶点总数的数组。例如一个默认的cube,有6个面,每个面有4个顶点,polygonCounts是{4,4,4,4,4,4}
faceConnects(polygonConnects) 是顶点与顶点的连接的数组。例如一个默认的cube的polygonConnects是{ 0, 1, 2, 3, 4, 5, 6, 7, 3, 2, 6, 5, 0, 3, 5, 4, 0, 4, 7, 1, 1, 7, 6, 2 }
outData(parentOrOwner) 会成为该多边形的父物体

可以观察下图来理解,我也是通过这张图才能明白的

animCubeNode.py

你可以在maya安装目录下的devkit/plug-ins/scripted找到animCubeNode.py。
在线版
http://download.autodesk.com/us/maya/2010help/API/anim_cube_node_8py-example.html

你可能感兴趣的:(python)