actually, speaking of pymel, pymel nodes sport many methods derived from api mfn classes, so this script would be a nice test of many of these methods. i may take a crack at it. would be nice for a speed comparison as well. pymel would of course be a bit slower because of the wrapping mechanisms, but the code required on the end-user's part would be much, much less. that's the inevitable trade-off.
-chad On Feb 26, 2010, at 5:49 PM, pjrich wrote: > You know, I don't think I actually checked to see if it was using > pymel or not, I've been using pymel so often I've begun to just assume > that's how python in maya ought to work, and of course between script > runs it stays in session, so to speak... so in my eagerness to get > this out I got sloppy. Thanks for the cleanup Richard, if you don't > mind I'm going to repost this at my site -- > Cheers, > Peter > > On Feb 26, 3:59 pm, Richard Kazuo <[email protected]> wrote: >> Sure, I hope the author doesn't mind as I modified to make it work without >> pyMel... I did it in a rush and didn't test it too much, but seems to work >> with simple spheres. >> >> ### start: voxelize meshes v.2 >> ### this script turns the selected meshes into cubes >> ### over the current timeline range. >> #cmds.progressBar(endProgress=1) >> import maya.OpenMaya as om >> import maya.cmds as cmds >> import maya.mel as mel >> >> # shoot a ray from point in direction and return all hits with mesh >> def rayIntersect(mesh, point, direction=(0.0, 0.0, -1.0)): >> # get dag path of mesh - so obnoxious >> om.MGlobal.clearSelectionList() >> om.MGlobal.selectByName(mesh) >> sList = om.MSelectionList() >> om.MGlobal.getActiveSelectionList(sList) >> item = om.MDagPath() >> sList.getDagPath(0, item) >> item.extendToShape() >> fnMesh = om.MFnMesh(item) >> >> raySource = om.MFloatPoint(point[0], point[1], point[2], 1.0) >> rayDir = om.MFloatVector(direction[0], direction[1], direction[2]) >> faceIds = None >> triIds = None >> idsSorted = False >> worldSpace = om.MSpace.kWorld >> maxParam = 99999999 >> testBothDirections = False >> accelParams = None >> sortHits = True >> hitPoints = om.MFloatPointArray() >> hitRayParams = om.MFloatArray() >> hitFaces = om.MIntArray() >> hitTris = None >> hitBarys1 = None >> hitBarys2 = None >> tolerance = 0.0001 >> >> hit = fnMesh.allIntersections(raySource, rayDir, faceIds, triIds, >> idsSorted, worldSpace, maxParam, testBothDirections, accelParams, sortHits, >> hitPoints, hitRayParams, hitFaces, hitTris, hitBarys1, hitBarys2, tolerance) >> >> # clear selection as may cause problems if called repeatedly >> om.MGlobal.clearSelectionList() >> result = [] >> for x in range(hitPoints.length()): >> result.append((hitPoints[x][0], hitPoints[x][1], hitPoints[x][2])) >> return result >> >> # round to nearest fraction in decimal form: 1, .5, .25 >> def roundToFraction(input, fraction): >> factor = 1/fraction >> return round(input*factor)/factor >> >> # progress bar, enabling "Esc" >> def makeProgBar(length): >> global gMainProgressBar >> gMainProgressBar = mel.eval('$tmp = $gMainProgressBar'); >> cmds.progressBar( gMainProgressBar, >> edit=True, >> beginProgress=True, >> isInterruptable=True, >> maxValue=length >> ) >> >> def promptNumber(): >> result = cmds.promptDialog( >> title='Grow Shrub', >> message='Block size:', >> text="1", >> button=['OK', 'Cancel'], >> defaultButton='OK', >> cancelButton='Cancel', >> dismissString='Cancel') >> if result == 'OK': >> return float(cmds.promptDialog(query=True, text=True)) >> else: return 0 >> >> def init(cubeSize): >> global cubeDict, xLocs, yLocs, zLocs >> cubeDict = {} >> xLocs = [] >> yLocs = [] >> zLocs = [] >> >> # make 3 arrays of ray start points, one for each axis >> # this is necessary because rays aren't likely to catch surfaces >> # which are edge-on... so to make sure to catch all faces, >> # we shoot rays along each axis >> fac = 1/cubeSize >> for y in range(ymin*fac, ymax*fac+1): >> for z in range(zmin*fac, zmax*fac+1): >> loc = (xmax, y*cubeSize, z*cubeSize) >> xLocs.append(loc) >> for z in range(zmin*fac, zmax*fac+1): >> for x in range(xmin*fac, xmax*fac+1): >> loc = (x*cubeSize, ymax, z*cubeSize) >> yLocs.append(loc) >> for x in range(xmin*fac, xmax*fac+1): >> for y in range(ymin*fac, ymax*fac+1): >> loc = (x*cubeSize, y*cubeSize, zmax) >> zLocs.append(loc) >> >> # start the action >> *#EDIT: I dont have pyMel to test this, but commented this line because I >> think this is only checking for the first >> # selected object. If you select a mesh and then a nurbs, it still runs >> and raises an exception... >> # at least thats whats happening in Maya's native python* >> if len(cmds.ls(sl=1)) == 0: #or >> cmds.objectType(cmds.listRelatives(cmds.ls(sl=1)[0], >> s=1, ni=1)) != "mesh": >> result = cmds.confirmDialog( title='Mesh selection', message='Please >> select a mesh.', button=['OK']) >> else: >> startTime= cmds.timerX() >> cubeSize = promptNumber() >> >> # set selected objects to be the shape targets, aka controls >> ctrl = cmds.ls(sl=1) >> >> firstFrame = int(cmds.playbackOptions(query=1, min=1)) >> lastFrame = int(cmds.playbackOptions(query=1, max=1)) >> duration = int(lastFrame-firstFrame) >> >> makeProgBar(duration*len(ctrl)) >> cmds.progressBar(gMainProgressBar, edit=True, beginProgress=1) >> >> bb = cmds.exactWorldBoundingBox(ctrl[0]) >> xmin = bb[0] >> xmax = bb[3] >> xdist = abs(xmin)+abs(xmax) >> ymin = bb[1] >> ymax = bb[4] >> ydist = abs(ymin)+abs(ymax) >> zmin = bb[2] >> zmax = bb[5] >> >> print "Finding bounding box of animation..." >> print "Press ESC to cancel" >> # find outer boundaries of animation >> for f in range(firstFrame,lastFrame): >> for c in ctrl: >> if cmds.progressBar(gMainProgressBar, query=1, isCancelled=1 ): >> break >> cmds.currentTime(f) >> cmds.progressBar(gMainProgressBar, edit=1, step=1) >> >> bb = cmds.exactWorldBoundingBox(c) >> xmin = min(xmin, bb[0]) >> xmax = max(xmax, bb[3]) >> ymin = min(ymin, bb[1]) >> ymax = max(ymax, bb[4]) >> zmin = min(zmin, bb[2]) >> zmax = max(zmax, bb[5]) >> >> cmds.progressBar(gMainProgressBar, edit=1, endProgress=1) >> >> init(cubeSize) >> >> cmds.progressBar(gMainProgressBar, edit=1, endProgress=1) >> makeProgBar(duration*len(ctrl)) >> cmds.progressBar(gMainProgressBar, edit=1, beginProgress=1) >> >> print "Animating visibility over", duration, "frames..." >> print "Press ESC to cancel" >> >> # animate cube visibility >> resetList = [] >> #EDIT: incremented by one because it was not calculating the last frame >> for f in range(firstFrame,lastFrame+1): # for each frame >> cmds.currentTime(f, edit=1, update=1) >> # if the cube was visible last frame, hide it >> for x in resetList: >> cmds.setKeyframe(x, at="scale", v=0, t=f) >> resetList = [] >> locArrays = [xLocs, yLocs, zLocs] >> directions = [(-1.0, 0.0, 0,0), (0.0, -1.0, 0,0), (0.0, 0.0, -1.0)] >> # for every target control object: >> for c in ctrl: >> if cmds.progressBar(gMainProgressBar, query=1, isCancelled=1 ): >> break >> cmds.progressBar(gMainProgressBar, edit=1, step=1) >> # for each axis: >> for i in range(3): >> cmds.flushUndo() >> # for every gridpoint orthagonal to the animation: >> for loc in locArrays[i]: >> hits = [] >> # zap a ray thrugh the object >> hits = rayIntersect(c, loc, directions[i]) >> for x in hits: >> # snap hit locations to cubegrid >> x = (roundToFraction(x[0], cubeSize), roundToFraction(x[1], >> cubeSize), roundToFraction(x[2], cubeSize) ) >> # if location isn't in cubeDict, add it and a new cube >> if x not in cubeDict: >> cubeDict[x] = cmds.polyCube(sz=1, sy=1, sx=1, cuv=4, >> d=cubeSize, h=cubeSize, w=cubeSize, ch=1)[0] >> # move cube to quantized location >> cmds.xform(cubeDict[x], t=x) >> # set a scale key >> cmds.setKeyframe(cubeDict[x], at="scale", v=1, t=f) >> # if previous frame didn't have a scale key, set it to 0 >> tempCurTime = cmds.currentTime(q=1)-1 >> lastKey = cmds.keyframe(cubeDict[x], at="scale", q=1, >> t=(tempCurTime,tempCurTime), valueChange=1) >> if lastKey == None or lastKey[0] != 1.0: >> cmds.setKeyframe(cubeDict[x], at="scale", v=0, t=(f-1)) >> # add cube to resetList >> resetList.append(cubeDict[x]) >> cmds.currentTime(f, edit=1, update=1) >> >> cmds.progressBar(gMainProgressBar, edit=1, endProgress=1) >> totalTime = cmds.timerX(startTime=startTime) >> print("Total Time: "+str(totalTime)) >> >> ### end voxelize meshes v.2 >> >> Really nice effect! Works like a charm. :) >> >> >> >> On Fri, Feb 26, 2010 at 4:29 PM, Chris G <[email protected]> wrote: >> >>> I'm doing some modifications to be able to run the script without PyMel and >>>> found out some things: >> >>> Can you post that? I'd like to try it out. >> >>>> You're not importing "maya.mel as mel" nor "maya.cmds as cmds" at the >>>> beggining of the code, is this something that PyMel installation does >>>> automatically? >> >>> from pymel.core import * >>> will give you cmds and mel names, but mel corresponds to pymel's >>> pymel.core.language.Mel >> >>> - Chris >> >>> -- >>> http://groups.google.com/group/python_inside_maya > > -- > http://groups.google.com/group/python_inside_maya -- http://groups.google.com/group/python_inside_maya
