[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [10966] trunk/blender/source/blender: == Action Editor - Long Keyframes ==

Joshua Leung aligorith at gmail.com
Tue Jun 19 11:46:54 CEST 2007


Revision: 10966
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=10966
Author:   aligorith
Date:     2007-06-19 11:46:52 +0200 (Tue, 19 Jun 2007)

Log Message:
-----------
== Action Editor - Long Keyframes ==

I've recoded the way long keyframes work a bit, so that more cases are handled accurately. Now, it takes into account the number of IPO-curves that have keyframes in them on the start/end frame of the long-keyframe, instead of just taking the total number of IPO-curves present for the channel being drawn.

Modified Paths:
--------------
    trunk/blender/source/blender/include/BDR_drawaction.h
    trunk/blender/source/blender/src/drawaction.c

Modified: trunk/blender/source/blender/include/BDR_drawaction.h
===================================================================
--- trunk/blender/source/blender/include/BDR_drawaction.h	2007-06-19 04:12:08 UTC (rev 10965)
+++ trunk/blender/source/blender/include/BDR_drawaction.h	2007-06-19 09:46:52 UTC (rev 10966)
@@ -41,6 +41,19 @@
 struct Object;
 struct ListBase;
 
+/* ****************************** Base Structs ****************************** */
+
+/* Keyframe Column Struct */
+typedef struct ActKeyColumn {
+	struct ActKeyColumn *next, *prev;
+	short sel, handle_type;
+	float cfra;
+	
+	/* only while drawing - used to determine if long-keyframe needs to be drawn */
+	short modified;
+	short totcurve;
+} ActKeyColumn;
+
 /* 'Long Keyframe' Struct */
 typedef struct ActKeyBlock {
 	struct ActKeyBlock *next, *prev;
@@ -53,7 +66,10 @@
 	short totcurve; 
 } ActKeyBlock;
 
-/*Action Generics */
+
+/* ******************************* Methods ****************************** */
+
+/* Action Generics */
 void draw_cfra_action(void);
 int count_action_levels (struct bAction *act);
 
@@ -65,9 +81,9 @@
 
 /* Keydata Generation */
 void icu_to_keylist(struct IpoCurve *icu, ListBase *keys, ListBase *blocks);
-int ipo_to_keylist(struct Ipo *ipo, ListBase *keys, ListBase *blocks);
-int action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks);
-int ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks);
+void ipo_to_keylist(struct Ipo *ipo, ListBase *keys, ListBase *blocks);
+void action_to_keylist(bAction *act, ListBase *keys, ListBase *blocks);
+void ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks);
 
 #endif  /*  BDR_DRAWACTION_H */
 

Modified: trunk/blender/source/blender/src/drawaction.c
===================================================================
--- trunk/blender/source/blender/src/drawaction.c	2007-06-19 04:12:08 UTC (rev 10965)
+++ trunk/blender/source/blender/src/drawaction.c	2007-06-19 09:46:52 UTC (rev 10966)
@@ -926,6 +926,8 @@
 	uiDrawBlocksPanels(sa, 0);
 }
 
+/* ************************* Action Editor Space ***************************** */
+
 void drawactionspace(ScrArea *sa, void *spacedata)
 {
 	short ofsx = 0, ofsy = 0;
@@ -1077,9 +1079,131 @@
 	curarea->win_swap= WIN_BACK_OK;
 }
 
