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);
|
void transform_meshchannel_keys(char mode, struct Key *key);
|
||||||
struct Key *get_action_mesh_key(void);
|
struct Key *get_action_mesh_key(void);
|
||||||
int get_nearest_key_num(struct Key *key, short *mval, float *x);
|
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 up_sel_action(void);
|
||||||
void down_sel_action(void);
|
void down_sel_action(void);
|
||||||
void top_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 ipo_record(void);
|
||||||
|
|
||||||
void sethandles_ipo_keys(struct Ipo *ipo, int code);
|
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 setipotype_ipo(struct Ipo *ipo, int code);
|
||||||
void set_ipo_key_selection(struct Ipo *ipo, int sel);
|
void set_ipo_key_selection(struct Ipo *ipo, int sel);
|
||||||
int is_ipo_key_selected(struct Ipo *ipo);
|
int is_ipo_key_selected(struct Ipo *ipo);
|
||||||
|
@ -1997,41 +1997,91 @@ void set_extendtype_actionchannels(int extendtype)
|
|||||||
allqueue(REDRAWNLA, 0);
|
allqueue(REDRAWNLA, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_snap_actionchannels(void)
|
static void set_snap_actionchannels(bAction *act, short snaptype)
|
||||||
{
|
{
|
||||||
|
/* snapping function for action channels*/
|
||||||
bAction *act;
|
|
||||||
bActionChannel *chan;
|
bActionChannel *chan;
|
||||||
bConstraintChannel *conchan;
|
bConstraintChannel *conchan;
|
||||||
|
|
||||||
/* Get the selected action, exit if none are selected
|
|
||||||
*/
|
|
||||||
act = G.saction->action;
|
|
||||||
if (!act)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/* Loop through the channels */
|
/* Loop through the channels */
|
||||||
for (chan = act->chanbase.first; chan; chan=chan->next){
|
for (chan = act->chanbase.first; chan; chan=chan->next){
|
||||||
if((chan->flag & ACHAN_HIDDEN)==0) {
|
if((chan->flag & ACHAN_HIDDEN)==0) {
|
||||||
if (chan->ipo) {
|
if (chan->ipo) {
|
||||||
snap_ipo_keys(chan->ipo);
|
snap_ipo_keys(chan->ipo, snaptype);
|
||||||
}
|
}
|
||||||
/* constraint channels */
|
/* constraint channels */
|
||||||
for (conchan=chan->constraintChannels.first; conchan; conchan= conchan->next) {
|
for (conchan=chan->constraintChannels.first; conchan; conchan= conchan->next) {
|
||||||
if (conchan->ipo) {
|
if (conchan->ipo) {
|
||||||
snap_ipo_keys(conchan->ipo);
|
snap_ipo_keys(conchan->ipo, snaptype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 */
|
/* Clean up and redraw stuff */
|
||||||
remake_action_ipos (act);
|
remake_action_ipos (act);
|
||||||
BIF_undo_push("Snap Ipo Action channel");
|
BIF_undo_push("Snap To Nearest Frame");
|
||||||
allspace(REMAKEIPO, 0);
|
allspace(REMAKEIPO, 0);
|
||||||
allqueue(REDRAWACTION, 0);
|
allqueue(REDRAWACTION, 0);
|
||||||
allqueue(REDRAWIPO, 0);
|
allqueue(REDRAWIPO, 0);
|
||||||
allqueue(REDRAWNLA, 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:
|
case SKEY:
|
||||||
if (mval[0]>=ACTWIDTH) {
|
if (mval[0]>=ACTWIDTH) {
|
||||||
if(G.qual & LR_SHIFTKEY) {
|
if(G.qual & LR_SHIFTKEY) {
|
||||||
if(okee("Snap to frame"))
|
snap_keys_to_frame();
|
||||||
set_snap_actionchannels();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (key)
|
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)
|
if(bezt->f2 & SELECT)
|
||||||
bezt->vec[1][0]= (float)(floor(bezt->vec[1][0]+0.5));
|
bezt->vec[1][0]= (float)(floor(bezt->vec[1][0]+0.5));
|
||||||
return 0;
|
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)
|
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);
|
bake_action_with_client (G.saction->action, OBACT, 0.01);
|
||||||
break;
|
break;
|
||||||
case ACTMENU_KEY_SNAP:
|
case ACTMENU_KEY_SNAP:
|
||||||
set_snap_actionchannels();
|
snap_keys_to_frame();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user