diff options
Diffstat (limited to 'source/blender/editors/animation/anim_filter.c')
-rw-r--r-- | source/blender/editors/animation/anim_filter.c | 131 |
1 files changed, 71 insertions, 60 deletions
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 4659fc2ca18..8fb32e5b82e 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -74,6 +74,7 @@ #include "DNA_gpencil_types.h" #include "DNA_object_types.h" #include "DNA_userdef_types.h" +#include "DNA_layer_types.h" #include "MEM_guardedalloc.h" @@ -83,13 +84,14 @@ #include "BLI_ghash.h" #include "BLI_string.h" -#include "BKE_animsys.h" #include "BKE_action.h" -#include "BKE_fcurve.h" +#include "BKE_animsys.h" +#include "BKE_collection.h" #include "BKE_context.h" +#include "BKE_fcurve.h" #include "BKE_global.h" -#include "BKE_group.h" #include "BKE_key.h" +#include "BKE_layer.h" #include "BKE_main.h" #include "BKE_material.h" #include "BKE_modifier.h" @@ -130,11 +132,11 @@ static void animedit_get_yscale_factor(bAnimContext *ac) /* Note: there's a similar function in key.c (BKE_key_from_object) */ static Key *actedit_get_shapekeys(bAnimContext *ac) { - Scene *scene = ac->scene; + ViewLayer *view_layer = ac->view_layer; Object *ob; Key *key; - ob = OBACT; + ob = OBACT(view_layer); if (ob == NULL) return NULL; @@ -228,6 +230,7 @@ static bool actedit_get_context(bAnimContext *ac, SpaceAction *saction) ac->mode = saction->mode; return true; } + case SACTCONT_DOPESHEET: /* DopeSheet */ /* update scene-pointer (no need to check for pinning yet, as not implemented) */ saction->ads.source = (ID *)ac->scene; @@ -238,6 +241,28 @@ static bool actedit_get_context(bAnimContext *ac, SpaceAction *saction) ac->mode = saction->mode; return true; + case SACTCONT_TIMELINE: /* Timeline */ + /* update scene-pointer (no need to check for pinning yet, as not implemented) */ + saction->ads.source = (ID *)ac->scene; + + /* sync scene's "selected keys only" flag with our "only selected" flag + * XXX: This is a workaround for T55525. We shouldn't really be syncing the flags like this, + * but it's a simpler fix for now than also figuring out how the next/prev keyframe tools + * should work in the 3D View if we allowed full access to the timeline's dopesheet filters + * (i.e. we'd have to figure out where to host those settings, to be on a scene level like + * this flag currently is, along with several other unknowns) + */ + if (ac->scene->flag & SCE_KEYS_NO_SELONLY) + saction->ads.filterflag &= ~ADS_FILTER_ONLYSEL; + else + saction->ads.filterflag |= ADS_FILTER_ONLYSEL; + + ac->datatype = ANIMCONT_TIMELINE; + ac->data = &saction->ads; + + ac->mode = saction->mode; + return true; + default: /* unhandled yet */ ac->datatype = ANIMCONT_NONE; ac->data = NULL; @@ -380,8 +405,10 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac) ac->scene = scene; if (scene) { ac->markers = ED_context_get_markers(C); - ac->obact = (scene->basact) ? scene->basact->object : NULL; } + ac->depsgraph = CTX_data_depsgraph(C); + ac->view_layer = CTX_data_view_layer(C); + ac->obact = (ac->view_layer->basact) ? ac->view_layer->basact->object : NULL; ac->sa = sa; ac->ar = ar; ac->sl = sl; @@ -1673,6 +1700,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi if (ads->filterflag & ADS_FILTER_GP_3DONLY) { Scene *scene = (Scene *)ads->source; + ViewLayer *view_layer = (ViewLayer *)ac->view_layer; Base *base; /* Active scene's GPencil block first - No parent item needed... */ @@ -1681,7 +1709,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi } /* Objects in the scene */ - for (base = scene->base.first; base; base = base->next) { + for (base = view_layer->object_bases.first; base; base = base->next) { /* Only consider this object if it has got some GP data (saving on all the other tests) */ if (base->object && base->object->gpd) { Object *ob = base->object; @@ -1697,14 +1725,14 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi */ if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) { /* layer visibility - we check both object and base, since these may not be in sync yet */ - if ((scene->lay & (ob->lay | base->lay)) == 0) continue; + if ((base->flag & BASE_VISIBLED) == 0) continue; /* outliner restrict-flag */ if (ob->restrictflag & OB_RESTRICT_VIEW) continue; } /* check selection and object type filters */ - if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (base == scene->basact)*/) ) { + if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & BASE_SELECTED) /*|| (base == scene->basact)*/) ) { /* only selected should be shown */ continue; } @@ -1714,7 +1742,7 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi * - used to ease the process of doing multiple-character choreographies */ if (ads->filterflag & ADS_FILTER_ONLYOBGROUP) { - if (BKE_group_object_exists(ads->filter_grp, ob) == 0) + if (BKE_collection_has_object_recursive(ads->filter_grp, ob) == 0) continue; } @@ -1944,25 +1972,26 @@ static size_t animdata_filter_ds_nodetree(bAnimContext *ac, ListBase *anim_data, static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode) { - SceneRenderLayer *srl; + ViewLayer *view_layer; FreestyleLineSet *lineset; size_t items = 0; - for (srl = sce->r.layers.first; srl; srl = srl->next) { - for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) { + for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) { + for (lineset = view_layer->freestyle_config.linesets.first; lineset; lineset = lineset->next) { if (lineset->linestyle) { lineset->linestyle->id.tag |= LIB_TAG_DOIT; } } } - for (srl = sce->r.layers.first; srl; srl = srl->next) { + for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) { /* skip render layers without Freestyle enabled */ - if (!(srl->layflag & SCE_LAY_FRS)) + if ((view_layer->flag & VIEW_LAYER_FREESTYLE) == 0) { continue; + } /* loop over linesets defined in the render layer */ - for (lineset = srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) { + for (lineset = view_layer->freestyle_config.linesets.first; lineset; lineset = lineset->next) { FreestyleLineStyle *linestyle = lineset->linestyle; ListBase tmp_data = {NULL, NULL}; size_t tmp_items = 0; @@ -2047,7 +2076,9 @@ static size_t animdata_filter_ds_texture(bAnimContext *ac, ListBase *anim_data, return items; } -/* NOTE: owner_id is either material, lamp, or world block, which is the direct owner of the texture stack in question */ +/* NOTE: owner_id is the direct owner of the texture stack in question + * It used to be Material/Lamp/World before the Blender Internal removal for 2.8 + */ static size_t animdata_filter_ds_textures(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, int filter_mode) { MTex **mtex = NULL; @@ -2059,24 +2090,6 @@ static size_t animdata_filter_ds_textures(bAnimContext *ac, ListBase *anim_data, return 0; switch (GS(owner_id->name)) { - case ID_MA: - { - Material *ma = (Material *)owner_id; - mtex = (MTex **)(&ma->mtex); - break; - } - case ID_LA: - { - Lamp *la = (Lamp *)owner_id; - mtex = (MTex **)(&la->mtex); - break; - } - case ID_WO: - { - World *wo = (World *)owner_id; - mtex = (MTex **)(&wo->mtex); - break; - } case ID_PA: { ParticleSettings *part = (ParticleSettings *)owner_id; @@ -2121,10 +2134,6 @@ static size_t animdata_filter_ds_material(bAnimContext *ac, ListBase *anim_data, /* 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); @@ -2443,10 +2452,6 @@ static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, b /* nodetree */ if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE)) tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, &la->id, ntree, filter_mode); - - /* textures */ - if (!(ads->filterflag & ADS_FILTER_NOTEX)) - tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, &la->id, filter_mode); break; } } @@ -2621,7 +2626,7 @@ static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data if (filter_mode & ANIMFILTER_LIST_CHANNELS) { /* check if filtering by selection */ // XXX: double-check on this - most of the time, a lot of tools need to filter out these channels! - if (ANIMCHANNEL_SELOK((base->flag & SELECT))) { + if (ANIMCHANNEL_SELOK((base->flag & BASE_SELECTED))) { /* check if filtering by active status */ if (ANIMCHANNEL_ACTIVEOK(ob)) { ANIMCHANNEL_NEW_CHANNEL(base, ANIMTYPE_OBJECT, ob); @@ -2651,10 +2656,6 @@ static size_t animdata_filter_ds_world(bAnimContext *ac, ListBase *anim_data, bD /* animation data filtering */ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)wo, filter_mode); - /* textures for world */ - if (!(ads->filterflag & ADS_FILTER_NOTEX)) - tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)wo, filter_mode); - /* nodes */ if ((wo->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)wo, wo->nodetree, filter_mode); @@ -2845,7 +2846,7 @@ static size_t animdata_filter_dopesheet_movieclips(bAnimContext *ac, ListBase *a } /* Helper for animdata_filter_dopesheet() - For checking if an object should be included or not */ -static bool animdata_filter_base_is_ok(bDopeSheet *ads, Scene *scene, Base *base, int filter_mode) +static bool animdata_filter_base_is_ok(bDopeSheet *ads, Base *base, int filter_mode) { Object *ob = base->object; @@ -2863,7 +2864,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Scene *scene, Base *base */ if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) { /* layer visibility - we check both object and base, since these may not be in sync yet */ - if ((scene->lay & (ob->lay | base->lay)) == 0) + if ((base->flag & BASE_VISIBLED) == 0) return false; /* outliner restrict-flag */ @@ -2898,7 +2899,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Scene *scene, Base *base } /* check selection and object type filters */ - if ((ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (base == sce->basact)*/)) { + if ((ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & BASE_SELECTED) /*|| (base == sce->basact)*/)) { /* only selected should be shown */ return false; } @@ -2908,7 +2909,7 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Scene *scene, Base *base * - used to ease the process of doing multiple-character choreographies */ if (ads->filterflag & ADS_FILTER_ONLYOBGROUP) { - if (BKE_group_object_exists(ads->filter_grp, ob) == 0) + if (BKE_collection_has_object_recursive(ads->filter_grp, ob) == 0) return false; } @@ -2926,15 +2927,15 @@ static int ds_base_sorting_cmp(const void *base1_ptr, const void *base2_ptr) } /* Get a sorted list of all the bases - for inclusion in dopesheet (when drawing channels) */ -static Base **animdata_filter_ds_sorted_bases(bDopeSheet *ads, Scene *scene, int filter_mode, size_t *r_usable_bases) +static Base **animdata_filter_ds_sorted_bases(bDopeSheet *ads, ViewLayer *view_layer, int filter_mode, size_t *r_usable_bases) { /* Create an array with space for all the bases, but only containing the usable ones */ - size_t tot_bases = BLI_listbase_count(&scene->base); + size_t tot_bases = BLI_listbase_count(&view_layer->object_bases); size_t num_bases = 0; Base **sorted_bases = MEM_mallocN(sizeof(Base *) * tot_bases, "Dopesheet Usable Sorted Bases"); - for (Base *base = scene->base.first; base; base = base->next) { - if (animdata_filter_base_is_ok(ads, scene, base, filter_mode)) { + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + if (animdata_filter_base_is_ok(ads, base, filter_mode)) { sorted_bases[num_bases++] = base; } } @@ -2952,6 +2953,7 @@ static Base **animdata_filter_ds_sorted_bases(bDopeSheet *ads, Scene *scene, int static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, int filter_mode) { Scene *scene = (Scene *)ads->source; + ViewLayer *view_layer = (ViewLayer *)ac->view_layer; size_t items = 0; /* check that we do indeed have a scene */ @@ -2990,14 +2992,14 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, b * - Don't do this if there's just a single object */ if ((filter_mode & ANIMFILTER_LIST_CHANNELS) && !(ads->flag & ADS_FLAG_NO_DB_SORT) && - (scene->base.first != scene->base.last)) + (view_layer->object_bases.first != view_layer->object_bases.last)) { /* Filter list of bases (i.e. objects), sort them, then add their contents normally... */ // TODO: Cache the old sorted order - if the set of bases hasn't changed, don't re-sort... Base **sorted_bases; size_t num_bases; - sorted_bases = animdata_filter_ds_sorted_bases(ads, scene, filter_mode, &num_bases); + sorted_bases = animdata_filter_ds_sorted_bases(ads, view_layer, filter_mode, &num_bases); if (sorted_bases) { /* Add the necessary channels for these bases... */ for (size_t i = 0; i < num_bases; i++) { @@ -3014,8 +3016,8 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, b /* Filter and add contents of each base (i.e. object) without them sorting first * NOTE: This saves performance in cases where order doesn't matter */ - for (Base *base = scene->base.first; base; base = base->next) { - if (animdata_filter_base_is_ok(ads, scene, base, filter_mode)) { + for (Base *base = view_layer->object_bases.first; base; base = base->next) { + if (animdata_filter_base_is_ok(ads, base, filter_mode)) { /* since we're still here, this object should be usable */ items += animdata_filter_dopesheet_ob(ac, anim_data, ads, base, filter_mode); } @@ -3258,6 +3260,15 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_F } + /* Timeline Mode - Basically the same as dopesheet, except we only have the summary for now */ + case ANIMCONT_TIMELINE: + { + /* the DopeSheet editor is the primary place where the DopeSheet summaries are useful */ + if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items)) + items += animdata_filter_dopesheet(ac, anim_data, data, filter_mode); + break; + } + /* Special/Internal Use */ case ANIMCONT_CHANNEL: /* animation channel */ { |