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