[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [20356] branches/soc-2009-aligorith/source /blender/blenkernel: NLA SoC: Adding more backend code/utilities

Joshua Leung aligorith at gmail.com
Sat May 23 11:36:19 CEST 2009


Revision: 20356
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=20356
Author:   aligorith
Date:     2009-05-23 11:36:18 +0200 (Sat, 23 May 2009)

Log Message:
-----------
NLA SoC: Adding more backend code/utilities

* Data copying
* Strip sorting

Modified Paths:
--------------
    branches/soc-2009-aligorith/source/blender/blenkernel/BKE_action.h
    branches/soc-2009-aligorith/source/blender/blenkernel/BKE_nla.h
    branches/soc-2009-aligorith/source/blender/blenkernel/intern/action.c
    branches/soc-2009-aligorith/source/blender/blenkernel/intern/anim_sys.c
    branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c

Modified: branches/soc-2009-aligorith/source/blender/blenkernel/BKE_action.h
===================================================================
--- branches/soc-2009-aligorith/source/blender/blenkernel/BKE_action.h	2009-05-23 07:37:02 UTC (rev 20355)
+++ branches/soc-2009-aligorith/source/blender/blenkernel/BKE_action.h	2009-05-23 09:36:18 UTC (rev 20356)
@@ -68,6 +68,9 @@
 /* Some kind of bounding box operation on the action */
 void calc_action_range(const struct bAction *act, float *start, float *end, int incl_hidden);
 
+/* Does action have any motion data at all? */
+short action_has_motion(const struct bAction *act);
+
 /* Action Groups API ----------------- */
 
 /* Make the given Action Group the active one */

Modified: branches/soc-2009-aligorith/source/blender/blenkernel/BKE_nla.h
===================================================================
--- branches/soc-2009-aligorith/source/blender/blenkernel/BKE_nla.h	2009-05-23 07:37:02 UTC (rev 20355)
+++ branches/soc-2009-aligorith/source/blender/blenkernel/BKE_nla.h	2009-05-23 09:36:18 UTC (rev 20356)
@@ -42,6 +42,10 @@
 void free_nlatrack(ListBase *tracks, struct NlaTrack *nlt);
 void free_nladata(ListBase *tracks);
 
+struct NlaStrip *copy_nlastrip(struct NlaStrip *strip);
+struct NlaTrack *copy_nlatrack(struct NlaTrack *nlt);
+void copy_nladata(ListBase *dst, ListBase *src);
+
 struct NlaStrip *add_nlastrip(struct NlaTrack *nlt, struct bAction *act);
 struct NlaTrack *add_nlatrack(struct AnimData *adt);
 
@@ -49,8 +53,11 @@
 /* API */
 
 struct NlaTrack *BKE_nlatrack_find_active(ListBase *tracks);
-void BKE_nlatrack_set_active(ListBase *tracks, struct NlaTrack *nlt_a);
+void BKE_nlatrack_set_active(ListBase *tracks, struct NlaTrack *nlt);
 
+short BKE_nlatrack_has_space(struct NlaTrack *nlt, float start, float end);
+void BKE_nlatrack_sort_strips(struct NlaTrack *nlt);
+
 void BKE_nla_action_pushdown(struct AnimData *adt);
 
 #endif

Modified: branches/soc-2009-aligorith/source/blender/blenkernel/intern/action.c
===================================================================
--- branches/soc-2009-aligorith/source/blender/blenkernel/intern/action.c	2009-05-23 07:37:02 UTC (rev 20355)
+++ branches/soc-2009-aligorith/source/blender/blenkernel/intern/action.c	2009-05-23 09:36:18 UTC (rev 20356)
@@ -740,8 +740,23 @@
 }
 
 
+/* Check if the given action has any keyframes */
+short action_has_motion(const bAction *act)
+{
+	FCurve *fcu;
+	
+	/* return on the first F-Curve that has some keyframes/samples defined */
+	if (act) {
+		for (fcu= act->curves.first; fcu; fcu= fcu->next) {
+			if (fcu->totvert)
+				return 1;
+		}
+	}
+	
+	/* nothing found */
+	return 0;
+}
 
