[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [13169] trunk/blender/source/blender: == Action Editor - Sample Keys ==
Joshua Leung
aligorith at gmail.com
Tue Jan 8 12:51:45 CET 2008
Revision: 13169
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=13169
Author: aligorith
Date: 2008-01-08 12:51:44 +0100 (Tue, 08 Jan 2008)
Log Message:
-----------
== Action Editor - Sample Keys ==
Cessen Request - Added a tool which inserts keyframes on every frame between two selected keyframes. This is useful for adding overlapping motion (apparently).
Use Alt-O to run this tool. The name of this tool is also open to suggestions ;)
Note:
There is currently a bug with this. When there are 4 consecutive keyframes, it won't add keyframes between keyframes 2 and 3.
Modified Paths:
--------------
trunk/blender/source/blender/include/BIF_editaction.h
trunk/blender/source/blender/src/editaction.c
trunk/blender/source/blender/src/header_action.c
Modified: trunk/blender/source/blender/include/BIF_editaction.h
===================================================================
--- trunk/blender/source/blender/include/BIF_editaction.h 2008-01-08 09:47:44 UTC (rev 13168)
+++ trunk/blender/source/blender/include/BIF_editaction.h 2008-01-08 11:51:44 UTC (rev 13169)
@@ -112,6 +112,7 @@
void delete_action_keys(void);
void delete_action_channels(void);
void clean_action(void);
+void sample_action_keys(void);
/* Column/Channel Key select */
void column_select_action_keys(int mode);
Modified: trunk/blender/source/blender/src/editaction.c
===================================================================
--- trunk/blender/source/blender/src/editaction.c 2008-01-08 09:47:44 UTC (rev 13168)
+++ trunk/blender/source/blender/src/editaction.c 2008-01-08 11:51:44 UTC (rev 13169)
@@ -962,7 +962,7 @@
ListBase act_data = {NULL, NULL};
bActListElem *ale;
int filter;
-
+
/* ask user what to keyframe */
mode = pupmenu("Insert Key%t|All Channels%x1|Only Selected Channels%x2");
if (mode <= 0) return;
@@ -1142,6 +1142,99 @@
allqueue(REDRAWNLA, 0);
}
+
+/* little cache for values... */
+typedef struct tempFrameValCache {
+ float frame, val;
+} tempFrameValCache;
+
+/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
+void sample_action_keys (void)
+{
+ ListBase act_data = {NULL, NULL};
+ bActListElem *ale;
+ int filter;
+ void *data;
+ short datatype;
+
+ /* sanity checks */
+ data= get_action_context(&datatype);
+ if (data == NULL) return;
+
+ /* filter data */
+ filter= (ACTFILTER_VISIBLE | ACTFILTER_FOREDIT | ACTFILTER_ONLYICU);
+ actdata_filter(&act_data, filter, data, datatype);
+
+ /* loop through filtered data and add keys between selected keyframes on every frame */
+ for (ale= act_data.first; ale; ale= ale->next) {
+ IpoCurve *icu= (IpoCurve *)ale->key_data;
+ BezTriple *bezt, *start=NULL, *end=NULL;
+ tempFrameValCache *value_cache, *fp;
+ int sfra, range;
+ int i, n;
+
+ /* find selected keyframes... once pair has been found, add keyframes */
+ for (i=0, bezt=icu->bezt; i < icu->totvert; i++, bezt++) {
+ /* check if selected, and which end this is */
+ if (BEZSELECTED(bezt)) {
+ if (start) {
+ /* set end */
+ end= bezt;
+
+ /* cache values then add keyframes using these values, as adding
+ * keyframes while sampling will affect the outcome...
+ */
+ range= (int)( ceil(end->vec[1][0] - start->vec[1][0]) );
+ sfra= (int)( floor(start->vec[1][0]) );
+
+ if (range) {
+ value_cache= MEM_callocN(sizeof(tempFrameValCache)*range, "IcuFrameValCache");
+
+ /* sample values */
+ for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
+ fp->frame= (float)(sfra + n);
+ fp->val= eval_icu(icu, fp->frame);
+ }
+
+ /* add keyframes with these */
+ for (n=0, fp=value_cache; n<range && fp; n++, fp++) {
+ insert_vert_icu(icu, fp->frame, fp->val, 1);
+ }
+
+ /* free temp cache */
+ MEM_freeN(value_cache);
+ }
+
+ /* as we added keyframes, we need to compensate so that bezt is at the right place */
+ bezt = icu->bezt + i + range;
+ i += range;
+
+ /* bezt was selected, so it now marks the start of a whole new chain to search */
+ start= bezt;
+ end= NULL;
+ }
+ else {
+ /* just set start keyframe */
+ start= bezt;
+ end= NULL;
+ }
+ }
+ }
+
+ /* recalculate channel's handles? */
+ calchandles_ipocurve(icu);
+ }
+
+ /* admin and redraws */
+ BLI_freelistN(&act_data);
+
+ BIF_undo_push("Sample Action Keys");
+ allqueue(REMAKEIPO, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+}
+
/* **************************************************** */
/* COPY/PASTE FOR ACTIONS */
/* - The copy/paste buffer currently stores a set of Action Channels, with temporary
@@ -3087,7 +3180,10 @@
break;
case OKEY:
- clean_action();
+ if (G.qual & LR_ALTKEY)
+ sample_action_keys();
+ else
+ clean_action();
break;
case PKEY:
Modified: trunk/blender/source/blender/src/header_action.c
===================================================================
--- trunk/blender/source/blender/src/header_action.c 2008-01-08 09:47:44 UTC (rev 13168)
+++ trunk/blender/source/blender/src/header_action.c 2008-01-08 11:51:44 UTC (rev 13169)
@@ -117,7 +117,8 @@
enum {
ACTMENU_KEY_DUPLICATE = 0,
ACTMENU_KEY_DELETE,
- ACTMENU_KEY_CLEAN
+ ACTMENU_KEY_CLEAN,
+ ACTMENU_KEY_SAMPLEKEYS
};
enum {
@@ -1006,11 +1007,14 @@
duplicate_action_keys();
break;
case ACTMENU_KEY_DELETE:
- delete_action_keys ();
+ delete_action_keys();
break;
case ACTMENU_KEY_CLEAN:
clean_action();
break;
+ case ACTMENU_KEY_SAMPLEKEYS:
+ sample_action_keys();
+ break;
}
}
@@ -1052,6 +1056,11 @@
"Clean Action|O", 0, yco-=20,
menuwidth, 19, NULL, 0.0, 0.0, 0,
ACTMENU_KEY_CLEAN, "");
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Sample Keys|Alt O", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_KEY_SAMPLEKEYS, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
More information about the Bf-blender-cvs
mailing list