Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2008-12-21 07:11:19 +0300
committerJoshua Leung <aligorith@gmail.com>2008-12-21 07:11:19 +0300
commite2cca3320ac9e32c9f5ad51e1c6de1d049aa5b98 (patch)
treece60a42269481d7b2bdd87d9f0859ef681d53d27
parent62f4d2884c5d0a99cc84f23af29f9aea7977dd4d (diff)
2.5 - Animation Editors - Filtering API
Brought back the Filtering API for Animation Editors. This is the 'backbone' of the current Action/Dopesheet Editor code, so it is essential to have this working.
-rw-r--r--source/blender/editors/animation/anim_filter.c984
-rw-r--r--source/blender/editors/animation/anim_keyframing.c14
-rw-r--r--source/blender/editors/include/ED_anim_api.h62
-rw-r--r--source/blender/editors/include/ED_keyframing.h10
4 files changed, 1040 insertions, 30 deletions
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index edd89ac7f2f..19dafc439dc 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -26,16 +26,21 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/* This file defines the system for filtering data into a form suitable for
- * use by the Animation Editors, thus acting as a means by which the Animation
- * Editors maintain a level of abstraction from the data they actually manipulate.
- * Thus, they only need to check on the type of the data they're manipulating, and
- * NOT worry about various layers of context/hierarchy checks.
+/* This file contains a system used to provide a layer of abstraction between sources
+ * of animation data and tools in Animation Editors. The method used here involves
+ * generating a list of edit structures which enable tools to naively perform the actions
+ * they require without all the boiler-plate associated with loops within loops and checking
+ * for cases to ignore.
*
* While this is primarily used for the Action/Dopesheet Editor (and its accessory modes),
* the IPO Editor also uses this for it's channel list and for determining which curves
* are being edited.
*
+ * Note: much of the original system this was based on was built before the creation of the RNA
+ * system. In future, it would be interesting to replace some parts of this code with RNA queries,
+ * however, RNA does not eliminate some of the boiler-plate reduction benefits presented by this
+ * system, so if any such work does occur, it should only be used for the internals used here...
+ *
* -- Joshua Leung, Dec 2008
*/
@@ -45,11 +50,15 @@
#include "DNA_listBase.h"
#include "DNA_ID.h"
#include "DNA_action_types.h"
+#include "DNA_constraint_types.h"
#include "DNA_camera_types.h"
#include "DNA_curve_types.h"
+#include "DNA_gpencil_types.h"
#include "DNA_ipo_types.h"
+#include "DNA_lamp_types.h"
#include "DNA_lattice_types.h"
#include "DNA_key_types.h"
+#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_object_types.h"
#include "DNA_space_types.h"
@@ -63,6 +72,9 @@
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_key.h"
+#include "BKE_object.h"
+#include "BKE_material.h"
#include "BKE_screen.h"
#include "BKE_utildefines.h"
@@ -97,7 +109,7 @@ Key *actedit_get_shapekeys (const bContext *C, SpaceAction *saction)
if (ob == NULL)
return NULL;
- /* pinning is not available in 'ShapeKey' mode... */
+ /* XXX pinning is not available in 'ShapeKey' mode... */
//if (saction->pin) return NULL;
/* shapekey data is stored with geometry data */
@@ -215,6 +227,958 @@ void *ANIM_animdata_get_context (const bContext *C, short *datatype)
/* ----------- 'Private' Stuff --------------- */
+/* this function allocates memory for a new bAnimListElem struct for the
+ * provided animation channel-data.
+ */
+bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, short ownertype)
+{
+ bAnimListElem *ale= NULL;
+
+ /* only allocate memory if there is data to convert */
+ if (data) {
+ /* allocate and set generic data */
+ ale= MEM_callocN(sizeof(bAnimListElem), "bAnimListElem");
+
+ ale->data= data;
+ ale->type= datatype;
+ ale->owner= owner;
+ ale->ownertype= ownertype;
+
+ if ((owner) && (ownertype == ANIMTYPE_ACHAN)) {
+ bActionChannel *ochan= (bActionChannel *)owner;
+ ale->grp= ochan->grp;
+ }
+ else
+ ale->grp= NULL;
+
+ /* do specifics */
+ switch (datatype) {
+ case ANIMTYPE_OBJECT:
+ {
+ Base *base= (Base *)data;
+ Object *ob= base->object;
+
+ ale->flag= ob->flag;
+
+ ale->key_data= ob;
+ ale->datatype= ALE_OB;
+ }
+ break;
+ case ANIMTYPE_FILLACTD:
+ {
+ bAction *act= (bAction *)data;
+
+ ale->flag= act->flag;
+
+ ale->key_data= act;
+ ale->datatype= ALE_ACT;
+ }
+ break;
+ case ANIMTYPE_FILLIPOD:
+ {
+ Object *ob= (Object *)data;
+
+ ale->flag= FILTER_IPO_OBJC(ob);
+
+ ale->key_data= ob->ipo;
+ ale->datatype= ALE_IPO;
+ }
+ break;
+ case ANIMTYPE_FILLCOND:
+ {
+ Object *ob= (Object *)data;
+
+ ale->flag= FILTER_CON_OBJC(ob);
+
+ ale->key_data= NULL;
+ ale->datatype= ALE_NONE;
+ }
+ break;
+ case ANIMTYPE_FILLMATD:
+ {
+ Object *ob= (Object *)data;
+
+ ale->flag= FILTER_MAT_OBJC(ob);
+
+ ale->key_data= NULL;
+ ale->datatype= ALE_NONE;
+ }
+ break;
+
+ case ANIMTYPE_DSMAT:
+ {
+ Material *ma= (Material *)data;
+
+ ale->flag= FILTER_MAT_OBJD(ma);
+
+ ale->key_data= ma->ipo;
+ ale->datatype= ALE_IPO;
+ }
+ break;
+ case ANIMTYPE_DSLAM:
+ {
+ Lamp *la= (Lamp *)data;
+
+ ale->flag= FILTER_LAM_OBJD(la);
+
+ ale->key_data= la->ipo;
+ ale->datatype= ALE_IPO;
+ }
+ break;
+ case ANIMTYPE_DSCAM:
+ {
+ Camera *ca= (Camera *)data;
+
+ ale->flag= FILTER_CAM_OBJD(ca);
+
+ ale->key_data= ca->ipo;
+ ale->datatype= ALE_IPO;
+ }
+ break;
+ case ANIMTYPE_DSCUR:
+ {
+ Curve *cu= (Curve *)data;
+
+ ale->flag= FILTER_CUR_OBJD(cu);
+
+ ale->key_data= cu->ipo;
+ ale->datatype= ALE_IPO;
+ }
+ break;
+ case ANIMTYPE_DSSKEY:
+ {
+ Key *key= (Key *)data;
+
+ ale->flag= FILTER_SKE_OBJD(key);
+
+ ale->key_data= key->ipo;
+ ale->datatype= ALE_IPO;
+ }
+ break;
+
+ case ANIMTYPE_GROUP:
+ {
+ bActionGroup *agrp= (bActionGroup *)data;
+
+ ale->flag= agrp->flag;
+
+ ale->key_data= NULL;
+ ale->datatype= ALE_GROUP;
+ }
+ break;
+ case ANIMTYPE_ACHAN:
+ {
+ bActionChannel *achan= (bActionChannel *)data;
+
+ ale->flag= achan->flag;
+
+ if (achan->ipo) {
+ ale->key_data= achan->ipo;
+ ale->datatype= ALE_IPO;
+ }
+ else {
+ ale->key_data= NULL;
+ ale->datatype= ALE_NONE;
+ }
+ }
+ break;
+ case ANIMTYPE_CONCHAN:
+ case ANIMTYPE_CONCHAN2:
+ {
+ bConstraintChannel *conchan= (bConstraintChannel *)data;
+
+ ale->flag= conchan->flag;
+
+ if (datatype == ANIMTYPE_CONCHAN2) {
+ /* CONCHAN2 is a hack so that constraint-channels keyframes can be edited */
+ if (conchan->ipo) {
+ ale->key_data= conchan->ipo;
+ ale->datatype= ALE_IPO;
+ }
+ else {
+ ale->key_data= NULL;
+ ale->datatype= ALE_NONE;
+ }
+ }
+ else {
+ if ((conchan->ipo) && (conchan->ipo->curve.first)) {
+ /* we assume that constraint ipo blocks only have 1 curve:
+ * INFLUENCE, so we pretend that a constraint channel is
+ * really just a Ipo-Curve channel instead.
+ */
+ ale->key_data= conchan->ipo->curve.first;
+ ale->datatype= ALE_ICU;
+ }
+ else {
+ ale->key_data= NULL;
+ ale->datatype= ALE_NONE;
+ }
+ }
+ }
+ break;
+ case ANIMTYPE_ICU:
+ {
+ IpoCurve *icu= (IpoCurve *)data;
+
+ ale->flag= icu->flag;
+ ale->key_data= icu;
+ ale->datatype= ALE_ICU;
+ }
+ break;
+ case ANIMTYPE_FILLIPO:
+ case ANIMTYPE_FILLCON:
+ {
+ bActionChannel *achan= (bActionChannel *)data;
+
+ if (datatype == ANIMTYPE_FILLIPO)
+ ale->flag= FILTER_IPO_ACHAN(achan);
+ else
+ ale->flag= FILTER_CON_ACHAN(achan);
+
+ ale->key_data= NULL;
+ ale->datatype= ALE_NONE;
+ }
+ break;
+ case ANIMTYPE_IPO:
+ {
+ ale->flag= 0;
+ ale->key_data= data;
+ ale->datatype= ALE_IPO;
+ }
+ break;
+
+ case ANIMTYPE_GPLAYER:
+ {
+ bGPDlayer *gpl= (bGPDlayer *)data;
+
+ ale->flag= gpl->flag;
+
+ ale->key_data= NULL;
+ ale->datatype= ALE_GPFRAME;
+ }
+ break;
+ }
+ }
+
+ /* return created datatype */
+ return ale;
+}
+
+/* ----------------------------------------- */
+
+static void animdata_filter_animionchannel (ListBase *anim_data, bActionChannel *achan, int filter_mode, void *owner, short ownertype)
+{
+ bAnimListElem *ale = NULL;
+ bConstraintChannel *conchan;
+ IpoCurve *icu;
+ short owned= (owner && ownertype)? 1 : 0;
+
+ /* only work with this channel and its subchannels if it is visible */
+ if (!(filter_mode & ANIMFILTER_VISIBLE) || VISIBLE_ACHAN(achan)) {
+ /* only work with this channel and its subchannels if it is editable */
+ if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_ACHAN(achan)) {
+ /* check if this achan should only be included if it is selected */
+ if (!(filter_mode & ANIMFILTER_SEL) || SEL_ACHAN(achan)) {
+ /* are we only interested in the ipo-curves? */
+ if ((filter_mode & ANIMFILTER_ONLYICU)==0) {
+ ale= make_new_animlistelem(achan, ANIMTYPE_ACHAN, achan, ANIMTYPE_ACHAN);
+
+ if (ale) {
+ if (owned) ale->id= owner;
+ BLI_addtail(anim_data, ale);
+ }
+ }
+ }
+ else {
+ /* for insert key... this check could be improved */
+ return;
+ }
+
+ /* check if expanded - if not, continue on to next animion channel */
+ if (EXPANDED_ACHAN(achan) == 0 && (filter_mode & ANIMFILTER_ONLYICU)==0) {
+ /* only exit if we don't need to include constraint channels for group-channel keyframes */
+ if ( !(filter_mode & ANIMFILTER_IPOKEYS) || (achan->grp == NULL) || (EXPANDED_AGRP(achan->grp)==0) )
+ return;
+ }
+
+ /* ipo channels */
+ if ((achan->ipo) && (filter_mode & ANIMFILTER_IPOKEYS)==0) {
+ /* include ipo-expand widget? */
+ if ((filter_mode & ANIMFILTER_CHANNELS) && (filter_mode & ANIMFILTER_ONLYICU)==0) {
+ ale= make_new_animlistelem(achan, ANIMTYPE_FILLIPO, achan, ANIMTYPE_ACHAN);
+
+ if (ale) {
+ if (owned) ale->id= owner;
+ BLI_addtail(anim_data, ale);
+ }
+ }
+
+ /* add ipo-curve channels? */
+ if (FILTER_IPO_ACHAN(achan) || (filter_mode & ANIMFILTER_ONLYICU)) {
+ /* loop through ipo-curve channels, adding them */
+ for (icu= achan->ipo->curve.first; icu; icu=icu->next) {
+ ale= make_new_animlistelem(icu, ANIMTYPE_ICU, achan, ANIMTYPE_ACHAN);
+
+ if (ale) {
+ if (owned) ale->id= owner;
+ BLI_addtail(anim_data, ale);
+ }
+ }
+ }
+ }
+
+ /* constraint channels */
+ if (achan->constraintChannels.first) {
+ /* include constraint-expand widget? */
+ if ( (filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_ONLYICU)
+ && !(filter_mode & ANIMFILTER_IPOKEYS) )
+ {
+ ale= make_new_animlistelem(achan, ANIMTYPE_FILLCON, achan, ANIMTYPE_ACHAN);
+
+ if (ale) {
+ if (owned) ale->id= owner;
+ BLI_addtail(anim_data, ale);
+ }
+ }
+
+ /* add constraint channels? */
+ if (FILTER_CON_ACHAN(achan) || (filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYICU)) {
+ /* loop through constraint channels, checking and adding them */
+ for (conchan=achan->constraintChannels.first; conchan; conchan=conchan->next) {
+ /* only work with this channel and its subchannels if it is editable */
+ if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_CONCHAN(conchan)) {
+ /* check if this conchan should only be included if it is selected */
+ if (!(filter_mode & ANIMFILTER_SEL) || SEL_CONCHAN(conchan)) {
+ if (filter_mode & ANIMFILTER_IPOKEYS) {
+ if (ale) BLI_addtail(anim_data, ale);
+ ale= make_new_animlistelem(conchan, ANIMTYPE_CONCHAN2, achan, ANIMTYPE_ACHAN);
+
+ if (ale) {
+ if (owned) ale->id= owner;
+ BLI_addtail(anim_data, ale);
+ }
+ }
+ else {
+ ale= make_new_animlistelem(conchan, ANIMTYPE_CONCHAN, achan, ANIMTYPE_ACHAN);
+
+ if (ale) {
+ if (owned) ale->id= owner;
+ BLI_addtail(anim_data, ale);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+static void animdata_filter_action (ListBase *anim_data, bAction *act, int filter_mode, void *owner, short ownertype)
+{
+ bAnimListElem *ale=NULL;
+ bActionGroup *agrp;
+ bActionChannel *achan, *lastchan=NULL;
+ short owned= (owner && ownertype) ? 1 : 0;
+
+ /* loop over groups */
+ for (agrp= act->groups.first; agrp; agrp= agrp->next) {
+ /* add this group as a channel first */
+ if (!(filter_mode & ANIMFILTER_ONLYICU) && !(filter_mode & ANIMFILTER_IPOKEYS)) {
+ /* check if filtering by selection */
+ if ( !(filter_mode & ANIMFILTER_SEL) || SEL_AGRP(agrp) ) {
+ ale= make_new_animlistelem(agrp, ANIMTYPE_GROUP, NULL, ANIMTYPE_NONE);
+ if (ale) {
+ if (owned) ale->id= owner;
+ BLI_addtail(anim_data, ale);
+ }
+ }
+ }
+
+ /* store reference to last channel of group */
+ if (agrp->channels.last)
+ lastchan= agrp->channels.last;
+
+
+ /* there are some situations, where only the channels of the animive group should get considered */
+ if (!(filter_mode & ANIMFILTER_ACTGROUPED) || (agrp->flag & AGRP_ACTIVE)) {
+ /* filters here are a bit convoulted...
+ * - groups show a "summary" of keyframes beside their name which must accessable for tools which handle keyframes
+ * - groups can be collapsed (and those tools which are only interested in channels rely on knowing that group is closed)
+ *
+ * cases when we should include animion-channels and so-forth inside group:
+ * - we don't care about visibility
+ * - group is expanded
+ * - we're interested in keyframes, but not if they appear in selected channels
+ */
+ if ( (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_AGRP(agrp)) ||
+ ( ((filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYICU)) &&
+ (!(filter_mode & ANIMFILTER_SEL) || (SEL_AGRP(agrp))) ) )
+ {
+ if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) {
+ for (achan= agrp->channels.first; achan && achan->grp==agrp; achan= achan->next) {
+ animdata_filter_animionchannel(anim_data, achan, filter_mode, owner, ownertype);
+ }
+
+ /* remove group from filtered list if last element is group
+ * (i.e. only if group had channels, which were all hidden)
+ */
+ // XXX this is really hacky... it should be fixed in a much more elegant way!
+ if ( (ale) && (anim_data->last == ale) &&
+ (ale->data == agrp) && (agrp->channels.first) )
+ {
+ BLI_freelinkN(anim_data, ale);
+ }
+ }
+ }
+ }
+ }
+
+ /* loop over un-grouped animion channels (only if we're not only considering those channels in the animive group) */
+ if (!(filter_mode & ANIMFILTER_ACTGROUPED)) {
+ for (achan=(lastchan)?lastchan->next:act->chanbase.first; achan; achan=achan->next) {
+ animdata_filter_animionchannel(anim_data, achan, filter_mode, owner, ownertype);
+ }
+ }
+}
+
+static void animdata_filter_shapekey (ListBase *anim_data, Key *key, int filter_mode, void *owner, short ownertype)
+{
+ bAnimListElem *ale;
+ KeyBlock *kb;
+ IpoCurve *icu;
+ short owned= (owner && ownertype)? 1 : 0;
+ int i;
+
+ /* are we filtering for display or editing */
+ if (filter_mode & ANIMFILTER_FORDRAWING) {
+ /* for display - loop over shapekeys, adding ipo-curve references where needed */
+ kb= key->block.first;
+
+ /* loop through possible shapekeys, manually creating entries */
+ for (i= 1; i < key->totkey; i++) {
+ ale= MEM_callocN(sizeof(bAnimListElem), "bAnimListElem");
+ kb = kb->next; /* do this even on the first try, as the first is 'Basis' (which doesn't get included) */
+
+ ale->data= kb;
+ ale->type= ANIMTYPE_SHAPEKEY; /* 'abused' usage of this type */
+ ale->owner= key;
+ ale->ownertype= ANIMTYPE_SHAPEKEY;
+ ale->datatype= ALE_NONE;
+ ale->index = i;
+
+ if (key->ipo) {
+ for (icu= key->ipo->curve.first; icu; icu=icu->next) {
+ if (icu->adrcode == i) {
+ ale->key_data= icu;
+ ale->datatype= ALE_ICU;
+ break;
+ }
+ }
+ }
+
+ if (owned) ale->id= owner;
+
+ BLI_addtail(anim_data, ale);
+ }
+ }
+ else {
+ /* loop over ipo curves if present - for editing */
+ if (key->ipo) {
+ if (filter_mode & ANIMFILTER_IPOKEYS) {
+ ale= make_new_animlistelem(key->ipo, ANIMTYPE_IPO, key, ANIMTYPE_SHAPEKEY);
+ if (ale) {
+ if (owned) ale->id= owner;
+ BLI_addtail(anim_data, ale);
+ }
+ }
+ else {
+ for (icu= key->ipo->curve.first; icu; icu=icu->next) {
+ ale= make_new_animlistelem(icu, ANIMTYPE_ICU, key, ANIMTYPE_SHAPEKEY);
+ if (ale) {
+ if (owned) ale->id= owner;
+ BLI_addtail(anim_data, ale);
+ }
+ }
+ }
+ }
+ }
+}
+
+#if 0
+// FIXME: switch this to use the bDopeSheet...
+static void animdata_filter_gpencil (ListBase *anim_data, bScreen *sc, int filter_mode)
+{
+ bAnimListElem *ale;
+ ScrArea *sa, *curarea;
+ bGPdata *gpd;
+ bGPDlayer *gpl;
+
+ /* check if filtering types are appropriate */
+ if ( !(filter_mode & (ANIMFILTER_IPOKEYS|ANIMFILTER_ONLYICU|ANIMFILTER_ACTGROUPED)) )
+ {
+ /* special hack for fullscreen area (which must be this one then):
+ * - we use the curarea->full as screen to get spaces from, since the
+ * old (pre-fullscreen) screen was stored there...
+ * - this is needed as all data would otherwise disappear
+ */
+ // XXX need to get new alternative for curarea
+ if ((curarea->full) && (curarea->spacetype==SPACE_ACTION))
+ sc= curarea->full;
+
+ /* loop over spaces in current screen, finding gpd blocks (could be slow!) */
+ for (sa= sc->areabase.first; sa; sa= sa->next) {
+ /* try to get gp data */
+ // XXX need to put back grease pencil api...
+ gpd= gpencil_data_getactive(sa);
+ if (gpd == NULL) continue;
+
+ /* add gpd as channel too (if for drawing, and it has layers) */
+ if ((filter_mode & ANIMFILTER_FORDRAWING) && (gpd->layers.first)) {
+ /* add to list */
+ ale= make_new_animlistelem(gpd, ANIMTYPE_GPDATABLOCK, sa, ANIMTYPE_SPECIALDATA);
+ if (ale) BLI_addtail(anim_data, ale);
+ }
+
+ /* only add layers if they will be visible (if drawing channels) */
+ if ( !(filter_mode & ANIMFILTER_VISIBLE) || (EXPANDED_GPD(gpd)) ) {
+ /* loop over layers as the conditions are acceptable */
+ for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
+ /* only if selected */
+ if (!(filter_mode & ANIMFILTER_SEL) || SEL_GPL(gpl)) {
+ /* only if editable */
+ if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_GPL(gpl)) {
+ /* add to list */
+ ale= make_new_animlistelem(gpl, ANIMTYPE_GPLAYER, gpd, ANIMTYPE_GPDATABLOCK);
+ if (ale) BLI_addtail(anim_data, ale);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+#endif
+
+static void animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
+{
+ bAnimListElem *ale=NULL;
+ Object *ob= base->object;
+ IpoCurve *icu;
+
+ /* include materials-expand widget? */
+ if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & (ANIMFILTER_IPOKEYS|ANIMFILTER_ONLYICU))) {
+ ale= make_new_animlistelem(ob, ANIMTYPE_FILLMATD, base, ANIMTYPE_OBJECT);
+ if (ale) BLI_addtail(anim_data, ale);
+ }
+
+ /* add materials? */
+ if (FILTER_MAT_OBJC(ob) || (filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYICU)) {
+ short a;
+
+ /* for each material, either add channels separately, or as ipo-block */
+ for (a=0; a<ob->totcol; a++) {
+ Material *ma= give_current_material(ob, a);
+
+ /* for now, if no material returned, skip (this shouldn't confuse the user I hope) */
+ if (ELEM(NULL, ma, ma->ipo)) continue;
+
+ /* include material-expand widget? */
+ // hmm... do we need to store the index of this material in the array anywhere?
+ if (filter_mode & (ANIMFILTER_CHANNELS|ANIMFILTER_IPOKEYS)) {
+ ale= make_new_animlistelem(ma, ANIMTYPE_DSMAT, base, ANIMTYPE_OBJECT);
+ if (ale) BLI_addtail(anim_data, ale);
+ }
+
+ /* add material's ipo-curve channels? */
+ if ( (FILTER_MAT_OBJD(ma) || (filter_mode & ANIMFILTER_ONLYICU)) &&
+ !(filter_mode & ANIMFILTER_IPOKEYS) )
+ {
+ /* loop through ipo-curve channels, adding them */
+ for (icu= ma->ipo->curve.first; icu; icu=icu->next) {
+ /* only if selected (if checking for selection) */
+ if ( !(filter_mode & ANIMFILTER_SEL) || (SEL_ICU(icu)) ) {
+ ale= make_new_animlistelem(icu, ANIMTYPE_ICU, base, ANIMTYPE_OBJECT);
+ if (ale) {
+ /* make owner the material not object, so that indent is not just object level */
+ ale->id= (ID *)ma;
+ BLI_addtail(anim_data, ale);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+static void animdata_filter_dopesheet_cam (ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
+{
+ bAnimListElem *ale=NULL;
+ Object *ob= base->object;
+ Camera *ca= (Camera *)ob->data;
+ IpoCurve *icu;
+
+ /* include camera-expand widget? */
+ if (filter_mode & (ANIMFILTER_CHANNELS|ANIMFILTER_IPOKEYS)) {
+ ale= make_new_animlistelem(ca, ANIMTYPE_DSCAM, base, ANIMTYPE_OBJECT);
+ if (ale) BLI_addtail(anim_data, ale);
+ }
+
+ /* add camera ipo-curve channels? */
+ if ( (FILTER_CAM_OBJD(ca) || (filter_mode & ANIMFILTER_ONLYICU)) &&
+ !(filter_mode & ANIMFILTER_IPOKEYS) )
+ {
+ /* loop through ipo-curve channels, adding them */
+ for (icu= ca->ipo->curve.first; icu; icu=icu->next) {
+ /* only if selected (if checking for selection) */
+ if ( !(filter_mode & ANIMFILTER_SEL) || (SEL_ICU(icu)) ) {
+ ale= make_new_animlistelem(icu, ANIMTYPE_ICU, base, ANIMTYPE_OBJECT);
+ if (ale) {
+ /* make owner the material not object, so that indent is not just object level */
+ ale->id= (ID *)ca;
+ BLI_addtail(anim_data, ale);
+ }
+ }
+ }
+ }
+}
+
+static void animdata_filter_dopesheet_lamp (ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
+{
+ bAnimListElem *ale=NULL;
+ Object *ob= base->object;
+ Lamp *la= (Lamp *)ob->data;
+ IpoCurve *icu;
+
+ /* include lamp-expand widget? */
+ if (filter_mode & (ANIMFILTER_CHANNELS|ANIMFILTER_IPOKEYS)) {
+ ale= make_new_animlistelem(la, ANIMTYPE_DSLAM, base, ANIMTYPE_OBJECT);
+ if (ale) BLI_addtail(anim_data, ale);
+ }
+
+ /* add lamp ipo-curve channels? */
+ if ( (FILTER_LAM_OBJD(la) || (filter_mode & ANIMFILTER_ONLYICU)) &&
+ !(filter_mode & ANIMFILTER_IPOKEYS) )
+ {
+ /* loop through ipo-curve channels, adding them */
+ for (icu= la->ipo->curve.first; icu; icu=icu->next) {
+ /* only if selected (if checking for selection) */
+ if ( !(filter_mode & ANIMFILTER_SEL) || (SEL_ICU(icu)) ) {
+ ale= make_new_animlistelem(icu, ANIMTYPE_ICU, base, ANIMTYPE_OBJECT);
+ if (ale) {
+ /* make owner the material not object, so that indent is not just object level */
+ ale->id= (ID *)la;
+ BLI_addtail(anim_data, ale);
+ }
+ }
+ }
+ }
+}
+
+static void animdata_filter_dopesheet_curve (ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
+{
+ bAnimListElem *ale=NULL;
+ Object *ob= base->object;
+ Curve *cu= (Curve *)ob->data;
+ IpoCurve *icu;
+
+ /* include curve-expand widget? */
+ if (filter_mode & (ANIMFILTER_CHANNELS|ANIMFILTER_IPOKEYS)) {
+ ale= make_new_animlistelem(cu, ANIMTYPE_DSCUR, base, ANIMTYPE_OBJECT);
+ if (ale) BLI_addtail(anim_data, ale);
+ }
+
+ /* add curve ipo-curve channels? */
+ if ( (FILTER_CUR_OBJD(cu) || (filter_mode & ANIMFILTER_ONLYICU)) &&
+ !(filter_mode & ANIMFILTER_IPOKEYS) )
+ {
+ /* loop through ipo-curve channels, adding them */
+ for (icu= cu->ipo->curve.first; icu; icu=icu->next) {
+ /* only if selected (if checking for selection) */
+ if ( !(filter_mode & ANIMFILTER_SEL) || (SEL_ICU(icu)) ) {
+ ale= make_new_animlistelem(icu, ANIMTYPE_ICU, base, ANIMTYPE_OBJECT);
+ if (ale) {
+ /* make owner the material not object, so that indent is not just object level */
+ ale->id= (ID *)cu;
+ BLI_addtail(anim_data, ale);
+ }
+ }
+ }
+ }
+}
+
+static void animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
+{
+ bAnimListElem *ale=NULL;
+ Scene *sce= (Scene *)ads->source;
+ Object *ob= base->object;
+ Key *key= ob_get_key(ob);
+ IpoCurve *icu;
+
+ /* add this object as a channel first */
+ if (!(filter_mode & ANIMFILTER_ONLYICU) && !(filter_mode & ANIMFILTER_IPOKEYS)) {
+ /* check if filtering by selection */
+ if ( !(filter_mode & ANIMFILTER_SEL) || ((base->flag & SELECT) || (base == sce->basact)) ) {
+ ale= make_new_animlistelem(base, ANIMTYPE_OBJECT, NULL, ANIMTYPE_NONE);
+ if (ale) BLI_addtail(anim_data, ale);
+ }
+ }
+
+ /* if collapsed, don't go any further (unless adding keyframes only) */
+ if ( (EXPANDED_OBJC(ob) == 0) && !(filter_mode & (ANIMFILTER_IPOKEYS|ANIMFILTER_ONLYICU)) )
+ return;
+
+ /* IPO? */
+ if ((ob->ipo) && !(ads->filterflag & ADS_FILTER_NOIPOS)) {
+ /* include ipo-expand widget? */
+ if (filter_mode & (ANIMFILTER_CHANNELS|ANIMFILTER_IPOKEYS)) {
+ ale= make_new_animlistelem(ob, ANIMTYPE_FILLIPOD, base, ANIMTYPE_OBJECT);
+ if (ale) BLI_addtail(anim_data, ale);
+ }
+
+ /* add ipo-curve channels? */
+ if ( (FILTER_IPO_OBJC(ob) || (filter_mode & ANIMFILTER_ONLYICU)) &&
+ !(filter_mode & ANIMFILTER_IPOKEYS) )
+ {
+ /* loop through ipo-curve channels, adding them */
+ for (icu= ob->ipo->curve.first; icu; icu=icu->next) {
+ /* only if selected (if checking for selection) */
+ if ( !(filter_mode & ANIMFILTER_SEL) || (SEL_ICU(icu)) ) {
+ ale= make_new_animlistelem(icu, ANIMTYPE_ICU, base, ANIMTYPE_OBJECT);
+ if (ale) BLI_addtail(anim_data, ale);
+ }
+ }
+ }
+ }
+
+ /* Action? */
+ if ((ob->action) && !(ads->filterflag & ADS_FILTER_NOACTS)) {
+ /* include animion-expand widget? */
+ if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & (ANIMFILTER_IPOKEYS|ANIMFILTER_ONLYICU))) {
+ ale= make_new_animlistelem(ob->action, ANIMTYPE_FILLACTD, base, ANIMTYPE_OBJECT);
+ if (ale) {
+ ale->id= (ID *)ob; // err.... is this a good idea?
+ BLI_addtail(anim_data, ale);
+ }
+ }
+
+ /* add ipo-curve channels? */
+ if (EXPANDED_ACTC(ob->action) || !(filter_mode & (ANIMFILTER_CHANNELS|ANIMFILTER_FORDRAWING))) {
+ // need to make the ownertype normal object here... (maybe type should be a separate one for clarity?)
+ animdata_filter_action(anim_data, ob->action, filter_mode, ob, ANIMTYPE_OBJECT);
+ }
+ }
+
+ /* ShapeKeys? */
+ if ((key) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS)) {
+ /* include shapekey-expand widget? */
+ if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & (ANIMFILTER_IPOKEYS|ANIMFILTER_ONLYICU))) {
+ ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT);
+ if (ale) BLI_addtail(anim_data, ale);
+ }
+
+ /* add channels */
+ if (FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYICU)) {
+ animdata_filter_shapekey (anim_data, key, filter_mode, ob, ANIMTYPE_OBJECT);
+ }
+ }
+
+ /* Materials? */
+ if ((ob->totcol) && !(ads->filterflag & ADS_FILTER_NOMAT))
+ animdata_filter_dopesheet_mats(anim_data, ads, base, filter_mode);
+
+ /* Object Data */
+ switch (ob->type) {
+ case OB_CAMERA: /* ------- Camera ------------ */
+ {
+ Camera *ca= (Camera *)ob->data;
+ if ((ca->ipo) && !(ads->filterflag & ADS_FILTER_NOCAM))
+ animdata_filter_dopesheet_cam(anim_data, ads, base, filter_mode);
+ }
+ break;
+ case OB_LAMP: /* ---------- Lamp ----------- */
+ {
+ Lamp *la= (Lamp *)ob->data;
+ if ((la->ipo) && !(ads->filterflag & ADS_FILTER_NOLAM))
+ animdata_filter_dopesheet_lamp(anim_data, ads, base, filter_mode);
+ }
+ break;
+ case OB_CURVE: /* ------- Curve ---------- */
+ {
+ Curve *cu= (Curve *)ob->data;
+ if ((cu->ipo) && !(ads->filterflag & ADS_FILTER_NOCUR))
+ animdata_filter_dopesheet_curve(anim_data, ads, base, filter_mode);
+ }
+ break;
+ }
+
+ /* Constraint Channels? */
+ if ((ob->constraintChannels.first) && !(ads->filterflag & ADS_FILTER_NOCONSTRAINTS)) {
+ bConstraintChannel *conchan;
+
+ /* include constraint-expand widget? */
+ if ( (filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_ONLYICU)
+ && !(filter_mode & ANIMFILTER_IPOKEYS) )
+ {
+ ale= make_new_animlistelem(ob, ANIMTYPE_FILLCOND, base, ANIMTYPE_OBJECT);
+ if (ale) BLI_addtail(anim_data, ale);
+ }
+
+ /* add constraint channels? */
+ if (FILTER_CON_OBJC(ob) || (filter_mode & ANIMFILTER_IPOKEYS) || (filter_mode & ANIMFILTER_ONLYICU)) {
+ /* loop through constraint channels, checking and adding them */
+ for (conchan=ob->constraintChannels.first; conchan; conchan=conchan->next) {
+ /* only work with this channel and its subchannels if it is editable */
+ if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_CONCHAN(conchan)) {
+ /* check if this conchan should only be included if it is selected */
+ if (!(filter_mode & ANIMFILTER_SEL) || SEL_CONCHAN(conchan)) {
+ if (filter_mode & ANIMFILTER_IPOKEYS) {
+ ale= make_new_animlistelem(conchan, ANIMTYPE_CONCHAN2, base, ANIMTYPE_OBJECT);
+ if (ale) {
+ ale->id= (ID *)ob;
+ BLI_addtail(anim_data, ale);
+ }
+ }
+ else {
+ ale= make_new_animlistelem(conchan, ANIMTYPE_CONCHAN, base, ANIMTYPE_OBJECT);
+ if (ale) {
+ ale->id= (ID *)ob;
+ BLI_addtail(anim_data, ale);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// TODO: implement pinning... (if and when pinning is done, what we need to do is to provide freeing mechanisms - to protect against data that was deleted)
+static void animdata_filter_dopesheet (ListBase *anim_data, bDopeSheet *ads, int filter_mode)
+{
+ Scene *sce= (Scene *)ads->source;
+ Base *base;
+
+ /* check that we do indeed have a scene */
+ if ((ads->source == NULL) || (GS(ads->source->name)!=ID_SCE)) {
+ printf("DopeSheet Error: Not scene! \n");
+ return;
+ }
+
+ /* loop over all bases in the scene */
+ for (base= sce->base.first; base; base= base->next) {
+ /* check if there's an object (all the relevant checks are done in the ob-function) */
+ if (base->object) {
+ Object *ob= base->object;
+ Key *key= ob_get_key(ob);
+ short ipoOk, actOk, constsOk, keyOk, dataOk;
+
+ /* firstly, check if object can be included, by the following fanimors:
+ * - if only visible, must check for layer and also viewport visibility
+ * - if only selected, must check if object is selected
+ * - there must be animation data to edit
+ */
+ // TODO: if cache is implemented, just check name here, and then
+ if (filter_mode & ANIMFILTER_VISIBLE) {
+ /* layer visibility */
+ if ((ob->lay & sce->lay)==0) continue;
+
+ /* outliner restrict-flag */
+ if (ob->restrictflag & OB_RESTRICT_VIEW) continue;
+ }
+
+ /* additionally, dopesheet filtering also affects what objects to consider */
+ if (ads->filterflag) {
+ /* check selection and object type filters */
+ if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) || (base == sce->basact)) ) {
+ /* only selected should be shown */
+ continue;
+ }
+ if ((ads->filterflag & ADS_FILTER_NOARM) && (ob->type == OB_ARMATURE)) {
+ /* not showing armatures */
+ continue;
+ }
+ if ((ads->filterflag & ADS_FILTER_NOOBJ) && (ob->type != OB_ARMATURE)) {
+ /* not showing objects that aren't armatures */
+ continue;
+ }
+
+ /* check filters for datatypes */
+ ipoOk= ((ob->ipo) && !(ads->filterflag & ADS_FILTER_NOIPOS));
+ actOk= ((ob->action) && !(ads->filterflag & ADS_FILTER_NOACTS));
+ constsOk= ((ob->constraintChannels.first) && !(ads->filterflag & ADS_FILTER_NOCONSTRAINTS));
+ keyOk= ((key) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS));
+
+ switch (ob->type) {
+ case OB_CAMERA: /* ------- Camera ------------ */
+ {
+ Camera *ca= (Camera *)ob->data;
+ dataOk= ((ca->ipo) && !(ads->filterflag & ADS_FILTER_NOCAM));
+ }
+ break;
+ case OB_LAMP: /* ---------- Lamp ----------- */
+ {
+ Lamp *la= (Lamp *)ob->data;
+ dataOk= ((la->ipo) && !(ads->filterflag & ADS_FILTER_NOLAM));
+ }
+ break;
+ case OB_CURVE: /* -------- Curve ---------- */
+ {
+ Curve *cu= (Curve *)ob->data;
+ dataOk= ((cu->ipo) && !(ads->filterflag & ADS_FILTER_NOCUR));
+ }
+ break;
+ default: /* --- other --- */
+ dataOk= 0;
+ break;
+ }
+
+ /* check if all bad (i.e. nothing to show) */
+ if (!ipoOk && !actOk && !constsOk && !keyOk && !dataOk)
+ continue;
+ }
+ else {
+ /* check data-types */
+ ipoOk= (ob->ipo != NULL);
+ actOk= (ob->action != NULL);
+ constsOk= (ob->constraintChannels.first != NULL);
+ keyOk= (key != NULL);
+
+ switch (ob->type) {
+ case OB_CAMERA: /* ------- Camera ------------ */
+ {
+ Camera *ca= (Camera *)ob->data;
+ dataOk= (ca->ipo != NULL);
+ }
+ break;
+ case OB_LAMP: /* ---------- Lamp ----------- */
+ {
+ Lamp *la= (Lamp *)ob->data;
+ dataOk= (la->ipo != NULL);
+ }
+ break;
+ case OB_CURVE: /* -------- Curve ---------- */
+ {
+ Curve *cu= (Curve *)ob->data;
+ dataOk= (cu->ipo != NULL);
+ }
+ break;
+ default: /* --- other --- */
+ dataOk= 0;
+ break;
+ }
+
+ /* check if all bad (i.e. nothing to show) */
+ if (!ipoOk && !actOk && !constsOk && !keyOk && !dataOk)
+ continue;
+ }
+
+ /* since we're still here, this object should be usable */
+ animdata_filter_dopesheet_ob(anim_data, ads, base, filter_mode);
+ }
+ }
+}
/* ----------- Public API --------------- */
@@ -233,16 +1197,16 @@ void ANIM_animdata_filter (ListBase *anim_data, int filter_mode, void *data, sho
/* firstly filter the data */
switch (datatype) {
case ANIMCONT_ACTION:
- //animdata_filter_action(anim_data, data, filter_mode, NULL, ANIMTYPE_NONE);
+ animdata_filter_action(anim_data, data, filter_mode, NULL, ANIMTYPE_NONE);
break;
case ANIMCONT_SHAPEKEY:
- //animdata_filter_shapekey(anim_data, data, filter_mode, NULL, ANIMTYPE_NONE);
+ animdata_filter_shapekey(anim_data, data, filter_mode, NULL, ANIMTYPE_NONE);
break;
case ANIMCONT_GPENCIL:
//animdata_filter_gpencil(anim_data, data, filter_mode);
break;
case ANIMCONT_DOPESHEET:
- //animdata_filter_dopesheet(anim_data, data, filter_mode);
+ animdata_filter_dopesheet(anim_data, data, filter_mode);
break;
}
@@ -254,7 +1218,7 @@ void ANIM_animdata_filter (ListBase *anim_data, int filter_mode, void *data, sho
if (ale->type == ANIMTYPE_NONE)
BLI_freelinkN(anim_data, ale);
- if (filter_mode & ALEFILTER_IPOKEYS) {
+ if (filter_mode & ANIMFILTER_IPOKEYS) {
if (ale->datatype != ALE_IPO)
BLI_freelinkN(anim_data, ale);
else if (ale->key_data == NULL)
diff --git a/source/blender/editors/animation/anim_keyframing.c b/source/blender/editors/animation/anim_keyframing.c
index 3e303a2d26c..51dc04fa407 100644
--- a/source/blender/editors/animation/anim_keyframing.c
+++ b/source/blender/editors/animation/anim_keyframing.c
@@ -2100,7 +2100,7 @@ short ipo_frame_has_keyframe (Ipo *ipo, float frame, short filter)
return 0;
/* if only check non-muted, check if muted */
- if ((filter & ANIMFILTER_MUTED) || (ipo->muteipo))
+ if ((filter & ANIMFILTER_KEYS_MUTED) || (ipo->muteipo))
return 0;
/* loop over IPO-curves, using binary-search to try to find matches
@@ -2110,7 +2110,7 @@ short ipo_frame_has_keyframe (Ipo *ipo, float frame, short filter)
/* only check if there are keyframes (currently only of type BezTriple) */
if (icu->bezt) {
/* we either include all regardless of muting, or only non-muted */
- if ((filter & ANIMFILTER_MUTED) || (icu->flag & IPO_MUTE)==0) {
+ if ((filter & ANIMFILTER_KEYS_MUTED) || (icu->flag & IPO_MUTE)==0) {
short replace = -1;
int i = binarysearch_bezt_index(icu->bezt, frame, icu->totvert, &replace);
@@ -2146,7 +2146,7 @@ short action_frame_has_keyframe (bAction *act, float frame, short filter)
/* we either include all regardless of muting, or only non-muted
* - here we include 'hidden' channels in the muted definition
*/
- if ((filter & ANIMFILTER_MUTED) || (achan->flag & ACHAN_HIDDEN)==0) {
+ if ((filter & ANIMFILTER_KEYS_MUTED) || (achan->flag & ACHAN_HIDDEN)==0) {
if (ipo_frame_has_keyframe(achan->ipo, frame, filter))
return 1;
}
@@ -2176,7 +2176,7 @@ short object_frame_has_keyframe (Object *ob, float frame, short filter)
/* priority check here goes to pose-channel checks (for armatures) */
if ((ob->pose) && (ob->flag & OB_POSEMODE)) {
/* only relevant check here is to only show active... */
- if (filter & ANIMFILTER_ACTIVE) {
+ if (filter & ANIMFILTER_KEYS_ACTIVE) {
bPoseChannel *pchan= get_active_posechannel(ob);
bActionChannel *achan= (pchan) ? get_action_channel(ob->action, pchan->name) : NULL;
@@ -2196,7 +2196,7 @@ short object_frame_has_keyframe (Object *ob, float frame, short filter)
}
/* try shapekey keyframes (if available, and allowed by filter) */
- if ( !(filter & ANIMFILTER_LOCAL) && !(filter & ANIMFILTER_NOSKEY) ) {
+ if ( !(filter & ANIMFILTER_KEYS_LOCAL) && !(filter & ANIMFILTER_KEYS_NOSKEY) ) {
Key *key= ob_get_key(ob);
/* shapekeys can have keyframes ('Relative Shape Keys')
@@ -2212,9 +2212,9 @@ short object_frame_has_keyframe (Object *ob, float frame, short filter)
}
/* try materials */
- if ( !(filter & ANIMFILTER_LOCAL) && !(filter & ANIMFILTER_NOMAT) ) {
+ if ( !(filter & ANIMFILTER_KEYS_LOCAL) && !(filter & ANIMFILTER_KEYS_NOMAT) ) {
/* if only active, then we can skip a lot of looping */
- if (filter & ANIMFILTER_ACTIVE) {
+ if (filter & ANIMFILTER_KEYS_ACTIVE) {
Material *ma= give_current_material(ob, (ob->actcol + 1));
/* we only retrieve the active material... */
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 2a5082e2094..a2786b5ed1c 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -122,17 +122,63 @@ typedef enum eAnimCont_Types {
/* filtering flags - under what circumstances should a channel be added */
// XXX was ACTFILTER_*
typedef enum eAnimFilter_Flags {
- ALEFILTER_VISIBLE = (1<<0), /* should channels be visible */
- ALEFILTER_SEL = (1<<1), /* should channels be selected */
- ALEFILTER_FOREDIT = (1<<2), /* does editable status matter */
- ALEFILTER_CHANNELS = (1<<3), /* do we only care that it is a channel */
- ALEFILTER_IPOKEYS = (1<<4), /* only channels referencing ipo's */
- ALEFILTER_ONLYICU = (1<<5), /* only reference ipo-curves */
- ALEFILTER_FORDRAWING = (1<<6), /* make list for interface drawing */
- ALEFILTER_ACTGROUPED = (1<<7), /* belongs to the active actiongroup */
+ ANIMFILTER_VISIBLE = (1<<0), /* should channels be visible */
+ ANIMFILTER_SEL = (1<<1), /* should channels be selected */
+ ANIMFILTER_FOREDIT = (1<<2), /* does editable status matter */
+ ANIMFILTER_CHANNELS = (1<<3), /* do we only care that it is a channel */
+ ANIMFILTER_IPOKEYS = (1<<4), /* only channels referencing ipo's */
+ ANIMFILTER_ONLYICU = (1<<5), /* only reference ipo-curves */
+ ANIMFILTER_FORDRAWING = (1<<6), /* make list for interface drawing */
+ ANIMFILTER_ACTGROUPED = (1<<7), /* belongs to the active actiongroup */
} eAnimFilter_Flags;
+/* ---------- Flag Checking Macros ------------ */
+
+/* Dopesheet only */
+ /* 'Object' channels */
+#define SEL_OBJC(base) ((base->flag & SELECT))
+#define EXPANDED_OBJC(ob) ((ob->nlaflag & OB_ADS_COLLAPSED)==0)
+ /* 'Sub-object' channels (flags stored in Object block) */
+#define FILTER_IPO_OBJC(ob) ((ob->nlaflag & OB_ADS_SHOWIPO))
+#define FILTER_CON_OBJC(ob) ((ob->nlaflag & OB_ADS_SHOWCONS))
+#define FILTER_MAT_OBJC(ob) ((ob->nlaflag & OB_ADS_SHOWMATS))
+ /* 'Sub-object' channels (flags stored in Data block) */
+#define FILTER_SKE_OBJD(key) ((key->flag & KEYBLOCK_DS_EXPAND))
+#define FILTER_MAT_OBJD(ma) ((ma->flag & MA_DS_EXPAND))
+#define FILTER_LAM_OBJD(la) ((la->flag & LA_DS_EXPAND))
+#define FILTER_CAM_OBJD(ca) ((ca->flag & CAM_DS_EXPAND))
+#define FILTER_CUR_OBJD(cu) ((cu->flag & CU_DS_EXPAND))
+ /* 'Sub-object/Action' channels (flags stored in Action) */
+#define SEL_ACTC(actc) ((actc->flag & ACTC_SELECTED))
+#define EXPANDED_ACTC(actc) ((actc->flag & ACTC_EXPANDED))
+
+/* Actions (also used for Dopesheet) */
+ /* Action Channel Group */
+#define EDITABLE_AGRP(agrp) ((agrp->flag & AGRP_PROTECTED)==0)
+#define EXPANDED_AGRP(agrp) (agrp->flag & AGRP_EXPANDED)
+#define SEL_AGRP(agrp) ((agrp->flag & AGRP_SELECTED) || (agrp->flag & AGRP_ACTIVE))
+ /* Action Channel Settings */
+#define VISIBLE_ACHAN(achan) ((achan->flag & ACHAN_HIDDEN)==0)
+#define EDITABLE_ACHAN(achan) ((VISIBLE_ACHAN(achan)) && ((achan->flag & ACHAN_PROTECTED)==0))
+#define EXPANDED_ACHAN(achan) ((VISIBLE_ACHAN(achan)) && (achan->flag & ACHAN_EXPANDED))
+#define SEL_ACHAN(achan) ((achan->flag & ACHAN_SELECTED) || (achan->flag & ACHAN_HILIGHTED))
+#define FILTER_IPO_ACHAN(achan) ((achan->flag & ACHAN_SHOWIPO))
+#define FILTER_CON_ACHAN(achan) ((achan->flag & ACHAN_SHOWCONS))
+ /* Constraint Channel Settings */
+#define EDITABLE_CONCHAN(conchan) ((conchan->flag & CONSTRAINT_CHANNEL_PROTECTED)==0)
+#define SEL_CONCHAN(conchan) (conchan->flag & CONSTRAINT_CHANNEL_SELECT)
+ /* IPO Curve Channels */
+#define EDITABLE_ICU(icu) ((icu->flag & IPO_PROTECT)==0)
+#define SEL_ICU(icu) (icu->flag & IPO_SELECT)
+
+/* Grease Pencil only */
+ /* Grease Pencil datablock settings */
+#define EXPANDED_GPD(gpd) (gpd->flag & GP_DATA_EXPAND)
+ /* Grease Pencil Layer settings */
+#define EDITABLE_GPL(gpl) ((gpl->flag & GP_LAYER_LOCKED)==0)
+#define SEL_GPL(gpl) ((gpl->flag & GP_LAYER_ACTIVE) || (gpl->flag & GP_LAYER_SELECT))
+
/* ---------------- API -------------------- */
/* Obtain list of filtered Animation channels to operate on */
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index 29d19cd18e3..f4be3f06c6b 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -122,13 +122,13 @@ short id_frame_has_keyframe(struct ID *id, float frame, short filter);
*/
enum {
/* general */
- ANIMFILTER_LOCAL = (1<<0), /* only include locally available anim data */
- ANIMFILTER_MUTED = (1<<1), /* include muted elements */
- ANIMFILTER_ACTIVE = (1<<2), /* only include active-subelements */
+ ANIMFILTER_KEYS_LOCAL = (1<<0), /* only include locally available anim data */
+ ANIMFILTER_KEYS_MUTED = (1<<1), /* include muted elements */
+ ANIMFILTER_KEYS_ACTIVE = (1<<2), /* only include active-subelements */
/* object specific */
- ANIMFILTER_NOMAT = (1<<9), /* don't include material keyframes */
- ANIMFILTER_NOSKEY = (1<<10), /* don't include shape keys (for geometry) */
+ ANIMFILTER_KEYS_NOMAT = (1<<9), /* don't include material keyframes */
+ ANIMFILTER_KEYS_NOSKEY = (1<<10), /* don't include shape keys (for geometry) */
} eAnimFilterFlags;
#endif /* BIF_KEYFRAMING_H */