[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [37826] branches/soc-2011-pepper/source/ blender/editors: AnimChannels Filtering Refactor - Part 4
Joshua Leung
aligorith at gmail.com
Sun Jun 26 16:50:20 CEST 2011
Revision: 37826
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=37826
Author: aligorith
Date: 2011-06-26 14:50:19 +0000 (Sun, 26 Jun 2011)
Log Message:
-----------
AnimChannels Filtering Refactor - Part 4
This commit is aimed at cleaning up the filtering code by changing the
filtering idiom/pattern used. While the old code used a "check then
do" approach, the new code does a "grab then assimilate".
The main benefits are that:
* the code duplication that used to exist has now been removed, making
it easier to add new channel types for data
* a recursive "peeking" ability now means that the old problems with
data existing deep in the tree (i.e. figuring out whether a channel
should be shown based on whether it will have any descendents) should
now work much better than before.
In the process, I've found and fixed a few previously unnoticed bugs
with how some channels were constructed, so hopefully things work a
bit better now.
TODO's:
* Action-Group filtering stuff hasn't been refactored yet. This was
causing some grief in the past, so I still need to check this
carefully.
* Material Nodes support (missing in trunk) should be easy to slot in
now :)
Modified Paths:
--------------
branches/soc-2011-pepper/source/blender/editors/animation/anim_filter.c
branches/soc-2011-pepper/source/blender/editors/include/ED_anim_api.h
Modified: branches/soc-2011-pepper/source/blender/editors/animation/anim_filter.c
===================================================================
--- branches/soc-2011-pepper/source/blender/editors/animation/anim_filter.c 2011-06-26 11:08:12 UTC (rev 37825)
+++ branches/soc-2011-pepper/source/blender/editors/animation/anim_filter.c 2011-06-26 14:50:19 UTC (rev 37826)
@@ -329,6 +329,35 @@
/* ************************************************************ */
/* 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)
@@ -338,8 +367,7 @@
/* 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.
@@ -395,17 +423,31 @@
}\
}
+/* ............................... */
-/* 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, (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) )
@@ -860,7 +902,7 @@
}
/* 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;
@@ -907,7 +949,7 @@
return NULL;
}
-static size_t animdata_filter_fcurves (ListBase *anim_data, bDopeSheet *ads, FCurve *first, bActionGroup *grp, 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;
size_t items = 0;
@@ -921,23 +963,18 @@
* 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)
{
- bAnimListElem *ale = make_new_animlistelem(fcu, ANIMTYPE_FCURVE, owner_id);
-
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
+ ANIMCHANNEL_NEW_CHANNEL(fcu, ANIMTYPE_FCURVE, owner_id);
}
/* return the number of items added to the list */
return items;
}
+// TODO: group-filtering stuff still needs cleanup
static size_t animdata_filter_action (bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAction *act, int filter_mode, ID *owner_id)
{
- bAnimListElem *ale=NULL;
bActionGroup *agrp;
FCurve *lastchan=NULL;
size_t items = 0;
@@ -993,7 +1030,7 @@
*
* 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);
+ first_fcu = animfilter_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
@@ -1010,11 +1047,7 @@
if (filter_gmode & ANIMFILTER_LIST_CHANNELS) {
/* 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, owner_id);
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
+ ANIMCHANNEL_NEW_CHANNEL(agrp, ANIMTYPE_GROUP, owner_id);
}
}
@@ -1041,7 +1074,7 @@
{
if (!(filter_gmode & 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, filter_gmode, owner_id);
+ items += animfilter_fcurves(anim_data, ads, first_fcu, agrp, filter_gmode, owner_id);
}
}
}
@@ -1052,7 +1085,7 @@
/* loop over un-grouped F-Curves (only if we're not only considering those channels in the animive 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, filter_mode, owner_id);
+ items += animfilter_fcurves(anim_data, ads, (lastchan)?(lastchan->next):(act->curves.first), NULL, filter_mode, owner_id);
}
/* return the number of items added to the list */
@@ -1067,9 +1100,8 @@
* - 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 size_t animdata_filter_nla (bAnimContext *UNUSED(ac), ListBase *anim_data, bDopeSheet *UNUSED(ads), AnimData *adt, int filter_mode, ID *owner_id)
+static size_t animfilter_nla (bAnimContext *UNUSED(ac), ListBase *anim_data, bDopeSheet *UNUSED(ads), AnimData *adt, int filter_mode, ID *owner_id)
{
- bAnimListElem *ale;
NlaTrack *nlt;
NlaTrack *first=NULL, *next=NULL;
size_t items = 0;
@@ -1077,19 +1109,15 @@
/* if showing channels, include active action */
if (filter_mode & ANIMFILTER_LIST_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_id);
- ale->data= (adt->action) ? adt->action : NULL;
-
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
+ ANIMCHANNEL_NEW_CHANNEL_FULL((void *)(&adt->action), ANIMTYPE_NLAACTION, owner_id,
+ {
+ ale->data= adt->action ? adt->action : NULL;
+ });
}
/* first track to include will be the last one if we're filtering by channels */
@@ -1121,12 +1149,7 @@
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_id);
-
- if (ale) {
- BLI_addtail(anim_data, ale);
- items++;
- }
+ ANIMCHANNEL_NEW_CHANNEL(nlt, ANIMTYPE_NLATRACK, owner_id);
}
}
}
@@ -1136,10 +1159,40 @@
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)
+{
+ IdAdtTemplate *iat = (IdAdtTemplate*)id;
+ AnimData *adt = BKE_animdata_from_id(id);
+ size_t items = 0;
+
+ /* 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 */
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list