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. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to