Wednesday, April 20, 2011

Enough of the "layer animation" bugz already!

In recent days, there has been an "explosion" in the number of bug-reports about various aspects of "layer animation" (overnight, there have been 3 in rapid succession even!). Before going ahead and pressing the submit button on the bug tracker another several dozen times, calm down, read this, and figure out if you're just barking up the wrong tree as a result of incorrect terminology and understanding about what's going on.


Although in 2.5 we can animate "everything", in some ways, this is actually turning out to be a bit too much freedom for some. To clarify things, let's define and clarify some terminology, which is necessary since most people seem to completely confuse the two, and end up submitting flawed bug reports ("iiit nooot wurrkeeinngg!!!!!!!!!!!!!! HELP!!!!!!!!!!!!!!!").

"Object Layer Membership"
Previously (pre 2.5), whenever you "animated layers" (i.e. IKEY -> Layer in the 3D-View), you were actually animating an object's layer membership. That is, every time you set a keyframe, you're telling Blender: "from this frame onwards, this object will be on layer 2 (or layer 19)" and then after going forward a few frames and using the Move to Layer (MKEY) and moving the object to layer 1,  "now from this frame onwards, this object will be back on layer 1".

To do this back then, you'd need to enable the layer on which you were moving the object to so that you could keyframe it using IKEY in the 3D-View (otherwise, Blender wouldn't pick up that you had an object selected for keyframing).

The only reason that an object would appear and disappear from the scene as you played back the animation is that after setting these keyframes, you would go and turn off the visibility of all layers that contain objects that you don't want visible. For example, as a de-facto convention, all "junk" objects (i.e. rig widgets, deform cages, unused props, temporary chunks of geometry, etc.) are all dumped on layer 20, and then this layer is turned off so that it is not shown (in the 3D-View or in Renders). This leads nicely into the next piece of terminology...

"Scene Layer Visibility"
By and large (* there's a slight catch that we'll get to in a moment), when you go through enabling and disabling that cluster of those 20 toggle-buttons on the 3D-View header, you're toggling whether each of the 20 Scene Layers is visible or not.

To crudely visualise this, imagine that you've got a bank of 20 bird cages, where the birds are free to roam between cages. Now, each cage has a curtain in front of it that can either be pulled back to reveal the contents, or to hide the contents from view. Toggling the visibility of scene layers is like selectively pulling back the curtains. At any point, you can pull back the curtain, and you might see 5 birds there. Pulling open another curtain, you might initially see that there are no birds there, but then a bird sees the light and flies over from the other cage. If the birds represent objects and the cages layers, then hopefully you can see that visibility of scene layers and object-layer membership are two different things which don't affect each other.

The ability to have access to and animate this is new in 2.5, though in most cases, you really SHOULD NOT try to do so. There are parts of Blender (notably the depsgraph) that effectively assume that this does not change over time (i.e. assume that it will not be animated, and that it will only change when the property is changed directly from the UI). Furthermore, I really don't think that most of the case where people have used it so far have necessarily been warranted; that is, most were cases of users confusing "animating layers" from past experience to literally mean animating "scene layer visibility" instead of animating "object layer membership" (which was what they were doing in the past).

(*) "3D-View Layer Visibility"
Hopefully the previous two made sense. Now we're going to describe a little complication. On the 3D-View header beside the layer toggles, there is an additional toggle: the tooltip will be something like "link to scene", and will either have a linked-chain or separated-chain icon depending on its state.

This option often causes confusion, even amongst experienced users, often when we forget that we have it enabled. What this option effectively does is that it makes the layer toggles on the header of a specific 3D-View only affect the layers visible in the 3D-View where this toggle was turned off. By default, this is enabled, so changing the visible layers from the 3D-View header results in the scene's visible layers also changing.

For example, say we had layers 1, 3, 5 enabled before disabling this option. Now, if we disable this option, and change the layers visible in the 3D-View to only be 2 and 4, in that particular 3D-View instance, only layers 2 and 4 would be visible (though in other views, 1,3,5 would still be visible). If we were to start a render in that particular 3D-View, only the layers that you've got enabled will be used.
NOTE: this is particularly a problem if you try use this feature to disable lights and backdrops while animating, and then try to do a quick test render to check that a pose reads properly only to find that you forgot about this. Test renders of this sort are practically essential when doing facial animation, where even slight rendering differences can mean the difference between a pose that reads and one that doesn't.
Anyways, if you start a render from anywhere else, or perhaps from the command-line (i.e. via some batch render/renderfarm), you'll notice that that the layers don't match up. You have been warned about this!

