提供: wiki
移動先: 案内検索

Making a Datablock Animateable

This checklist covers how to make a datablock able to be animated (using Actions/NLA), and maybe also get drivers too.

  • The advice in this checklist only applies to datablocks - structs in the SDNA (DNA_*_types.h) headers where the first member is ID id;

WARNING: This checklist may be incomplete. Please contact User:Aligorith if you come across any errors or omissions.


Blender3D FreeTip.png
In most of these examples, a Grease Pencil datablock (i.e. bGPdata, referred to as gpd) has been used as a stand-in. You should replace this with a suitable identifier for your datablock type - e.g. ob or me or sce


  • Immediately after the ID id; line for your datablock, add the following line:

   struct AnimData *adt;

   You may need to forward-declare this type reference - i.e. struct AnimData; - before actually using it in the struct, to avoid compilers complaining

File Reading - blenloader/intern/readfile.c

  • lib_link_[your_datablock]() - For relinking ID-blocks attached to your datablock (i.e. in this case, the Actions and anything the Drivers may refer to):

   if (gpd->adt)
        lib_link_animdata(fd, &gpd->id, gpd->adt);

  • direct_link_[your_datablock]() - For relinking any "soft" blobs that are part of the datablock (i.e. in this case, the AnimData instance itself, along with all the Drivers + NLA Strips, etc. that go with it):

   /* relink animdata */
   gpd->adt = newdataadr(fd, gpd->adt);
   direct_link_animdata(fd, gpd->adt);

Some of the following steps only apply if your datablock didn't previous refer to any other datablocks, you will have to do the following as well. These have been marked as "optional":

  • lib_link_all() - [OPTIONAL] Add the following line to the list of lib_link_[datatype](fd, main); calls:

   lib_link_[your_datatype](fd, main);

  • expand_[your_datatype]() - Add the following lines to this function (create it if necessary):

      if (gpd->adt)
          expand_animdata(fd, mainvar, gpd->adt);

  • BLO_expand_main() - [OPTIONAL] Add the following lines if you had to add the expand_[datatype]() in the previous step:

      case ID_GD:
            expand_gpencil(fd, mainvar, (bGPdata *)id);

File Writing - blenloader/intern/writefile.c

  • write_[datablocks_of_type]() - Add the following line:

   if (gpd->adt) write_animdata(wd, gpd->adt);

Integrating the datablock in the Animato Anim System - (blenkernel/intern/animsys.c)

  • id_type_can_have_animdata(ID *id) - Add the datablock's type code (e.g. ID_GD) to the switch statement. This enables most of the magic to happen.
  • BKE_animdata_main_cb() - Add the following lines for your datatype (with the a single-line comment immediately before saying what it is). e.g.

   /* grease pencil */

  • BKE_all_animdata_fix_paths_rename() - Add the following lines for your datatype. e.g.

    /* grease pencil */

  • BKE_animsys_evaluate_all_animation() - Add the following lines for your datatype. (See clarifications below for notes on placement) e.g.

    /* grease pencil */
    EVAL_ANIM_IDS(main->gpencil.first, ADT_RECALC_ANIM);

Data Management

  • blenkernel/intern/[your_type].c
    • free_[yourtype]() - Remember to free the AnimData

      /* free animation data */
      if (gpd->adt) {
              gpd->adt = NULL;

  • blenkernel/intern/library.c
    •  ??? rename/relink/duplicate?


  • makesrna/intern/rna_[your_type].c
    • Somewhere in the datablock's struct, add the following lines, to expose the AnimData reference (i.e. datablock.animation_data):

      /* Animation Data */

New Depsgraph

  • depsgraph/intern/ - Make the Depsgraph aware of the Animation data objects

       if (gpd->adt) {

  • depsgraph/intern/ - Make the Depsgraph aware of the links between Animation data objects and everything else (mostly for drivers, but also essential to ensure that time/animation link exists)

       if (gpd->adt) {

Animation Editor Support

... To be written - Refer to docs on adding a new anim channel type...


  • Special care is needed when dealing with "nested nodetrees" (e.g. like those used for Material, World, and Scene/Compo nodes). There are dedicated versions of the *_ANIM_IDS_* macros to be used for those, which will go into the node trees as expected
  • Order matters when adding entries into the BKE_animsys_evaluate_all_animation() method. The idea is: If the struct references other datablocks which can be animated, you should only include that your datablock type AFTER all the things it depends on have been evaluated. This allows the user-block (i.e. your datablock) to override anything that came from the shared datablocks)