First Post: trying to get the first and last keyframe

2,968 views
Skip to first unread message

Ctorres

unread,
Feb 25, 2011, 8:39:56 PM2/25/11
to python_inside_maya
Hey all,
For some reason I can't get this code to work correctly.Please help.
I'm working out of Maya 2009. So when I run this python code I get the
values for the firstKey and lastKey as 0 but if I just run the last 4
lines of code. I will get something different now, firstKey=5 and
lastKey=10. I'm not sure what is happening here. I guess my ultimate
goal is to find out what is the first keyframe and lastkeyframe of any
maya scene and be able to set a piece of code in the end like this
------ mc.playbackOptions(aet=lastKey, ast=firstKey)

Thanks Again,
Chris

--------Start New Scene----------

import maya.cmds as mc
#create sphere
mc.polySphere(ch=True,o=True, r=5)

#key sphere in diffrent time
mc.currentTime(5, edit=True )
mc.setKeyframe("pSphere1")
mc.currentTime(10, edit=True )
mc.setAttr("pSphere1.translateY", 5)
mc.setKeyframe("pSphere1")
mc.currentTime(0, edit=True )

#getting first and last key
firstKey = mc.findKeyframe(timeSlider=True, which='first')
lastKey = mc.findKeyframe(timeSlider=True, which='last')
print firstKey
print lastKey

Ian Jones

unread,
Mar 2, 2011, 11:28:42 PM3/2/11
to python_in...@googlegroups.com, Ctorres
So this is annoying but I think this has something to do with how findKeyframe works. 

If you add a pause it seems to work just fine:

import maya.cmds as mc

#create sphere

mc.polySphere(ch=True,o=True, r=5)

#key sphere in diffrent time

mc.currentTime(5, edit=True )

mc.setKeyframe("pSphere1")

mc.currentTime(10, edit=True )

mc.setAttr("pSphere1.translateY", 5)

mc.setKeyframe("pSphere1")

mc.currentTime(0, edit=True )


#Not sure why this fixes it technically - but it seems to have removed it for myself.

import time

time.sleep(1) #.4 was actually the smallest value that seemed to reliably get the correct result


#getting first and last key

firstKey = mc.findKeyframe(timeSlider=True, which='first')

lastKey = mc.findKeyframe(timeSlider=True, which='last')

print firstKey

print lastKey


Of interesting note this didn't fix it without the pause and I'm not sure why:

import maya.utils

firstKey = maya.utils.executeInMainThreadWithResult( mc.findKeyframe,timeSlider=True, which='first')

lastKey = maya.utils.executeInMainThreadWithResult( mc.findKeyframe,timeSlider=True, which='last')


Ian


Paul Molodowitch

unread,
Mar 3, 2011, 1:40:29 AM3/3/11
to python_in...@googlegroups.com
On Wed, Mar 2, 2011 at 8:28 PM, Ian Jones <i...@ambientdivide.com> wrote:
So this is annoying but I think this has something to do with how findKeyframe works. 

If you add a pause it seems to work just fine:

import maya.cmds as mc

#create sphere

mc.polySphere(ch=True,o=True, r=5)

#key sphere in diffrent time

mc.currentTime(5, edit=True )

mc.setKeyframe("pSphere1")

mc.currentTime(10, edit=True )

mc.setAttr("pSphere1.translateY", 5)

mc.setKeyframe("pSphere1")

mc.currentTime(0, edit=True )


#Not sure why this fixes it technically - but it seems to have removed it for myself.

import time

time.sleep(1) #.4 was actually the smallest value that seemed to reliably get the correct result



Out of curiosity, I gave maya.utils.processIdleEvents() and mc.refresh() a shot, and those both seemed to do the trick.  Though I was testing in gui mode, and sometimes those don't work so hot in batch mode... so you might want to test that if you need it there.
 

#getting first and last key

firstKey = mc.findKeyframe(timeSlider=True, which='first')

lastKey = mc.findKeyframe(timeSlider=True, which='last')

print firstKey

print lastKey


Of interesting note this didn't fix it without the pause and I'm not sure why:

import maya.utils

firstKey = maya.utils.executeInMainThreadWithResult( mc.findKeyframe,timeSlider=True, which='first')

lastKey = maya.utils.executeInMainThreadWithResult( mc.findKeyframe,timeSlider=True, which='last')



According to the docstring for executeInMainThreadWithResult, if you're already in the main thread, this essentially doesn't do anything... were you thinking of maya.utils.executeDeferred? Of course, then you'd have to find some way to get the result back...

- Paul
 

Ian Jones

unread,
Mar 3, 2011, 7:55:45 PM3/3/11
to python_in...@googlegroups.com, Paul Molodowitch
I tested mc.refresh() and mc.dgdirty(a=True) and both when placed in loops (new-file, run code) didn't end up printing the correct results. However on single runs seemed to work okay.

maya.utils.processIdleEvents() was probably what I was looking for though when I was thinking about the executeInMainThread. Just wanted something to make sure everything was caught up before running.

Ian

Ian Jones

unread,
Mar 3, 2011, 7:59:28 PM3/3/11
to python_in...@googlegroups.com, Paul Molodowitch
Here is what I was seeing with refresh:

