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:
Diffstat (limited to 'source/blender/editors/animation/anim_filter.c')
-rw-r--r--source/blender/editors/animation/anim_filter.c1998
1 files changed, 801 insertions, 1197 deletions
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 967002131c2..bb710a32794 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -67,6 +65,7 @@
#include "DNA_sequence_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "DNA_speaker_types.h"
#include "DNA_world_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_object_types.h"
@@ -127,6 +126,9 @@ static Key *actedit_get_shapekeys (bAnimContext *ac)
/* Get data being edited in Action Editor (depending on current 'mode') */
static short actedit_get_context (bAnimContext *ac, SpaceAction *saction)
{
+ /* get dopesheet */
+ ac->ads = &saction->ads;
+
/* sync settings with current view status, then return appropriate data */
switch (saction->mode) {
case SACTCONT_ACTION: /* 'Action Editor' */
@@ -190,6 +192,7 @@ static short graphedit_get_context (bAnimContext *ac, SpaceIpo *sipo)
sipo->ads= MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
sipo->ads->source= (ID *)ac->scene;
}
+ ac->ads = sipo->ads;
/* set settings for Graph Editor - "Selected = Editable" */
if (sipo->flag & SIPO_SELCUVERTSONLY)
@@ -238,6 +241,7 @@ static short nlaedit_get_context (bAnimContext *ac, SpaceNla *snla)
/* init dopesheet data if non-existant (i.e. for old files) */
if (snla->ads == NULL)
snla->ads= MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet");
+ ac->ads = snla->ads;
/* sync settings with current view status, then return appropriate data */
/* update scene-pointer (no need to check for pinning yet, as not implemented) */
@@ -258,29 +262,29 @@ static short nlaedit_get_context (bAnimContext *ac, SpaceNla *snla)
*/
short ANIM_animdata_context_getdata (bAnimContext *ac)
{
- ScrArea *sa= ac->sa;
+ SpaceLink *sl = ac->sl;
short ok= 0;
/* context depends on editor we are currently in */
- if (sa) {
- switch (sa->spacetype) {
+ if (sl) {
+ switch (ac->spacetype) {
case SPACE_ACTION:
{
- SpaceAction *saction= (SpaceAction *)sa->spacedata.first;
+ SpaceAction *saction= (SpaceAction *)sl;
ok= actedit_get_context(ac, saction);
}
break;
case SPACE_IPO:
{
- SpaceIpo *sipo= (SpaceIpo *)sa->spacedata.first;
+ SpaceIpo *sipo= (SpaceIpo *)sl;
ok= graphedit_get_context(ac, sipo);
}
break;
case SPACE_NLA:
{
- SpaceNla *snla= (SpaceNla *)sa->spacedata.first;
+ SpaceNla *snla= (SpaceNla *)sl;
ok= nlaedit_get_context(ac, snla);
}
break;
@@ -303,6 +307,7 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
{
ScrArea *sa= CTX_wm_area(C);
ARegion *ar= CTX_wm_region(C);
+ SpaceLink *sl= CTX_wm_space_data(C);
Scene *scene= CTX_data_scene(C);
/* clear old context info */
@@ -317,6 +322,7 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
}
ac->sa= sa;
ac->ar= ar;
+ ac->sl= sl;
ac->spacetype= (sa) ? sa->spacetype : 0;
ac->regiontype= (ar) ? ar->regiontype : 0;
@@ -327,6 +333,35 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
/* ************************************************************ */
/* Blender Data <-- Filter --> Channels to be operated on */
+/* macros to use before/after getting the sub-channels of some channel,
+ * to abstract away some of the tricky logic involved
+ *
+ * cases:
+ * 1) Graph Edit main area (just data) OR channels visible in Channel List
+ * 2) If not showing channels, we're only interested in the data (Action Editor's editing)
+ * 3) We don't care what data, we just care there is some (so that a collapsed
+ * channel can be kept around). No need to clear channels-flag in order to
+ * keep expander channels with no sub-data out, as those cases should get
+ * dealt with by the recursive detection idiom in place.
+ */
+#define BEGIN_ANIMFILTER_SUBCHANNELS(expanded_check) \
+ { \
+ int _filter = filter_mode; \
+ short _doSubChannels = 0; \
+ if (!(filter_mode & ANIMFILTER_LIST_VISIBLE) || (expanded_check)) \
+ _doSubChannels=1; \
+ else if (!(filter_mode & ANIMFILTER_LIST_CHANNELS)) \
+ _doSubChannels=2; \
+ else {\
+ filter_mode |= ANIMFILTER_TMP_PEEK; \
+ }
+ /* ... standard sub-channel filtering can go on here now ... */
+#define END_ANIMFILTER_SUBCHANNELS \
+ filter_mode = _filter; \
+ }
+
+/* ............................... */
+
/* quick macro to test if AnimData is usable */
#define ANIMDATA_HAS_KEYS(id) ((id)->adt && (id)->adt->action)
@@ -336,8 +371,7 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
/* quick macro to test if AnimData is usable for NLA */
#define ANIMDATA_HAS_NLA(id) ((id)->adt && (id)->adt->nla_tracks.first)
-
-/* Quick macro to test for all three avove usability tests, performing the appropriate provided
+/* Quick macro to test for all three above usability tests, performing the appropriate provided
* action for each when the AnimData context is appropriate.
*
* Priority order for this goes (most important, to least): AnimData blocks, NLA, Drivers, Keyframes.
@@ -347,7 +381,7 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
* - ListBase anim_data;
* - bDopeSheet *ads;
* - bAnimListElem *ale;
- * - int items;
+ * - size_t items;
*
* - id: ID block which should have an AnimData pointer following it immediately, to use
* - adtOk: line or block of code to execute for AnimData-blocks case (usually ANIMDATA_ADD_ANIMDATA)
@@ -361,13 +395,14 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
* 2A) nla tracks: include animdata block's data as there are NLA tracks+strips there
* 2B) actions to convert to nla: include animdata block's data as there is an action that can be
* converted to a new NLA strip, and the filtering options allow this
+ * 2C) allow non-animated datablocks to be included so that datablocks can be added
* 3) drivers: include drivers from animdata block (for Drivers mode in Graph Editor)
* 4) normal keyframes: only when there is an active action
*/
#define ANIMDATA_FILTER_CASES(id, adtOk, nlaOk, driversOk, keysOk) \
{\
if ((id)->adt) {\
- if (!(filter_mode & ANIMFILTER_CURVEVISIBLE) || !((id)->adt->flag & ADT_CURVES_NOT_VISIBLE)) {\
+ if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || !((id)->adt->flag & ADT_CURVES_NOT_VISIBLE)) {\
if (filter_mode & ANIMFILTER_ANIMDATA) {\
adtOk\
}\
@@ -393,17 +428,31 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
}\
}
+/* ............................... */
-/* quick macro to add a pointer to an AnimData block as a channel */
-#define ANIMDATA_ADD_ANIMDATA(id) \
- {\
- ale= make_new_animlistelem((id)->adt, ANIMTYPE_ANIMDATA, NULL, ANIMTYPE_NONE, (ID *)id);\
+/* Add a new animation channel, taking into account the "peek" flag, which is used to just check
+ * whether any channels will be added (but without needing them to actually get created).
+ *
+ * ! This causes the calling function to return early if we're only "peeking" for channels
+ */
+// XXX: ale_statement stuff is really a hack for one special case. It shouldn't really be needed...
+#define ANIMCHANNEL_NEW_CHANNEL_FULL(channel_data, channel_type, owner_id, ale_statement) \
+ if (filter_mode & ANIMFILTER_TMP_PEEK) \
+ return 1; \
+ else { \
+ bAnimListElem *ale= make_new_animlistelem(channel_data, channel_type, (ID *)owner_id); \
if (ale) {\
- BLI_addtail(anim_data, ale);\
- items++;\
- }\
+ BLI_addtail(anim_data, ale); \
+ items++; \
+ ale_statement \
+ } \
}
+#define ANIMCHANNEL_NEW_CHANNEL(channel_data, channel_type, owner_id) \
+ ANIMCHANNEL_NEW_CHANNEL_FULL(channel_data, channel_type, owner_id, {})
+
+/* ............................... */
+
/* quick macro to test if an anim-channel representing an AnimData block is suitably active */
#define ANIMCHANNEL_ACTIVEOK(ale) \
( !(filter_mode & ANIMFILTER_ACTIVE) || !(ale->adt) || (ale->adt->flag & ADT_UI_ACTIVE) )
@@ -432,7 +481,7 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
/* this function allocates memory for a new bAnimListElem struct for the
* provided animation channel-data.
*/
-static bAnimListElem *make_new_animlistelem (void *data, short datatype, void *owner, short ownertype, ID *owner_id)
+static bAnimListElem *make_new_animlistelem (void *data, short datatype, ID *owner_id)
{
bAnimListElem *ale= NULL;
@@ -443,10 +492,6 @@ static bAnimListElem *make_new_animlistelem (void *data, short datatype, void *o
ale->data= data;
ale->type= datatype;
- // XXX what is the point of the owner data?
- // xxx try and use this to simplify the problem of finding whether parent channels are working...
- ale->owner= owner;
- ale->ownertype= ownertype;
ale->id= owner_id;
ale->adt= BKE_animdata_from_id(owner_id);
@@ -509,55 +554,6 @@ static bAnimListElem *make_new_animlistelem (void *data, short datatype, void *o
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_FILLPARTD:
- {
- Object *ob= (Object *)data;
-
- ale->flag= FILTER_PART_OBJC(ob);
-
- ale->key_data= NULL;
- ale->datatype= ALE_NONE;
- }
- break;
- case ANIMTYPE_FILLTEXD:
- {
- ID *id= (ID *)data;
-
- switch (GS(id->name)) {
- case ID_MA:
- {
- Material *ma= (Material *)id;
- ale->flag= FILTER_TEX_MATC(ma);
- }
- break;
- case ID_LA:
- {
- Lamp *la= (Lamp *)id;
- ale->flag= FILTER_TEX_LAMC(la);
- }
- break;
- case ID_WO:
- {
- World *wo= (World *)id;
- ale->flag= FILTER_TEX_WORC(wo);
- }
- break;
- }
-
- ale->key_data= NULL;
- ale->datatype= ALE_NONE;
- }
- break;
case ANIMTYPE_DSMAT:
{
@@ -650,6 +646,19 @@ static bAnimListElem *make_new_animlistelem (void *data, short datatype, void *o
ale->adt= BKE_animdata_from_id(data);
}
break;
+ case ANIMTYPE_DSSPK:
+ {
+ Speaker *spk= (Speaker *)data;
+ AnimData *adt= spk->adt;
+
+ ale->flag= FILTER_SPK_OBJD(spk);
+
+ ale->key_data= (adt) ? adt->action : NULL;
+ ale->datatype= ALE_ACT;
+
+ ale->adt= BKE_animdata_from_id(data);
+ }
+ break;
case ANIMTYPE_DSSKEY:
{
Key *key= (Key *)data;
@@ -681,7 +690,7 @@ static bAnimListElem *make_new_animlistelem (void *data, short datatype, void *o
bNodeTree *ntree= (bNodeTree *)data;
AnimData *adt= ntree->adt;
- ale->flag= FILTER_NTREE_SCED(ntree);
+ ale->flag= FILTER_NTREE_DATA(ntree);
ale->key_data= (adt) ? adt->action : NULL;
ale->datatype= ALE_ACT;
@@ -807,7 +816,7 @@ static bAnimListElem *make_new_animlistelem (void *data, short datatype, void *o
/* 'Only Selected' selected data filtering
* NOTE: when this function returns true, the F-Curve is to be skipped
*/
-static int skip_fcurve_selected_data (bDopeSheet *ads, FCurve *fcu, ID *owner_id, int filter_mode)
+static size_t skip_fcurve_selected_data (bDopeSheet *ads, FCurve *fcu, ID *owner_id, int filter_mode)
{
if (GS(owner_id->name) == ID_OB) {
Object *ob= (Object *)owner_id;
@@ -825,11 +834,12 @@ static int skip_fcurve_selected_data (bDopeSheet *ads, FCurve *fcu, ID *owner_id
/* check whether to continue or skip */
if ((pchan) && (pchan->bone)) {
/* if only visible channels, skip if bone not visible unless user wants channels from hidden data too */
- if ((filter_mode & ANIMFILTER_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
+ if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
bArmature *arm= (bArmature *)ob->data;
if ((arm->layer & pchan->bone->layer) == 0)
return 1;
+ // TODO: manually hidden using flags
}
/* can only add this F-Curve if it is selected */
@@ -910,7 +920,7 @@ static short skip_fcurve_with_name (bDopeSheet *ads, FCurve *fcu, ID *owner_id)
}
/* find the next F-Curve that is usable for inclusion */
-static FCurve *animdata_filter_fcurve_next (bDopeSheet *ads, FCurve *first, bActionGroup *grp, int filter_mode, ID *owner_id)
+static FCurve *animfilter_fcurve_next (bDopeSheet *ads, FCurve *first, bActionGroup *grp, int filter_mode, ID *owner_id)
{
FCurve *fcu = NULL;
@@ -932,7 +942,7 @@ static FCurve *animdata_filter_fcurve_next (bDopeSheet *ads, FCurve *first, bAct
}
/* only include if visible (Graph Editor check, not channels check) */
- if (!(filter_mode & ANIMFILTER_CURVEVISIBLE) || (fcu->flag & FCURVE_VISIBLE)) {
+ if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || (fcu->flag & FCURVE_VISIBLE)) {
/* only work with this channel and its subchannels if it is editable */
if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_FCU(fcu)) {
/* only include this curve if selected in a way consistent with the filtering requirements */
@@ -957,10 +967,10 @@ static FCurve *animdata_filter_fcurve_next (bDopeSheet *ads, FCurve *first, bAct
return NULL;
}
-static int animdata_filter_fcurves (ListBase *anim_data, bDopeSheet *ads, FCurve *first, bActionGroup *grp, void *owner, short ownertype, int filter_mode, ID *owner_id)
+static size_t animfilter_fcurves (ListBase *anim_data, bDopeSheet *ads, FCurve *first, bActionGroup *grp, int filter_mode, ID *owner_id)
{
FCurve *fcu;
- int items = 0;
+ size_t items = 0;
/* loop over every F-Curve able to be included
* - this for-loop works like this:
@@ -971,26 +981,98 @@ static int animdata_filter_fcurves (ListBase *anim_data, bDopeSheet *ads, FCurve
* 4) the fcu pointer is set to the F-Curve after the one we just added, so that we can keep going through
* the rest of the F-Curve list without an eternal loop. Back to step 2 :)
*/
- for (fcu=first; ( (fcu = animdata_filter_fcurve_next(ads, fcu, grp, filter_mode, owner_id)) ); fcu=fcu->next)
+ for (fcu=first; ( (fcu = animfilter_fcurve_next(ads, fcu, grp, filter_mode, owner_id)) ); fcu=fcu->next)
+ {
+ ANIMCHANNEL_NEW_CHANNEL(fcu, ANIMTYPE_FCURVE, owner_id);
+ }
+
+ /* return the number of items added to the list */
+ return items;
+}
+
+static size_t animfilter_act_group (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAction *UNUSED(act), bActionGroup *agrp, int filter_mode, ID *owner_id)
+{
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+ //int ofilter = filter_mode;
+
+ /* if we care about the selection status of the channels,
+ * but the group isn't expanded (1)...
+ * (1) this only matters if we actually care about the hierarchy though.
+ * - Hierarchy matters: this hack should be applied
+ * - Hierarchy ignored: cases like [#21276] won't work properly, unless we skip this hack
+ */
+ if ( ((filter_mode & ANIMFILTER_LIST_VISIBLE) && EXPANDED_AGRP(ac, agrp)==0) && /* care about hierarchy but group isn't expanded */
+ (filter_mode & (ANIMFILTER_SEL|ANIMFILTER_UNSEL)) ) /* care about selection status */
{
- bAnimListElem *ale = make_new_animlistelem(fcu, ANIMTYPE_FCURVE, owner, ownertype, owner_id);
+ /* if the group itself isn't selected appropriately, we shouldn't consider it's children either */
+ if (ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) == 0)
+ return 0;
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
+ /* if we're still here, then the selection status of the curves within this group should not matter,
+ * since this creates too much overhead for animators (i.e. making a slow workflow)
+ *
+ * Tools affected by this at time of coding (2010 Feb 09):
+ * - inserting keyframes on selected channels only
+ * - pasting keyframes
+ * - creating ghost curves in Graph Editor
+ */
+ filter_mode &= ~(ANIMFILTER_SEL|ANIMFILTER_UNSEL|ANIMFILTER_LIST_VISIBLE);
+ }
+
+ /* add grouped F-Curves */
+ BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_AGRP(ac, agrp))
+ {
+ /* special filter so that we can get just the F-Curves within the active group */
+ if (!(filter_mode & ANIMFILTER_ACTGROUPED) || (agrp->flag & AGRP_ACTIVE)) {
+ /* for the Graph Editor, curves may be set to not be visible in the view to lessen clutter,
+ * but to do this, we need to check that the group doesn't have it's not-visible flag set preventing
+ * all its sub-curves to be shown
+ */
+ if ( !(filter_mode & ANIMFILTER_CURVE_VISIBLE) || !(agrp->flag & AGRP_NOTVISIBLE) )
+ {
+ /* group must be editable for its children to be editable (if we care about this) */
+ if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) {
+ /* get first F-Curve which can be used here */
+ FCurve *first_fcu = animfilter_fcurve_next(ads, agrp->channels.first, agrp, filter_mode, owner_id);
+
+ /* filter list, starting from this F-Curve */
+ tmp_items += animfilter_fcurves(&tmp_data, ads, first_fcu, agrp, filter_mode, owner_id);
+ }
+ }
+ }
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* add this group as a channel first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* restore original filter mode so that this next step works ok... */
+ //filter_mode = ofilter;
+
+ /* filter selection of channel specially here again, since may be open and not subject to previous test */
+ if ( ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) ) {
+ ANIMCHANNEL_NEW_CHANNEL(agrp, ANIMTYPE_GROUP, owner_id);
+ }
}
+
+ /* 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 the number of items added to the list */
return items;
}
-static int animdata_filter_action (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAction *act, int filter_mode, void *owner, short ownertype, ID *owner_id)
+static size_t animfilter_action (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAction *act, int filter_mode, ID *owner_id)
{
- bAnimListElem *ale=NULL;
bActionGroup *agrp;
- FCurve *lastchan=NULL;
- int items = 0;
+ FCurve *lastchan = NULL;
+ size_t items = 0;
/* don't include anything from this action if it is linked in from another file,
* and we're getting stuff for editing...
@@ -998,106 +1080,22 @@ static int animdata_filter_action (bAnimContext *ac, ListBase *anim_data, bDopeS
// TODO: need a way of tagging other channels that may also be affected...
if ((filter_mode & ANIMFILTER_FOREDIT) && (act->id.lib))
return 0;
-
- /* loop over groups */
- // TODO: in future, should we expect to need nested groups?
- for (agrp= act->groups.first; agrp; agrp= agrp->next) {
- FCurve *first_fcu;
- int filter_gmode;
+ /* do groups */
+ // TODO: do nested groups?
+ for (agrp = act->groups.first; agrp; agrp = agrp->next) {
/* store reference to last channel of group */
if (agrp->channels.last)
lastchan= agrp->channels.last;
-
-
- /* make a copy of filtering flags for use by the sub-channels of this group */
- filter_gmode= filter_mode;
-
- /* if we care about the selection status of the channels,
- * but the group isn't expanded...
- */
- if ( (filter_mode & (ANIMFILTER_SEL|ANIMFILTER_UNSEL)) && /* care about selection status */
- (EXPANDED_AGRP(ac, agrp)==0) ) /* group isn't expanded */
- {
- /* if the group itself isn't selected appropriately, we shouldn't consider it's children either */
- if (ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) == 0)
- continue;
- /* if we're still here, then the selection status of the curves within this group should not matter,
- * since this creates too much overhead for animators (i.e. making a slow workflow)
- *
- * Tools affected by this at time of coding (2010 Feb 09):
- * - inserting keyframes on selected channels only
- * - pasting keyframes
- * - creating ghost curves in Graph Editor
- */
- filter_gmode &= ~(ANIMFILTER_SEL|ANIMFILTER_UNSEL);
- }
-
-
- /* get the first F-Curve in this group we can start to use, and if there isn't any F-Curve to start from,
- * then don't use this group at all...
- *
- * NOTE: use filter_gmode here not filter_mode, since there may be some flags we shouldn't consider under certain circumstances
- */
- first_fcu = animdata_filter_fcurve_next(ads, agrp->channels.first, agrp, filter_gmode, owner_id);
-
- /* Bug note:
- * Selecting open group to toggle visbility of the group, where the F-Curves of the group are not suitable
- * for inclusion due to their selection status (vs visibility status of bones/etc., as is usually the case),
- * will not work, since the group gets skipped. However, fixing this can easily reintroduce the bugs whereby
- * hidden groups (due to visibility status of bones/etc.) that were selected before becoming invisible, can
- * easily get deleted accidentally as they'd be included in the list filtered for that purpose.
- *
- * So, for now, best solution is to just leave this note here, and hope to find a solution at a later date.
- * -- Joshua Leung, 2010 Feb 10
- */
- if (first_fcu) {
- /* add this group as a channel first */
- if ((filter_mode & ANIMFILTER_CHANNELS) || !(filter_mode & ANIMFILTER_CURVESONLY)) {
- /* filter selection of channel specially here again, since may be open and not subject to previous test */
- if ( ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) ) {
- ale= make_new_animlistelem(agrp, ANIMTYPE_GROUP, NULL, ANIMTYPE_NONE, owner_id);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- }
- }
-
- /* there are some situations, where only the channels of the action 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 F-Curves inside group:
- * - we don't care about visibility
- * - group is expanded
- * - we just need the F-Curves present
- */
- if ( (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_AGRP(ac, agrp)) || (filter_mode & ANIMFILTER_CURVESONLY) )
- {
- /* for the Graph Editor, curves may be set to not be visible in the view to lessen clutter,
- * but to do this, we need to check that the group doesn't have it's not-visible flag set preventing
- * all its sub-curves to be shown
- */
- if ( !(filter_mode & ANIMFILTER_CURVEVISIBLE) || !(agrp->flag & AGRP_NOTVISIBLE) )
- {
- if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) {
- /* NOTE: filter_gmode is used here, not standard filter_mode, since there may be some flags that shouldn't apply */
- items += animdata_filter_fcurves(anim_data, ads, first_fcu, agrp, owner, ownertype, filter_gmode, owner_id);
- }
- }
- }
- }
- }
+ /* action group's channels */
+ items += animfilter_act_group(ac, anim_data, ads, act, agrp, filter_mode, owner_id);
}
- /* loop over un-grouped F-Curves (only if we're not only considering those channels in the animive group) */
+ /* un-grouped F-Curves (only if we're not only considering those channels in the active group) */
if (!(filter_mode & ANIMFILTER_ACTGROUPED)) {
- // XXX the 'owner' info here needs review...
- items += animdata_filter_fcurves(anim_data, ads, (lastchan)?(lastchan->next):(act->curves.first), NULL, owner, ownertype, filter_mode, owner_id);
+ FCurve *firstfcu = (lastchan)? (lastchan->next) : (act->curves.first);
+ items += animfilter_fcurves(anim_data, ads, firstfcu, NULL, filter_mode, owner_id);
}
/* return the number of items added to the list */
@@ -1105,35 +1103,35 @@ static int animdata_filter_action (bAnimContext *ac, ListBase *anim_data, bDopeS
}
/* Include NLA-Data for NLA-Editor:
- * - when ANIMFILTER_CHANNELS is used, that means we should be filtering the list for display
+ * - when ANIMFILTER_LIST_CHANNELS is used, that means we should be filtering the list for display
* Although the evaluation order is from the first track to the last and then apply the Action on top,
* we present this in the UI as the Active Action followed by the last track to the first so that we
* get the evaluation order presented as per a stack.
* - for normal filtering (i.e. for editing), we only need the NLA-tracks but they can be in 'normal' evaluation
* order, i.e. first to last. Otherwise, some tools may get screwed up.
*/
-static int animdata_filter_nla (bAnimContext *UNUSED(ac), ListBase *anim_data, bDopeSheet *UNUSED(ads), AnimData *adt, int filter_mode, void *owner, short ownertype, ID *owner_id)
+static size_t animfilter_nla (bAnimContext *UNUSED(ac), ListBase *anim_data, bDopeSheet *ads, AnimData *adt, int filter_mode, ID *owner_id)
{
- bAnimListElem *ale;
NlaTrack *nlt;
NlaTrack *first=NULL, *next=NULL;
- int items = 0;
+ size_t items = 0;
/* if showing channels, include active action */
- if (filter_mode & ANIMFILTER_CHANNELS) {
- /* there isn't really anything editable here, so skip if need editable */
- // TODO: currently, selection isn't checked since it doesn't matter
- if ((filter_mode & ANIMFILTER_FOREDIT) == 0) {
- /* just add the action track now (this MUST appear for drawing)
- * - as AnimData may not have an action, we pass a dummy pointer just to get the list elem created, then
- * overwrite this with the real value - REVIEW THIS...
- */
- ale= make_new_animlistelem((void *)(&adt->action), ANIMTYPE_NLAACTION, owner, ownertype, owner_id);
- ale->data= (adt->action) ? adt->action : NULL;
-
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* if NLA action-line filtering is off, don't show unless there are keyframes,
+ * in order to keep things more compact for doing transforms
+ */
+ if (!(ads->filterflag & ADS_FILTER_NLA_NOACT) || (adt->action)) {
+ /* there isn't really anything editable here, so skip if need editable */
+ if ((filter_mode & ANIMFILTER_FOREDIT) == 0) {
+ /* just add the action track now (this MUST appear for drawing)
+ * - as AnimData may not have an action, we pass a dummy pointer just to get the list elem created, then
+ * overwrite this with the real value - REVIEW THIS...
+ */
+ ANIMCHANNEL_NEW_CHANNEL_FULL((void *)(&adt->action), ANIMTYPE_NLAACTION, owner_id,
+ {
+ ale->data= adt->action ? adt->action : NULL;
+ });
}
}
@@ -1148,7 +1146,7 @@ static int animdata_filter_nla (bAnimContext *UNUSED(ac), ListBase *anim_data, b
/* loop over NLA Tracks - assume that the caller of this has already checked that these should be included */
for (nlt= first; nlt; nlt= next) {
/* 'next' NLA-Track to use depends on whether we're filtering for drawing or not */
- if (filter_mode & ANIMFILTER_CHANNELS)
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS)
next= nlt->prev;
else
next= nlt->next;
@@ -1166,12 +1164,7 @@ static int animdata_filter_nla (bAnimContext *UNUSED(ac), ListBase *anim_data, b
if ( ANIMCHANNEL_SELOK(SEL_NLT(nlt)) ) {
/* only include if this track is active */
if (!(filter_mode & ANIMFILTER_ACTIVE) || (nlt->flag & NLATRACK_ACTIVE)) {
- ale= make_new_animlistelem(nlt, ANIMTYPE_NLATRACK, owner, ownertype, owner_id);
-
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
+ ANIMCHANNEL_NEW_CHANNEL(nlt, ANIMTYPE_NLATRACK, owner_id);
}
}
}
@@ -1181,14 +1174,49 @@ static int animdata_filter_nla (bAnimContext *UNUSED(ac), ListBase *anim_data, b
return items;
}
+/* determine what animation data from AnimData block should get displayed */
+static size_t animfilter_block_data (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *id, int filter_mode)
+{
+ AnimData *adt = BKE_animdata_from_id(id);
+ size_t items = 0;
+
+ /* image object datablocks have no anim-data so check for NULL */
+ if(adt) {
+ IdAdtTemplate *iat = (IdAdtTemplate*)id;
+
+ /* NOTE: this macro is used instead of inlining the logic here, since this sort of filtering is still needed
+ * in a few places in he rest of the code still - notably for the few cases where special mode-based
+ * different types of data expanders are required.
+ */
+ ANIMDATA_FILTER_CASES(iat,
+ { /* AnimData */
+ /* specifically filter animdata block */
+ ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_ANIMDATA, id);
+ },
+ { /* NLA */
+ items += animfilter_nla(ac, anim_data, ads, adt, filter_mode, id);
+ },
+ { /* Drivers */
+ items += animfilter_fcurves(anim_data, ads, adt->drivers.first, NULL, filter_mode, id);
+ },
+ { /* Keyframes */
+ items += animfilter_action(ac, anim_data, ads, adt->action, filter_mode, id);
+ }
+ );
+ }
+
+ return items;
+}
+
+
+
/* Include ShapeKey Data for ShapeKey Editor */
-static int animdata_filter_shapekey (bAnimContext *ac, ListBase *anim_data, Key *key, int filter_mode)
+static size_t animdata_filter_shapekey (bAnimContext *ac, ListBase *anim_data, Key *key, int filter_mode)
{
- bAnimListElem *ale;
- int items = 0;
+ size_t items = 0;
/* check if channels or only F-Curves */
- if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) {
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
KeyBlock *kb;
/* loop through the channels adding ShapeKeys as appropriate */
@@ -1204,24 +1232,21 @@ static int animdata_filter_shapekey (bAnimContext *ac, ListBase *anim_data, Key
// TODO: consider 'active' too?
/* owner-id here must be key so that the F-Curve can be resolved... */
- ale= make_new_animlistelem(kb, ANIMTYPE_SHAPEKEY, NULL, ANIMTYPE_NONE, (ID *)key);
-
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
+ ANIMCHANNEL_NEW_CHANNEL(kb, ANIMTYPE_SHAPEKEY, key);
}
}
}
}
else {
/* just use the action associated with the shapekey */
- // FIXME: is owner-id and having no owner/dopesheet really fine?
+ // TODO: somehow manage to pass dopesheet info down here too?
if (key->adt) {
- if (filter_mode & ANIMFILTER_ANIMDATA)
- ANIMDATA_ADD_ANIMDATA(key)
- else if (key->adt->action)
- items= animdata_filter_action(ac, anim_data, NULL, key->adt->action, filter_mode, NULL, ANIMTYPE_NONE, (ID *)key);
+ if (filter_mode & ANIMFILTER_ANIMDATA) {
+ ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, key);
+ }
+ else if (key->adt->action) {
+ items= animfilter_action(ac, anim_data, NULL, key->adt->action, filter_mode, (ID *)key);
+ }
}
}
@@ -1229,53 +1254,102 @@ static int animdata_filter_shapekey (bAnimContext *ac, ListBase *anim_data, Key
return items;
}
+static size_t animdata_filter_gpencil_data (ListBase *anim_data, bGPdata *gpd, int filter_mode)
+{
+ bGPDlayer *gpl;
+ size_t items = 0;
+
+ /* loop over layers as the conditions are acceptable */
+ for (gpl= gpd->layers.first; gpl; gpl= gpl->next) {
+ /* only if selected */
+ if ( ANIMCHANNEL_SELOK(SEL_GPL(gpl)) ) {
+ /* only if editable */
+ if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_GPL(gpl)) {
+ /* active... */
+ if (!(filter_mode & ANIMFILTER_ACTIVE) || (gpl->flag & GP_LAYER_ACTIVE)) {
+ /* add to list */
+ ANIMCHANNEL_NEW_CHANNEL(gpl, ANIMTYPE_GPLAYER, gpd);
+ }
+ }
+ }
+ }
+
+ return items;
+}
+
/* Grab all Grase Pencil datablocks in file */
// TODO: should this be amalgamated with the dopesheet filtering code?
-static int animdata_filter_gpencil (ListBase *anim_data, void *UNUSED(data), int filter_mode)
+static size_t animdata_filter_gpencil (ListBase *anim_data, void *UNUSED(data), int filter_mode)
{
- bAnimListElem *ale;
bGPdata *gpd;
- bGPDlayer *gpl;
- int items = 0;
+ size_t items = 0;
- /* check if filtering types are appropriate */
- if (!(filter_mode & (ANIMFILTER_ACTGROUPED|ANIMFILTER_CURVESONLY)))
- {
- /* for now, grab grease pencil datablocks directly from main*/
- for (gpd = G.main->gpencil.first; gpd; gpd = gpd->id.next) {
- /* only show if gpd is used by something... */
- if (ID_REAL_USERS(gpd) < 1)
- continue;
+ /* for now, grab grease pencil datablocks directly from main */
+ // XXX: this is not good...
+ for (gpd = G.main->gpencil.first; gpd; gpd = gpd->id.next) {
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+
+ /* only show if gpd is used by something... */
+ if (ID_REAL_USERS(gpd) < 1)
+ continue;
- /* add gpd as channel too (if for drawing, and it has layers) */
- if ((filter_mode & ANIMFILTER_CHANNELS) && (gpd->layers.first)) {
- /* add to list */
- ale= make_new_animlistelem(gpd, ANIMTYPE_GPDATABLOCK, NULL, ANIMTYPE_NONE, NULL);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
+ /* add gpencil animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_GPD(gpd))
+ {
+ tmp_items += animdata_filter_gpencil_data(&tmp_data, gpd, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include data-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* add gpd as channel too (if for drawing, and it has layers) */
+ ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, NULL);
}
- /* 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 ( ANIMCHANNEL_SELOK(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, (ID*)gpd);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- }
- }
- }
+ /* 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 the number of items added to the list */
+ return items;
+}
+
+/* NOTE: owner_id is scene, material, or texture block, which is the direct owner of the node tree in question */
+// TODO: how to handle group nodes is still unclear...
+static size_t animdata_filter_ds_nodetree (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, bNodeTree *ntree, int filter_mode)
+{
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ /* add nodetree animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_NTREE_DATA(ntree))
+ {
+ /* animation data filtering */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ntree, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include data-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by active status */
+ if ANIMCHANNEL_ACTIVEOK(ntree) {
+ ANIMCHANNEL_NEW_CHANNEL(ntree, ANIMTYPE_DSNTREE, owner_id);
}
}
+
+ /* 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 the number of items added to the list */
@@ -1283,16 +1357,11 @@ static int animdata_filter_gpencil (ListBase *anim_data, void *UNUSED(data), int
}
/* NOTE: owner_id is either material, lamp, or world block, which is the direct owner of the texture stack in question */
-static int animdata_filter_dopesheet_texs (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, int filter_mode)
+static size_t animdata_filter_ds_textures (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, int filter_mode)
{
- ListBase texs = {NULL, NULL};
- LinkData *ld;
MTex **mtex = NULL;
- short expanded=0;
- int ownertype = ANIMTYPE_NONE;
-
- bAnimListElem *ale=NULL;
- int items=0, a=0;
+ size_t items=0;
+ int a=0;
/* get datatype specific data first */
if (owner_id == NULL)
@@ -1302,28 +1371,19 @@ static int animdata_filter_dopesheet_texs (bAnimContext *ac, ListBase *anim_data
case ID_MA:
{
Material *ma= (Material *)owner_id;
-
mtex= (MTex**)(&ma->mtex);
- expanded= FILTER_TEX_MATC(ma);
- ownertype= ANIMTYPE_DSMAT;
}
break;
case ID_LA:
{
Lamp *la= (Lamp *)owner_id;
-
mtex= (MTex**)(&la->mtex);
- expanded= FILTER_TEX_LAMC(la);
- ownertype= ANIMTYPE_DSLAM;
}
break;
case ID_WO:
{
World *wo= (World *)owner_id;
-
mtex= (MTex**)(&wo->mtex);
- expanded= FILTER_TEX_WORC(wo);
- ownertype= ANIMTYPE_DSWOR;
}
break;
default:
@@ -1338,235 +1398,137 @@ static int animdata_filter_dopesheet_texs (bAnimContext *ac, ListBase *anim_data
/* firstly check that we actuallly have some textures, by gathering all textures in a temp list */
for (a=0; a < MAX_MTEX; a++) {
Tex *tex= (mtex[a]) ? mtex[a]->tex : NULL;
- short ok = 0;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
/* for now, if no texture returned, skip (this shouldn't confuse the user I hope) */
- if (ELEM(NULL, tex, tex->adt))
+ if (tex == NULL)
continue;
- /* check if ok */
- ANIMDATA_FILTER_CASES(tex,
- { /* AnimData blocks - do nothing... */ },
- ok=1;,
- ok=1;,
- ok=1;)
- if (ok == 0) continue;
-
- /* make a temp list elem for this */
- ld= MEM_callocN(sizeof(LinkData), "DopeSheet-TextureCache");
- ld->data= tex;
- BLI_addtail(&texs, ld);
- }
-
- /* if there were no channels found, no need to carry on */
- if (texs.first == NULL)
- return 0;
-
- /* include textures-expand widget? */
- if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
- ale= make_new_animlistelem(owner_id, ANIMTYPE_FILLTEXD, owner_id, ownertype, owner_id);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- }
-
- /* add textures */
- if ((expanded) || (filter_mode & ANIMFILTER_CURVESONLY)) {
- /* for each texture in cache, add channels */
- for (ld= texs.first; ld; ld= ld->next) {
- Tex *tex= (Tex *)ld->data;
+ /* add texture's animation data to temp collection */
+ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_TEX_DATA(tex))
+ {
+ /* texture animdata */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)tex, filter_mode);
+ /* nodes */
+ if ((tex->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
+ /* owner_id as id instead of texture, since it'll otherwise be impossible to track the depth */
+ // FIXME: perhaps as a result, textures should NOT be included under materials, but under their own section instead
+ // so that free-floating textures can also be animated
+ tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)tex, tex->nodetree, filter_mode);
+ }
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
/* include texture-expand widget? */
- if (filter_mode & ANIMFILTER_CHANNELS) {
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
/* check if filtering by active status */
if ANIMCHANNEL_ACTIVEOK(tex) {
- ale= make_new_animlistelem(tex, ANIMTYPE_DSTEX, owner_id, ownertype, owner_id);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
+ ANIMCHANNEL_NEW_CHANNEL(tex, ANIMTYPE_DSTEX, owner_id);
}
}
- /* add texture's animation data
- * NOTE: for these, we make the owner/ownertype the material/lamp/etc. not the texture, otherwise the
- * drawing code cannot resolve the indention easily
- */
- if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_TEX_DATA(tex) || (filter_mode & ANIMFILTER_CURVESONLY)) {
- ANIMDATA_FILTER_CASES(tex,
- { /* AnimData blocks - do nothing... */ },
- items += animdata_filter_nla(ac, anim_data, ads, tex->adt, filter_mode, owner_id, ownertype, (ID *)tex);,
- items += animdata_filter_fcurves(anim_data, ads, tex->adt->drivers.first, NULL, owner_id, ownertype, filter_mode, (ID *)tex);,
- items += animdata_filter_action(ac, anim_data, ads, tex->adt->action, filter_mode, owner_id, ownertype, (ID *)tex);)
- }
+ /* 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;
}
}
- /* free cache */
- BLI_freelistN(&texs);
-
/* return the number of items added to the list */
return items;
}
-static int animdata_filter_dopesheet_mats (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
+static size_t animdata_filter_ds_materials (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
{
- ListBase mats = {NULL, NULL};
- LinkData *ld;
-
- bAnimListElem *ale=NULL;
- Object *ob= base->object;
- int items=0, a=0;
+ size_t items=0;
+ int a=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);
- short ok = 0;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
- /* for now, if no material returned, skip (this shouldn't confuse the user I hope) */
+ /* if no material returned, skip - so that we don't get weird blank entries... */
if (ma == NULL) continue;
-
- /* check if ok */
- ANIMDATA_FILTER_CASES(ma,
- { /* AnimData blocks - do nothing... */ },
- ok=1;,
- ok=1;,
- ok=1;)
-
- /* need to check textures */
- if (ok == 0 && !(ads->filterflag & ADS_FILTER_NOTEX)) {
- int mtInd;
-
- for (mtInd=0; mtInd < MAX_MTEX; mtInd++) {
- MTex *mtex = ma->mtex[mtInd];
-
- if(mtex && mtex->tex) {
- ANIMDATA_FILTER_CASES(mtex->tex,
- { /* AnimData blocks - do nothing... */ },
- ok=1;,
- ok=1;,
- ok=1;)
- }
-
- if(ok)
- break;
- }
- }
- if (ok == 0) continue;
-
- /* make a temp list elem for this */
- ld= MEM_callocN(sizeof(LinkData), "DopeSheet-MaterialCache");
- ld->data= ma;
- BLI_addtail(&mats, ld);
- }
-
- /* if there were no channels found, no need to carry on */
- if (mats.first == NULL)
- return 0;
-
- /* include materials-expand widget? */
- if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
- ale= make_new_animlistelem(ob, ANIMTYPE_FILLMATD, base, ANIMTYPE_OBJECT, (ID *)ob);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
+ /* 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);
}
- }
-
- /* add materials? */
- if (FILTER_MAT_OBJC(ob) || (filter_mode & ANIMFILTER_CURVESONLY)) {
- /* for each material in cache, add channels */
- for (ld= mats.first; ld; ld= ld->next) {
- Material *ma= (Material *)ld->data;
-
- /* include material-expand widget? */
+ 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_CHANNELS) {
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
/* check if filtering by active status */
if ANIMCHANNEL_ACTIVEOK(ma) {
- ale= make_new_animlistelem(ma, ANIMTYPE_DSMAT, base, ANIMTYPE_OBJECT, (ID *)ma);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
+ ANIMCHANNEL_NEW_CHANNEL(ma, ANIMTYPE_DSMAT, ma);
}
}
- /* add material's animation data */
- if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_MAT_OBJD(ma) || (filter_mode & ANIMFILTER_CURVESONLY)) {
- /* material's animation data */
- ANIMDATA_FILTER_CASES(ma,
- { /* AnimData blocks - do nothing... */ },
- items += animdata_filter_nla(ac, anim_data, ads, ma->adt, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);,
- items += animdata_filter_fcurves(anim_data, ads, ma->adt->drivers.first, NULL, ma, ANIMTYPE_DSMAT, filter_mode, (ID *)ma);,
- items += animdata_filter_action(ac, anim_data, ads, ma->adt->action, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);)
-
- /* textures */
- if (!(ads->filterflag & ADS_FILTER_NOTEX))
- items += animdata_filter_dopesheet_texs(ac, anim_data, ads, (ID *)ma, filter_mode);
- }
+ /* 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;
}
}
- /* free cache */
- BLI_freelistN(&mats);
-
/* return the number of items added to the list */
return items;
}
-static int animdata_filter_dopesheet_particles (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
+static size_t animdata_filter_ds_particles (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
{
- bAnimListElem *ale=NULL;
- Object *ob= base->object;
- ParticleSystem *psys = ob->particlesystem.first;
- int items= 0, first = 1;
-
- for(; psys; psys=psys->next) {
- short ok = 0;
+ ParticleSystem *psys;
+ size_t items= 0;
- if(ELEM(NULL, psys->part, psys->part->adt))
+ for (psys = ob->particlesystem.first; psys; psys=psys->next) {
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+
+ /* if no material returned, skip - so that we don't get weird blank entries... */
+ if (ELEM(NULL, psys->part, psys->part->adt))
continue;
-
- ANIMDATA_FILTER_CASES(psys->part,
- { /* AnimData blocks - do nothing... */ },
- ok=1;,
- ok=1;,
- ok=1;)
- if (ok == 0) continue;
-
- /* include particles-expand widget? */
- if (first && (filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
- ale= make_new_animlistelem(ob, ANIMTYPE_FILLPARTD, base, ANIMTYPE_OBJECT, (ID *)ob);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- first = 0;
+
+ /* add particle-system's animation data to temp collection */
+ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_PART_OBJD(psys->part))
+ {
+ /* material's animation data */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)psys->part, filter_mode);
}
+ END_ANIMFILTER_SUBCHANNELS;
- /* add particle settings? */
- if (FILTER_PART_OBJC(ob) || (filter_mode & ANIMFILTER_CURVESONLY)) {
- if ((filter_mode & ANIMFILTER_CHANNELS)) {
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include particle-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
/* check if filtering by active status */
if ANIMCHANNEL_ACTIVEOK(psys->part) {
- ale = make_new_animlistelem(psys->part, ANIMTYPE_DSPART, base, ANIMTYPE_OBJECT, (ID *)psys->part);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
+ ANIMCHANNEL_NEW_CHANNEL(psys->part, ANIMTYPE_DSPART, psys->part);
}
}
- if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_PART_OBJD(psys->part) || (filter_mode & ANIMFILTER_CURVESONLY)) {
- ANIMDATA_FILTER_CASES(psys->part,
- { /* AnimData blocks - do nothing... */ },
- items += animdata_filter_nla(ac, anim_data, ads, psys->part->adt, filter_mode, psys->part, ANIMTYPE_DSPART, (ID *)psys->part);,
- items += animdata_filter_fcurves(anim_data, ads, psys->part->adt->drivers.first, NULL, psys->part, ANIMTYPE_DSPART, filter_mode, (ID *)psys->part);,
- items += animdata_filter_action(ac, anim_data, ads, psys->part->adt->action, filter_mode, psys->part, ANIMTYPE_DSPART, (ID *)psys->part);)
- }
+ /* 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;
}
}
@@ -1574,14 +1536,14 @@ static int animdata_filter_dopesheet_particles (bAnimContext *ac, ListBase *anim
return items;
}
-static int animdata_filter_dopesheet_obdata (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
+static size_t animdata_filter_ds_obdata (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
{
- bAnimListElem *ale=NULL;
- Object *ob= base->object;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items= 0;
+
IdAdtTemplate *iat= ob->data;
- AnimData *adt= iat->adt;
short type=0, expanded=0;
- int items= 0;
/* get settings based on data type */
switch (ob->type) {
@@ -1589,6 +1551,9 @@ static int animdata_filter_dopesheet_obdata (bAnimContext *ac, ListBase *anim_da
{
Camera *ca= (Camera *)ob->data;
+ if (ads->filterflag & ADS_FILTER_NOCAM)
+ return 0;
+
type= ANIMTYPE_DSCAM;
expanded= FILTER_CAM_OBJD(ca);
}
@@ -1597,6 +1562,9 @@ static int animdata_filter_dopesheet_obdata (bAnimContext *ac, ListBase *anim_da
{
Lamp *la= (Lamp *)ob->data;
+ if (ads->filterflag & ADS_FILTER_NOLAM)
+ return 0;
+
type= ANIMTYPE_DSLAM;
expanded= FILTER_LAM_OBJD(la);
}
@@ -1607,6 +1575,9 @@ static int animdata_filter_dopesheet_obdata (bAnimContext *ac, ListBase *anim_da
{
Curve *cu= (Curve *)ob->data;
+ if (ads->filterflag & ADS_FILTER_NOCUR)
+ return 0;
+
type= ANIMTYPE_DSCUR;
expanded= FILTER_CUR_OBJD(cu);
}
@@ -1615,6 +1586,9 @@ static int animdata_filter_dopesheet_obdata (bAnimContext *ac, ListBase *anim_da
{
MetaBall *mb= (MetaBall *)ob->data;
+ if (ads->filterflag & ADS_FILTER_NOMBA)
+ return 0;
+
type= ANIMTYPE_DSMBALL;
expanded= FILTER_MBALL_OBJD(mb);
}
@@ -1623,6 +1597,9 @@ static int animdata_filter_dopesheet_obdata (bAnimContext *ac, ListBase *anim_da
{
bArmature *arm= (bArmature *)ob->data;
+ if (ads->filterflag & ADS_FILTER_NOARM)
+ return 0;
+
type= ANIMTYPE_DSARM;
expanded= FILTER_ARM_OBJD(arm);
}
@@ -1631,6 +1608,9 @@ static int animdata_filter_dopesheet_obdata (bAnimContext *ac, ListBase *anim_da
{
Mesh *me= (Mesh *)ob->data;
+ if (ads->filterflag & ADS_FILTER_NOMESH)
+ return 0;
+
type= ANIMTYPE_DSMESH;
expanded= FILTER_MESH_OBJD(me);
}
@@ -1639,463 +1619,366 @@ static int animdata_filter_dopesheet_obdata (bAnimContext *ac, ListBase *anim_da
{
Lattice *lt = (Lattice *)ob->data;
+ if (ads->filterflag & ADS_FILTER_NOLAT)
+ return 0;
+
type= ANIMTYPE_DSLAT;
expanded= FILTER_LATTICE_OBJD(lt);
}
break;
- }
-
- /* include data-expand widget? */
- if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) {
- /* check if filtering by active status */
- if ANIMCHANNEL_ACTIVEOK(iat) {
- ale= make_new_animlistelem(iat, type, base, ANIMTYPE_OBJECT, (ID *)iat);
- if (ale) BLI_addtail(anim_data, ale);
+ case OB_SPEAKER: /* ---------- Speaker ----------- */
+ {
+ Speaker *spk= (Speaker *)ob->data;
+
+ type= ANIMTYPE_DSSPK;
+ expanded= FILTER_SPK_OBJD(spk);
}
+ break;
}
- /* add object-data animation channels? */
- if (!(filter_mode & ANIMFILTER_VISIBLE) || (expanded) || (filter_mode & ANIMFILTER_CURVESONLY)) {
- /* filtering for channels - nla, drivers, keyframes */
- ANIMDATA_FILTER_CASES(iat,
- { /* AnimData blocks - do nothing... */ },
- items+= animdata_filter_nla(ac, anim_data, ads, iat->adt, filter_mode, iat, type, (ID *)iat);,
- items+= animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, iat, type, filter_mode, (ID *)iat);,
- items+= animdata_filter_action(ac, anim_data, ads, iat->adt->action, filter_mode, iat, type, (ID *)iat);)
-
+ /* add object data animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
+ {
+ /* animation data filtering */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)iat, filter_mode);
+
/* sub-data filtering... */
switch (ob->type) {
case OB_LAMP: /* lamp - textures */
{
/* textures */
if (!(ads->filterflag & ADS_FILTER_NOTEX))
- items += animdata_filter_dopesheet_texs(ac, anim_data, ads, ob->data, filter_mode);
+ tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, ob->data, filter_mode);
}
break;
}
}
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include data-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by active status */
+ if ANIMCHANNEL_ACTIVEOK(iat) {
+ ANIMCHANNEL_NEW_CHANNEL(iat, type, iat);
+ }
+ }
+
+ /* 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 the number of items added to the list */
return items;
}
-static int animdata_filter_dopesheet_ob (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
+/* shapekey-level animation */
+static size_t animdata_filter_ds_keyanim (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, Key *key, int filter_mode)
{
- bAnimListElem *ale=NULL;
- AnimData *adt = NULL;
- Object *ob= base->object;
- Key *key= ob_get_key(ob);
- short obdata_ok = 0;
- int items = 0;
-
- /* add this object as a channel first */
- if ((filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) == 0) {
- /* check if filtering by selection */
- if ANIMCHANNEL_SELOK((base->flag & SELECT)) {
- /* check if filtering by active status */
- if ANIMCHANNEL_ACTIVEOK(ob) {
- ale= make_new_animlistelem(base, ANIMTYPE_OBJECT, NULL, ANIMTYPE_NONE, (ID *)ob);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- }
- }
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ /* add shapekey-level animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_SKE_OBJD(key))
+ {
+ /* animation data filtering */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)key, filter_mode);
}
+ END_ANIMFILTER_SUBCHANNELS;
- /* if collapsed, don't go any further (unless adding keyframes only) */
- if ( ((filter_mode & ANIMFILTER_VISIBLE) && EXPANDED_OBJC(ob) == 0) &&
- !(filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) )
- return items;
-
- /* Action, Drivers, or NLA */
- if (ob->adt && !(ads->filterflag & ADS_FILTER_NOOBJ)) {
- adt= ob->adt;
- ANIMDATA_FILTER_CASES(ob,
- { /* AnimData blocks - do nothing... */ },
- { /* nla */
- /* add NLA tracks */
- items += animdata_filter_nla(ac, anim_data, ads, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob);
- },
- { /* drivers */
- /* include drivers-expand widget? */
- if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
- ale= make_new_animlistelem(adt->action, ANIMTYPE_FILLDRIVERS, base, ANIMTYPE_OBJECT, (ID *)ob);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- }
-
- /* add F-Curve channels (drivers are F-Curves) */
- if (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_DRVD(adt) || !(filter_mode & ANIMFILTER_CHANNELS)) {
- // need to make the ownertype normal object here... (maybe type should be a separate one for clarity?)
- items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, ob, ANIMTYPE_OBJECT, filter_mode, (ID *)ob);
- }
- },
- { /* action (keyframes) */
- /* include action-expand widget? */
- if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
- ale= make_new_animlistelem(adt->action, ANIMTYPE_FILLACTD, base, ANIMTYPE_OBJECT, (ID *)ob);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- }
-
- /* add F-Curve channels? */
- if (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_ACTC(adt->action) || !(filter_mode & ANIMFILTER_CHANNELS)) {
- // need to make the ownertype normal object here... (maybe type should be a separate one for clarity?)
- items += animdata_filter_action(ac, anim_data, ads, adt->action, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob);
- }
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include key-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ if ANIMCHANNEL_ACTIVEOK(key) {
+ ANIMCHANNEL_NEW_CHANNEL(key, ANIMTYPE_DSSKEY, ob);
}
- );
+ }
+
+ /* 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 the number of items added to the list */
+ return items;
+}
+
+/* object-level animation */
+static size_t animdata_filter_ds_obanim (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
+{
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ AnimData *adt = ob->adt;
+ short type=0, expanded=1;
+ void *cdata = NULL;
+
+ /* determine the type of expander channels to use */
+ // this is the best way to do this for now...
+ ANIMDATA_FILTER_CASES(ob,
+ {/* AnimData - no channel, but consider data */},
+ {/* NLA - no channel, but consider data */},
+ {/* Drivers */
+ type = ANIMTYPE_FILLDRIVERS;
+ cdata = adt;
+ expanded = EXPANDED_DRVD(adt);
+ },
+ {/* Keyframes */
+ type = ANIMTYPE_FILLACTD;
+ cdata = adt->action;
+ expanded = EXPANDED_ACTC(adt->action);
+ });
+
+ /* add object-level animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
+ {
+ /* animation data filtering */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ob, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
- /* ShapeKeys? */
- if ((key) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS)) {
- adt= key->adt;
- ANIMDATA_FILTER_CASES(key,
- { /* AnimData blocks - do nothing... */ },
- { /* nla */
- /* include shapekey-expand widget? */
- if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
- /* check if filtering by active status */
- if ANIMCHANNEL_ACTIVEOK(key) {
- ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- }
- }
-
- /* add NLA tracks - only if expanded or so */
- if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY))
- items += animdata_filter_nla(ac, anim_data, ads, adt, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)key);
- },
- { /* drivers */
- /* include shapekey-expand widget? */
- if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
- ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- }
-
- /* add channels */
- if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY)) {
- items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, key, ANIMTYPE_DSSKEY, filter_mode, (ID *)key);
- }
- },
- { /* action (keyframes) */
- /* include shapekey-expand widget? */
- if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
- /* check if filtering by active status */
- if ANIMCHANNEL_ACTIVEOK(key) {
- ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- }
- }
-
- /* add channels */
- if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY)) {
- items += animdata_filter_action(ac, anim_data, ads, adt->action, filter_mode, key, ANIMTYPE_DSSKEY, (ID *)key);
- }
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include anim-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ if (type != ANIMTYPE_NONE) {
+ /* NOTE: active-status (and the associated checks) don't apply here... */
+ ANIMCHANNEL_NEW_CHANNEL(cdata, type, ob);
}
- );
+ }
+
+ /* 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 the number of items added to the list */
+ return items;
+}
- /* Materials? */
- if ((ob->totcol) && !(ads->filterflag & ADS_FILTER_NOMAT))
- items += animdata_filter_dopesheet_mats(ac, anim_data, ads, base, filter_mode);
+/* get animation channels from object2 */
+static size_t animdata_filter_dopesheet_ob (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
+{
+ ListBase tmp_data = {NULL, NULL};
+ Object *ob= base->object;
+ size_t tmp_items = 0;
+ size_t items = 0;
- /* Object Data */
- switch (ob->type) {
- case OB_CAMERA: /* ------- Camera ------------ */
- {
- Camera *ca= (Camera *)ob->data;
-
- if ((ads->filterflag & ADS_FILTER_NOCAM) == 0) {
- ANIMDATA_FILTER_CASES(ca,
- { /* AnimData blocks - do nothing... */ },
- obdata_ok= 1;,
- obdata_ok= 1;,
- obdata_ok= 1;)
- }
- }
- break;
- case OB_LAMP: /* ---------- Lamp ----------- */
- {
- Lamp *la= (Lamp *)ob->data;
-
- if ((ads->filterflag & ADS_FILTER_NOLAM) == 0) {
- ANIMDATA_FILTER_CASES(la,
- { /* AnimData blocks - do nothing... */ },
- obdata_ok= 1;,
- obdata_ok= 1;,
- obdata_ok= 1;)
- }
+ /* filter data contained under object first */
+ BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_OBJC(ob))
+ {
+ Key *key= ob_get_key(ob);
+
+ /* object-level animation */
+ if ((ob->adt) && !(ads->filterflag & ADS_FILTER_NOOBJ)) {
+ tmp_items += animdata_filter_ds_obanim(ac, &tmp_data, ads, ob, filter_mode);
}
- break;
- case OB_CURVE: /* ------- Curve ---------- */
- case OB_SURF: /* ------- Nurbs Surface ---------- */
- case OB_FONT: /* ------- Text Curve ---------- */
- {
- Curve *cu= (Curve *)ob->data;
-
- if ((ads->filterflag & ADS_FILTER_NOCUR) == 0) {
- ANIMDATA_FILTER_CASES(cu,
- { /* AnimData blocks - do nothing... */ },
- obdata_ok= 1;,
- obdata_ok= 1;,
- obdata_ok= 1;)
- }
+
+ /* shape-key */
+ if ((key && key->adt) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS)) {
+ tmp_items += animdata_filter_ds_keyanim(ac, &tmp_data, ads, ob, key, filter_mode);
}
- break;
- case OB_MBALL: /* ------- MetaBall ---------- */
- {
- MetaBall *mb= (MetaBall *)ob->data;
-
- if ((ads->filterflag & ADS_FILTER_NOMBA) == 0) {
- ANIMDATA_FILTER_CASES(mb,
- { /* AnimData blocks - do nothing... */ },
- obdata_ok= 1;,
- obdata_ok= 1;,
- obdata_ok= 1;)
- }
+
+ /* materials */
+ if ((ob->totcol) && !(ads->filterflag & ADS_FILTER_NOMAT)) {
+ tmp_items += animdata_filter_ds_materials(ac, &tmp_data, ads, ob, filter_mode);
}
- break;
- case OB_ARMATURE: /* ------- Armature ---------- */
- {
- bArmature *arm= (bArmature *)ob->data;
-
- if ((ads->filterflag & ADS_FILTER_NOARM) == 0) {
- ANIMDATA_FILTER_CASES(arm,
- { /* AnimData blocks - do nothing... */ },
- obdata_ok= 1;,
- obdata_ok= 1;,
- obdata_ok= 1;)
- }
+
+ /* object data */
+ if (ob->data) {
+ tmp_items += animdata_filter_ds_obdata(ac, &tmp_data, ads, ob, filter_mode);
}
- break;
- case OB_MESH: /* ------- Mesh ---------- */
- {
- Mesh *me= (Mesh *)ob->data;
-
- if ((ads->filterflag & ADS_FILTER_NOMESH) == 0) {
- ANIMDATA_FILTER_CASES(me,
- { /* AnimData blocks - do nothing... */ },
- obdata_ok= 1;,
- obdata_ok= 1;,
- obdata_ok= 1;)
- }
+
+ /* particles */
+ if ((ob->particlesystem.first) && !(ads->filterflag & ADS_FILTER_NOPART)) {
+ tmp_items += animdata_filter_ds_particles(ac, &tmp_data, ads, ob, filter_mode);
}
- break;
- case OB_LATTICE: /* ------- Lattice ---------- */
- {
- Lattice *lt= (Lattice *)ob->data;
-
- if ((ads->filterflag & ADS_FILTER_NOLAT) == 0) {
- ANIMDATA_FILTER_CASES(lt,
- { /* AnimData blocks - do nothing... */ },
- obdata_ok= 1;,
- obdata_ok= 1;,
- obdata_ok= 1;)
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+
+ /* if we collected some channels, add these to the new list... */
+ if (tmp_items) {
+ /* firstly add object expander if required */
+ 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)) {
+ /* check if filtering by active status */
+ if (ANIMCHANNEL_ACTIVEOK(ob)) {
+ ANIMCHANNEL_NEW_CHANNEL(base, ANIMTYPE_OBJECT, ob);
+ }
}
}
- break;
+
+ /* 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;
}
- if (obdata_ok)
- items += animdata_filter_dopesheet_obdata(ac, anim_data, ads, base, filter_mode);
-
- /* particles */
- if (ob->particlesystem.first && !(ads->filterflag & ADS_FILTER_NOPART))
- items += animdata_filter_dopesheet_particles(ac, anim_data, ads, base, filter_mode);
- /* return the number of items added to the list */
+ /* return the number of items added */
return items;
-}
+}
-static int animdata_filter_dopesheet_scene (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
+static size_t animdata_filter_ds_world (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, World *wo, int filter_mode)
{
- World *wo= sce->world;
- bNodeTree *ntree= sce->nodetree;
- AnimData *adt= NULL;
- bAnimListElem *ale;
- int items = 0;
-
- /* add scene as a channel first (even if we aren't showing scenes we still need to show the scene's sub-data */
- if ((filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) == 0) {
- /* check if filtering by selection */
- if (ANIMCHANNEL_SELOK( (sce->flag & SCE_DS_SELECTED) )) {
- ale= make_new_animlistelem(sce, ANIMTYPE_SCENE, NULL, ANIMTYPE_NONE, NULL);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ /* add world animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_WOR_SCED(wo))
+ {
+ /* 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))
+ items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)wo, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include data-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by active status */
+ if ANIMCHANNEL_ACTIVEOK(wo) {
+ ANIMCHANNEL_NEW_CHANNEL(wo, ANIMTYPE_DSWOR, sce);
}
}
+
+ /* 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;
}
- /* if collapsed, don't go any further (unless adding keyframes only) */
- if ( (EXPANDED_SCEC(sce) == 0) && !(filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) )
- return items;
+ /* return the number of items added to the list */
+ return items;
+}
+
+static size_t animdata_filter_ds_scene (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
+{
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ AnimData *adt = sce->adt;
+ short type=0, expanded=1;
+ void *cdata = NULL;
+
+ /* determine the type of expander channels to use */
+ // this is the best way to do this for now...
+ ANIMDATA_FILTER_CASES(sce,
+ {/* AnimData - no channel, but consider data */},
+ {/* NLA - no channel, but consider data */},
+ {/* Drivers */
+ type = ANIMTYPE_FILLDRIVERS;
+ cdata = adt;
+ expanded = EXPANDED_DRVD(adt);
+ },
+ {/* Keyframes */
+ type = ANIMTYPE_FILLACTD;
+ cdata = adt->action;
+ expanded = EXPANDED_ACTC(adt->action);
+ });
- /* Action, Drivers, or NLA for Scene */
- if ((ads->filterflag & ADS_FILTER_NOSCE) == 0) {
- adt= sce->adt;
- ANIMDATA_FILTER_CASES(sce,
- { /* AnimData blocks - do nothing... */ },
- { /* nla */
- /* add NLA tracks */
- items += animdata_filter_nla(ac, anim_data, ads, adt, filter_mode, sce, ANIMTYPE_SCENE, (ID *)sce);
- },
- { /* drivers */
- /* include drivers-expand widget? */
- if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
- ale= make_new_animlistelem(adt->action, ANIMTYPE_FILLDRIVERS, sce, ANIMTYPE_SCENE, (ID *)sce);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- }
-
- /* add F-Curve channels (drivers are F-Curves) */
- if (EXPANDED_DRVD(adt) || !(filter_mode & ANIMFILTER_CHANNELS)) {
- items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, sce, ANIMTYPE_SCENE, filter_mode, (ID *)sce);
- }
- },
- { /* action */
- /* include action-expand widget? */
- if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
- ale= make_new_animlistelem(adt->action, ANIMTYPE_FILLACTD, sce, ANIMTYPE_SCENE, (ID *)sce);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- }
-
- /* add F-Curve channels? */
- if (EXPANDED_ACTC(adt->action) || !(filter_mode & ANIMFILTER_CHANNELS)) {
- items += animdata_filter_action(ac, anim_data, ads, adt->action, filter_mode, sce, ANIMTYPE_SCENE, (ID *)sce);
- }
- }
- )
+ /* add scene-level animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
+ {
+ /* animation data filtering */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)sce, filter_mode);
}
+ END_ANIMFILTER_SUBCHANNELS;
- /* world */
- if ((wo && wo->adt) && !(ads->filterflag & ADS_FILTER_NOWOR)) {
- /* Action, Drivers, or NLA for World */
- adt= wo->adt;
- ANIMDATA_FILTER_CASES(wo,
- { /* AnimData blocks - do nothing... */ },
- { /* nla */
- /* add NLA tracks */
- items += animdata_filter_nla(ac, anim_data, ads, adt, filter_mode, wo, ANIMTYPE_DSWOR, (ID *)wo);
- },
- { /* drivers */
- /* include world-expand widget? */
- if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
- ale= make_new_animlistelem(wo, ANIMTYPE_DSWOR, sce, ANIMTYPE_SCENE, (ID *)wo);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- }
-
- /* add F-Curve channels (drivers are F-Curves) */
- if (FILTER_WOR_SCED(wo)/*EXPANDED_DRVD(adt)*/ || !(filter_mode & ANIMFILTER_CHANNELS)) {
- // XXX owner info is messed up now...
- items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, wo, ANIMTYPE_DSWOR, filter_mode, (ID *)wo);
- }
- },
- { /* action */
- /* include world-expand widget? */
- if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
- ale= make_new_animlistelem(wo, ANIMTYPE_DSWOR, sce, ANIMTYPE_SCENE, (ID *)sce);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- }
-
- /* add channels */
- if (FILTER_WOR_SCED(wo) || (filter_mode & ANIMFILTER_CURVESONLY)) {
- items += animdata_filter_action(ac, anim_data, ads, adt->action, filter_mode, wo, ANIMTYPE_DSWOR, (ID *)wo);
- }
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include anim-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ if (type != ANIMTYPE_NONE) {
+ /* NOTE: active-status (and the associated checks) don't apply here... */
+ ANIMCHANNEL_NEW_CHANNEL(cdata, type, sce);
}
- )
+ }
- /* if expanded, check world textures too */
- if (FILTER_WOR_SCED(wo) || (filter_mode & ANIMFILTER_CURVESONLY)) {
- /* textures for world */
- if (!(ads->filterflag & ADS_FILTER_NOTEX))
- items += animdata_filter_dopesheet_texs(ac, anim_data, ads, (ID *)wo, filter_mode);
+ /* 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 the number of items added to the list */
+ return items;
+}
+
+static size_t animdata_filter_dopesheet_scene (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
+{
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ /* filter data contained under object first */
+ BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_SCEC(sce))
+ {
+ bNodeTree *ntree= sce->nodetree;
+ World *wo= sce->world;
+
+ /* Action, Drivers, or NLA for Scene */
+ if ((ads->filterflag & ADS_FILTER_NOSCE) == 0) {
+ tmp_items += animdata_filter_ds_scene(ac, &tmp_data, ads, sce, filter_mode);
+ }
+
+ /* world */
+ if ((wo && wo->adt) && !(ads->filterflag & ADS_FILTER_NOWOR)) {
+ tmp_items += animdata_filter_ds_world(ac, &tmp_data, ads, sce, wo, filter_mode);
}
+
+ /* nodetree */
+ if ((ntree && ntree->adt) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
+ tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)sce, ntree, filter_mode);
+ }
+
+ // TODO: one day, when sequencer becomes its own datatype, perhaps it should be included here
}
- /* nodetree */
- if ((ntree && ntree->adt) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
- /* Action, Drivers, or NLA for Nodetree */
- adt= ntree->adt;
- ANIMDATA_FILTER_CASES(ntree,
- { /* AnimData blocks - do nothing... */ },
- { /* nla */
- /* add NLA tracks */
- items += animdata_filter_nla(ac, anim_data, ads, adt, filter_mode, ntree, ANIMTYPE_DSNTREE, (ID *)ntree);
- },
- { /* drivers */
- /* include nodetree-expand widget? */
- if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
- ale= make_new_animlistelem(ntree, ANIMTYPE_DSNTREE, sce, ANIMTYPE_SCENE, (ID *)ntree);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- }
-
- /* add F-Curve channels (drivers are F-Curves) */
- if (FILTER_NTREE_SCED(ntree)/*EXPANDED_DRVD(adt)*/ || !(filter_mode & ANIMFILTER_CHANNELS)) {
- // XXX owner info is messed up now...
- items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, ntree, ANIMTYPE_DSNTREE, filter_mode, (ID *)ntree);
- }
- },
- { /* action */
- /* include nodetree-expand widget? */
- if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
- ale= make_new_animlistelem(ntree, ANIMTYPE_DSNTREE, sce, ANIMTYPE_SCENE, (ID *)sce);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
- }
-
- /* add channels */
- if (FILTER_NTREE_SCED(ntree) || (filter_mode & ANIMFILTER_CURVESONLY)) {
- items += animdata_filter_action(ac, anim_data, ads, adt->action, filter_mode, ntree, ANIMTYPE_DSNTREE, (ID *)ntree);
- }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* if we collected some channels, add these to the new list... */
+ if (tmp_items) {
+ /* firstly add object expander if required */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by selection */
+ if ANIMCHANNEL_SELOK((sce->flag & SCE_DS_SELECTED)) {
+ /* NOTE: active-status doesn't matter for this! */
+ ANIMCHANNEL_NEW_CHANNEL(sce, ANIMTYPE_SCENE, sce);
}
- )
+ }
+
+ /* 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;
}
-
-
- // TODO: scene compositing nodes (these aren't standard node-trees)
- /* return the number of items added to the list */
+ /* return the number of items added */
return items;
}
// 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 int animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, int filter_mode)
+static size_t animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, int filter_mode)
{
Scene *sce= (Scene *)ads->source;
Base *base;
- bAnimListElem *ale;
- int items = 0;
+ size_t items = 0;
/* check that we do indeed have a scene */
if ((ads->source == NULL) || (GS(ads->source->name)!=ID_SCE)) {
@@ -2113,73 +1996,14 @@ static int animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data, bDo
filter_mode |= ANIMFILTER_SELEDIT;
}
- /* scene-linked animation */
- // TODO: sequencer, composite nodes - are we to include those here too?
- {
- short sceOk= 0, worOk= 0, nodeOk=0;
-
- /* check filtering-flags if ok */
- ANIMDATA_FILTER_CASES(sce,
- {
- /* for the special AnimData blocks only case, we only need to add
- * the block if it is valid... then other cases just get skipped (hence ok=0)
- */
- ANIMDATA_ADD_ANIMDATA(sce);
- sceOk=0;
- },
- sceOk= !(ads->filterflag & ADS_FILTER_NOSCE);,
- sceOk= !(ads->filterflag & ADS_FILTER_NOSCE);,
- sceOk= !(ads->filterflag & ADS_FILTER_NOSCE);)
- if (sce->world) {
- ANIMDATA_FILTER_CASES(sce->world,
- {
- /* for the special AnimData blocks only case, we only need to add
- * the block if it is valid... then other cases just get skipped (hence ok=0)
- */
- ANIMDATA_ADD_ANIMDATA(sce->world);
- worOk=0;
- },
- worOk= !(ads->filterflag & ADS_FILTER_NOWOR);,
- worOk= !(ads->filterflag & ADS_FILTER_NOWOR);,
- worOk= !(ads->filterflag & ADS_FILTER_NOWOR);)
- }
- if (sce->nodetree) {
- ANIMDATA_FILTER_CASES(sce->nodetree,
- {
- /* for the special AnimData blocks only case, we only need to add
- * the block if it is valid... then other cases just get skipped (hence ok=0)
- */
- ANIMDATA_ADD_ANIMDATA(sce->nodetree);
- nodeOk=0;
- },
- nodeOk= !(ads->filterflag & ADS_FILTER_NONTREE);,
- nodeOk= !(ads->filterflag & ADS_FILTER_NONTREE);,
- nodeOk= !(ads->filterflag & ADS_FILTER_NONTREE);)
- }
-
- /* if only F-Curves with visible flags set can be shown, check that
- * datablocks haven't been set to invisible
- */
- if (filter_mode & ANIMFILTER_CURVEVISIBLE) {
- if ((sce->adt) && (sce->adt->flag & ADT_CURVES_NOT_VISIBLE))
- sceOk= worOk= nodeOk= 0;
- }
-
- /* check if not all bad (i.e. so there is something to show) */
- if ( !(!sceOk && !worOk && !nodeOk) ) {
- /* add scene data to the list of filtered channels */
- items += animdata_filter_dopesheet_scene(ac, anim_data, ads, sce, filter_mode);
- }
- }
-
+ /* scene-linked animation - e.g. world, compositing nodes, scene anim (including sequencer currently) */
+ items += animdata_filter_dopesheet_scene(ac, anim_data, ads, sce, filter_mode);
- /* loop over all bases in the scene */
+ /* loop over all bases (i.e.objects) 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 actOk=1, keyOk=1, dataOk=1, matOk=1, partOk=1;
/* firstly, check if object can be included, by the following factors:
* - if only visible, must check for layer and also viewport visibility
@@ -2187,10 +2011,10 @@ static int animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data, bDo
* as user option controls whether sets of channels get included while
* tool-flag takes into account collapsed/open channels too
* - if only selected, must check if object is selected
- * - there must be animation data to edit
+ * - there must be animation data to edit (this is done recursively as we
+ * try to add the channels)
*/
- // TODO: if cache is implemented, just check name here, and then
- if ((filter_mode & ANIMFILTER_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
+ 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 ((sce->lay & (ob->lay|base->lay))==0) continue;
@@ -2201,280 +2025,26 @@ static int animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data, bDo
/* if only F-Curves with visible flags set can be shown, check that
* datablock hasn't been set to invisible
*/
- if (filter_mode & ANIMFILTER_CURVEVISIBLE) {
+ if (filter_mode & ANIMFILTER_CURVE_VISIBLE) {
if ((ob->adt) && (ob->adt->flag & ADT_CURVES_NOT_VISIBLE))
continue;
}
- /* additionally, dopesheet filtering also affects what objects to consider */
- {
- /* check selection and object type filters */
- if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (base == sce->basact)*/) ) {
- /* only selected should be shown */
- continue;
- }
-
- /* check if object belongs to the filtering group if option to filter
- * objects by the grouped status is on
- * - used to ease the process of doing multiple-character choreographies
- */
- if (ads->filterflag & ADS_FILTER_ONLYOBGROUP) {
- if (object_in_group(ob, ads->filter_grp) == 0)
- continue;
- }
-
- /* check filters for datatypes */
- /* object */
- actOk= 0;
- if (!(ads->filterflag & ADS_FILTER_NOOBJ)) {
- ANIMDATA_FILTER_CASES(ob,
- {
- /* for the special AnimData blocks only case, we only need to add
- * the block if it is valid... then other cases just get skipped (hence ok=0)
- */
- ANIMDATA_ADD_ANIMDATA(ob);
- actOk=0;
- },
- actOk= 1;,
- actOk= 1;,
- actOk= 1;)
- }
-
- keyOk= 0;
- if ((key) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS)) {
- /* shapekeys */
- ANIMDATA_FILTER_CASES(key,
- {
- /* for the special AnimData blocks only case, we only need to add
- * the block if it is valid... then other cases just get skipped (hence ok=0)
- */
- ANIMDATA_ADD_ANIMDATA(key);
- keyOk=0;
- },
- keyOk= 1;,
- keyOk= 1;,
- keyOk= 1;)
- }
-
- /* materials - only for geometric types */
- matOk= 0; /* by default, not ok... */
- if ( !(ads->filterflag & ADS_FILTER_NOMAT) && (ob->totcol) &&
- ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_MBALL) )
- {
- int a;
-
- /* firstly check that we actuallly have some materials */
- for (a=1; a <= ob->totcol; a++) {
- Material *ma= give_current_material(ob, a);
-
- if (ma) {
- /* if material has relevant animation data, break */
- ANIMDATA_FILTER_CASES(ma,
- {
- /* for the special AnimData blocks only case, we only need to add
- * the block if it is valid... then other cases just get skipped (hence ok=0)
- */
- ANIMDATA_ADD_ANIMDATA(ma);
- matOk=0;
- },
- matOk= 1;,
- matOk= 1;,
- matOk= 1;)
-
- if (matOk)
- break;
-
- /* textures? */
- // TODO: make this a macro that is used in the other checks too
- // NOTE: this has little use on its own, since the actual filtering still ignores if no anim on the data
- if (!(ads->filterflag & ADS_FILTER_NOTEX)) {
- int mtInd;
-
- for (mtInd= 0; mtInd < MAX_MTEX; mtInd++) {
- MTex *mtex= ma->mtex[mtInd];
-
- if (mtex && mtex->tex) {
- /* if texture has relevant animation data, break */
- ANIMDATA_FILTER_CASES(mtex->tex,
- {
- /* for the special AnimData blocks only case, we only need to add
- * the block if it is valid... then other cases just get skipped (hence ok=0)
- */
- ANIMDATA_ADD_ANIMDATA(mtex->tex);
- matOk=0;
- },
- matOk= 1;,
- matOk= 1;,
- matOk= 1;)
-
- if (matOk)
- break;
- }
- }
- }
-
- }
- }
- }
-
- /* data */
- switch (ob->type) {
- case OB_CAMERA: /* ------- Camera ------------ */
- {
- Camera *ca= (Camera *)ob->data;
- dataOk= 0;
- ANIMDATA_FILTER_CASES(ca,
- if ((ads->filterflag & ADS_FILTER_NOCAM)==0) {
- /* for the special AnimData blocks only case, we only need to add
- * the block if it is valid... then other cases just get skipped (hence ok=0)
- */
- ANIMDATA_ADD_ANIMDATA(ca);
- dataOk=0;
- },
- dataOk= !(ads->filterflag & ADS_FILTER_NOCAM);,
- dataOk= !(ads->filterflag & ADS_FILTER_NOCAM);,
- dataOk= !(ads->filterflag & ADS_FILTER_NOCAM);)
- }
- break;
- case OB_LAMP: /* ---------- Lamp ----------- */
- {
- Lamp *la= (Lamp *)ob->data;
- dataOk= 0;
- ANIMDATA_FILTER_CASES(la,
- if ((ads->filterflag & ADS_FILTER_NOLAM)==0) {
- /* for the special AnimData blocks only case, we only need to add
- * the block if it is valid... then other cases just get skipped (hence ok=0)
- */
- ANIMDATA_ADD_ANIMDATA(la);
- dataOk=0;
- },
- dataOk= !(ads->filterflag & ADS_FILTER_NOLAM);,
- dataOk= !(ads->filterflag & ADS_FILTER_NOLAM);,
- dataOk= !(ads->filterflag & ADS_FILTER_NOLAM);)
- }
- break;
- case OB_CURVE: /* ------- Curve ---------- */
- case OB_SURF: /* ------- Nurbs Surface ---------- */
- case OB_FONT: /* ------- Text Curve ---------- */
- {
- Curve *cu= (Curve *)ob->data;
- dataOk= 0;
- ANIMDATA_FILTER_CASES(cu,
- if ((ads->filterflag & ADS_FILTER_NOCUR)==0) {
- /* for the special AnimData blocks only case, we only need to add
- * the block if it is valid... then other cases just get skipped (hence ok=0)
- */
- ANIMDATA_ADD_ANIMDATA(cu);
- dataOk=0;
- },
- dataOk= !(ads->filterflag & ADS_FILTER_NOCUR);,
- dataOk= !(ads->filterflag & ADS_FILTER_NOCUR);,
- dataOk= !(ads->filterflag & ADS_FILTER_NOCUR);)
- }
- break;
- case OB_MBALL: /* ------- MetaBall ---------- */
- {
- MetaBall *mb= (MetaBall *)ob->data;
- dataOk= 0;
- ANIMDATA_FILTER_CASES(mb,
- if ((ads->filterflag & ADS_FILTER_NOMBA)==0) {
- /* for the special AnimData blocks only case, we only need to add
- * the block if it is valid... then other cases just get skipped (hence ok=0)
- */
- ANIMDATA_ADD_ANIMDATA(mb);
- dataOk=0;
- },
- dataOk= !(ads->filterflag & ADS_FILTER_NOMBA);,
- dataOk= !(ads->filterflag & ADS_FILTER_NOMBA);,
- dataOk= !(ads->filterflag & ADS_FILTER_NOMBA);)
- }
- break;
- case OB_ARMATURE: /* ------- Armature ---------- */
- {
- bArmature *arm= (bArmature *)ob->data;
- dataOk= 0;
- ANIMDATA_FILTER_CASES(arm,
- if ((ads->filterflag & ADS_FILTER_NOARM)==0) {
- /* for the special AnimData blocks only case, we only need to add
- * the block if it is valid... then other cases just get skipped (hence ok=0)
- */
- ANIMDATA_ADD_ANIMDATA(arm);
- dataOk=0;
- },
- dataOk= !(ads->filterflag & ADS_FILTER_NOARM);,
- dataOk= !(ads->filterflag & ADS_FILTER_NOARM);,
- dataOk= !(ads->filterflag & ADS_FILTER_NOARM);)
- }
- break;
- case OB_MESH: /* ------- Mesh ---------- */
- {
- Mesh *me= (Mesh *)ob->data;
- dataOk= 0;
- ANIMDATA_FILTER_CASES(me,
- if ((ads->filterflag & ADS_FILTER_NOMESH)==0) {
- /* for the special AnimData blocks only case, we only need to add
- * the block if it is valid... then other cases just get skipped (hence ok=0)
- */
- ANIMDATA_ADD_ANIMDATA(me);
- dataOk=0;
- },
- dataOk= !(ads->filterflag & ADS_FILTER_NOMESH);,
- dataOk= !(ads->filterflag & ADS_FILTER_NOMESH);,
- dataOk= !(ads->filterflag & ADS_FILTER_NOMESH);)
- }
- break;
- case OB_LATTICE: /* ------- Lattice ---------- */
- {
- Lattice *lt= (Lattice *)ob->data;
- dataOk= 0;
- ANIMDATA_FILTER_CASES(lt,
- if ((ads->filterflag & ADS_FILTER_NOLAT)==0) {
- /* for the special AnimData blocks only case, we only need to add
- * the block if it is valid... then other cases just get skipped (hence ok=0)
- */
- ANIMDATA_ADD_ANIMDATA(lt);
- dataOk=0;
- },
- dataOk= !(ads->filterflag & ADS_FILTER_NOLAT);,
- dataOk= !(ads->filterflag & ADS_FILTER_NOLAT);,
- dataOk= !(ads->filterflag & ADS_FILTER_NOLAT);)
- }
- break;
- default: /* --- other --- */
- dataOk= 0;
- break;
- }
-
- /* particles */
- partOk = 0;
- if (!(ads->filterflag & ADS_FILTER_NOPART) && ob->particlesystem.first) {
- ParticleSystem *psys = ob->particlesystem.first;
- for(; psys; psys=psys->next) {
- if (psys->part) {
- /* if particlesettings has relevant animation data, break */
- ANIMDATA_FILTER_CASES(psys->part,
- {
- /* for the special AnimData blocks only case, we only need to add
- * the block if it is valid... then other cases just get skipped (hence ok=0)
- */
- ANIMDATA_ADD_ANIMDATA(psys->part);
- partOk=0;
- },
- partOk= 1;,
- partOk= 1;,
- partOk= 1;)
- }
-
- if (partOk)
- break;
- }
- }
-
- /* check if all bad (i.e. nothing to show) */
- if (!actOk && !keyOk && !dataOk && !matOk && !partOk)
- continue;
+ /* check selection and object type filters */
+ if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (base == sce->basact)*/) ) {
+ /* only selected should be shown */
+ continue;
}
+ /* check if object belongs to the filtering group if option to filter
+ * objects by the grouped status is on
+ * - used to ease the process of doing multiple-character choreographies
+ */
+ if (ads->filterflag & ADS_FILTER_ONLYOBGROUP) {
+ if (object_in_group(ob, ads->filter_grp) == 0)
+ continue;
+ }
+
/* since we're still here, this object should be usable */
items += animdata_filter_dopesheet_ob(ac, anim_data, ads, base, filter_mode);
}
@@ -2487,7 +2057,7 @@ static int animdata_filter_dopesheet (bAnimContext *ac, ListBase *anim_data, bDo
/* Summary track for DopeSheet/Action Editor
* - return code is whether the summary lets the other channels get drawn
*/
-static short animdata_filter_dopesheet_summary (bAnimContext *ac, ListBase *anim_data, int filter_mode, int *items)
+static short animdata_filter_dopesheet_summary (bAnimContext *ac, ListBase *anim_data, int filter_mode, size_t *items)
{
bDopeSheet *ads = NULL;
@@ -2496,8 +2066,8 @@ static short animdata_filter_dopesheet_summary (bAnimContext *ac, ListBase *anim
* since all the other Animation Editors won't have this concept
* being applicable.
*/
- if ((ac && ac->sa) && (ac->sa->spacetype == SPACE_ACTION)) {
- SpaceAction *saction= (SpaceAction *)ac->sa->spacedata.first;
+ if ((ac && ac->sl) && (ac->spacetype == SPACE_ACTION)) {
+ SpaceAction *saction= (SpaceAction *)ac->sl;
ads= &saction->ads;
}
else {
@@ -2509,9 +2079,8 @@ static short animdata_filter_dopesheet_summary (bAnimContext *ac, ListBase *anim
* - only for drawing and/or selecting keyframes in channels, but not for real editing
* - only useful for DopeSheet/Action/etc. editors where it is actually useful
*/
- // TODO: we should really check if some other prohibited filters are also active, but that can be for later
- if ((filter_mode & ANIMFILTER_CHANNELS) && (ads->filterflag & ADS_FILTER_SUMMARY)) {
- bAnimListElem *ale= make_new_animlistelem(ac, ANIMTYPE_SUMMARY, NULL, ANIMTYPE_NONE, NULL);
+ if ((filter_mode & ANIMFILTER_LIST_CHANNELS) && (ads->filterflag & ADS_FILTER_SUMMARY)) {
+ bAnimListElem *ale= make_new_animlistelem(ac, ANIMTYPE_SUMMARY, NULL);
if (ale) {
BLI_addtail(anim_data, ale);
(*items)++;
@@ -2528,13 +2097,39 @@ static short animdata_filter_dopesheet_summary (bAnimContext *ac, ListBase *anim
return 1;
}
+/* ......................... */
+
+/* filter data associated with a channel - usually for handling summary-channels in DopeSheet */
+static size_t animdata_filter_animchan (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAnimListElem *channel, int filter_mode)
+{
+ size_t items = 0;
+
+ /* data to filter depends on channel type */
+ // XXX: only common channel-types have been handled for now
+ switch (channel->type) {
+ case ANIMTYPE_SUMMARY:
+ items += animdata_filter_dopesheet(ac, anim_data, ads, filter_mode);
+ break;
+
+ case ANIMTYPE_SCENE:
+ items += animdata_filter_dopesheet_scene(ac, anim_data, ads, channel->data, filter_mode);
+ break;
+
+ case ANIMTYPE_OBJECT:
+ items += animdata_filter_dopesheet_ob(ac, anim_data, ads, channel->data, filter_mode);
+ break;
+ }
+
+ return items;
+}
+
/* ----------- Cleanup API --------------- */
/* Remove entries with invalid types in animation channel list */
-static int animdata_filter_remove_invalid (ListBase *anim_data)
+static size_t animdata_filter_remove_invalid (ListBase *anim_data)
{
bAnimListElem *ale, *next;
- int items = 0;
+ size_t items = 0;
/* only keep entries with valid types */
for (ale= anim_data->first; ale; ale= next) {
@@ -2550,11 +2145,11 @@ static int animdata_filter_remove_invalid (ListBase *anim_data)
}
/* Remove duplicate entries in animation channel list */
-static int animdata_filter_remove_duplis (ListBase *anim_data)
+static size_t animdata_filter_remove_duplis (ListBase *anim_data)
{
bAnimListElem *ale, *next;
GHash *gh;
- int items = 0;
+ size_t items = 0;
/* build new hashtable to efficiently store and retrieve which entries have been
* encountered already while searching
@@ -2596,9 +2191,9 @@ static int animdata_filter_remove_duplis (ListBase *anim_data)
* will be placed for use.
* filter_mode: how should the data be filtered - bitmapping accessed flags
*/
-int ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode, void *data, short datatype)
+size_t ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode, void *data, short datatype)
{
- int items = 0;
+ size_t items = 0;
/* only filter data if there's somewhere to put it */
if (data && anim_data) {
@@ -2608,12 +2203,12 @@ int ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode
switch (datatype) {
case ANIMCONT_ACTION: /* 'Action Editor' */
{
- SpaceAction *saction = (SpaceAction *)ac->sa->spacedata.first;
+ SpaceAction *saction = (SpaceAction *)ac->sl;
bDopeSheet *ads = (saction)? &saction->ads : NULL;
/* the check for the DopeSheet summary is included here since the summary works here too */
if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
- items += animdata_filter_action(ac, anim_data, ads, data, filter_mode, NULL, ANIMTYPE_NONE, (ID *)obact);
+ items += animfilter_action(ac, anim_data, ads, data, filter_mode, (ID *)obact);
}
break;
@@ -2647,6 +2242,15 @@ int ANIM_animdata_filter (bAnimContext *ac, ListBase *anim_data, int filter_mode
items = animdata_filter_dopesheet(ac, anim_data, data, filter_mode);
}
break;
+
+ case ANIMCONT_CHANNEL: /* animation channel */
+ {
+ bDopeSheet *ads = ac->ads;
+
+ /* based on the channel type, filter relevant data for this */
+ items = animdata_filter_animchan(ac, anim_data, ads, data, filter_mode);
+ }
+ break;
}
/* remove any 'weedy' entries */