error only in maya batch ? polyGeoSampler ?

78 views
Skip to first unread message

pric...@gmail.com

unread,
Oct 21, 2010, 10:49:22 AM10/21/10
to python_inside_maya
Hi guys,
To cut a long story short, I m trying to converta voxelisation script
to run on our render farm, this is gonig ok, and it works fine on he
farm, you save the script into a python sript node in maya2011 that
will run when the render farm triesto open the submitted file. Dandy.
Except the color command will not work . I ve reached the end of my
teather with it.

The problem arrises from the cmds.polyGeoSampler() command that bakes
the color into the verts. For some reason mayabatch will not accept
the command. I can only theorise that it has some relation to the UI
and thus won t work in the render farm batchrender mode, when I open
the file in mayapy I get a maya command error returning
maya.cmds.__dict__ which can t be good. I know it is DEFINATELY coming
from polySampler as if its commented out it runs fine. Here s the
script feel free to run it in a script node that runs on opening and
insde UI maya it will run ( if you comment out polyGeoSampler ),
weirdly i got an error when I ran the comand on its own saying "error
retireving default arguments" ?

any ideas? any potential work arounds ? please ! ! !

ps. I realise this is Fugly code, its adapted in a rush



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 = []
faces = []
for x in range(hitPoints.length()):
result.append((hitPoints[x][0], hitPoints[x][1], hitPoints[x][2]))
for x in range(hitFaces.length()):
faces.append(hitFaces[x])
result = [result, faces]
return result

# round to nearest fraction in decimal form: 1, .5, .25
def roundToFraction(input, denominator):
factor = 1/denominator
return round(input*factor)/factor

# progress bar, enabling "Esc"


# make an array of points in space to shoot rays from
def setLocs(mesh):
global voxelSize, cubeSize, xmin, xmax, ymin, ymax, zmin, zmax,
xLocs, yLocs, zLocs
bb = cmds.exactWorldBoundingBox(mesh)
xmin = bb[0]
ymin = bb[1]
zmin = bb[2]
xmax = bb[3]
ymax = bb[4]
zmax = bb[5]

# make 3 arrays of ray start points, one for each axis
xLocs = []
yLocs = []
zLocs = []

fac = 1/voxelSize

for y in range(int(ymin*fac), int(ymax*fac+1)):
for z in range(int(zmin*fac), int(zmax*fac+1)):
loc = (xmax, y*voxelSize, z*voxelSize)
xLocs.append(loc)
for z in range(int(zmin*fac), int(zmax*fac+1)):
for x in range(int(xmin*fac), int(xmax*fac+1)):
loc = (x*voxelSize, ymax, z*voxelSize)
yLocs.append(loc)
for x in range(int(xmin*fac), int(xmax*fac+1)):
for y in range(int(ymin*fac), int(ymax*fac+1)):
loc = (x*voxelSize, y*voxelSize, zmax)
zLocs.append(loc)

def objIsVisible(obj):
visible = cmds.getAttr(obj+".visibility")
# If this is an intermediate mesh, it's not visible.
if cmds.attributeQuery("intermediateObject", node=obj, exists=True)
== 0:
visible = visible and cmds.getAttr(obj+".intermediateObject") == 0

# If the object is in a displayLayer, and the displayLayer is
hidden,
# then the object is hidden.
if cmds.attributeQuery("overrideEnabled", node=obj, exists=True) and
cmds.getAttr(obj+".overrideEnabled"):
visible = visible and cmds.getAttr(obj+".overrideVisibility")

# Ascend the hierarchy and check all of the parent nodes
if visible:
parents = cmds.listRelatives(obj, parent=True)
if parents != None and len(parents) > 0:
visible = visible and objIsVisible(parents[0])

return visible

def docancel():
global useAmbient, allLights, amb, disableUndos
if disableUndos: cmds.undoInfo(state=True)
if useAmbient:
cmds.delete(cmds.listRelatives(amb, parent=True)[0])
if allLights != None and len(allLights) > 0: cmds.sets(allLights,
add="defaultLightSet")
print "Voxelizer cancelled at frame %s."%cmds.currentTime(q=True)

return 0

## main procedure ##

def doit():
global voxelSize, cubeSize,cubeDict, allLights, amb, showCommands,
xmin, xmax, ymin, ymax, zmin, zmax, xLocs, yLocs, zLocs

