[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [21378] branches/soc-2009-aligorith/source /blender: NLA SoC: Start of 'Meta' Strips

Joshua Leung aligorith at gmail.com
Mon Jul 6 05:44:48 CEST 2009


Revision: 21378
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21378
Author:   aligorith
Date:     2009-07-06 05:44:44 +0200 (Mon, 06 Jul 2009)

Log Message:
-----------
NLA SoC: Start of 'Meta' Strips

Refactored the backend code/API's to support 'meta' strips (i.e. strips containing other strips). These have been implemented to be nested to 'unlimited' depths (in terms of common usages that is, though there is a very remote chance of stack-overflow in theoretrical evil cases only that shouldn't ever be encountered in production).

This paves the way for implementing the necessary tweaks needed for the transform code (in addition to some cool user-level tricks)

Modified Paths:
--------------
    branches/soc-2009-aligorith/source/blender/blenkernel/BKE_nla.h
    branches/soc-2009-aligorith/source/blender/blenkernel/intern/anim_sys.c
    branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c
    branches/soc-2009-aligorith/source/blender/blenloader/intern/readfile.c
    branches/soc-2009-aligorith/source/blender/blenloader/intern/writefile.c
    branches/soc-2009-aligorith/source/blender/editors/space_nla/nla_edit.c
    branches/soc-2009-aligorith/source/blender/editors/space_nla/nla_intern.h
    branches/soc-2009-aligorith/source/blender/makesdna/DNA_anim_types.h

Modified: branches/soc-2009-aligorith/source/blender/blenkernel/BKE_nla.h
===================================================================
--- branches/soc-2009-aligorith/source/blender/blenkernel/BKE_nla.h	2009-07-05 22:26:43 UTC (rev 21377)
+++ branches/soc-2009-aligorith/source/blender/blenkernel/BKE_nla.h	2009-07-06 03:44:44 UTC (rev 21378)
@@ -53,6 +53,13 @@
 /* ----------------------------- */
 /* API */
 
+short BKE_nlastrips_has_space(ListBase *strips, float start, float end);
+void BKE_nlastrips_sort_strips(ListBase *strips);
+
+short BKE_nlastrips_add_strip(ListBase *strips, struct NlaStrip *strip);
+
+/* ............ */
+
 struct NlaTrack *BKE_nlatrack_find_active(ListBase *tracks);
 void BKE_nlatrack_set_active(ListBase *tracks, struct NlaTrack *nlt);
 
@@ -63,6 +70,7 @@
 
 short BKE_nlatrack_add_strip(struct NlaTrack *nlt, struct NlaStrip *strip);
 
+/* ............ */
 
 struct NlaStrip *BKE_nlastrip_find_active(struct NlaTrack *nlt);
 short BKE_nlastrip_within_bounds(struct NlaStrip *strip, float min, float max);

Modified: branches/soc-2009-aligorith/source/blender/blenkernel/intern/anim_sys.c
===================================================================
--- branches/soc-2009-aligorith/source/blender/blenkernel/intern/anim_sys.c	2009-07-05 22:26:43 UTC (rev 21377)
+++ branches/soc-2009-aligorith/source/blender/blenkernel/intern/anim_sys.c	2009-07-06 03:44:44 UTC (rev 21378)
@@ -628,15 +628,13 @@
 }
 
 
