== 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 */
|
/* Key operations */
|
||||||
void transform_action_keys(int mode, int dummy);
|
void transform_action_keys(int mode, int dummy);
|
||||||
void duplicate_action_keys(void);
|
void duplicate_action_keys(void);
|
||||||
|
void snap_cfra_action(void);
|
||||||
void snap_action_keys(short mode);
|
void snap_action_keys(short mode);
|
||||||
void mirror_action_keys(short mode);
|
void mirror_action_keys(short mode);
|
||||||
void insertkey_action(void);
|
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 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 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 snap_ipo_keys(struct Ipo *ipo, short snaptype);
|
||||||
void mirror_ipo_keys(struct Ipo *ipo, short mirror_mode);
|
void mirror_ipo_keys(struct Ipo *ipo, short mirror_mode);
|
||||||
void setipotype_ipo(struct Ipo *ipo, int code);
|
void setipotype_ipo(struct Ipo *ipo, int code);
|
||||||
|
@@ -779,6 +779,45 @@ void duplicate_action_keys (void)
|
|||||||
transform_action_keys('g', 0);
|
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 */
|
/* this function is responsible for snapping keyframes to frame-times */
|
||||||
void snap_action_keys(short mode)
|
void snap_action_keys(short mode)
|
||||||
{
|
{
|
||||||
@@ -2793,7 +2832,12 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
|||||||
|
|
||||||
case SKEY:
|
case SKEY:
|
||||||
if (mval[0]>=ACTWIDTH) {
|
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 (data) {
|
||||||
if (G.saction->flag & SACTION_DRAWTIME)
|
if (G.saction->flag & SACTION_DRAWTIME)
|
||||||
val = pupmenu("Snap Keys To%t|Nearest Second%x4|Current Time%x2|Nearest Marker %x3");
|
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 */
|
/* 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
|
/* restore = whether to map points back to ipo-time
|
||||||
* only_keys = whether to only adjust the location of the center point of beztriples
|
* 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_CURFRAME,
|
||||||
ACTMENU_KEY_SNAP_NEARMARK,
|
ACTMENU_KEY_SNAP_NEARMARK,
|
||||||
ACTMENU_KEY_SNAP_NEARTIME,
|
ACTMENU_KEY_SNAP_NEARTIME,
|
||||||
|
ACTMENU_KEY_SNAP_CFRA2KEY,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -872,6 +873,10 @@ static void do_action_keymenu_snapmenu(void *arg, int event)
|
|||||||
case ACTMENU_KEY_SNAP_NEARTIME:
|
case ACTMENU_KEY_SNAP_NEARTIME:
|
||||||
snap_action_keys(event);
|
snap_action_keys(event);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ACTMENU_KEY_SNAP_CFRA2KEY:
|
||||||
|
snap_cfra_action();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
scrarea_queue_winredraw(curarea);
|
scrarea_queue_winredraw(curarea);
|
||||||
@@ -888,27 +893,35 @@ static uiBlock *action_keymenu_snapmenu(void *arg_unused)
|
|||||||
|
|
||||||
if (G.saction->flag & SACTION_DRAWTIME) {
|
if (G.saction->flag & SACTION_DRAWTIME) {
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
|
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,
|
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||||
ACTMENU_KEY_SNAP_NEARTIME, "");
|
ACTMENU_KEY_SNAP_NEARTIME, "");
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
|
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,
|
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||||
ACTMENU_KEY_SNAP_CURFRAME, "");
|
ACTMENU_KEY_SNAP_CURFRAME, "");
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
|
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,
|
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||||
ACTMENU_KEY_SNAP_NEARFRAME, "");
|
ACTMENU_KEY_SNAP_NEARFRAME, "");
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
|
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,
|
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||||
ACTMENU_KEY_SNAP_CURFRAME, "");
|
ACTMENU_KEY_SNAP_CURFRAME, "");
|
||||||
}
|
}
|
||||||
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
|
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,
|
menuwidth, 19, NULL, 0.0, 0.0, 0,
|
||||||
ACTMENU_KEY_SNAP_NEARMARK, "");
|
ACTMENU_KEY_SNAP_NEARMARK, "");
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user