forked from bartvdbraak/blender
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:
parent
e5ba49349f
commit
1ea97e5552
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user