Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Leung <aligorith@gmail.com>2006-12-02 09:00:31 +0300
committerJoshua Leung <aligorith@gmail.com>2006-12-02 09:00:31 +0300
commitac43fe5afdb4eb2d5684c686c31b087495e350d9 (patch)
treeac8f751c58f7e2dfec18b3c0d7186b557f87b3d0 /source/blender
parent28bbf2d61616f7b8b3c59b54b46af7ee4dbf1e11 (diff)
== Action Editor ==
Now it is possible to mirror selected keyframes in the action editor; either over the current frame or the vertical axis. Hotkey is: SHIFT M (like in ipo editor).
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/include/BIF_editaction.h2
-rw-r--r--source/blender/include/BSE_editipo.h1
-rw-r--r--source/blender/src/editaction.c156
-rw-r--r--source/blender/src/editipo_mods.c39
-rw-r--r--source/blender/src/header_action.c52
5 files changed, 202 insertions, 48 deletions
diff --git a/source/blender/include/BIF_editaction.h b/source/blender/include/BIF_editaction.h
index e6cd5765360..ca4f7944460 100644
--- a/source/blender/include/BIF_editaction.h
+++ b/source/blender/include/BIF_editaction.h
@@ -80,9 +80,11 @@ 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 snap_keys_to_frame(int snap_mode);
+void mirror_action_keys(short mirror_mode);
void clean_shapekeys(struct Key *key);
void clean_actionchannels(struct bAction *act);
+
/* Marker Operations */
void get_minmax_saction_markers(float *first, float *last);
void selectkeys_columns_markers(void);
diff --git a/source/blender/include/BSE_editipo.h b/source/blender/include/BSE_editipo.h
index b7da37bb2e2..b4f53979121 100644
--- a/source/blender/include/BSE_editipo.h
+++ b/source/blender/include/BSE_editipo.h
@@ -140,6 +140,7 @@ void ipo_record(void);
void sethandles_ipo_keys(struct Ipo *ipo, int code);
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);
void set_ipo_key_selection(struct Ipo *ipo, int sel);
int is_ipo_key_selected(struct Ipo *ipo);
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
index 54f5d041c2b..c7d5223f702 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -2083,48 +2083,113 @@ void snap_keys_to_frame(int snap_mode)
SpaceAction *saction;
bAction *act;
Key *key;
+ char str[32];
/* get data */
saction= curarea->spacedata.first;
if (!saction) return;
act = saction->action;
key = get_action_mesh_key();
-
- /* handle events */
+
+ /* determine mode */
switch (snap_mode) {
- case 1: /* snap to nearest frame */
- if (act)
- set_snap_actionchannels(act, snap_mode);
- else
- set_snap_meshchannels(key, snap_mode);
-
- /* 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);
-
+ case 1:
+ strcpy(str, "Snap Keys To Nearest Frame");
break;
- case 2: /* snap to current frame */
- if (act)
- set_snap_actionchannels(act, snap_mode);
- else
- set_snap_meshchannels(key, snap_mode);
-
- /* 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);
-
+ case 2:
+ strcpy(str, "Snap Keys To Current Frame");
break;
+ default:
+ return;
+ }
+
+ /* snap to frame */
+ if (key)
+ set_snap_meshchannels(key, snap_mode);
+ else
+ set_snap_actionchannels(act, snap_mode);
+ remake_action_ipos (act);
+
+ BIF_undo_push(str);
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+}
+
+static void mirror_actionchannels(bAction *act, short mirror_mode)
+{
+ /* mirror function for action channels */
+ bActionChannel *chan;
+ bConstraintChannel *conchan;
+
+ /* Loop through the channels */
+ for (chan = act->chanbase.first; chan; chan=chan->next){
+ if((chan->flag & ACHAN_HIDDEN)==0) {
+ if (chan->ipo) {
+ mirror_ipo_keys(chan->ipo, mirror_mode);
+ }
+ /* constraint channels */
+ for (conchan=chan->constraintChannels.first; conchan; conchan= conchan->next) {
+ if (conchan->ipo) {
+ mirror_ipo_keys(conchan->ipo, mirror_mode);
+ }
+ }
+ }
}
}
+static void mirror_meshchannels(Key *key, short mirror_mode)
+{
+ /* mirror function for mesh channels */
+ if(key->ipo) {
+ mirror_ipo_keys(key->ipo, mirror_mode);
+ }
+}
+
+void mirror_action_keys(short mirror_mode)
+{
+ /* This function is the generic entry-point for mirroring keyframes
+ * to over a frame. It passes the work off to sub-functions for the
+ * different types in the action editor.
+ */
+
+ SpaceAction *saction;
+ bAction *act;
+ Key *key;
+ char str[32];
+
+ /* get data */
+ saction= curarea->spacedata.first;
+ if (!saction) return;
+ act = saction->action;
+ key = get_action_mesh_key();
+
+ /* determine mode */
+ switch (mirror_mode) {
+ case 1:
+ strcpy(str, "Mirror Keys Over Current Frame");
+ break;
+ case 2:
+ strcpy(str, "Mirror Keys Over Y-Axis");
+ break;
+ default:
+ return;
+ }
+
+ /* mirror */
+ if (key)
+ mirror_meshchannels(key, mirror_mode);
+ else
+ mirror_actionchannels(act, mirror_mode);
+ remake_action_ipos (act);
+
+ BIF_undo_push(str);
+ allspace(REMAKEIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWNLA, 0);
+}
static void select_all_keys_frames(bAction *act, short *mval,
short *mvalo, int selectmode) {
@@ -2627,18 +2692,25 @@ void winqreadactionspace(ScrArea *sa, void *spacedata, BWinEvent *evt)
break;
case MKEY:
- /* marker operations */
- if (G.qual == 0)
- add_marker(CFRA);
- else if (G.qual == LR_CTRLKEY)
- rename_marker();
- else
- break;
- allqueue(REDRAWTIME, 0);
- allqueue(REDRAWIPO, 0);
- allqueue(REDRAWACTION, 0);
- allqueue(REDRAWNLA, 0);
- allqueue(REDRAWSOUND, 0);
+ if (G.qual & LR_SHIFTKEY) {
+ /* mirror keyframes */
+ val = pupmenu("Mirror Keys Over%t|Current Frame%x1|Vertical Axis%x2");
+ mirror_action_keys(val);
+ }
+ else {
+ /* marker operations */
+ if (G.qual == 0)
+ add_marker(CFRA);
+ else if (G.qual == LR_CTRLKEY)
+ rename_marker();
+ else
+ break;
+ allqueue(REDRAWTIME, 0);
+ allqueue(REDRAWIPO, 0);
+ allqueue(REDRAWACTION, 0);
+ allqueue(REDRAWNLA, 0);
+ allqueue(REDRAWSOUND, 0);
+ }
break;
case NKEY:
diff --git a/source/blender/src/editipo_mods.c b/source/blender/src/editipo_mods.c
index 822b085e734..fd9a60edf3e 100644
--- a/source/blender/src/editipo_mods.c
+++ b/source/blender/src/editipo_mods.c
@@ -585,6 +585,45 @@ void snap_ipo_keys(Ipo *ipo, short snaptype)
}
}
+static int mirror_bezier_cframe(BezTriple *bezt)
+{
+ float diff;
+
+ if(bezt->f2 & SELECT) {
+ diff= ((float)CFRA - bezt->vec[1][0]);
+ bezt->vec[1][0]= ((float)CFRA + diff);
+ }
+
+ return 0;
+}
+
+static int mirror_bezier_yaxis(BezTriple *bezt)
+{
+ float diff;
+
+ if(bezt->f2 & SELECT) {
+ diff= (0.0f - bezt->vec[1][0]);
+ bezt->vec[1][0]= (0.0f + diff);
+ }
+
+ return 0;
+}
+
+void mirror_ipo_keys(Ipo *ipo, short mirror_type)
+{
+ switch (mirror_type) {
+ case 1: /* mirror over current frame */
+ ipo_keys_bezier_loop(ipo, mirror_bezier_cframe, calchandles_ipocurve);
+ break;
+ case 2: /* snap over frame 0 */
+ ipo_keys_bezier_loop(ipo, mirror_bezier_yaxis, calchandles_ipocurve);
+ break;
+ default: /* just in case */
+ ipo_keys_bezier_loop(ipo, mirror_bezier_yaxis, calchandles_ipocurve);
+ break;
+ }
+}
+
static void ipo_curves_auto_horiz(void)
{
EditIpo *ei;
diff --git a/source/blender/src/header_action.c b/source/blender/src/header_action.c
index 3c06078b467..194d4976f51 100644
--- a/source/blender/src/header_action.c
+++ b/source/blender/src/header_action.c
@@ -101,7 +101,6 @@
#define ACTMENU_KEY_DELETE 1
#define ACTMENU_KEY_BAKE 2
#define ACTMENU_KEY_CLEAN 3
-#define ACTMENU_KEY_MIRROR 4
#define ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_UP 0
#define ACTMENU_KEY_CHANPOS_MOVE_CHANNEL_DOWN 1
@@ -126,8 +125,11 @@
#define ACTMENU_KEY_EXTEND_CYCLIC 2
#define ACTMENU_KEY_EXTEND_CYCLICEXTRAPOLATION 3
-#define ACTMENU_KEY_SNAP_NEARFRAME 0
-#define ACTMENU_KEY_SNAP_CURFRAME 1
+#define ACTMENU_KEY_SNAP_NEARFRAME 1
+#define ACTMENU_KEY_SNAP_CURFRAME 2
+
+#define ACTMENU_KEY_MIRROR_CURFRAME 1
+#define ACTMENU_KEY_MIRROR_YAXIS 2
#define ACTMENU_MARKERS_ADD 0
#define ACTMENU_MARKERS_DUPLICATE 1
@@ -832,10 +834,8 @@ static void do_action_keymenu_snapmenu(void *arg, int event)
switch(event)
{
case ACTMENU_KEY_SNAP_NEARFRAME:
- snap_keys_to_frame(1);
- break;
case ACTMENU_KEY_SNAP_CURFRAME:
- snap_keys_to_frame(2);
+ snap_keys_to_frame(event);
break;
}
@@ -866,6 +866,43 @@ static uiBlock *action_keymenu_snapmenu(void *arg_unused)
return block;
}
+static void do_action_keymenu_mirrormenu(void *arg, int event)
+{
+ switch(event)
+ {
+ case ACTMENU_KEY_MIRROR_CURFRAME:
+ case ACTMENU_KEY_MIRROR_YAXIS:
+ mirror_action_keys(event);
+ break;
+ }
+
+ scrarea_queue_winredraw(curarea);
+}
+
+static uiBlock *action_keymenu_mirrormenu(void *arg_unused)
+{
+ uiBlock *block;
+ short yco= 0, menuwidth=120;
+
+ block= uiNewBlock(&curarea->uiblocks, "action_keymenu_mirrormenu",
+ UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
+ uiBlockSetButmFunc(block, do_action_keymenu_mirrormenu, NULL);
+
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Current Frame|Shift M, 1", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_KEY_MIRROR_CURFRAME, "");
+ uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
+ "Vertical Axis|Shift M, 2", 0, yco-=20,
+ menuwidth, 19, NULL, 0.0, 0.0, 0,
+ ACTMENU_KEY_MIRROR_YAXIS, "");
+
+ uiBlockSetDirection(block, UI_RIGHT);
+ uiTextBoundsBlock(block, 60);
+
+ return block;
+}
+
static void do_action_keymenu(void *arg, int event)
{
SpaceAction *saction;
@@ -926,6 +963,9 @@ static uiBlock *action_keymenu(void *arg_unused)
uiDefIconTextBlockBut(block, action_keymenu_snapmenu,
NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 20, "");
+ uiDefIconTextBlockBut(block, action_keymenu_mirrormenu,
+ NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, 120, 20, "");
+
uiDefBut(block, SEPR, 0, "", 0, yco-=6,
menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");