我想知道是否有办法创建一个进度窗口,显示程序完成的时间。这是我到目前为止所做的,但它并没有达到我的预期。
我希望它一直运行,直到所有曲线都已创建然后停止。
import maya.cmds as cmds
cmds.setAttr( "nParticle1Shape.lifespanMode", 2 )
cmds.setAttr( "nParticle1Shape.maxCount", 5 )
cmds.setAttr( "nParticle1Shape.lifespanRandom", 3 )
allParticleDictionary = {}
minFrames = cmds.playbackOptions( q=True, min=True )
maxFrames = cmds.playbackOptions( q=True, max=True )
running = 0
amount = 0
cmds.progressWindow( title='Doing Nothing',progress=amount,status='Sleeping: 0%',isInterruptable=True )
for currentFrame in range(0, int(maxFrames)):
cmds.currentTime( currentFrame, update=True, edit=True )
cmds.select( 'nParticle1' )
Particles = cmds.ls( sl=True, type='transform' )
for part in Particles:
for particleCount in range( 0,cmds.particle(part, q=True,ct=True) ):
particleName = cmds.particle( part, q=True, order=particleCount, at='id' )
particlesPosition = cmds.particle( part, q=True, order=particleCount, at='position' )
particleDictionary = {}
if str( particleName[0] ) in allParticleDictionary.keys():
particleDictionary = allParticleDictionary[str(particleName[0])]
particleDictionary[currentFrame] = particlesPosition
allParticleDictionary[str(particleName[0])] = particleDictionary
emptyFolder = cmds.group( em=True, n="Curves" )
for curveParticleId in allParticleDictionary.keys():
pointList = []
sortedKeyFrameList = sorted( allParticleDictionary[curveParticleId].keys() )
if len( sortedKeyFrameList ) > 1:
for keyFrame in sortedKeyFrameList:
pointList.append( allParticleDictionary[curveParticleId][keyFrame] )
curveObj = cmds.curve( name = "pCurve" + str(curveParticleId ), p = pointList)
Locators = cmds.spaceLocator( name = "locator" + str(curveParticleId) )
cmds.pathAnimation( Locators, stu=sortedKeyFrameList[0], etu=sortedKeyFrameList[-1], c=curveObj )
running = 1
# place all objects in Group called Curves
cmds.parent( curveObj, emptyFolder )
cmds.select( Locators )
cmds.delete()
while running == 0:
# Checks if the dialog has been cancelled
if cmds.progressWindow( query=True, isCancelled=True ) :
break
# Checks if end condition has been reached
if cmds.progressWindow( query=True, progress=True ) >= 100 :
break
amount += 20
cmds.progressWindow( edit=True, progress=amount, status=('Sleeping: ' + `amount` + '%' ) )
cmds.pause( seconds=1 )
cmds.progressWindow( endProgress=1 )
答案 0 :(得分:1)
前言是我不完全确定我的逻辑是正确的:as @theodox said, your indents seem wrong即使在你最近的修正之后也是如此。
无论如何,如果我解释正确的话,这里的版本应该是你的目标:
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
语句中循环endProgress
参数的命令;尽管如此,你仍然需要检查用户是否转义了这个过程在旁注中,您可能想知道(如果您还没有)maya is mostly single threaded。使用API时,您可能会遇到一些限制,但通常情况下,使用maya cmds 时,您可以非常确定自己是在单个线程上工作。
这意味着进度条将在您的逻辑运行的同一个线程上运行,因此将脚本的性能限制了几个数量级:我已经在使用粒子+进度条和I进行了大量工作发现绘制UI可能比运行逻辑慢得多。 随着粒子数量的增加,你的脚本变得非常慢,只是因为你的进度条刷新,不是因为逻辑本身。
一个好的做法是仅以已知的时间间隔更新进度(读取:每个 n 粒子)。假设您有100万个粒子,并且您只想以5%的步长更新侧边栏,您可以这样写:
import random
cmds.progressWindow(title='Stepped Progress Bar', progress=0, status='Progress (stepped by 1): 0%%', isInterruptable=True)
limit = 1000000
step = 5
for i in xrange(limit):
progress = 100.0 / limit * i
if progress % step:
continue
cmds.progressWindow(e=1, progress=progress, status='Progress (stepped by 1): %d%%' % progress)
# the following is to simulate some processing time
cmds.pause(seconds=random.random() * 2)
cmds.progressWindow(endProgress=1)