Monday, March 14, 2016

New Animation Feature - "New Keyframe Type" Setting

Yippee! I've finally gotten around to finishing off a little feature I've been trying to get into Blender for a while now: A per-scene option for controlling the type of keyframes that get created when inserting keyframes.

The "New Keyframe Type" setting in action - It can be found on the Timeline header, between the Auto Keying toggle and the Keying Set selector.

This setting is useful if you use a conventional multi-pass "pose-to-pose" method for animating, where after blocking in all your key poses, you might start creating breakdowns, then doing other in-between stuff. With this setting, once you've finished your initial pass, you can just click on the next keyframe type that you'll be using for your next pass, and all the keyframes you insert from that point onwards will be the right colour.

I've been meaning to add this little feature for a few years now. It's just that everytime I've come to implementing it, I've come up against the "oh crap, you can't get access toolsettings like you can with the userprefs, as it's not a handy global", and just gone on to deal with other easier stuff. Yeah, yeah... excuses ;)

VICON Voodoo
Now, if you look carefully, you may notice that the menu shows what each keyframe type looks like. I'm quite pleased to announce that was all made possible by some pretty nifty/evil voodoo that I had some fun playing around with tonight.

Proof - The Keyframe icons are dynamically generated, and are immediately updated in response to theme changes

Basically, to get it so that the icons for these look as the keyframes will in the Dope Sheet, complete with whatever theme colours you may be using), I ended up having to make these get rendered procedurally (i.e. these are dynamically generated, using the same code used to render them in the Dope Sheet timeline to render them as icons). But then, how did I manage to get these icons to be rendered procedurally instead of just being images like the rest of them?

Well, apparently Blender's UI toolkit has quite a lot of tricks up its sleeve, including some little known ancient magic/voodoo known as "VIcons" (or Vector Icons). If you're curious, these can be found in editors/interface/interface_icons.c  (Note: This file also deals with loading the Brush and Matcap icons). The "VIcon" system basically makes it possible to define some icon types which can be used whereever the normal icons can be used, but with the key difference being that they are drawn at runtime using whatever theme settings are in play. This means that for things like sharp/fine lines, the resulting icons could potentially be much sharper than the raster icons that got blown up.

I also documented the steps for adding new Vector Icons like this, since it's unlikely that you'd stumble across them unless you knew where to look. (That said, they're not really something that most people should be trying to use... just in special cases like this, where a little auto-generated magic might go a long way)

Other Keyframe Type Features - On the horizon
A few weeks ago, over the course of an interesting weekend, I had a few interesting discussions with a few users and devs about keyframe type stuff. All that was started off by the following teaser:

Dalai Felinto (dalai)'s hacky prototypes of some new functionality for keyframe types

Some interesting things to come out of those discussions were that there is apparently demand for several particular things:
1) The ability to define Custom Keyframe Types  - with the ability to specify the name, colour, and perhaps size too.  (Realistically, most people probably only want to define about 2-5 types of these anyway I'm guessing.... Am I right?  Please leave some examples of what you may use this for below in the comments :)
2) The ability to "lock" keyframes - Apparently, it's useful to be able to "lock down" sets of keyframes, so that instead of only locking on a channel by channel basis, you're able to lock down say all the keyframes from frames 100-400 where you're already happy with what you've done, while continuing to work on the stuff from 500-800. (For example, you've already blocked + polished all of the animation in the earlier section, but now the director changed their mind and wants 500-800 reblocked... To avoid losing/clobbering work, the keyframe locking functionality would come in handy).  I'm currently thinking that such keyframes will probably need a different shape to make it clearer that they're "locked" - I was originally thinking of just adding a bar across them somehow, but now I'm beginning to ponder using crosses for those instead... hmm...
3) The ability to hide/filter keyframes by type - For example, hiding all your breakdowns again so that you can focus again on the timing of your key frames (or maybe to just make it easier to see where they are, and to jump between them).  (There are of course some tricky interaction questions to answer here about what happens when you start moving the visible keyframes around, and whether the invisible ones should "adapt" or not to avoid being clobbered and/or getting out of sync... but that's another discussion altogether)
4) Greater awareness of keyframe types for various tools - e.g. An old request from Beorn (freen - most recently, "Glass Half" director) was that the breakdown keyframes should move proportionally to the keyframes around them. (This probably ties into the previous points about what we do when keyframes are invisible, etc.)

