Exploring Maya API

I decided to mess around with the MayaAPI a little bit, just to see what it could do. This is by no means a finished script! You can NOT undo, so only test it out on an object you’re not terribly fond of. Select an object and run the script– a random length is added to each point of the object’s mesh along the normal, so it looks like noise has been applied to the surface.

Remeber, this does NOT undo the point changes! However, you can still undo the full object’s position, rotation, scaling, etc.

import maya.OpenMaya as OpenMaya
 import maya.cmds as cmds
 import time
 import random
 import math
   
 selection = OpenMaya.MSelectionList()
 OpenMaya.MGlobal.getActiveSelectionList( selection )
 iterSel = OpenMaya.MItSelectionList(selection, OpenMaya.MFn.kMesh)
 component = OpenMaya.MObject()
 vertCount = 0
 vertIndex = 0
 
 print "Iter Sel: " 
 print iterSel
 
 while not iterSel.isDone(): 
     # get dagPath
     dagPath = OpenMaya.MDagPath()
     iterSel.getDagPath( dagPath, component )
 
     fullDagPath = dagPath.fullPathName()
     print "Full Dag Path: " + fullDagPath 
     
 
         
     # create empty point array
     inMeshMPointArray = OpenMaya.MPointArray()
  
 
  
     # create function set and get points in world space
     currentInMeshMFnMesh = OpenMaya.MFnMesh(dagPath)
     currentInMeshMFnMesh.getPoints(inMeshMPointArray, OpenMaya.MSpace.kWorld)
     listLen = inMeshMPointArray.length()
     print "List Length: " + str(listLen)
     
     '''
     while not meshIter.isDone():
         pt = OpenMaya.MPoint(meshIter.position(OpenMaya.MSpace.kworld))
         vertIndex = meshIter.index()
         print "Vertex Index: " + str(vertIndex)
         
         meshIter.next()
     '''
     
     #create empty MPointArray (for later)
     newPoints = OpenMaya.MFloatPointArray()
     
     # put each point to a list
     pointList = []
     tempList = []
     for i in range( inMeshMPointArray.length() ) :
         #print i
         pointList.append( [inMeshMPointArray[i][0], inMeshMPointArray[i][1], inMeshMPointArray[i][2]] )
 
     print pointList
     print "Point List Orig ID: " + str(id(pointList)) #just making sure
     pointListLen = len(pointList)
     print "Point List Length: " + str(pointListLen) 
     for j in range (pointListLen):
         print "ROW " + str(j) #I think this can also be used as the pointID?
         print "Orig Coords: X: " + str(pointList[j][0]) + "\tY: " + str(pointList[j][1]) + "\tZ: " + str(pointList[j][2])
         
         
         '''
         #noise deformer in y
         #add a random value between 0.0 and 1.0 in the Y direction to each point
         #factor = 10.0
         #rand = random.random() * factor
         #print "Random to add: " + str(rand)
         #pointList[j][1] += rand #you have to assign to indices or slices, otherwise you're just changing where the name(reference) points to
         #print "New Coords:  X: " + str(pointList[j][0]) + "\tY: " + str(pointList[j][1]) + "\tZ: " + str(pointList[j][2])
         '''
         #turn each of the points into an MPoint
         #create MPoint object
         tmpPoint = OpenMaya.MPoint(pointList[j][0], pointList[j][1], pointList[j][2])        
         #print "Temp Point: " + str(tmpPoint)
                 
         #create a MVector object
         normVec = OpenMaya.MVector()
         #create some weird MScriptUtil Int that I got from a scripting blog...
         util = OpenMaya.MScriptUtil()
         util.createFromInt(0)
         idPointer = util.asIntPtr()
         
         space = OpenMaya.MSpace.kWorld
         
         #currentInMeshMFnMesh.getClosestNormal(tmpPoint, normVec, space, idPointer)
         #must go by vertex, as getClosestNormal only gets the normal of the closest point. As each point can have more than one
         #vertex, sometimes this picks a normal that shoots off in a funky direction. Technically correct, but looks bad.
         #So, first get the vertexID (we'll just pluck that idPointer from the bad getClosestNormal function)
         
         currentInMeshMFnMesh.getVertexNormal(j, False, normVec, space)
         
         
         #print "Vector Obj: " + str(vectorObj)
         #print "Point Face ID: " + str(faceID)
         #idx = OpenMaya.MScriptUtil(idPointer).asInt()
         #print "IDX: " + str(idx)
         print "Normal Vector: X: " + str(normVec.x) + "\tY: " + str(normVec.y) + "\tZ: " + str(normVec.z) 
         
         factor = 2.0       
         factor *= random.random()
         #multiply the vector by the scalar factor
         normVec *= factor #be careful, this returns a new reference to the vector
         pointList[j][0] += normVec.x 
         pointList[j][1] += normVec.y
         pointList[j][2] += normVec.z
         print "New Coords:  X: " + str(pointList[j][0]) + "\tY: " + str(pointList[j][1]) + "\tZ: " + str(pointList[j][2])
         
         #turn each of the points into an MFloatPoint
         #create MFloatPoint object
         tmpFloatPoint = OpenMaya.MFloatPoint(pointList[j][0], pointList[j][1], pointList[j][2])
         #print "Temp Float Point: " + str(tmpFloatPoint)
         
         newPoints.append(tmpFloatPoint)
         
         #
 
     print "Point List New ID: " + str(id(pointList)) #just making sure
     #now assign the (new) point list to the new MPointArray object you created earlier
     #print newPoints
     print "Length of New Array: " + str(newPoints.length())
     currentInMeshMFnMesh.setPoints(newPoints, OpenMaya.MSpace.kWorld) 
     
     iterSel.next()

Leave a Reply

Your email address will not be published. Required fields are marked *