forked from bartvdbraak/blender
Patch #5028. by Joshua Leung (aligorith)
Key snapping in Action Window, cleanup and added option to snap to current frame.
This commit is contained in:
parent
a221ddcf9b
commit
2e93510a6b
@ -77,7 +77,9 @@ void transform_actionchannel_keys(int mode, int dummy);
|
||||
void transform_meshchannel_keys(char mode, struct Key *key);
|
||||
struct Key *get_action_mesh_key(void);
|
||||
int get_nearest_key_num(struct Key *key, short *mval, float *x);
|
||||
void set_snap_actionchannels(void);
|
||||
void snap_keys_to_frame(void);
|
||||
|
||||
/* channel/strip operations */
|
||||
void up_sel_action(void);
|
||||
void down_sel_action(void);
|
||||
void top_sel_action(void);
|
||||
|
@ -135,7 +135,7 @@ void sampledata_to_ipocurve(float *data, int sfra, int efra, struct IpoCurve *ic
|
||||
void ipo_record(void);
|
||||
|
||||
void sethandles_ipo_keys(struct Ipo *ipo, int code);
|
||||
void snap_ipo_keys(struct Ipo *ipo);
|
||||
void snap_ipo_keys(struct Ipo *ipo, short snaptype);
|
||||
void setipotype_ipo(struct Ipo *ipo, int code);
|
||||
void set_ipo_key_selection(struct Ipo *ipo, int sel);
|
||||
int is_ipo_key_selected(struct Ipo *ipo);
|
||||
|
@ -1997,41 +1997,91 @@ void set_extendtype_actionchannels(int extendtype)
|
||||
allqueue(REDRAWNLA, 0);
|
||||
}
|
||||
|
||||
void set_snap_actionchannels(void)
|
||||
static void set_snap_actionchannels(bAction *act, short snaptype)
|
||||
{
|
||||
|
||||
bAction *act;
|
||||
/* snapping function for action channels*/
|
||||
bActionChannel *chan;
|
||||
bConstraintChannel *conchan;
|
||||
|
||||
/* Get the selected action, exit if none are selected
|
||||
*/
|
||||
act = G.saction->action;
|
||||
if (!act)
|
||||
return;
|
||||
|
||||
/* Loop through the channels */
|
||||
for (chan = act->chanbase.first; chan; chan=chan->next){
|
||||
if((chan->flag & ACHAN_HIDDEN)==0) {
|
||||
if (chan->ipo) {
|
||||
snap_ipo_keys(chan->ipo);
|
||||
snap_ipo_keys(chan->ipo, snaptype);
|
||||
}
|
||||
/* constraint channels */
|
||||
for (conchan=chan->constraintChannels.first; conchan; conchan= conchan->next) {
|
||||
if (conchan->ipo) {
|
||||
snap_ipo_keys(conchan->ipo);
|
||||
snap_ipo_keys(conchan->ipo, snaptype);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up and redraw stuff */
|
||||
remake_action_ipos (act);
|
||||
BIF_undo_push("Snap Ipo Action channel");
|
||||
allspace(REMAKEIPO, 0);
|
||||
allqueue(REDRAWACTION, 0);
|
||||
allqueue(REDRAWIPO, 0);
|
||||
allqueue(REDRAWNLA, 0);
|
||||
static void set_snap_meshchannels(Key *key, short snaptype)
|
||||
{
|
||||
/* snapping function for mesh channels */
|
||||
if(key->ipo) {
|
||||
snap_ipo_keys(key->ipo, snaptype);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void snap_keys_to_frame()
|
||||
{
|
||||
/* This function is the generic entry-point for snapping keyframes
|
||||
* to a frame(s). It passes the work off to sub-functions for the
|
||||
* different types in the action editor.
|
||||
*/
|
||||
|
||||
SpaceAction *saction;
|
||||
bAction *act;
|
||||
Key *key;
|
||||
short event;
|
||||
|
||||
/* get data */
|
||||
saction= curarea->spacedata.first;
|
||||
if (!saction) return;
|
||||
act = saction->action;
|
||||
key = get_action_mesh_key();
|
||||
|
||||
/* find the type of snapping to do */
|
||||
event = pupmenu("Snap Frames To%t|Nearest Frame%x1|Current Frame%x2");
|
||||
|
||||
/* handle events */
|
||||
switch (event) {
|
||||
case 1: /* snap to nearest frame */
|
||||
if (act)
|
||||
set_snap_actionchannels(act, event);
|
||||
else
|
||||
set_snap_meshchannels(key, event);
|
||||
|
||||
/* Clean up and redraw stuff */
|
||||
remake_action_ipos (act);
|
||||
BIF_undo_push("Snap To Nearest Frame");
|
||||
allspace(REMAKEIPO, 0);
|
||||
allqueue(REDRAWACTION, 0);
|
||||
allqueue(REDRAWIPO, 0);
|
||||
allqueue(REDRAWNLA, 0);
|
||||
|
||||
break;
|
||||
case 2: /* snap to current frame */
|
||||
if (act)
|
||||
set_snap_actionchannels(act, event);
|
||||
else
|
||||
set_snap_meshchannels(key, event);
|
||||
|
||||
/* Clean up and redraw stuff */
|
||||
remake_action_ipos (act);
|
||||
BIF_undo_push("Snap To Current Frame");
|
||||
allspace(REMAKEIPO, 0);
|
||||
allqueue(REDRAWACTION, 0);
|
||||
allqueue(REDRAWIPO, 0);
|
||||
allqueue(REDRAWNLA, 0);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2517,8 +2567,7 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
|
||||
case SKEY:
|
||||
if (mval[0]>=ACTWIDTH) {
|
||||
if(G.qual & LR_SHIFTKEY) {
|
||||
if(okee("Snap to frame"))
|
||||
set_snap_actionchannels();
|
||||
snap_keys_to_frame();
|
||||
}
|
||||
else {
|
||||
if (key)
|
||||
|
@ -555,16 +555,33 @@ void sethandles_ipo_keys(Ipo *ipo, int code)
|
||||
}
|
||||
}
|
||||
|
||||
static int snap_bezier(BezTriple *bezt)
|
||||
static int snap_bezier_nearest(BezTriple *bezt)
|
||||
{
|
||||
if(bezt->f2 & SELECT)
|
||||
bezt->vec[1][0]= (float)(floor(bezt->vec[1][0]+0.5));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void snap_ipo_keys(Ipo *ipo)
|
||||
static int snap_bezier_cframe(BezTriple *bezt)
|
||||
{
|
||||
ipo_keys_bezier_loop(ipo, snap_bezier, calchandles_ipocurve);
|
||||
if(bezt->f2 & SELECT)
|
||||
bezt->vec[1][0]= (float)CFRA;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void snap_ipo_keys(Ipo *ipo, short snaptype)
|
||||
{
|
||||
switch (snaptype) {
|
||||
case 1: /* snap to nearest */
|
||||
ipo_keys_bezier_loop(ipo, snap_bezier_nearest, calchandles_ipocurve);
|
||||
break;
|
||||
case 2: /* snap to current frame */
|
||||
ipo_keys_bezier_loop(ipo, snap_bezier_cframe, calchandles_ipocurve);
|
||||
break;
|
||||
default: /* just in case */
|
||||
ipo_keys_bezier_loop(ipo, snap_bezier_nearest, calchandles_ipocurve);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void ipo_curves_auto_horiz(void)
|
||||
|
@ -778,7 +778,7 @@ static void do_action_keymenu(void *arg, int event)
|
||||
bake_action_with_client (G.saction->action, OBACT, 0.01);
|
||||
break;
|
||||
case ACTMENU_KEY_SNAP:
|
||||
set_snap_actionchannels();
|
||||
snap_keys_to_frame();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user