diff options
Diffstat (limited to 'source/blender/editors/animation/anim_filter.c')
-rw-r--r-- | source/blender/editors/animation/anim_filter.c | 158 |
1 files changed, 86 insertions, 72 deletions
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index fdfe08e03b6..5f23762386e 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -72,8 +72,10 @@ #include "DNA_speaker_types.h" #include "DNA_world_types.h" #include "DNA_gpencil_types.h" +#include "DNA_brush_types.h" #include "DNA_object_types.h" #include "DNA_userdef_types.h" +#include "DNA_layer_types.h" #include "MEM_guardedalloc.h" @@ -83,13 +85,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 +133,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 +231,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 +242,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 +406,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; @@ -1194,7 +1222,7 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, eAnim_Chan /* only include if this curve is active */ if (!(filter_mode & ANIMFILTER_ACTIVE) || (fcu->flag & FCURVE_ACTIVE)) { /* name based filtering... */ - if ( ((ads) && (ads->filterflag & ADS_FILTER_BY_FCU_NAME)) && (owner_id) ) { + if ( ((ads) && (ads->searchstr[0] != '\0')) && (owner_id) ) { if (skip_fcurve_with_name(ads, fcu, channel_type, owner, owner_id)) continue; } @@ -1426,7 +1454,7 @@ static size_t animfilter_nla(bAnimContext *UNUSED(ac), ListBase *anim_data, bDop /* only include if this track is active */ if (!(filter_mode & ANIMFILTER_ACTIVE) || (nlt->flag & NLATRACK_ACTIVE)) { /* name based filtering... */ - if (((ads) && (ads->filterflag & ADS_FILTER_BY_FCU_NAME)) && (owner_id)) { + if (((ads) && (ads->searchstr[0] != '\0')) && (owner_id)) { bool track_ok = false, strip_ok = false; /* check if the name of the track, or the strips it has are ok... */ @@ -1597,8 +1625,8 @@ static size_t animdata_filter_gpencil_layers_data(ListBase *anim_data, bDopeShee bGPDlayer *gpl; size_t items = 0; - /* loop over layers as the conditions are acceptable */ - for (gpl = gpd->layers.first; gpl; gpl = gpl->next) { + /* loop over layers as the conditions are acceptable (top-Down order) */ + for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) { /* only if selected */ if (ANIMCHANNEL_SELOK(SEL_GPL(gpl)) ) { /* only if editable */ @@ -1606,7 +1634,7 @@ static size_t animdata_filter_gpencil_layers_data(ListBase *anim_data, bDopeShee /* active... */ if (!(filter_mode & ANIMFILTER_ACTIVE) || (gpl->flag & GP_LAYER_ACTIVE)) { /* skip layer if the name doesn't match the filter string */ - if ((ads) && (ads->filterflag & ADS_FILTER_BY_FCU_NAME)) { + if ((ads) && (ads->searchstr[0] != '\0')) { if (name_matches_dopesheet_filter(ads, gpl->info) == false) continue; } @@ -1633,7 +1661,7 @@ static size_t animdata_filter_gpencil_data(ListBase *anim_data, bDopeSheet *ads, */ if (filter_mode & ANIMFILTER_ANIMDATA) { /* just add GPD as a channel - this will add everything needed */ - ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, NULL); + ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, gpd); } else { ListBase tmp_data = {NULL, NULL}; @@ -1673,6 +1701,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,9 +1710,9 @@ 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) { + if (base->object && (base->object->type == OB_GPENCIL)) { Object *ob = base->object; /* firstly, check if object can be included, by the following factors: @@ -1697,14 +1726,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_VISIBLE) == 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; } @@ -1713,14 +1742,14 @@ static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, voi * objects by the grouped status is on * - 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 (ads->filter_grp != NULL) { + if (BKE_collection_has_object_recursive(ads->filter_grp, ob) == 0) continue; } /* finally, include this object's grease pencil datablock */ /* XXX: Should we store these under expanders per item? */ - items += animdata_filter_gpencil_data(anim_data, ads, ob->gpd, filter_mode); + items += animdata_filter_gpencil_data(anim_data, ads, ob->data, filter_mode); } } } @@ -1944,25 +1973,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 +2077,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 +2091,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 +2135,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 +2453,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; } } @@ -2608,8 +2614,10 @@ static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data } /* grease pencil */ - if ((ob->gpd) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) { - tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, ob->gpd, filter_mode); + if ((ob->type == OB_GPENCIL) && + (ob->data) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) + { + tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, ob->data, filter_mode); } } END_ANIMFILTER_SUBCHANNELS; @@ -2621,7 +2629,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 +2659,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 +2849,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 +2867,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_VISIBLE) == 0) return false; /* outliner restrict-flag */ @@ -2898,7 +2902,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; } @@ -2907,8 +2911,8 @@ static bool animdata_filter_base_is_ok(bDopeSheet *ads, Scene *scene, Base *base * objects by the grouped status is on * - 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 (ads->filter_grp != NULL) { + if (BKE_collection_has_object_recursive(ads->filter_grp, ob) == 0) return false; } @@ -2926,15 +2930,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 +2956,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 +2995,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 +3019,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 +3263,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 */ { |