Patch: [ #5036 ] IPO Curve Mirroring by Joshua Leung (aligorith)

This patch adds the feature of IPO curve mirroring. It mirrors the selected keyframes in the active ipo curves over a user-nominated mirror-line.

Options are:
- Mirror over current frame
- Mirror over vertical axis (X = 0)
- Mirror over horizontal axis (Y = 0)

Functionality can be accessed from:
- Hotkey M in IPO editor
- Submenu in header of IPO editor
This commit is contained in:
Martin Poirier 2006-10-01 19:45:37 +00:00
parent e5ba49349f
commit 1ea97e5552
4 changed files with 123 additions and 0 deletions

@ -96,6 +96,8 @@ void join_ipo_menu(void);
void join_ipo(int mode);
void ipo_snap_menu(void);
void ipo_snap(short event);
void ipo_mirror_menu(void);
void ipo_mirror(short event);
void mouse_select_ipo(void);
void sethandles_ipo(int code);
void select_ipo_bezier_keys(struct Ipo *ipo, int selectmode);

@ -100,6 +100,7 @@
#include "BDR_drawobject.h"
#include "BDR_editobject.h"
#include "BDR_editcurve.h" // for bezt_compare
#include "BSE_trans_types.h"
#include "BSE_editipo_types.h"
@ -3073,6 +3074,91 @@ void ipo_snap(short event)
BIF_undo_push("Snap Ipo");
}
void ipo_mirror_menu(void)
{
int mode = 0;
mode= pupmenu("Mirror Over%t|Current Frame%x1|Vertical Axis%x2|Horizontal Axis%x3");
if (mode == -1) return;
ipo_mirror(mode);
}
void ipo_mirror(short mode)
{
EditIpo *ei;
BezTriple *bezt;
int a, b;
int ok, ok2;
float diff;
/* what's this for? */
get_status_editipo();
/* get edit ipo */
ei= G.sipo->editipo;
if (!ei) return;
/* look throught ipo curves */
for(b=0; b<G.sipo->totipo; b++, ei++) {
if (ISPOIN3(ei, flag & IPO_VISIBLE, icu, icu->bezt)) {
ok2= 0;
if(G.sipo->showkey) ok2= 1;
else if(totipo_vert && (ei->flag & IPO_EDIT)) ok2= 2;
else if(totipo_vert==0 && (ei->flag & IPO_SELECT)) ok2= 3;
if(ok2) {
bezt= ei->icu->bezt;
a= ei->icu->totvert;
/* loop through beztriples, mirroring them */
while(a--) {
ok= 0;
if(totipo_vert) {
if(bezt->f2 & 1) ok= 1;
}
else ok= 1;
if(ok) {
switch (mode) {
case 1: /* mirror over current frame */
{
diff= ((float)CFRA - bezt->vec[1][0]);
bezt->vec[1][0]= ((float)CFRA + diff);
}
break;
case 2: /* mirror over vertical axis (frame 0) */
{
diff= (0.0f - bezt->vec[1][0]);
bezt->vec[1][0]= (0.0f + diff);
}
break;
case 3: /* mirror over horizontal axis */
{
diff= (0.0f - bezt->vec[1][1]);
bezt->vec[1][1]= (0.0f + diff);
}
break;
}
}
bezt++;
}
/* sort out order and handles */
sort_time_ipocurve(ei->icu);
calchandles_ipocurve(ei->icu);
}
}
}
/* cleanup and undo push */
editipo_changed(G.sipo, 1);
BIF_undo_push("Mirror Ipo");
}
/*
* When deleting an IPO curve from Python, check if the Ipo is being
* edited and if so clear the pointer to the old curve.

@ -316,6 +316,35 @@ static uiBlock *ipo_editmenu_snapmenu(void *arg_unused)
return block;
}
static void do_ipo_editmenu_mirrormenu(void *arg, int event)
{
switch(event) {
case 1: /* mirror over current frame */
case 2: /* mirror over frame 0 */
case 3: /* mirror over horizontal axis */
ipo_mirror(event);
break;
}
allqueue(REDRAWVIEW3D, 0);
}
static uiBlock *ipo_editmenu_mirrormenu(void *arg_unused)
{
uiBlock *block;
short yco = 20, menuwidth = 120;
block= uiNewBlock(&curarea->uiblocks, "ipo_editmenu_mirrormenu", UI_EMBOSSP, UI_HELV, G.curscreen->mainwin);
uiBlockSetButmFunc(block, do_ipo_editmenu_mirrormenu, NULL);
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Over Current Frame|M, 1", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Over Vertical Axis|M, 2", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Over Horizontal Axis|M, 3", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
uiBlockSetDirection(block, UI_RIGHT);
uiTextBoundsBlock(block, 60);
return block;
}
static void do_ipo_editmenu_joinmenu(void *arg, int event)
{
switch(event) {
@ -573,6 +602,8 @@ static uiBlock *ipo_editmenu(void *arg_unused)
uiDefIconTextBlockBut(block, ipo_editmenu_snapmenu, NULL, ICON_RIGHTARROW_THIN, "Snap", 0, yco-=20, 120, 19, "");
uiDefIconTextBlockBut(block, ipo_editmenu_mirrormenu, NULL, ICON_RIGHTARROW_THIN, "Mirror", 0, yco-=20, 120, 19, "");
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
/*Look to see if any ipos are being edited, so there can be a check next to the menu option*/

@ -2244,6 +2244,10 @@ static void winqreadipospace(ScrArea *sa, void *spacedata, BWinEvent *evt)
doredraw= 1;
}
break;
case MKEY:
if((G.qual==0))
ipo_mirror_menu();
break;
case NKEY:
toggle_blockhandler(sa, IPO_HANDLER_PROPERTIES, UI_PNL_TO_MOUSE);
doredraw= 1;