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

Reply via email to