[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