-
 /* Calculate the extents of given action */
 void calc_action_range(const bAction *act, float *start, float *end, int incl_hidden)
 {

Modified: branches/soc-2009-aligorith/source/blender/blenkernel/intern/anim_sys.c
===================================================================
--- branches/soc-2009-aligorith/source/blender/blenkernel/intern/anim_sys.c	2009-05-23 07:37:02 UTC (rev 20355)
+++ branches/soc-2009-aligorith/source/blender/blenkernel/intern/anim_sys.c	2009-05-23 09:36:18 UTC (rev 20356)
@@ -153,7 +153,7 @@
 	dadt->action= copy_action(adt->action);
 	
 	/* duplicate NLA data */
-	// XXX todo...
+	copy_nladata(&dadt->nla_tracks, &adt->nla_tracks);
 	
 	/* duplicate drivers (F-Curves) */
 	copy_fcurves(&dadt->drivers, &adt->drivers);

Modified: branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c
===================================================================
--- branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c	2009-05-23 07:37:02 UTC (rev 20355)
+++ branches/soc-2009-aligorith/source/blender/blenkernel/intern/nla.c	2009-05-23 09:36:18 UTC (rev 20356)
@@ -145,8 +145,74 @@
 
 /* Copying ------------------------------------------- */
 
-// TODO...
+/* Copy NLA strip */
+NlaStrip *copy_nlastrip (NlaStrip *strip)
+{
+	NlaStrip *strip_d;
+	
+	/* sanity check */
+	if (strip == NULL)
+		return NULL;
+		
+	/* make a copy */
+	strip_d= MEM_dupallocN(strip);
+	strip_d->next= strip_d->prev= NULL;
+	
+	/* increase user-count of action */
+	if (strip_d->act)
+		strip_d->act->id.us++;
+		
+	/* copy F-Curves and modifiers */
+	copy_fcurves(&strip_d->fcurves, &strip->fcurves);
+	fcurve_copy_modifiers(&strip_d->modifiers, &strip->modifiers);
+	
+	/* return the strip */
+	return strip_d;
+}
 
+/* Copy NLA Track */
+NlaTrack *copy_nlatrack (NlaTrack *nlt)
+{
+	NlaStrip *strip, *strip_d;
+	NlaTrack *nlt_d;
+	
+	/* sanity check */
+	if (nlt == NULL)
+		return NULL;
+		
+	/* make a copy */
+	nlt_d= MEM_dupallocN(nlt);
+	nlt_d->next= nlt_d->prev= NULL;
+	
+	/* make a copy of all the strips, one at a time */
+	nlt_d->strips.first= nlt_d->strips.last= NULL;
+	
+	for (strip= nlt->strips.first; strip; strip= strip->next) {
+		strip_d= copy_nlastrip(strip);
+		BLI_addtail(&nlt_d->strips, strip_d);
+	}
+	
+	/* return the copy */
+	return nlt_d;
+}
+
+/* Copy all NLA data */
+void copy_nladata (ListBase *dst, ListBase *src)
+{
+	NlaTrack *nlt, *nlt_d;
+	
+	/* sanity checks */
+	if ELEM(NULL, dst, src)
+		return;
+		
+	/* copy each NLA-track, one at a time */
+	for (nlt= src->first; nlt; nlt= nlt->next) {
+		/* make a copy, and add the copy to the destination list */
+		nlt_d= copy_nlatrack(nlt);
+		BLI_addtail(dst, nlt_d);
+	}
+}
+
 /* Adding ------------------------------------------- */
 
 /* Add a NLA Strip referencing the given Action, to the given NLA Track */
@@ -224,7 +290,7 @@
 /* *************************************************** */
 /* Basic Utilities */
 
-/* States ------------------------------------------- */
+/* NLA-Tracks ---------------------------------------- */
 
 /* Find the active NLA-track for the given stack */
 NlaTrack *BKE_nlatrack_find_active (ListBase *tracks)
@@ -265,6 +331,80 @@
 		nlt_a->flag |= NLATRACK_ACTIVE;
 }
 
+/* Check if there is any space in the last track to add the given strip */
+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");
+		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
+		 * 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_nlatrack_sort_strips (NlaTrack *nlt)
+{
+	ListBase tmp = {NULL, NULL};
+	NlaStrip *strip, *sstrip;
+	
+	/* sanity checks */
+	if ELEM(NULL, nlt, nlt->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= nlt->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(&nlt->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 */
+	nlt->strips.first= tmp.first;
+	nlt->strips.last= tmp.last;
+}
+ 
 /* Tools ------------------------------------------- */
 
 /* For the given AnimData block, add the active action to the NLA
@@ -286,7 +426,9 @@
 	/* if the action is empty, we also shouldn't try to add to stack, 
 	 * as that will cause us grief down the track
 	 */
-	// TODO: code a method for this, and report errors after...
+	// TODO: what about modifiers?
+	if (action_has_motion(adt->action) == 0)
+		return;
 		
 	/* add a new NLA track to house this action 
 	 *	- we could investigate trying to fit the action into an appropriately





More information about the Bf-blender-cvs mailing list