不管怎样,这里有一个版本,如果我解释正确的话,它应该能满足你的目标:from maya import cmds
def checkProgressEscape():
# check if dialog has been cancelled
cancelled = cmds.progressWindow(query=True, isCancelled=True)
if cancelled:
cmds.progressWindow(endProgress=1)
return cancelled
def getAllParticlesDictionary(shape):
cmds.progressWindow(title='Fetch Particle Data', progress=0, status='Fetched: 0%', isInterruptable=True)
ptcsDict = {}
minFrames = int(cmds.playbackOptions( q=True, min=True))
maxFrames = int(cmds.playbackOptions( q=True, max=True))
nFrames = float(maxFrames - minFrames)
# better use the actual range, since you queried the playback options
for currentFrame in range(minFrames, maxFrames):
if checkProgressEscape():
return
amount = 100.0 / nFrames * (currentFrame - minFrames + 1)
cmds.progressWindow(edit=True, progress=amount, status='Fetched: %d%%' % amount)
# cmds.pause(seconds=.001)
cmds.currentTime(currentFrame, update=True, edit=True)
for particleCount in xrange(cmds.particle(shape, q=True, ct=True)):
particleId = int(cmds.particle(shape, q=True, order=particleCount, at='id')[0])
# better check the key exists first, then add your logic
if particleId not in ptcsDict.keys():
ptcsDict[particleId] = {}
ptcsDict[particleId][currentFrame] = cmds.particle(shape, q=True, order=particleCount, at='position')
cmds.progressWindow(endProgress=1)
return ptcsDict
def curvesFromParticle(ptcsDict):
cmds.progressWindow(title='Build Curves', progress=0, status='Building Curves: 0%', isInterruptable=True)
# this section had to be de-indented
emptyFolder = cmds.group(em=True, n="Curves")
ptcCount = len(ptcsDict)
for i, (curveParticleId, data) in enumerate(ptcsDict.iteritems()):
if checkProgressEscape():
return
sortedKeyFrameList = sorted(data.keys())
pointList = []
for keyFrame in sortedKeyFrameList:
pointList.append(ptcsDict[curveParticleId][keyFrame])
curveObj = cmds.curve(name="pCurve%d" % curveParticleId, p=pointList)
locators = cmds.spaceLocator( name = "locator%d" % curveParticleId)
cmds.pathAnimation( locators, stu=sortedKeyFrameList[0], etu=sortedKeyFrameList[-1], c=curveObj)
# place all objects in Group called Curves
cmds.parent(curveObj, emptyFolder)
cmds.delete(locators)
amount = 100 / ptcCount * float(i)
cmds.progressWindow(edit=True, progress=amount, status='Building Curves: %d%%' % amount)
cmds.progressWindow(endProgress=1)
ptcs = cmds.ls(typ='nParticle')
for shape in ptcs:
cmds.setAttr("%s.lifespanMode" % (shape, ), 2)
cmds.setAttr("%s.maxCount" % (shape, ), 100)
cmds.setAttr("%s.lifespanRandom" % (shape, ), 3)
ptcDict = getAllParticlesDictionary(shape)
if not ptcDict:
print 'data was not be fetched for %s; skipped' % (shape, )
continue
curvesFromParticle(ptcDict)
上面是脚本的一个(稍微)修改版本;如您所见:我把主要的逻辑块移到函数中(只是为了可读性)
我删除了您的while语句,因为进度条不需要它们:您已经在for语句中循环了
我还删除了您的进度检查,如果它等于或大于100,因为一旦您退出循环,您可以假设您不再需要显示进度,只需使用endProgress参数调用侧边栏命令;但是,您仍然需要检查用户是否逃过了该过程
我添加了两个进度条“会话”,一个用于获取粒子数据并填充字典的循环,另一个用于构建曲线
另一方面,你可能想知道(如果你还不知道的话)maya is mostly single threaded。使用API时,您可能会绕过一些限制,但通常,当使用mayacmds时,您可以非常确定您正在处理单个线程。在
这意味着进度条将运行在逻辑运行的同一线程上,因此会将脚本的性能限制在几个数量级上:我对粒子+进度条做了大量的工作,我发现绘制UI比运行逻辑慢得多。
随着粒子数的增加,你的脚本会变得非常缓慢,仅仅是因为你的进度条在刷新,而不是是因为逻辑本身。在
一个好的做法是只在已知的时间间隔更新进度(读:everyn粒子)。假设你有1000000个粒子,你只想以5%的步骤更新边栏,你可以这样写:
^{pr2}$