for x in xrange(0,10):
    mc.file(new=True,force=True)

    mc.polySphere(ch=True,o=True, r=5)

    #key sphere in diffrent time

    mc.currentTime(5, edit=True )

    mc.setKeyframe("pSphere1")

    mc.currentTime(10, edit=True )

    mc.setAttr("pSphere1.translateY", 5)

    mc.setKeyframe("pSphere1")

    mc.currentTime(0, edit=True )

    mc.refresh()

    #getting first and last key

    firstKey = mc.findKeyframe(timeSlider=True, which='first')

    lastKey = mc.findKeyframe(timeSlider=True, which='last')

    print firstKey

    print lastKey

0.0

0.0

0.0

0.0

0.0

0.0

0.0

0.0

0.0

0.0

0.0

0.0

0.0

0.0

0.0

0.0

0.0

0.0

0.0

0.0


Not sure why though.

Ctorres

unread,
Mar 9, 2011, 3:30:34 PM3/9/11
to python_inside_maya
Thanks all for your information... I tried all those things suggested
and i couldn't get any of those things to work. I'm not sure if its
because I'm using Maya 2009, but I experimented with other things to
try to fix my problem. The only other solution i got to work was
replacing timeSlider=True in the mc.keyFrame with time=(0, 1000).
Thanks again.

-------------------------------------new
code-----------------------------
import maya.cmds as mc
#create sphere
mc.polySphere(ch=True,o=True, r=5)

#key sphere in diffrent time
mc.currentTime(5, edit=True )
mc.setKeyframe("pSphere1")
mc.currentTime(10, edit=True )
mc.setAttr("pSphere1.translateY", 5)
mc.setKeyframe("pSphere1")
mc.currentTime(0, edit=True )

#getting first and last key
firstKey = mc.findKeyframe(time=(0, 1000), which='first')
lastKey = mc.findKeyframe(time=(0, 1000), which='last')
print firstKey
print lastKey


firstKey = mc.findKeyframe(timeSlider=True, which='first')
lastKey = mc.findKeyframe(timeSlider=True, which='last')


Ted Charlton

unread,
Mar 9, 2011, 8:17:36 PM3/9/11
to python_in...@googlegroups.com
The mel proc setPlayBackRangeToMinMax.mel probably has some help for you.

Here is the auto pymel version.

# script created by pymel.melparse.mel2py from mel file:
# ~\maya\2009\scripts\tcSetPlayBackRangeToMinMax.mel

from pymel import *
import uiRes
#
# Description:
#  Sometimes it's useful to set the playback range to be the
#  min/max of all the animation in the system.  We define that
#  to be the first and last keys from all the time-based
#  animation curves we can find.
#
def setPlaybackRangeToMinMax():
    animTL=ls(type='animCurveTL')
    #  Get a list of animCurve in the system.
    #  Check only for types created through
    #  keyframing: time to linear, time to
    #  angular, and time to unitless (for scale,
    #  or user created attributes).
    #
    animTA=ls(type='animCurveTA')
    animTU=ls(type='animCurveTU')
    animTT=ls(type='animCurveTT')
    keys=[]
    largestKey=-100000.0
    smallestKey=100000.0
    keyCount=0
    for curve in animTL:
        last=int(keyframe(curve,
            q=1,kc=1))
        if last>0:
            last-=1
           
        keys=keyframe(curve,
            q=1,index=[0, last],tc=1)
        keyCount+=len(keys)
        for key in keys:
            if key>largestKey:
                largestKey=float(key)
               
            if key<smallestKey:
                smallestKey=float(key)
               
           
       
    for curve in animTA:
        last=int(keyframe(curve,
            q=1,kc=1))
        if last>0:
            last-=1
           
        keys=keyframe(curve,
            q=1,index=[0, last],tc=1)
        keyCount+=len(keys)
        for key in keys:
            if key>largestKey:
                largestKey=float(key)
               
            if key<smallestKey:
                smallestKey=float(key)
               
           
       
    for curve in animTU:
        last=int(keyframe(curve,
            q=1,kc=1))
        if last>0:
            last-=1
           
        keys=keyframe(curve,
            q=1,index=[0, last],tc=1)
        keyCount+=len(keys)
        for key in keys:
            if key>largestKey:
                largestKey=float(key)
               
            if key<smallestKey:
                smallestKey=float(key)
               
           
       
    for curve in animTT:
        last=int(keyframe(curve,
            q=1,kc=1))
        if last>0:
            last-=1
           
        keys=keyframe(curve,
            q=1,index=[0, last],tc=1)
        keyCount+=len(keys)
        for key in keys:
            if key>largestKey:
                largestKey=float(key)
               
            if key<smallestKey:
                smallestKey=float(key)
               
           
       
    if keyCount>0:
        playbackOptions(max=(int(largestKey)),min=(int(smallestKey)))
        # Only adjust the playback range if we've found animation.
        #
       
   
    else:
        mel.error(uiRes.uiRes("m_TimeSliderMenu.kNoKeysError"))
       
  




Reply all
Reply to author
Forward
0 new messages