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()