---
tags: Animation, Animation 2025
---
# Animation Filtering Replacement
[TOC]
## Weaknesses of the Current System
These are some of the weaknesses of the current system that we'll try to lift with the rewrite:
- It uses the **low-level data**, like selection state of objects/bones, flags on F-Curves, etc. **as the basis** of all further processing. Afterwards, in practice, the system can only remove data, not add to it. This is, for example, why pinning works so badly.
- The **data itself**, its **presentation** (indentation, for example), and its **organisation** (hierarchies, grouping) are **all determined at the same time**, in the same bit of code. That bit of code also doesn't know anything about its bigger context. Each channel in the list can only 'reason' about itself, and not its relationship to other data.
- The above two points mean that it's **not possible to have per-editor customisation** of presentation & organisation of the data (apart from very basic filtering options).
- **Operators _have_ to know** which filtering flags are used by the editor they run in, so that they can copy those and operate on the same data as shown in the UI.
- The desire for per-editor customisation, combined with the fragility of the above point, means the **editor itself should expose the data it's displaying**. This way operators can just query that.
- There are **no 'hooks' that allow customisation** of the shown data, or its presentation. This means that any adjustment of the system is always going to apply to everything. It would be deisrable to have more of a "plug-in" system, giving the user of the filtering system more power to reorganize things before they are displayed / operated on.
## ! ⇒ Below Be Dragons ⇐ !
> [!Warning]
> **The rest of this document is relatively old. I (Sybren) wrote that before Project Baklava (where we designed the new slotted & layered actions). It is still aiming for cooperation with the NLA; the new system will have to do that to _some_ level, but with the richer Actions there's more to take into account that is written here. So take with a grain of old salt.**
>
> I think the analysis of the current filtering system is still fairly accurate, though.
## Also...
> [name=Sybren]
> bit off-topic but I wanted to mention this somewhere where we run into it again.
- Check [Campbell's suggestion for gizmos to report on the RNA properties they manipulate](https://projects.blender.org/blender/blender/pulls/146168#issuecomment-1734936). Might be an interesting approach for the new animation tool framework as well.
## Animation Data Sources
Current datasources (and a few desired ones):
* FCurves in Actions on:
* Object (regular action, but also pose data)
* [color=purple] Collection (targeting contained datablocks)
* [color=purple] Scene (targeting contained datablocks)
* Shapekey (sort of object-owned, but also heavily mesh-related data)
* Object Data (Armature, Camera, Curves, Grease Pencil, Lattice, Light, LightProbe, Mesh, MetaBall, PointCloud, Speaker, Volume)
* Other animatable IDs (CacheFile, FreestyleLineStyle, Mask, Material, MovieClip, NodeTree, ParticleSettings, Scene, Simulation, Sound, Tex, World)
* Grease Pencil frames
* Masks
* Drivers
* NLA
* Tracks
* Strips
* [color=purple] Non-numerical data, like camera switches
Purple tag: yet to be implemented.
## UI Filters / Source Selectors
We may want to split these up. Currently these are about the source of the shown data, while others are filtering that data. I’m listing them here in one place anyway, because they are currently rather entangled.
* Unfiltered (so everything in the file, except unused Actions)
* Selected object / bone
* Hidden (by the user)
* Errors (animation data for non-existent properties)
* Specific Action
* Specific Source (Shape Key, Grease Pencil, Mask, Cache File)
* [color=purple] Selected properties (and multiple, configurable pages of those)
* [color=purple] Specific property types (only transform, only custom props, etc)
Purple tag: yet to be implemented.
### Code-side Filters
These filters are currently defined in Blender’s code to achieve the above, and usually combinations are used to query for animation data.
| Filter | Expanation |
|---------------------------------|---------------------------------------------------------------------------------------------------------------------------------|
| `ANIMFILTER_DATA_VISIBLE` | Data which channel represents is fits the dope-sheet filters (i.e. scene visibility criteria) |
| `ANIMFILTER_LIST_VISIBLE` | channel is visible within the channel-list hierarchy (i.e. F-Curves within Groups in ActEdit) |
| `ANIMFILTER_CURVE_VISIBLE` | channel has specifically been tagged as visible in Graph Editor (Graph Editor Only) |
| `ANIMFILTER_LIST_CHANNELS` | include summary channels and "expanders" (for drawing/mouse-selection in channel list) |
| `ANIMFILTER_ACTIVE` | for its type, channel should be "active" one |
| `ANIMFILTER_ACTGROUPED` | channel is a child of the active group (Actions specialty) |
| `ANIMFILTER_SEL` | channel must be selected/not-selected, but both must not be set together |
| `ANIMFILTER_UNSEL` | |
| `ANIMFILTER_FOREDIT` | editability status - must be editable to be included |
| `ANIMFILTER_SELEDIT` | only selected animchannels should be considerable as editable - mainly for Graph Editor's option for keys on select curves only |
| `ANIMFILTER_ANIMDATA` | Flags used to enforce certain data types. The ones for curves and NLA tracks were redundant and have been removed for now. |
| `ANIMFILTER_NODUPLIS` | duplicate entries for animation data attached to multi-user blocks must not occur |
| `ANIMFILTER_FCURVESONLY` | avoid channel that does not have any F-curve data |
| `ANIMFILTER_TMP_PEEK` | for checking if we should keep some collapsed channel around (internal use only!) |
| `ANIMFILTER_TMP_IGNORE_ONLYSEL` | Ignore ONLYSEL flag from #bDopeSheet.filterflag (internal use only!) |
These combine the following concepts:
* Visibility as per global toggles in the user interface.
* Properties of animation channels (like FCurve FCURVE_VISIBLE, FCURVE_SELECTED, etc.)
* Relationship with other animation data
* Animation source properties (intrinsincly editable vs. non-editable)
* Properties of the animation data source (number of users)
* Animation data type (FCurve, Grease Pencil)
* “Internal use only”
### Uses of those filters
- Transform code (`transform_convert_nla.c`, `transform_convert_graph.c`, `transform_convert_action.c`)
- NLA code (`nla_buttons.c`, `nla_channels.c`, `nla_select.c`, `nla_edit.c`, `nla_draw.c`):
- which data to 'push down'
- which NLA tracks are selected & visible (in two different ways, with and without `ANIMFILTER_ANIMDATA`)?
- what are the active strip/track/animdata?
- which NLA tracks & strips are draw where on screen? Various incarnations of the same query across different files.
-
- Animation channels (`anim_channels_define.c`, `anim_channels_edit.c`)
- Mostly just 'what is visible?' and 'what is selected?', with or without `ANIMFILTER_NODUPLIS`, and depending on whether editing is necessary, `ANIMFILTER_FOREDIT`. Rather inconsistent with the other flags, though.
- Selection
- Selection / 'activeness' state synchronisation (`anim_deps.c`)
- Key selection (`graph_select.c`)
- The actual filtering code (`anim_filters.c`)
- Keyframes (`keyframes_edit.c`, `keyframes_keylist.cc`)
- Only `ANIMFILTER_DATA_VISIBLE` with the occasional `ANIMFILTER_FCURVESONLY`
- Grease Pencil (`editaction_gpencil.c`): copy-pasting of GP frames.
- Context (`screen_context.c`)
- Selecting driver channels (`screen_ops.c`)
- Animation editor drawing and interaction (`action_draw.cc`, `action_edit.cc`, `graph_draw.c`, `graph_ops.c`, `space_graph.c`)
- Animation data manipulation (`action_edit.cc`, `graph_edit.c`, `graph_slider_ops.c`)
- Baking to 'ghost curves' (`graph_view.c`)
- Animation data queries (`action_select.cc`, `graph_view.c`), both screen-space and the regular 'selected and visible' queries.
- Getting active FCurve, some poll functions (`graph_util.c`)
### Almost name collision
:::success
What's described below is handled in [#106028: Refactor: remove enum eAnimFilterFlags](https://projects.blender.org/blender/blender/pulls/106028).
:::
The above flags are defined in `ED_anim_api.h` as `enum eAnimFilter_Flags`. BUT: in `ED_keyframing.h` there is `enum eAnimFilterFlags`. Note the different names, one has `_` and the other does not. The latter has the following flags:
| Filter | Expanation | Remarks |
| ---------------------- | ---------------------------------------- | - |
| ANIMFILTER_KEYS_LOCAL | only include locally available anim data | here 'local' means 'on the datablock' and not 'its materials/shapekeys' |
| ANIMFILTER_KEYS_MUTED | include muted elements | never set, so can be removed |
| ANIMFILTER_KEYS_ACTIVE | only include active-subelements | never set, so can be removed |
| ANIMFILTER_KEYS_NOMAT | don't include material keyframes | never set, so can be removed |
| ANIMFILTER_KEYS_NOSKEY | don't include shape keys (for geometry) | never set, so can be removed |
These are used in:
- 3D Viewport drawing (`view3d_draw.cc`), to colour the name of the selected object depending on whether there is a key on the current frame or not. Always uses `ANIMFILTER_KEYS_LOCAL`.
- Auto-keying code (`keyframing.c`), to determine whether the 'only replace existing keys' mode should auto-key. Always uses `ANIMFILTER_KEYS_LOCAL`.
- `fcurve_frame_has_keyframe(..., filter)` is used in a few places, sometimes with, sometimes without filters. But the only filter it uses is `ANIMFILTER_KEYS_MUTED`, which is never set.
Conclusion: the use of these filter flags seems to have been reduced over time to only, always use `ANIMFILTER_KEYS_LOCAL`. This means that:
- the entire set of flags can be removed,
- the code that handles those filters can be removed, and
- the `filter` parameters can be removed from the functions that pass them.
## Editor-side Behaviour
Editors should be able to set up their own sources and filtering. This should allow pinning of animation data to those editors, making them independent of the selected/active datablocks in the scene.
## Transform System Integration
It should be possible to connect the filtered data with the transform system.
## Dependency Graph Integration
Animation Data Sources need to be able to set up depsgraph relations.
## Data Flow Diagram
```mermaid
erDiagram
ID ||..o| ActionDataSource : "has"
ID ||..o| NLADataSource : "has"
OBJECT ||..o| GreasePencilDataSource : "has"
ActionDataSource ||..o{ ChannelGroup : "produces"
NLADataSource ||..|| NLARetimer : "has"
NLARetimer ||..o{ ChannelGroup : "produces"
GreasePencilDataSource ||..o{ ChannelGroup : "produces"
ChannelGroup ||..o{ Channel : "contains"
ChannelGroup ||..o{ ChannelGroup : "contains"
```
<!-- ### Example graphs for reference
Just for reference on how to draw these things.
```graphviz
digraph summary{
start [label="Start with a Node"]
next [label="Choose your shape", shape=box]
warning [label="Don't go overboard", color=Blue, fontcolor=Red,fontsize=24,style=filled, fillcolor=green,shape=octagon]
end [label="Draw your graph!", shape=box, style=filled, fillcolor=yellow]
start->next
start->warning
next->end [label="Getting Better...", fontcolor=darkblue]
}
```
```graphviz
digraph structs {
node[shape=record]
struct1 [label="<f0> left|<f1> mid\ dle|<f2> right"];
struct2 [label="{<f0> one|<f1> two\n\n\n}" shape=Mrecord];
struct3 [label="hello\nworld |{ b |{c|<here> d|e}| f}| g | h"];
struct1:f1 -> struct2:f0;
struct1:f0 -> struct3:f1;
}
```
```graphviz
digraph dfd2{
node[shape=record]
subgraph level0{
enti1 [label="Customer" shape=box];
enti2 [label="Manager" shape=box];
}
subgraph cluster_level1{
label ="Level 1";
proc1 [label="{<f0> 1.0|<f1> One process here\n\n\n}" shape=Mrecord];
proc2 [label="{<f0> 2.0|<f1> Other process here\n\n\n}" shape=Mrecord];
store1 [label="<f0> |<f1> Data store one"];
store2 [label="<f0> |<f1> Data store two"];
{rank=same; store1, store2}
}
enti1 -> proc1
enti2 -> proc2
store1 -> proc1
store2 -> proc2
proc1 -> store2
store2 -> proc1
}
```
-->