Milan Posted July 23, 2014 Share Posted July 23, 2014 Hey guys. I've started working on a little toolkit to make life easier for animators but I ran into a bit of an issue. The whole thing is written in Python with Qt iterface. One of the functions is simply moving keyframes on a timeline. Say I have keyframe on f10, f20 and f30. When I run the function it should shift all of them by given amount. The problem is that I can't figure out how to actually move a keyframe using python. I collect keyframes from a parameter (that gives me a list of hou.Keyframe objects). Then I assumed I can just iterate through them and set new frame number. This however doesn't actually move the keyframes and if I assing the changed keyframe to it's parameter using hou.Parm.setKeyframe(keyframe) it makes a new key, but leaves the old one there as well. So the questions is, am I missing something very obvious (I've been do a lot of python scripting for maya before, so maybe I just need to get my 'houdini style thinking cap' on), or am I out of luck? I could just delete the old keyframe once I create the new one, but I can't actually find anywhere in the reference, how to delete a keyframe using python in hou. This is simplified version of the code I'm using import hou def getKeyedParms(selected, parmList): for node in selected: parmsTemp = node.parms() for parm in parmsTemp: parm = parm.getReferencedParm() keyframes = parm.keyframes() if keyframes: parmList[parm] = keyframes return parmList def shiftKeys(parmList, shift): with hou.undos.group('Shift Keys'): curFrame = hou.frame() for parm in parmList: for keyframe in parmList[parm]: if keyframe.frame() >= curFrame: newTime = keyframe.frame() + shift keyframe.setFrame(newTime) selected = hou.selectedNodes() parmList = {} parmList = getKeyedParms(selected, parmList) shiftKeys(parmList, 5) Any tips appreciated. Quote Link to comment Share on other sites More sharing options...
pezetko Posted July 23, 2014 Share Posted July 23, 2014 (edited) Hi Milan,I'm not sure if it's best workflow but I solved this by deleting all keyframes with parm.deleteAllKeyframes() and then rebuilding them.This is my add inbetween keyframe script that shifts keyframes right or left from current timeslider position. ## add inbetween ## Petr Zloty 2014 import hou # get all keyframes on all selected nodes def getKeyframes(oNodes): keyframes = {} for oNode in oNodes: oParms = oNode.parms() for oParm in oParms: if oParm.keyframes() != (): #if keyframe exists keyframes[oParm] = oParm.keyframes() return keyframes #keyframes = hou.playbar.selectedKeyframes() #recompute new keys def inbetween(keyframes, offset): for parm in keyframes.keys(): for key in keyframes[parm]: if hou.frame() <= key.frame(): #apply only to keys right from time cursor key.setFrame(key.frame()+offset) parm.deleteAllKeyframes() #delete old keys #save new keys for parm in keyframes.keys(): for key in keyframes[parm]: parm.setKeyframe(key) return True oNodes = hou.selectedNodes() keyframes = getKeyframes(oNodes) inbetween(keyframes, 1) #add inbetween #inbetween(keyframes, -1) #remove inbetween Edited July 23, 2014 by pezetko 1 Quote Link to comment Share on other sites More sharing options...
Milan Posted July 23, 2014 Author Share Posted July 23, 2014 Yeah I had that as a backup option if I find that it's actually impossible to move them. Not that it's a problem deleting all keys and assigning them again. It just seem really strange that we can't actually offset them. Again maybe it's just my old maya head talking. btw: looking at your code, it's very similar to my snippet, however I have a feeling that yours won't work on locked assets (e.g. most of the rigs) when your selection is controllers with published parameters. I had to use Parm.getReferencedParm() to get around that. Quote Link to comment Share on other sites More sharing options...
pezetko Posted July 23, 2014 Share Posted July 23, 2014 You are right, thanks for the tip. I didn't have any need to use it on any locked rigs yet. Most of the animation is still done in Softimage or Maya here (for interactive playback speed).That undo stuff is also nice. Quote Link to comment Share on other sites More sharing options...
anim Posted July 23, 2014 Share Posted July 23, 2014 until Hou.Parm.stretch() and hou.Parm.stretchSubrange() get implemented, you can use their Hscript command counterpart chkeymv: http://www.sidefx.com/docs/houdini13.0/commands/chkeymv so your shiftKeys() may look like this: def shiftKeys(parmList, shift): with hou.undos.group('Shift Keys'): for parm in parmList: fRangeStart = hou.frame() fRangeEnd = parmList[parm][-1].frame() hou.hscript( "chkeymv -r %s %s %s %s %s" %(parm.path(), fRangeStart, fRangeEnd, fRangeStart + shift, fRangeEnd + shift) ) you can even use chkeymv to stretch the range or reverse, also have look at other ch* commands as they may already do stuff you want to implement like chls for getting animated channels, etc Quote Link to comment Share on other sites More sharing options...
Milan Posted July 23, 2014 Author Share Posted July 23, 2014 Great! That should do the trick. There are some other things I was looking for in ch* commands. I'll just need to give them a bit of icing to make them easy to use for animators. Cheers Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.