Featured post

new redirect for blender.org bpy docs.

http://www.blender.org/api/blender_python_api_current/ As of 10/11 november 2015 we can now link to the current api docs and not be worr...

September 20, 2012

Python Driven Animation

Not everything can be keyframed, but almost everything can. There are benefits to keyframing, but it isn't always necessary. This short example shows how to use frame_change_pre handler, it is called on every frame change. This means if you have something you want to change as a function of time or frame number, that you can do this very easily. This works on text body too. Search blender API docs for more information about frame_change_pre. You could even combine the frame_change_pre with setting and adding keyframes, but unless you want to export the animation - that might be overkill.

While debugging, you might find that you are calling successive versions of a function from the event handler. There might be more efficient ways of fixing this, but i've found this method removes 'old' code from the event handler list just fine.

8 comments:

  1. So far so good ;-)
    Actually, this is exactly what I was looking for, but maybe I am missing some points because I am new to programming inside Blender.
    When I enter my script in the Text Console I am trying to "Run Script" to register the callback function. This seems not to work in any cases - especially during testing, I update my script very often, but the changes are some (or even most) times not reflected in Blender. Error messages appear in the console, which have been corrected already. Furthermore, I have the impression that the handler is not only called once but up to five times per frame.
    Any idea to make it work correctly?

    ReplyDelete
    Replies
    1. Hey,
      Making updates to your scripts can present some problems - none of which are show-stoppers to eventual success (ie, restarting blender and running an updated script will solve that - but that's not exactly ideal for debugging).

      I suggest to check the content of
      >> bpy.app.handlers.frame_change_pre (or whatever handler you are using
      - as there are a few to choose from).

      It might be worth your time to run
      >> bpy.app.handlers.frame_change_pre.pop()
      in the console until the event handler queue is empty, before running the script again (and thus re-registering a new handler).

      I updated the post to reflect this. Hope that works for you.

      Delete
  2. Thanks for the reply!
    I experimented a bit and observed that the handlers are stored in a list. And with the ".add" function I always add a new one. This should be the reason that I have had the impression that the handlers were called multiple times - no, they were not. But obviously, Blender traversed the list and called each of them, i.e. the history of my buggy versions of my growing script...
    And if there's a list I tried to remove everything before I add a new handler:
    del bpy.app.handlers.frame_change_pre[0:len(bpy.app.handlers.frame_change_pre)]
    This solved my problem. I am not sure if the solution is "good" Python but it removes everything before I add something new.

    ReplyDelete
    Replies
    1. I'm not sure you read my latest response and modification to the post, but I think I said the same thing as you just did.

      Empty the list using .pop() or del the indices manually, both are fine because you won't be using the older versions of the handler functions inside your 'working' final script.

      Delete
  3. hi. where we should use script in blender ?

    ReplyDelete
    Replies
    1. paste this into the text editor and hit Run, then when you press play on the timeline it should animate a cube

      Delete
  4. .now: bpy.app.handlers.frame_change_pre.clear()

    ReplyDelete

Please use Blender.StackExchange.com for python scripting questions unrelated to this post.