From eae05ff5413c07b8b3bb2eb3b3640af96af8ef39 Mon Sep 17 00:00:00 2001 From: Joshua Leung Date: Sun, 6 May 2012 12:37:19 +0000 Subject: Bugfix [#31003] Animation data (e.g. actions, drivers) from the active material of a material nodetree was not visible in the Animation Editors --- source/blender/editors/animation/anim_filter.c | 110 ++++++++++++++++--------- 1 file changed, 71 insertions(+), 39 deletions(-) diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 2f0f396eb10..d9f735f0559 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -1475,51 +1475,83 @@ static size_t animdata_filter_ds_textures (bAnimContext *ac, ListBase *anim_data return items; } -static size_t animdata_filter_ds_materials (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode) + +static size_t animdata_filter_ds_material (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Material *ma, int filter_mode) { - size_t items=0; - int a=0; + ListBase tmp_data = {NULL, NULL}; + size_t tmp_items = 0; + size_t items = 0; - /* firstly check that we actuallly have some materials, by gathering all materials in a temp list */ - for (a=1; a <= ob->totcol; a++) { - Material *ma= give_current_material(ob, a); - ListBase tmp_data = {NULL, NULL}; - size_t tmp_items = 0; + /* add material's animation data to temp collection */ + BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_MAT_OBJD(ma)) + { + /* material's animation data */ + tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ma, filter_mode); + + /* textures */ + if (!(ads->filterflag & ADS_FILTER_NOTEX)) + tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)ma, filter_mode); + + /* nodes */ + if ((ma->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) + tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)ma, ma->nodetree, filter_mode); + } + END_ANIMFILTER_SUBCHANNELS; + + /* did we find anything? */ + if (tmp_items) { + /* include material-expand widget first */ + // hmm... do we need to store the index of this material in the array anywhere? + if (filter_mode & ANIMFILTER_LIST_CHANNELS) { + /* check if filtering by active status */ + if (ANIMCHANNEL_ACTIVEOK(ma)) { + ANIMCHANNEL_NEW_CHANNEL(ma, ANIMTYPE_DSMAT, ma); + } + } - /* if no material returned, skip - so that we don't get weird blank entries... */ - if (ma == NULL) continue; + /* now add the list of collected channels */ + BLI_movelisttolist(anim_data, &tmp_data); + BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL)); + items += tmp_items; + } + + return items; +} + +static size_t animdata_filter_ds_materials (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode) +{ + short has_nested = 0; + size_t items = 0; + int a = 0; + + /* first pass: take the materials referenced via the Material slots of the object */ + for (a = 1; a <= ob->totcol; a++) { + Material *ma = give_current_material(ob, a); - /* add material's animation data to temp collection */ - BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_MAT_OBJD(ma)) - { - /* material's animation data */ - tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ma, filter_mode); - - /* textures */ - if (!(ads->filterflag & ADS_FILTER_NOTEX)) - tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)ma, filter_mode); - - /* nodes */ - if ((ma->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) - tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)ma, ma->nodetree, filter_mode); + /* if material is valid, try to add relevant contents from here */ + if (ma) { + /* add channels */ + items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode); + + /* for optimising second pass - check if there's a nested material here to come back for */ + if (has_nested == 0) + has_nested = give_node_material(ma) != NULL; } - END_ANIMFILTER_SUBCHANNELS; - - /* did we find anything? */ - if (tmp_items) { - /* include material-expand widget first */ - // hmm... do we need to store the index of this material in the array anywhere? - if (filter_mode & ANIMFILTER_LIST_CHANNELS) { - /* check if filtering by active status */ - if (ANIMCHANNEL_ACTIVEOK(ma)) { - ANIMCHANNEL_NEW_CHANNEL(ma, ANIMTYPE_DSMAT, ma); - } - } + } + + /* second pass: go through a second time looking for "nested" materials (material.material references) + * + * NOTE: here we ignore the expanded status of the parent, as it could be too confusing as to why these are + * disappearing/not available, since the relationships between these is not that clear + */ + if (has_nested) { + for (a = 1; a <= ob->totcol; a++) { + Material *base = give_current_material(ob, a); + Material *ma = give_node_material(base); - /* now add the list of collected channels */ - BLI_movelisttolist(anim_data, &tmp_data); - BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL)); - items += tmp_items; + /* add channels from the nested material if it exists */ + if (ma) + items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode); } } -- cgit v1.2.3