cubeDict = {}
shaderDict = {}
SGDict = {}
useAmbient = 1
useShadows = 0
verboseOutput = 0
disableUndos = 1
frameRange = [1,13]
showCommands = 0
if useAmbient:
# disable and store all existing lights
allLights = cmds.sets("defaultLightSet", q=1)
cmds.sets(clear="defaultLightSet")
# make an ambient light
amb = cmds.ambientLight(i=True, ambientShade=0)
else: allLights = None

# identify control objects
sel = cmds.ls(sl=True)
if len(sel) > 0:
# filter for polymeshes
ctrl = cmds.filterExpand(sel, fullPath=0, selectionMask=12)
cmds.select(cl=1)
sel = []
if ctrl == None:
print "No meshes found in selection, checking scene..."
# check for object or group named "voxelGeo"
if cmds.objExists("voxelGeo"):
cmds.select("voxelGeo")
sel = cmds.ls(sl=1)
if len(sel) == 0: # select all dag objects
cmds.select(ado=True)
sel = cmds.ls(sl=True)
if sel == None or sel == []:
cmds.confirmDialog( title='Mesh selection', message= 'No meshes
found in scene.', button=['OK'])
return 0
else: # filter for polymeshes
ctrl = cmds.filterExpand(sel, fullPath=0, selectionMask=12)
if ctrl == None:
cmds.confirmDialog( title='Mesh selection', message= 'No meshes
found in scene.', button=['OK'])
return 0

if disableUndos: cmds.undoInfo(state=False)
if not showCommands: cmds.scriptEditorInfo(sr=True, sw=True,
si=True)
firstFrame = frameRange[0]
lastFrame = frameRange[1]
duration = abs(int(lastFrame-firstFrame))+1

# deal with backwards frame ranges
if lastFrame < firstFrame:
lastFrame -= 1
frameStep = -1
else:
lastFrame += 1
frameStep = 1

startTime= cmds.timerX()


s = "s" if duration > 1 else ""
print "Voxelizer animating over", duration, "frame%s..."%s
print "Press ESC to cancel"

resetList = []
directions = [(-1.0, 0.0, 0,0), (0.0, -1.0, 0,0), (0.0, 0.0, -1.0)]
cubegroup = cmds.group(em=True, n='cubes')
cmds.select(cl=1)



for f in range(firstFrame,lastFrame,frameStep): # for each frame
stepTime= cmds.timerX()
cmds.currentTime(f, edit=True, update=True)
# get sizes from control objects,
voxelSize = round(cmds.getAttr('voxelScaleCtrl.scaleX'), 3)
cubeSize = round(cmds.getAttr('cubeScaleCtrl.scaleX'), 3)
# hide visible cubes
for x in resetList:
cmds.setKeyframe(x, at="scale", v=0, t=f)
resetList = []


# for every target control object:
for c in ctrl:
# if ctrl object is invisible, skip to the next one
if objIsVisible(c) == 0:
continue

# bake textures into verts
cmds.select(c)
cmds.polyGeoSampler(sampleByFace=True, computeShadows=0,
rs=0,ul=0, flatShading=1,lo=0,dg=0,sf=1.0,su=0,ac=0,cmn=[.
0,.0,.0],cmx=[1.0,1.0,1.0],amn=.
0,amx=1.0,colorBlend="none",alphaBlend="none",ignoreDoubleSided=1,colorDisplayOption=0 )
print "polyGeoSample"
# set ray starting points
setLocs(c)
locArrays = [xLocs, yLocs, zLocs]
# for each axis:
for i in range(3):
# for every gridpoint:
for loc in locArrays[i]:
hits = []
# zap a ray through the object
rayInt = rayIntersect(c, loc, directions[i])
hits = rayInt[0]
hfaces = rayInt[1]
for j, x in enumerate(hits):
# snap hit locations to cubegrid
x = (roundToFraction(x[0], voxelSize),
roundToFraction(x[1], voxelSize), roundToFraction(x[2], voxelSize) )
# if location isn't in cubeDict: make a new cube
if x not in cubeDict:
# add location and new cube to cubeDict
cubeDict[x] = cmds.polyCube(sz=1, sy=1, sx=1, cuv=4,
d=1, h=1, w=1, ch=1)[0]
cube = cubeDict[x]
if useShadows:
# prevent cubes from casting shadows onto the ctrl
objs
cmds.setAttr(cube+".castsShadows", 0)
cmds.parent(cube, cubegroup)
# move cube to location
cmds.xform(cube, t=x)
# shader coloring method: uses one shader per cube
shader = cmds.shadingNode("lambert", asShader=1)
# create a shading group
shaderSG = cmds.sets(renderable=True,
noSurfaceShader=True, empty=True, name=shader+"SG")
# connect the shader to the shading group
cmds.connectAttr('%s.outColor'%shader,
'%s.surfaceShader'%shaderSG, f=True)
# add cube to the shaderSG
shape = cmds.listRelatives(cube, shapes=1)[0]
cmds.sets('%s'%shape, e=True, fe='%s'%shaderSG)

shaderDict[cube] = shader
SGDict[cube] = shaderSG

# set scale key of 0 on the previous frame
cmds.setKeyframe(cube, at="scale", v=0, t=(f-1))

cube = cubeDict[x]
cubeshape = cmds.listRelatives(cube, shapes=1)[0]

# add cube to resetList
resetList.append(cube)

if len(hfaces) > 0:
# check the alpha of the face
alpha = cmds.polyColorPerVertex(c+'.f['+str(hfaces[j])
+']', q=True, a=True, cdo=True)

if alpha[0] > 0.5: # if more than half opaque
# get the color of the face
fcolor = cmds.polyColorPerVertex(c+'.f['+str(hfaces[j])
+']', q=True, rgb=True, cdo=True, nun=True)
cmds.setKeyframe(shaderDict[cube]+'.colorR',
v=fcolor[0])
cmds.setKeyframe(shaderDict[cube]+'.colorG',
v=fcolor[1])
cmds.setKeyframe(shaderDict[cube]+'.colorB',
v=fcolor[2])
print fcolor,c
# set a scale key
cmds.setKeyframe(cube, at="scale", v=cubeSize, t=f,
breakdown=0, hierarchy="none", controlPoints=0, shape=0)

# if previous frame didn't have a scale key, set it to
0
tempCurTime = cmds.currentTime(q=True)-1
lastKey = cmds.keyframe(cube, at="scale", q=True,
t=(tempCurTime,tempCurTime), valueChange=True)
if lastKey == None:
cmds.setKeyframe(cube, at="scale", v=0, t=(f-1))

if verboseOutput:
stepTime = cmds.timerX(st=stepTime)
totalTime = cmds.timerX(st=startTime)
print "frame:", cmds.currentTime(q=True), "\tkeyed cubes:",
len(resetList), "\ttotal cubes:", len(cubeDict)
cps = "inf" if stepTime == 0 else round(len(resetList)/stepTime,
2)
if useVoxCtrl or useCubeCtrl:
print "\t\tvoxelSize:", voxelSize, "\tcubeSize: ", cubeSize
print "\t\tstepTime:", round(stepTime, 2), "\ttotal time:",
round(totalTime, 2), "\tcubes per second:", cps

# restore scene state
if useAmbient:
if cmds.objExists(amb): cmds.delete(cmds.listRelatives(amb,
parent=True)[0])
cmds.sets(allLights, add="defaultLightSet")
elif useShadows:
# turn the cubes' shadows back on
for x in cubeDict:
cmds.setAttr(cubeDict[x]+".castsShadows", 1)
#if not showCommands: cmds.scriptEditorInfo(sr=srState, sw=swState,
si=siState)
#if disableUndos: cmds.undoInfo(state=True)

totalTime = cmds.timerX(st=startTime)
print("Voxelizer finished: "+str(round(totalTime, 2))+ " seconds
("+str(round(totalTime/60, 2)) + " minutes)")

doit()

def sceneName():
scenepath = cmds.file(q = 1, sn=1)
maPrune = scenepath.replace('.ma','')
fileName = maPrune.replace('.mb','')
return fileName

fileName = sceneName()
fullName = fileName + "_VOX" + ".ma"
cmds.select(cl=True)
cmds.select("cubes")
cmds.file(fullName ,es = True,shader = True, type = "mayaAscii" )
Reply all
Reply to author
Forward
0 new messages