-/* gets the strip active at the current time for a track for evaluation purposes */
-static void nlatrack_ctime_get_strip (ListBase *list, NlaTrack *nlt, short index, float ctime)
+/* gets the strip active at the current time for a given list of strips */
+static NlaStrip *ctime_get_strip (ListBase *strips, short *side, float ctime)
 {
 	NlaStrip *strip, *estrip=NULL;
-	NlaEvalStrip *nes;
-	short side= 0;
 	
 	/* loop over strips, checking if they fall within the range */
-	for (strip= nlt->strips.first; strip; strip= strip->next) {
+	for (strip= strips->first; strip; strip= strip->next) {
 		/* check if current time occurs within this strip  */
 		if (IN_RANGE_INCL(ctime, strip->start, strip->end)) {
 			/* this strip is active, so try to use it */
@@ -647,13 +645,13 @@
 		
 		/* if time occurred before current strip... */
 		if (ctime < strip->start) {
-			if (strip == nlt->strips.first) {
+			if (strip == strips->first) {
 				/* before first strip - only try to use it if it extends backwards in time too */
 				if (strip->extendmode == NLASTRIP_EXTEND_HOLD)
 					estrip= strip;
 					
 				/* side is 'before' regardless of whether there's a useful strip */
-				side= NES_TIME_BEFORE;
+				*side= NES_TIME_BEFORE;
 			}
 			else {
 				/* before next strip - previous strip has ended, but next hasn't begun, 
@@ -665,7 +663,7 @@
 				
 				if (strip->extendmode != NLASTRIP_EXTEND_NOTHING)
 					estrip= strip;
-				side= NES_TIME_AFTER;
+				*side= NES_TIME_AFTER;
 			}
 			break;
 		}
@@ -673,11 +671,11 @@
 		/* if time occurred after current strip... */
 		if (ctime > strip->end) {
 			/* only if this is the last strip should we do anything, and only if that is being held */
-			if (strip == nlt->strips.last) {
+			if (strip == strips->last) {
 				if (strip->extendmode != NLASTRIP_EXTEND_NOTHING)
 					estrip= strip;
 					
-				side= NES_TIME_AFTER;
+				*side= NES_TIME_AFTER;
 				break;
 			}
 			
@@ -685,6 +683,35 @@
 		}
 	}
 	
+	/* return the matching strip found */
+	return estrip;
+}
+
+/* gets the strip active at the current time for a track for evaluation purposes */
+static void nlatrack_ctime_get_strip (ListBase *list, NlaTrack *nlt, short index, float ctime)
+{
+	ListBase *strips= &nlt->strips;
+	NlaStrip *strip, *estrip=NULL;
+	NlaEvalStrip *nes;
+	short side= 0;
+	
+	/* keep looping over hierarchy of strips until one which fits for the current time is found */
+	while (strips->first) {
+		/* try to get the strip at this frame for this strip */
+		strip= ctime_get_strip(strips, &side, ctime);
+		
+		/* if a strip was found, make this the new estrip, otherwise, stop trying */
+		if (strip) {
+			/* set new estrip */
+			estrip= strip;
+			
+			/* check children (only available if this is a meta-strip) for better match */
+			strips= &strip->strips;
+		}
+		else
+			break;
+	}
+	
 	/* check if a valid strip was found
 	 *	- must not be muted (i.e. will have contribution
 	 */

Modified: branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c
===================================================================
--- branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c	2009-07-05 22:26:43 UTC (rev 21377)
+++ branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c	2009-07-06 03:44:44 UTC (rev 21378)
@@ -68,10 +68,18 @@
  */
 void free_nlastrip (ListBase *strips, NlaStrip *strip)
 {
+	NlaStrip *cs, *csn;
+	
 	/* sanity checks */
 	if (strip == NULL)
 		return;
 		
+	/* free child-strips */
+	for (cs= strip->strips.first; cs; cs= csn) {
+		csn= cs->next;
+		free_nlastrip(&strip->strips, cs);
+	}
+		
 	/* remove reference to action */
 	if (strip->act)
 		strip->act->id.us--;
@@ -144,6 +152,7 @@
 NlaStrip *copy_nlastrip (NlaStrip *strip)
 {
 	NlaStrip *strip_d;
+	NlaStrip *cs, *cs_d;
 	
 	/* sanity check */
 	if (strip == NULL)
@@ -161,6 +170,14 @@
 	copy_fcurves(&strip_d->fcurves, &strip->fcurves);
 	copy_fmodifiers(&strip_d->modifiers, &strip->modifiers);
 	
+	/* make a copy of all the child-strips, one at a time */
+	strip_d->strips.first= strip_d->strips.last= NULL;
+	
+	for (cs= strip->strips.first; cs; cs= cs->next) {
+		cs_d= copy_nlastrip(cs);
+		BLI_addtail(&strip_d->strips, cs_d);
+	}
+	
 	/* return the strip */
 	return strip_d;
 }
@@ -435,6 +452,7 @@
 float nlastrip_get_frame (NlaStrip *strip, float cframe, short mode)
 {
 	switch (strip->type) {
+		case NLASTRIP_TYPE_META: /* meta (is just a container for other strips, so shouldn't use the action-clip method) */
 		case NLASTRIP_TYPE_TRANSITION: /* transition */
 			return nlastrip_get_frame_transition(strip, cframe, mode);
 		
@@ -487,6 +505,117 @@
 /* *************************************************** */
 /* Basic Utilities */
 
+/* List of Strips ------------------------------------ */
+/* (these functions are used for NLA-Tracks and also for nested/meta-strips) */
+
+/* Check if there is any space in the given list to add the given strip */
+short BKE_nlastrips_has_space (ListBase *strips, float start, float end)
+{
+	NlaStrip *strip;
+	
+	/* sanity checks */
+	if ((strips == NULL) || IS_EQ(start, end))
+		return 0;
+	if (start > end) {
+		puts("BKE_nlastrips_has_space() error... start and end arguments swapped");
+		SWAP(float, start, end);
+	}
+	
+	/* loop over NLA strips checking for any overlaps with this area... */
+	for (strip= strips->first; strip; strip= strip->next) {
+		/* if start frame of strip is past the target end-frame, that means that
+		 * we've gone past the window we need to check for, so things are fine
+		 */
+		if (strip->start > end)
+			return 1;
+		
+		/* if the end of the strip is greater than either of the boundaries, the range
+		 * must fall within the extents of the strip
+		 */
+		if ((strip->end > start) || (strip->end > end))
+			return 0;
+	}
+	
+	/* if we are still here, we haven't encountered any overlapping strips */
+	return 1;
+}
+
+/* Rearrange the strips in the track so that they are always in order 
+ * (usually only needed after a strip has been moved) 
+ */
+void BKE_nlastrips_sort_strips (ListBase *strips)
+{
+	ListBase tmp = {NULL, NULL};
+	NlaStrip *strip, *sstrip;
+	
+	/* sanity checks */
+	if ELEM(NULL, strips, strips->first)
+		return;
+		
+	/* we simply perform insertion sort on this list, since it is assumed that per track,
+	 * there are only likely to be at most 5-10 strips
+	 */
+	for (strip= strips->first; strip; strip= strip->next) {
+		short not_added = 1;
+		
+		/* remove this strip from the list, and add it to the new list, searching from the end of 
+		 * the list, assuming that the lists are in order 
+		 */
+		BLI_remlink(strips, strip);
+		
+		for (sstrip= tmp.last; not_added && sstrip; sstrip= sstrip->prev) {
+			/* check if add after */
+			if (sstrip->end < strip->start) {
+				BLI_insertlinkafter(&tmp, sstrip, strip);
+				not_added= 0;
+				break;
+			}
+		}
+		
+		/* add before first? */
+		if (not_added)
+			BLI_addhead(&tmp, strip);
+	}
+	
+	/* reassign the start and end points of the strips */
+	strips->first= tmp.first;
+	strips->last= tmp.last;
+}
+
+/* Add the given NLA-Strip to the given list of strips, assuming that it 
+ * isn't currently a member of another list
+ */
+short BKE_nlastrips_add_strip (ListBase *strips, NlaStrip *strip)
+{
+	NlaStrip *ns;
+	short not_added = 1;
+	
+	/* sanity checks */
+	if ELEM(NULL, strips, strip)
+		return 0;
+		
+	/* check if any space to add */
+	if (BKE_nlastrips_has_space(strips, strip->start, strip->end)==0)
+		return 0;
+	
+	/* find the right place to add the strip to the nominated track */
+	for (ns= strips->first; ns; ns= ns->next) {
+		/* if current strip occurs after the new strip, add it before */
+		if (ns->start > strip->end) {
+			BLI_insertlinkbefore(strips, ns, strip);
+			not_added= 0;
+			break;
+		}
+	}
+	if (not_added) {
+		/* just add to the end of the list of the strips then... */
+		BLI_addtail(strips, strip);
+	}
+	
+	/* added... */
+	return 1;
+}
+
 /* NLA-Tracks ---------------------------------------- */
 
 /* Find the active NLA-track for the given stack */
@@ -560,36 +689,20 @@
 		nlt_a->flag |= NLATRACK_ACTIVE;
 }
 
-/* Check if there is any space in the last track to add the given strip */
+
+/* Check if there is any space in the given track to add a strip of the given length */
 short BKE_nlatrack_has_space (NlaTrack *nlt, float start, float end)
 {
-	NlaStrip *strip;
-	
 	/* sanity checks */
 	if ((nlt == NULL) || IS_EQ(start, end))
 		return 0;
 	if (start > end) {
-		puts("BKE_nlatrack_has_space error... start and end arguments swapped");
+		puts("BKE_nlatrack_has_space() error... start and end arguments swapped");
 		SWAP(float, start, end);
 	}
 	
-	/* loop over NLA strips checking for any overlaps with this area... */
-	for (strip= nlt->strips.first; strip; strip= strip->next) {
-		/* if start frame of strip is past the target end-frame, that means that
-		 * we've gone past the window we need to check for, so things are fine
-		 */
-		if (strip->start > end)
-			return 1;
-		
-		/* if the end of the strip is greater than either of the boundaries, the range

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list