== Action Editor - Snap Current-Frame Marker to Keys ==
This little feature snaps the current frame marker to the average frame of all the selected keyframes. Use the hotkey Ctrl-Shift-S to use it.
This commit is contained in:
@@ -104,6 +104,7 @@ struct ListBase;
|
||||
/* Key operations */
|
||||
void transform_action_keys(int mode, int dummy);
|
||||
void duplicate_action_keys(void);
|
||||
void snap_cfra_action(void);
|
||||
void snap_action_keys(short mode);
|
||||
void mirror_action_keys(short mode);
|
||||
void insertkey_action(void);
|
||||
|
@@ -151,6 +151,7 @@ void transform_ipo(int mode);
|
||||
void actstrip_map_ipo_keys(struct Object *ob, struct Ipo *ipo, short restore, short only_keys);
|
||||
|
||||
void sethandles_ipo_keys(struct Ipo *ipo, int code);
|
||||
void snap_cfra_ipo_keys(struct Ipo *ipo, short mode);
|
||||
void snap_ipo_keys(struct Ipo *ipo, short snaptype);
|
||||
void mirror_ipo_keys(struct Ipo *ipo, short mirror_mode);
|
||||
void setipotype_ipo(struct Ipo *ipo, int code);
|
||||
|
@@ -779,6 +779,45 @@ void duplicate_action_keys (void)
|
||||
transform_action_keys('g', 0);
|
||||
}
|
||||
|
||||
/* this function is responsible for snapping the current frame to selected data */
|
||||
void snap_cfra_action()
|
||||
{
|
||||
ListBase act_data = {NULL, NULL};
|
||||
bActListElem *ale;
|
||||
int filter;
|
||||
void *data;
|
||||
short datatype;
|
||||
|
||||
/* get data */
|
||||
data= get_action_context(&datatype);
|
||||
if (data == NULL) return;
|
||||
|
||||
/* filter data */
|
||||
filter= (ACTFILTER_VISIBLE | ACTFILTER_IPOKEYS);
|
||||
actdata_filter(&act_data, filter, data, datatype);
|
||||
|
||||
/* snap current frame to selected data */
|
||||
snap_cfra_ipo_keys(NULL, -1);
|
||||
|
||||
for (ale= act_data.first; ale; ale= ale->next) {
|
||||
if (NLA_ACTION_SCALED && datatype==ACTCONT_ACTION) {
|
||||
actstrip_map_ipo_keys(OBACT, ale->key_data, 0, 1);
|
||||
snap_cfra_ipo_keys(ale->key_data, 0);
|
||||
actstrip_map_ipo_keys(OBACT, ale->key_data, 1, 1);
|
||||
}
|
||||
else
|
||||
snap_cfra_ipo_keys(ale->key_data, 0);
|
||||
}
|
||||
BLI_freelistN(&act_data);
|
||||
|
||||
snap_cfra_ipo_keys(NULL, 1);
|
||||
|
||||
BIF_undo_push("Snap Current Frame to Keys");
|
||||
allqueue(REDRAWACTION, 0);
|
||||
allqueue(REDRAWIPO, 0);
|
||||
allqueue(REDRAWNLA, 0);
|
||||
}
|
||||
|
||||
/* this function is responsible for snapping keyframes to frame-times */
|
||||
void snap_action_keys(short mode)
|
||||
{
|
||||
@@ -2793,7 +2832,12 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
|
||||
case SKEY:
|
||||
if (mval[0]>=ACTWIDTH) {
|
||||
if (G.qual & LR_SHIFTKEY) {
|
||||
if (G.qual == (LR_SHIFTKEY|LR_CTRLKEY)) {
|
||||
if (data) {
|
||||
snap_cfra_action();
|
||||
}
|
||||
}
|
||||
else if (G.qual & LR_SHIFTKEY) {
|
||||
if (data) {
|
||||
if (G.saction->flag & SACTION_DRAWTIME)
|
||||
val = pupmenu("Snap Keys To%t|Nearest Second%x4|Current Time%x2|Nearest Marker %x3");
|
||||
|
@@ -723,6 +723,53 @@ void mirror_ipo_keys(Ipo *ipo, short mirror_type)
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is called to calculate the average location of the
|
||||
* selected keyframes, and place the current frame at that location.
|
||||
*
|
||||
* It must be called like so:
|
||||
* snap_cfra_ipo_keys(NULL, -1); // initialise the static vars first
|
||||
* for (ipo...) snap_cfra_ipo_keys(ipo, 0); // sum up keyframe times
|
||||
* snap_cfra_ipo_keys(NULL, 1); // set current frame after taking average
|
||||
*/
|
||||
void snap_cfra_ipo_keys(Ipo *ipo, short mode)
|
||||
{
|
||||
static int cfra;
|
||||
static int tot;
|
||||
|
||||
IpoCurve *icu;
|
||||
BezTriple *bezt;
|
||||
int a;
|
||||
|
||||
|
||||
if (mode == -1) {
|
||||
/* initialise a new snap-operation */
|
||||
cfra= 0;
|
||||
tot= 0;
|
||||
}
|
||||
else if (mode == 1) {
|
||||
/* set current frame - using average frame */
|
||||
if (tot != 0)
|
||||
CFRA = cfra / tot;
|
||||
}
|
||||
else {
|
||||
/* loop through keys in ipo, summing the frame
|
||||
* numbers of those that are selected
|
||||
*/
|
||||
if (ipo == NULL)
|
||||
return;
|
||||
|
||||
for (icu= ipo->curve.first; icu; icu= icu->next) {
|
||||
for (a=0, bezt=icu->bezt; a < icu->totvert; a++, bezt++) {
|
||||
if (BEZSELECTED(bezt)) {
|
||||
cfra += bezt->vec[1][0];
|
||||
tot++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* currently only used by some action editor tools, but may soon get used by ipo editor */
|
||||
/* restore = whether to map points back to ipo-time
|
||||
* only_keys = whether to only adjust the location of the center point of beztriples
|
||||
|
@@ -158,6 +158,7 @@ enum {
|
||||
ACTMENU_KEY_SNAP_CURFRAME,
|
||||
ACTMENU_KEY_SNAP_NEARMARK,
|
||||
ACTMENU_KEY_SNAP_NEARTIME,
|
||||
ACTMENU_KEY_SNAP_CFRA2KEY,
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -872,6 +873,10 @@ static void do_action_keymenu_snapmenu(void *arg, int event)
|
||||
case ACTMENU_KEY_SNAP_NEARTIME:
|
||||
snap_action_keys(event);
|
||||
break;
|
||||
|
||||
case ACTMENU_KEY_SNAP_CFRA2KEY:
|
||||
snap_cfra_action();
|
||||
break;
|
||||
}
|
||||
|
||||
scrarea_queue_winredraw(curarea);
|
||||
@@ -888,27 +893,35 @@ static uiBlock *action_keymenu_snapmenu(void *arg_unused)
|
||||
|
||||
if (G.saction->flag & SACTION_DRAWTIME) {
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
|
||||
"Nearest Second|Shift S, 1", 0, yco-=20,
|
||||
"Key -> Nearest Second|Shift S, 1", 0, yco-=20,
|
||||
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||
ACTMENU_KEY_SNAP_NEARTIME, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
|
||||
"Current Time|Shift S, 2", 0, yco-=20,
|
||||
"Key -> Current Time|Shift S, 2", 0, yco-=20,
|
||||
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||
ACTMENU_KEY_SNAP_CURFRAME, "");
|
||||
|
||||
}
|
||||
else {
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
|
||||
"Nearest Frame|Shift S, 1", 0, yco-=20,
|
||||
"Key -> Nearest Frame|Shift S, 1", 0, yco-=20,
|
||||
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||
ACTMENU_KEY_SNAP_NEARFRAME, "");
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
|
||||
"Current Frame|Shift S, 2", 0, yco-=20,
|
||||
"Key -> Current Frame|Shift S, 2", 0, yco-=20,
|
||||
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||
ACTMENU_KEY_SNAP_CURFRAME, "");
|
||||
}
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
|
||||
"Nearest Marker|Shift S, 3", 0, yco-=20,
|
||||
"Key -> Nearest Marker|Shift S, 3", 0, yco-=20,
|
||||
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||
ACTMENU_KEY_SNAP_NEARMARK, "");
|
||||
|
||||
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
|
||||
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
|
||||
|
||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
|
||||
"Current Frame -> Key|Ctrl Shift S", 0, yco-=20,
|
||||
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||
ACTMENU_KEY_SNAP_NEARMARK, "");
|
||||
|
||||
|
Reference in New Issue
Block a user