I woke up this morning with a major efficiency improvement in my
head... I really need a break from this. Here's the updated script:

http://zoomy.net/pub/voxelize_meshes_v.3.py

Okay, I'm done.

Peter

On Feb 27, 12:24 am, Chad Dombrova <[email protected]> wrote:
> 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