While I may not actually get around to working on these right now/for a few months yet (things are quite busy atm... I'm currently a bit pressed for time trying to get a study for my research work finalised, so Blender dev time has been a bit short as of late), these are some examples of things that may soon be coming to Blender.

IMO, with the greater Blender 2.8 project, I think it's time that we take a look at some other things like this where we can well start taking a second look at where we can try to push the state of the art of animation editing tools further than what's currently offered across the rest of the industry. There's a lot of interesting and potentially very powerful little stuff like this that a lot of people tend to overlook, in their pursuit of the glossy bright lights of "chasing-your-own-tail-fashion-hype-treadmills" such as creating yet another "me too" attempt at a "social media" site to gain another improbable slice of the "get rich fast" fictional pie...

(I've seen far too often that a lot of CS/SE people, when asked what they want to work on or include in their systems starting work on their Login, User Profile + Profile Management pages, and friend/contact lists attached to those, than on the real beefy issues such as how sensible it is to have tiny 6pt links on a touch screen device attached to a shaking+vibrating+swaying vehicle being operated by a stressed user under a high workload.... "we did create user personas, etc."... yeah right you did! </end sarcasm>)

Anyway, this was just a quick update on some new dev stuff heading your way. Thoughts, discussions about how these things could work?


  1. Here's a list of some small animation workflow tweaks I've been compiling in order to post on the wiki:

    Operators and buttons to reorder Poses in the Pose Library and Selection Sets in the same way we can reorder Shape Keys and Bone Groups.

    Expand Bone Groups operators to provide arguments for specifying a name and color set on creation (bpy.ops.pose.group_add())

    Toggle option in User Preferences to invert selection order of transform axes in axis locking (so the first key press will constrain to the active transform orientation, and the second will constrain to the global).

    Preferences > Editing > New F-Curve Defaults > XYZ to RGB only affects objects and bones with Euler rotation mode, but should affect (or have the option to affect) those with quaternion as well.

    Additional "Clear All Keying Set Properties" operator, with a hotkey alongside Alt-G, R, and S, which will set all properties in the active keying set to their defaults for the selected objects/bones. For example, resetting Location, Rotation, Scale and all Custom Properties for the selected bones when the active Keying Set is "Available".

    Toggle in the Timeline which would temporarily switch all F-Curves in the active Action to constant interpolation, in order to quickly preview the animation as "drawings" without having to unhide and select all keyed controls to switch their interpolation back and forth.

    Separate default curve mode for Armatures in User Preferences > Editing, so Armatures can be set to default to Constant interpolation for blocking without affecting everything else.

    1. Some good stuff here

      1) Reordering Poses and Selection Sets - Good idea. Not entirely straightforward (due to the way pose libraries actually work - i.e. they're really just glorified actions with local markers), but it's one of those things that can be done.

      2) Extra args for Bone Groups operators - Nice suggestion, and not hard either

      3) Toggle option for order that the axes work - Umm... this may be a bit more complicated. The keymap handling in that operator still isn't exactly that clear-cut.

      4) The question is: What colour would the "W" channel have then? Yellow? Are you proposing that the XYZ still get mapped to RGB there?

      5) "Clear All Keying Set Properties" - Good idea. Noted.

      6) Toggle in Timeline: The toggle itself is easy. Making the thing actually work though - maybe it'll be possible, maybe not so straightforward... I'd have to think about it a bit more...

      7) Separate default curve modes - Hmm... maybe... EDIT: on second thought, maybe it's technically not possible again.

    2. 4) Yellow's a good idea for the W channel. So then, I'm proposing that with "XYZ to RGB" active in User Preferences, Euler F-Curves behave just as they already do, and Quaternion F-Curves map WXYZ to YRGB.

      6) I've ruminated on how to do it using my limited knowledge of Python. Say activating the toggle calls a function that copies the existing F-Curves into a temporary variable, in order to preserve any hand-editing of the F-Curves' handles, and then switches all the F-Curves' interpolation modes to Constant. Deactivating the toggle somehow copies the stored F-Curves back into place, and discards the temporary Constant F-Curves. However, I soon found myself in over my head, as I'm not sure how best to have it delineate between F-Curves used for animation and those generated by F-Curve Modifiers or belonging to Drivers, which shouldn't be affected by this switch, and also how to safely store the original F-Curves in case the user saves and closes the .blend file with the toggle active.

      Thanks for taking a look!

    3. 4) Cool. That shouldn't be too hard. In the meantime, it's possible to use a script to manually set the colour of each FCurve (you just need to set it to manual mode or some equivalent per-curve IIRC)

      6) The challenge is really how we can pass it all the way down to where it needs to go. If we're only really interested in the active action, then it might be possible to make it so that there's a flag on the action for turning this sort of thing on/off. Then, when it's on, a special runtime flag gets set on each FCurve before it gets evaluated, which will cause its interpolation to get ignored (and to default to constant).

      Now, this approach may work well enough for the workflow you're aiming this for, but I'm sure we'll run into cases where slightly weird behaviour occurs (e.g. everything else that's animated keeps moving splined, while only the active object is constant; OR parts of the object - transforms - are constant while the rest - materials - are splined). Another thing that may not work nice is that you can apply FModifiers that can generate additional movement too... Then, do you mute those as well? Or only certain ones (e.g. generator/noise?)

    4. 4) Great, I'll try something like that in the meantime.

      6) You know, a per-Action flag like you describe is probably the best way to go, as it'd solve #7 from above also. The strange behavior you describe, where only the active object is Constant, is actually what I'm looking for. Often when animating a character I'll want to switch the entire Armature between Bezier and Constant, check movement and/or tweak something, and switch back. Currently, this is a rather lengthy process: Unhide all Armature layers with control bones -> Deselect-and-select all control bones in 3D View -> Deselect-and-select all Keyframes in the Dopesheet -> Switch interpolation mode. Switching back takes the same amount of steps. It's fine if everything else in the scene, like Camera movement and the like, stays as Bezier.

      I rarely use F-Modifiers in character animation because we don't have Quaternion blending in the NLA yet, but since this is such a specific use case maybe the "temporary Constant" state could just mute all F-Modifiers while it's active and mention this side-effect in the tooltip.

  2. 2) The ability to "lock" keyframes - for locking a range of frames (or specifying a range that can be edited) I would highlight the range similar to how the timeline/graph/dopesheet already highlights the background within the active/preview frame range. Keys outside of the editable range could also get "dimmed". The background of the editable range could be shaded in a light green. I would only put an X on a keyframe if there was a lock (or generating modifier?) on the specific key, ...hmmmm wonder if that would be useful, in the graph editor the properties show the frame and value of each keyframe, a padlock next to each to prevent it from being edited???? Anyway, this would also fit with locking a channel in the dopesheet where keys in a locked channel are dimmed - in the graph editor locked channels get dashed.

    1. Hmm.. some interesting ideas here. A while back, I did come to the conclusion that perhaps the dopesheet should in fact show the current frame range after all to make it easier to navigate/judge where things are. Of course, that means Preview Range drawing also needs to change a bit to make it more obvious when it is on vs off, otherwise the mode errors we'd get there would be a lot worse than they are now!

  3. This really kool work.

    Personally what i would love to see vanish diamond shaped key frames and have them turn into a much larger rabbit or at least make an option for artist that don't really want to exhaust mental energy on selecting these little microscopic diamonds on large monitor resolutions.

    I know that it's very similar to after effects, but i am pretty sure we as a community could think of something a little more user friendlier since as animators we spend a lot of time with these little guys (keyframes). So why not make them huge and easy to handle or an option to do that.

    1. I just noticed that I had changed the verts view under "themes - graph editor" setting to the maximum size to 10 (the handles can be anysize and would be good if it verts in the graph editor was the same)

      I wonder if its possible to take the graph editor settings and apply them to the Dope sheet. Better yet have them the scaling option right in the interface so you can change it really quickly.

    2. Would be also be really great to see timelines consolidated that you could really minimise and space and windows in blender.

      Do we really need all 6 time lines? Could the Dope sheet, Graph Editor, timeline and VSE be turned into one?

  4. Another thing is lasso select doesn't work in the dope sheet on keyframes which is super annoying. If you are using lasso select everywhere else than changing to box select is frustrating. Consistency is key.

  5. @Adam Earle:
    1) Regarding changing the diamond shape - The biggest challenge here is that many other shapes quickly become a lot harder to clearly read which frame they sit on. For example, the "rectangles" we used to have in 2.3x make it quite hard to tell where they sit.

    2) That said, perhaps we do need some better controls for making those items larger and easier to select. Having the new Properties Region will help a lot in this regard.

    It's not that simple to get the theme settings from one editor to apply in another one. We'd have to do some version patching to copy over the settings (when we start using it in a new editor), then there's also the additional burden that all theme authors now need to update their themes to take that into account

    3) Having the separate timelines makes it a hell of a lot easier to manage the differences between each of them. If there's anything I've learned from dealing with the transform code in Blender, it's that trying to squeeze together the requirements of too many similar but slightly-different-in-critical-ways tools is that you end up with a some hairy patches of code that are nearly impossible to work with. Therefore, IMO it's for the better that there is a clearly defined purpose for each of these editors: each one only operates on particular type of data, at a particular level of abstraction.

    4) Lasso in Dopesheet - Noted. Graph Editor support was a relatively recent thing too (like in the past 1-2 years), so it's not entirely a surprise that this doesn't work there yet.

  6. I love getting schooled up on things about blender thank you so much for getting back to me

    Just so you know the keyframes creep when you scale them in the dope sheet and the further the space is between key frames the slower they creep; one by one. I'm not sure if this designed this way or of its a bug. It kind of feels like a bug.

    Thank you again for taking the time to write back to me.

    1. That would be the auto-snapping (i.e. the dropdown beside the copy/paste buttons). It's essential to have in place for grabbing/translating the keys, or else they end up like 0.0000001 frames off, and then all of a sudden, everything thinks that there's no keyframe on that frame, and then you have heaps of trouble.

  7. I still don't understand the logic of the New Keyframe Type being in the Timeline when they are only visible in the Dopesheet. Doesn't it make more sense to have them there?

    Having said that, I don't really use the timeline as it's pretty much useless. Dopesheet all the way ;)

  8. I still don't understand the logic of the New Keyframe Type being in the Timeline when they are only visible in the Dopesheet. Doesn't it make more sense to have them there?

    Having said that, I don't really use the timeline as it's pretty much useless. Dopesheet all the way ;)