Fortunately though, we haven't actually seen any bug reports about this exact case. Perhaps it's just the fact that most of the community seems more "render" focused than anything else. Well, at least seeing some of the feature request lists that occasionally pop up gives that impression ("we want GI" x 10000, "we want caustics", blah blah). However, for some reason, this attitude strangely doesn't seem to carry over to other areas of Blender, which brings us to...

Animation Editors and Layer Visibility
The Animation Editors are ONLY aware of Scene Layer Visibility.

That is, they have no knowledge of what some 3D-View floating around somewhere on the same screen layout may be doing. This is also true of all other editors in fact: they don't have ANY knowledge of what other editors are doing; they only know about the global data and their own state which controls what what they decide to show you from that global data.

You might say: well, there's only one 3D-View on screen now, so it should just be able to find that and do whatever it does. If that is the case though, then the rendering behaviour above should do that too. Furthermore, what happens if I suddenly add a new 3D-View to the screen and have that do something different? Which one should I listen to now? Consistency at times comes with a price, but at least it's not as bad as the alternatives...


---

Now, moving on to another issue that comes up regarding the Animation Editors and "animating layers". As anyone who's tried animating "object layer membership" will have noticed, as soon as the objects move to scene layers which are not enabled, you will have trouble trying to edit their animation (i.e. the animation data isn't visible to edit!).

To this end, there's a feature built in to the Animation Editor filtering options which solves this problem. Just enable the ghost-icon toggle beside the cursor icon (i.e. "Include channels from objects/bones that aren't visible"). By default this is disabled, as it helps to reduce visual complexity by hiding animation data from objects that aren't visible and are assumed to not be relevant to the task at hand. 

Animating Object's Layer Membership in 2.5
So, to finish off, let's recap how you "should" go about animating an Object's layer membership in 2.5.

1. Make the object in question "active" 
The easiest way to do this (if you're going to be dealing with various layers being visible or not and at different times) is to use the Outliner. Simply click on the name of whatever object you want to start animating the layer membership of.

If you've managed to make it active, its name should now be white, and an orange circle should appear behind the icon to the left of the name. Otherwise, you may need to make sure it can be selected first (try enabling the cursor toggle in the middle column to the right of the object's name.

2. In the Properties Editor, go to the Object tab and locate the Layers button-cluster under the "Relationships" panel

3. For each keyframe you want to set...
a) Firstly, change the current frame to the frame on which you want to keyframe to be (do this click/dragging the green current-frame indicator line in the Timeline view, which is under the 3D View in the default layout).
b) Enable the toggles (in the cluster of buttons noted in step 2) for the layers you want the Object to be on on this frame, and disable all other layer buttons there.
c) Hovering over this cluster of buttons, simply press the IKEY to insert keyframes for these toggles on the current frame.
d) Repeat step 3 until you've got everything animated as you want.

Here are a few quick exercises to test if you understand this procedure:
1) Animate the default cube so that on frame 1 it belongs on layer 1, on frame 10 it is on layer 20, and on frame 20 it is on layer 1 again. Make sure only layer 1 is Scene-visible throughout. Once you've done this, you should see the cube visible for 10 frames, invisible for 10, then visible from then on until the end frame.
2) Add a UV sphere or Monkey head, move this to layer 10, and make Scene layer 2 visible. Now, repeat what you did in the first exercise, again animating the default cube. Having done that try animating the object you added, firstly adding a keyframe on frame 1 for where it currently is (layer 10), then adding another keyframe on frame 10 to have it on layer 2, and then a final keyframe on frame 20 to have it on layer 20. Playing this back, you should see the cube visible for 10 frames (and the sphere invisible for 10), followed by the sphere visible for 10 frames (while the cube is invisible for 10), and finally only the cube being visible for 10 frames.
3) Come up with your own little experiments, having fun moving things between layers.
---

To retime these keyframes, simply enter the DopeSheet/Action or Graph Editors, and start editing the keyframes for these layers around. You'll probably want to enable the "Include hidden channels" option from the header to prevent things jumping around as you edit.

If you want to edit which layer membership of an object animated in this way, the best way would be to simply use the inserting keyframes procedure to add some new keyframes after deleting the old ones using the animation editors.