-static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, float ypos, int totcurve)
+/* *************************** Keyframe Drawing *************************** */
+
+static void add_bezt_to_keycolumnslist(ListBase *keys, BezTriple *bezt)
 {
-	CfraElem *ce;
+	/* The equivilant of add_to_cfra_elem except this version 
+	 * makes ActKeyColumns - one of the two datatypes required
+	 * for action editor drawing.
+	 */
+	ActKeyColumn *ak, *akn;
+	
+	if (!(keys) || !(bezt)) return;
+	
+	/* try to find a keyblock that starts on the previous beztriple */
+	for (ak= keys->first; ak; ak= ak->next) {
+		/* do because of double keys */
+		if (ak->cfra == bezt->vec[1][0]) {			
+			/* set selection status and 'touched' status */
+			if (BEZSELECTED(bezt)) ak->sel = SELECT;
+			ak->modified += 1;
+			
+			return;
+		}
+		else if (ak->cfra > bezt->vec[1][0]) break;
+	}
+	
+	/* add new block */
+	akn= MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
+	if (ak) BLI_insertlinkbefore(keys, ak, akn);
+	else BLI_addtail(keys, akn);
+	
+	akn->cfra= bezt->vec[1][0];
+	akn->modified += 1;
+	
+	// TODO: handle type = bezt->h1 or bezt->h2
+	akn->handle_type= 0; 
+	
+	if (BEZSELECTED(bezt))
+		akn->sel = SELECT;
+	else
+		akn->sel = 0;
+}
+
+static void add_bezt_to_keyblockslist(ListBase *blocks, IpoCurve *icu, int index)
+{
+	/* The equivilant of add_to_cfra_elem except this version 
+	 * makes ActKeyBlocks - one of the two datatypes required
+	 * for action editor drawing.
+	 */
+	ActKeyBlock *ab, *abn;
+	BezTriple *beztn=NULL, *prev=NULL;
+	BezTriple *bezt;
+	int v;
+	
+	/* get beztriples */
+	beztn= (icu->bezt + index);
+	
+	for (v=0, bezt=icu->bezt; v<icu->totvert; v++, bezt++) {
+		/* skip if beztriple is current */
+		if (v != index) {
+			/* check if beztriple is immediately before */
+			if (beztn->vec[1][0] > bezt->vec[1][0]) {
+				/* check if closer than previous was */
+				if (prev) {
+					if (prev->vec[1][0] < bezt->vec[1][0])
+						prev= bezt;
+				}
+				else {
+					prev= bezt;
+				}
+			}
+		}
+	}
+	
+	/* check if block needed - same value? */
+	if ((!prev) || (!beztn))
+		return;
+	if (beztn->vec[1][1] != prev->vec[1][1])
+		return;
+	
+	/* try to find a keyblock that starts on the previous beztriple */
+	for (ab= blocks->first; ab; ab= ab->next) {
+		/* check if alter existing block or add new block */
+		if (ab->start == prev->vec[1][0]) {			
+			/* set selection status and 'touched' status */
+			if (BEZSELECTED(beztn)) ab->sel = SELECT;
+			ab->modified += 1;
+			
+			return;
+		}
+		else if (ab->start > prev->vec[1][0]) break;
+	}
+	
+	/* add new block */
+	abn= MEM_callocN(sizeof(ActKeyBlock), "ActKeyBlock");
+	if (ab) BLI_insertlinkbefore(blocks, ab, abn);
+	else BLI_addtail(blocks, abn);
+	
+	abn->start= prev->vec[1][0];
+	abn->end= beztn->vec[1][0];
+	abn->val= beztn->vec[1][1];
+	
+	if (BEZSELECTED(prev) || BEZSELECTED(beztn))
+		abn->sel = SELECT;
+	abn->modified = 1;
+}
+
+/* helper function - find actkeycolumn that occurs on cframe */
+static ActKeyColumn *cfra_find_actkeycolumn (ListBase *keys, float cframe)
+{
+	ActKeyColumn *ak;
+	
+	if (keys==NULL) 
+		return NULL;
+	 
+	for (ak= keys->first; ak; ak= ak->next) {
+		if (ak->cfra == cframe)
+			return ak;
+	}
+	
+	return NULL;
+}
+
+static void draw_keylist(gla2DDrawInfo *di, ListBase *keys, ListBase *blocks, float ypos)
+{
+	ActKeyColumn *ak;
 	ActKeyBlock *ab;
 	
 	glEnable(GL_BLEND);
@@ -1087,8 +1211,22 @@
 	/* draw keyblocks */
 	if (blocks) {
 		for (ab= blocks->first; ab; ab= ab->next) {
-			/* only draw keyblock if it appears in all curves sampled */
-			if (ab->totcurve == totcurve) {
+			short startCurves, endCurves, totCurves;
+			
+			/* find out how many curves occur at each keyframe */
+			ak= cfra_find_actkeycolumn(keys, ab->start);
+			startCurves = (ak)? ak->totcurve: 0;
+			
+			ak= cfra_find_actkeycolumn(keys, ab->end);
+			endCurves = (ak)? ak->totcurve: 0;
+			
+			/* only draw keyblock if it appears in at all of the keyframes at lowest end */
+			if (!startCurves && !endCurves) 
+				continue;
+			else
+				totCurves = (startCurves>endCurves)? endCurves: startCurves;
+				
+			if (ab->totcurve >= totCurves) {
 				int sc_xa, sc_ya;
 				int sc_xb, sc_yb;
 				
@@ -1108,13 +1246,13 @@
 	
 	/* draw keys */
 	if (keys) {
-		for (ce= keys->first; ce; ce= ce->next) {
+		for (ak= keys->first; ak; ak= ak->next) {
 			int sc_x, sc_y;
 			
 			/* get co-ordinate to draw at */
-			gla2DDrawTranslatePt(di, ce->cfra, ypos, &sc_x, &sc_y);
+			gla2DDrawTranslatePt(di, ak->cfra, ypos, &sc_x, &sc_y);
 			
-			if(ce->sel & 1) BIF_icon_draw_aspect(sc_x-7, sc_y-6, ICON_SPACE2, 1.0f);
+			if(ak->sel & 1) BIF_icon_draw_aspect(sc_x-7, sc_y-6, ICON_SPACE2, 1.0f);
 			else BIF_icon_draw_aspect(sc_x-7, sc_y-6, ICON_SPACE3, 1.0f);
 		}	
 	}
@@ -1126,10 +1264,9 @@
 {
 	ListBase keys = {0, 0};
 	ListBase blocks = {0, 0};
-	int totcurve;
 
-	totcurve= ob_to_keylist(ob, &keys, &blocks);
-	draw_keylist(di, &keys, &blocks, ypos, totcurve);
+	ob_to_keylist(ob, &keys, &blocks);
+	draw_keylist(di, &keys, &blocks, ypos);
 	
 	BLI_freelistN(&keys);
 	BLI_freelistN(&blocks);
@@ -1139,10 +1276,9 @@
 {
 	ListBase keys = {0, 0};
 	ListBase blocks = {0, 0};
-	int totcurve;
 
-	totcurve= ipo_to_keylist(ipo, &keys, &blocks);
-	draw_keylist(di, &keys, &blocks, ypos, totcurve);
+	ipo_to_keylist(ipo, &keys, &blocks);
+	draw_keylist(di, &keys, &blocks, ypos);
 	
 	BLI_freelistN(&keys);
 	BLI_freelistN(&blocks);
@@ -1154,7 +1290,7 @@
 	ListBase blocks = {0, 0};
 
 	icu_to_keylist(icu, &keys, &blocks);
-	draw_keylist(di, &keys, &blocks, ypos, 1);
+	draw_keylist(di, &keys, &blocks, ypos);
 	
 	BLI_freelistN(&keys);
 	BLI_freelistN(&blocks);
@@ -1165,116 +1301,35 @@
 	ListBase keys = {0, 0};
 
 	action_to_keylist(act, &keys, NULL);
-	draw_keylist(di, &keys, NULL, ypos, 0);
+	draw_keylist(di, &keys, NULL, ypos);
 	BLI_freelistN(&keys);
 }
 
-static void add_bezt_to_keyblockslist(ListBase *blocks, IpoCurve *icu, int index)
+void ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks)
 {
-	/* The equivilant of add_to_cfra_elem except this version 
-	 * makes ActKeyBlocks - one of the two datatypes required
-	 * for action editor drawing.
-	 */
-	ActKeyBlock *ab, *abn;
-	BezTriple *beztn=NULL, *prev=NULL;
-	BezTriple *bezt;
-	int v;
-	
-	/* get beztriples */
-	beztn= (icu->bezt + index);
-	/* The following search for previous beztriple doesn't work
-	 * that great on actions with a large amount of keys. There
-	 * are a few commented out shortcuts for these cases, which will
-	 * remain so until the definitive point where slowdown starts to
-	 * bite is determined.
-	 */
-	//if (icu->totvert > 3500) {
-	//	if (index >= 1) 
-	//		prev= (icu->bezt + (index - 1));
-	//}
-	//else {
-		for (v=0, bezt=icu->bezt; v<icu->totvert; v++, bezt++) {
-			/* skip if beztriple is current */
-			if (v != index) {
-				/* check if beztriple is immediately before */
-				if (beztn->vec[1][0] > bezt->vec[1][0]) {
-					/* check if closer than previous was */
-					if (prev) {
-						if (prev->vec[1][0] < bezt->vec[1][0])
-							prev= bezt;
-					}
-					else {
-						prev= bezt;
-					}
-				}
-			}
-		}
-	//}
-	
-	/* check if block needed - same value? */
-	if ((!prev) || (!beztn))
-		return;
-	if (beztn->vec[1][1] != prev->vec[1][1])
-		return;
-	
-	/* try to find a keyblock that starts on the previous beztriple */
-	for (ab= blocks->first; ab; ab= ab->next) {
-		/* check if alter existing block or add new block */
-		if (ab->start == prev->vec[1][0]) {			
-			/* set selection status and 'touched' status */
-			if (BEZSELECTED(beztn)) ab->sel = SELECT;
-			ab->modified += 1;
-			
-			return;
-		}
-		else if (ab->start > prev->vec[1][0]) break;
-	}
-	
-	/* add new block */
-	abn= MEM_callocN(sizeof(ActKeyBlock), "add_bezt_to_keyblockslist");
-	if (ab) BLI_insertlinkbefore(blocks, ab, abn);
-	else BLI_addtail(blocks, abn);
-	
-	abn->start= prev->vec[1][0];
-	abn->end= beztn->vec[1][0];
-	abn->val= beztn->vec[1][1];
-	
-	if (BEZSELECTED(prev) || BEZSELECTED(beztn))
-		abn->sel = SELECT;
-	else
-		abn->sel = 0;
-	abn->modified += 1;
-}
-
-int ob_to_keylist(Object *ob, ListBase *keys, ListBase *blocks)
-{
 	bConstraintChannel *conchan;
-	int totcurve = 0;
 
 	if (ob) {
 		/* Add object keyframes */
-		if (ob->ipo) {

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list