You could also go in and play with the keyframes in the Graph Editor. When doing this, just remember several things:
- An object's membership to each layer is represented as a separate F-Curve. So layer 1 membership is controlled separately to layer 2 membership for example.
- Layer membership equates to one of two discrete values only: on/yes = 1, and off/no = 0. Use other values at your peril, but there's no gain from setting the value to 5/200/1000/etc. as this is still fundamentally an on/off setting.

12 comments:

  1. Or even simpler, if you just want to make an object visible or invisible (which is what people want most of time when animating layer membership), just key the little visible/renderable icons in the outliner!

    ReplyDelete
  2. Indeed, but then they wonder why it works in the 3d view and not render (if they only figure that they need to key one of them) ;)

    But true, I should have pointed them to that instead. No need to be mucking around with layer membership and so forth in this day and age ;)

    ReplyDelete
  3. I made the two posts ... #27065 and #27064

    Thank you for your response. It took only a few seconds to add the layer membership keyframes per your instructions.

    In summary the I-Key is only accepted over the cluster of buttons within the resources window under Objects/Relations/Layers and not over the cluster of buttons displayed within the 3DView window where the edit operations are carried out.

    What was confusing is that within the 3DView one can set the layer visibility keys. It was assumed that a similar process would be used for layer membership within the context of the 3DView. What one gets are two sets of cluster-of-buttons to toggle the layer memberships for each layer but the I-Key has no control on either one of them. Further if one presses the "Insert Keyframe" button it also has no effect with respect to the layer membership. However, most all other relevant actions can be set within the 3DView context. Given that this was the context of adding layer membership keys within 2.49, it seems it might be the same for v2.57. As indicated this was not a good assumption.

    When migrating from 2.49 to 2.57 with a project file one finds that the method of adding object layer membership has changed. Within 2.49 I could generate some 500 objects and key-frame the layer membership and have only a few curves to deal with. In v5.7 the number of curves explode to around 10000 curves as it stands. I can delete 9000 of the curves and am left with only 1000 but this is still 990+ curves more than I had in v2.49. As noted, I am working with a project I imported from v2.49. What is done is done.

    I realize I need to rethink the overall process and conform to 2.57 methods. What was no issue at all in v2.49 is now a significant curve management issue.

    Unless there is still some hidden features I have not found as of yet, which may be the case, if one is coming into 2.57 with a file from 2.49 and there is an explosion of keyframe curves, then one might want to consider using python to manage the problem (See my sample code I added on to the original bug report which is bases on the wiki python into example), starting over, or going back to 2.49 for selected segments.

    Some of the new features in 2.57 are great and overall worth the migration. Some of the new smoke stuff is looking real good. Dealing with this layer problem is a minor issue since in the long term it will all be automated, but is critical path for project completion in my case with a project that may not conform to the new ideals of v5.7.

    When looking around the Internet, I noticed that a number of people had been addressing this problem. I did not see any sort of definitive answer, just confusion. Although not classified as a bug, this is a case where getting the word out is a good thing. At least in my case, I have a much better understanding of the issues.

    Again, thanks for your input.

    Hal

    ReplyDelete
  4. Oops ... Not sure what I was thinking ...
    In summary the I-Key is only accepted over the cluster of buttons within the [Not --> resources] properties window under Objects/Relations/Layers and not over the cluster of buttons displayed within the 3DView window where the edit operations are carried out.

    ReplyDelete
  5. I have made further progress in resolving the layer key-framing issues. Here are some of my findings that might be useful to someone doing something similar.

    As stated in an earlier posting keyframing layer membership of a large number of objects was almost trasparent in some cases in v2.49 and required little thought. This does not seem to be the case in v2.57. However, this is not all bad. Here is a procedure to consider that I found useful. There may be better methods to meet specific objectives in v2.57 that eliminate the need to keyframee layer membership to this degree. Do seek them out. I am not addressing such issues at the moment but will in my next design. I am just sharing my finding with you as I work though some of these issues that deal with layers.

    In this example procedure, roughly 200 objects have membership to a single layer. Then membership will be changed using keyframes. The purpose and need is unimportant. ALso membership to multible layers is easly adjustable at differeing times.

    1) Within 3DView select the layer where the objects are a member.
    2) Using the 3DView, pick one of the objects to be a parent or insert one such as an empty object to be the parent.
    3) Select all the objects including the parent that will be keyframed. If all of the objects within a layer will be keyframed then press a-key until all the objects are selcted.
    4) Using Shift-RMB unslect the parent object.
    5) To creat a child parent realtionship then perform "3DView - Object/Parent/Set/Object". You should see lines from all the children link to the parent.
    6) Now we will add the first keyframe.
    Start first by just selecting the parent by 3DView - RMB on the parent.
    7) Within the Time Line Window select the frame where you want to start the layer membership changes. Let's say Frame 101.
    8) Go to the properties windows perform object/Relations and with the cursor over the cluster of buttons used to select layers press i-Key. This will set the frist key for the parent.
    9) Advance the frame by one. In this example it is to Frame 102.
    10) Again go to the properties windows perform object/Relations and with the cursor over the cluster of buttons used to select layers press i-Key. This will now set the second key for the parent.
    11) Within the graph editor, deselect the layers that you want to keep. In this case it is the intial Layer 2 and the final Layer 0. Use shift-LMB to deslect. To delete the remaining entries perform "Channel/Delete Channels".
    12) Return to the 3DView window and select all of the children and the parent.
    13) Deselected the parent.
    14) With all the children still selected, to link the children's animation to the parent preform "3DView - Object/Make Links ../Animation Data" Wait a few seconds and you should see the children show within the Graph Editor View.
    15) Note that with 200 objects, if you did not deleted the 18 unsued layers you would have 4000 entries in the list which is a bit much.
    16) Now with the frame counter at 102 for this example, clear Layer 2 membership and activate Layer 0 membership within the Graph Edit window.
    17) Test it by moving the Frame count. Be sure to change the layer visibility as needed.

    I hope this helps others looking to use layers in a similar manner. Also I hope I did not make any typos ... If I did please correct them in a later post. I did write this while I was going though it step by step, so it should be very close.

    Again, it is clear it will be good to rethink an animaiton approach within v2.57 with respect to what was used in v2.49.

    Again, I want to thank Aligorith for the above Bug response which helped be move ahead.

    Hal

    ReplyDelete
  6. Thank you for this wide explanation! It must be included in wiki (in some shortened form) so all our stupid questions will be cutted out quickly :)
    P.S. Just yesterday I noticed that I can animate "renderable" so I decided to go in that way.

    /Moolah Nasreddin

    ReplyDelete
  7. @Matt: Animating the renderability icon is great for individual objects, but sometimes I'll need to keyframe the visibility of hundreds of different objects at the same time. That's when layer visibility comes in handy, I think, as I can assign them all to a specific layer and then can keyframe the layer's renderability rather than each object.

    ReplyDelete
  8. the freedom of allowing the "3D-View Layer Visibility" to allow for a different set of layers for renders depending on the viewport the mouse is over at the moment is a profound strength in Blender. I'd consider it a big loss to have such an ability taken out of Blender. This feature alone constantly saves me a lot of time, and allows for a FAR more advanced and faster/modern workflow.

    For complex scenes, having the ability to setup different un-linked 3d views, all with their own enabled/disabled layers, allows for great control over the layers that will render while working on complex projects.

    For example, and its a basic example, the ability to have one viewport with an "actors" layer enabled(with MANY actors on it), and an "environment" layer enabled(the scene environment); then another viewport with just the "Environment" layer enabled, makes for profound and immediate control over what renders when working on detailed scenes by simply mousing-over a given 3d viewport and rendering to see the 2 different renders without needing to setup a script, or manually change layers in the 3d viewport.

    Please don't consider taking this feature out of Blender, I rely on it for nearly all my Blender work.

    ReplyDelete
  9. Hi d...
    These posts are more about documenting v2.57 way of doing things with respect to layer key framing. Setting layer visibility within the 3D View is the current method in v2.57 and I do not think any of the discussion here was to diminish that ability. At least that was not the objective with respect to the original posting.

    ReplyDelete
  10. @Ben U: Personally, I'd prefer being able to keyframe Group visibility when dealing with a lot of objects. Currently, I can toggle group visibility/renderability, but I can't keyframe them.

    ReplyDelete
  11. @MikeB: I'm totally with you. Animating group visibility would be AWESOME!

    That said, when an object belongs to multiple groups, it can get a little messy. There's need to be some sort of hierarchy so that if one group is visible and another is not, the object knows whether to show itself or not....

    ReplyDelete
  12. Lawrence D’OliveiroMarch 17, 2015 at 11:26 AM

    Animating layer visibility has been removed in current Blender.

    ReplyDelete