Here's another milestone: Shape Keys now can be inserted in Actions and NLA

It works like for moving Object Ipos to the Action, press the Action icon
in the header of the IpoWindow, to the left of the mode selection menu.
It then creates an Action (if not existed) and moves the Shape Ipo to the
Action, using custom channel "Shape".

Main code change was that evaluating Ipo Curves for Relative Shapes had to
be recoded, but that's pretty minor and even much cleaner. (added "curval"
in the KeyBlock struct).
That this feature can work is thanks to the full modifier/derivedmesh
recode Daniel did, can't give him enough credits! :)

Also; small fixes in Outliner, for clicking on the Ipo icon (sets the Ipo
window to show that Ipo).
This commit is contained in:
2005-10-28 08:11:15 +00:00
parent 0dde486eea
commit 595447a85e
17 changed files with 260 additions and 156 deletions

View File

@@ -43,6 +43,7 @@
#include "DNA_constraint_types.h"
#include "DNA_curve_types.h"
#include "DNA_ipo_types.h"
#include "DNA_key_types.h"
#include "DNA_nla_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
@@ -55,6 +56,7 @@
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_ipo.h"
#include "BKE_key.h"
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_object.h"
@@ -636,12 +638,14 @@ static void blend_ipochannels(ListBase *dst, ListBase *src, float srcweight, int
}
}
static void execute_ipochannels(Object *ob, ListBase *lb)
static void execute_ipochannels(ListBase *lb)
{
NlaIpoChannel *nic;
for(nic= lb->first; nic; nic= nic->next) {
if(nic->poin) write_ipo_poin(nic->poin, nic->type, nic->val);
if(nic->poin) {
write_ipo_poin(nic->poin, nic->type, nic->val);
}
}
}
@@ -721,6 +725,7 @@ static float nla_time(float cfra, float unit)
static void do_nla(Object *ob, int blocktype)
{
bPose *tpose= NULL;
Key *key= NULL;
ListBase tchanbase={NULL, NULL}, chanbase={NULL, NULL};
bActionStrip *strip;
float striptime, frametime, length, actlength;
@@ -731,6 +736,9 @@ static void do_nla(Object *ob, int blocktype)
copy_pose(&tpose, ob->pose, 1);
rest_pose(ob->pose); // potentially destroying current not-keyed pose
}
else {
key= ob_get_key(ob);
}
for (strip=ob->nlastrips.first; strip; strip=strip->next){
doit=0;
@@ -776,12 +784,15 @@ static void do_nla(Object *ob, int blocktype)
striptime = (float)fmod (striptime, 1.0);
frametime = (striptime * actlength) + strip->actstart;
frametime= bsystem_time(ob, 0, frametime, 0.0);
if(blocktype==ID_AR)
extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
else if(blocktype==ID_OB)
extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", bsystem_time(ob, 0, frametime, 0.0));
extract_pose_from_action (tpose, strip->act, frametime);
else if(blocktype==ID_OB) {
extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
if(key)
extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
}
doit=1;
}
}
@@ -794,25 +805,32 @@ static void do_nla(Object *ob, int blocktype)
striptime = (float)fmod (striptime, 1.0);
frametime = (striptime * actlength) + strip->actstart;
if(blocktype==ID_AR)
extract_pose_from_action (tpose, strip->act, nla_time(frametime, (float)strip->repeat));
else if(blocktype==ID_OB)
extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", nla_time(frametime, (float)strip->repeat));
frametime= nla_time(frametime, (float)strip->repeat);
if(blocktype==ID_AR)
extract_pose_from_action (tpose, strip->act, frametime);
else if(blocktype==ID_OB) {
extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
if(key)
extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
}
doit=1;
}
/* Handle extend */
else{
if (strip->flag & ACTSTRIP_HOLDLASTFRAME){
striptime = 1.0;
frametime = (striptime * actlength) + strip->actstart;
frametime= bsystem_time(ob, 0, frametime, 0.0);
if(blocktype==ID_AR)
extract_pose_from_action (tpose, strip->act, bsystem_time(ob, 0, frametime, 0.0));
else if(blocktype==ID_OB)
extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", bsystem_time(ob, 0, frametime, 0.0));
extract_pose_from_action (tpose, strip->act, frametime);
else if(blocktype==ID_OB) {
extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
if(key)
extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
}
doit=1;
}
}
@@ -842,7 +860,7 @@ static void do_nla(Object *ob, int blocktype)
}
if(blocktype==ID_OB) {
execute_ipochannels(ob, &chanbase);
execute_ipochannels(&chanbase);
}
if (tpose){
@@ -886,13 +904,17 @@ void do_all_object_actions(Object *ob)
/* Do local action */
if(ob->action && ((ob->nlaflag & OB_NLA_OVERRIDE)==0 || ob->nlastrips.first==NULL) ) {
ListBase tchanbase= {NULL, NULL};
Key *key= ob_get_key(ob);
float cframe= (float) G.scene->r.cfra;
cframe= get_action_frame(ob, cframe);
extract_ipochannels_from_action(&tchanbase, &ob->id, ob->action, "Object", bsystem_time(ob, 0, cframe, 0.0));
if(key)
extract_ipochannels_from_action(&tchanbase, &key->id, ob->action, "Shape", bsystem_time(ob, 0, cframe, 0.0));
if(tchanbase.first) {
execute_ipochannels(ob, &tchanbase);
execute_ipochannels(&tchanbase);
BLI_freelistN(&tchanbase);
}
}

View File

@@ -1451,6 +1451,20 @@ static int object_modifiers_use_time(Object *ob)
return 0;
}
static int exists_channel(Object *ob, char *name)
{
bActionStrip *strip;
if(ob->action)
if(get_action_channel(ob->action, name))
return 1;
for (strip=ob->nlastrips.first; strip; strip=strip->next)
if(get_action_channel(strip->act, name))
return 1;
return 0;
}
/* flag all objects that need recalc, for changes in time for example */
void DAG_scene_update_flags(Scene *sce, unsigned int lay)
{
@@ -1474,9 +1488,11 @@ void DAG_scene_update_flags(Scene *sce, unsigned int lay)
if(ob->action || ob->nlastrips.first) {
/* since actions now are mixed, we set the recalcs on the safe side */
ob->recalc |= OB_RECALC_OB;
if(ob->type==OB_ARMATURE) {
if(ob->type==OB_ARMATURE)
ob->recalc |= OB_RECALC_DATA;
}
else if(exists_channel(ob, "Shape"))
ob->recalc |= OB_RECALC_DATA;
}
else if(modifiers_isSoftbodyEnabled(ob)) ob->recalc |= OB_RECALC_DATA;
else if(object_modifiers_use_time(ob)) ob->recalc |= OB_RECALC_DATA;

View File

@@ -1302,8 +1302,13 @@ void *get_ipo_poin(ID *id, IpoCurve *icu, int *type)
}
else if( GS(id->name)==ID_KE) {
KeyBlock *kb= ((Key *)id)->block.first;
poin= &(icu->curval);
for(; kb; kb= kb->next)
if(kb->adrcode==icu->adrcode)
break;
if(kb)
poin= &(kb->curval);
}
else if(GS(id->name)==ID_WO) {
@@ -1981,6 +1986,7 @@ void do_all_data_ipos()
World *wo;
Ipo *ipo;
Lamp *la;
Key *key;
Camera *ca;
bSound *snd;
Sequence *seq;
@@ -2018,24 +2024,22 @@ void do_all_data_ipos()
ipo= ipo->id.next;
}
tex= G.main->tex.first;
while(tex) {
for(tex= G.main->tex.first; tex; tex= tex->id.next) {
if(tex->ipo) execute_ipo((ID *)tex, tex->ipo);
tex= tex->id.next;
}
ma= G.main->mat.first;
while(ma) {
for(ma= G.main->mat.first; ma; ma= ma->id.next) {
if(ma->ipo) execute_ipo((ID *)ma, ma->ipo);
ma= ma->id.next;
}
wo= G.main->world.first;
while(wo) {
for(wo= G.main->world.first; wo; wo= wo->id.next) {
if(wo->ipo) execute_ipo((ID *)wo, wo->ipo);
wo= wo->id.next;
}
for(key= G.main->key.first; key; key= key->id.next) {
if(key->ipo) execute_ipo((ID *)key, key->ipo);
}
la= G.main->lamp.first;
while(la) {
if(la->ipo) execute_ipo((ID *)la, la->ipo);

View File

@@ -585,12 +585,10 @@ void cp_cu_key(Curve *cu, KeyBlock *kb, int start, int end)
static void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, float ctime, int mode)
{
KeyBlock *kb;
IpoCurve *icu;
int *ofsp, ofs[3], elemsize, b;
char *cp, *poin, *reffrom, *from, elemstr[8];
if(key->from==0) return;
if(key->ipo==0) return;
if(key->from==NULL) return;
if( GS(key->from->name)==ID_ME ) {
ofs[0]= sizeof(MVert);
@@ -627,14 +625,10 @@ static void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, f
while(kb) {
if(kb!=key->refkey) {
float icuval= 0.0f;
float icuval= kb->curval;
icu= find_ipocurve(key->ipo, kb->adrcode);
if(icu)
icuval= icu->curval;
/* only with value or weights, and no difference allowed */
if((icuval!=0.0f || (icu==NULL && kb->weights)) && kb->totelem==tot) {
/* only with value, and no difference allowed */
if(icuval!=0.0f && kb->totelem==tot) {
float weight, *weights= kb->weights;
poin= basispoin;
@@ -984,14 +978,6 @@ static int do_mesh_key(Object *ob, Mesh *me)
}
else {
ctime= bsystem_time(0, 0, (float)G.scene->r.cfra, 0.0);
calc_ipo(me->key->ipo, ctime); /* also all relative key positions */
if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
}
if(me->key->type==KEY_RELATIVE) {
KeyBlock *kb;
@@ -1006,6 +992,11 @@ static int do_mesh_key(Object *ob, Mesh *me)
}
}
else {
if(calc_ipo_spec(me->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
}
flag= setkeys(ctime, &me->key->block, k, t, 0);
if(flag==0) {
do_key(0, me->totvert, me->totvert, (char *)me->mvert->co, me->key, k, t, 0);
@@ -1142,15 +1133,16 @@ static int do_curve_key(Curve *cu)
else {
ctime= bsystem_time(0, 0, (float)G.scene->r.cfra, 0.0);
if(calc_ipo_spec(cu->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
}
if(cu->key->type==KEY_RELATIVE) {
do_rel_cu_key(cu, ctime);
}
else {
if(calc_ipo_spec(cu->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
}
flag= setkeys(ctime, &cu->key->block, k, t, 0);
if(flag==0) do_cu_key(cu, k, t);
@@ -1200,16 +1192,16 @@ static int do_latt_key(Lattice *lt)
}
else {
ctime= bsystem_time(0, 0, (float)G.scene->r.cfra, 0.0);
if(calc_ipo_spec(lt->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
}
if(lt->key->type==KEY_RELATIVE) {
do_rel_key(0, tot, tot, (char *)lt->def->vec, lt->key, ctime, 0);
}
else {
if(calc_ipo_spec(lt->key->ipo, KEY_SPEED, &ctime)==0) {
ctime /= 100.0;
CLAMP(ctime, 0.0, 1.0);
}
flag= setkeys(ctime, &lt->key->block, k, t, 0);
if(flag==0) {
do_key(0, tot, tot, (char *)lt->def->vec, lt->key, k, t, 0);
@@ -1273,6 +1265,7 @@ int do_ob_key(Object *ob)
Key *ob_get_key(Object *ob)
{
if(ob==NULL) return NULL;
if(ob->type==OB_MESH) {
Mesh *me= ob->data;

View File

@@ -1783,6 +1783,7 @@ void object_handle_update(Object *ob)
if(ob->recalc & OB_RECALC_DATA) {
// printf("recalcdata %s\n", ob->id.name+2);
/* includes all keys and modifiers */
if(ob->type==OB_MESH) {
makeDispListMesh(ob);

View File

@@ -58,7 +58,7 @@ void insert_shapekey(struct Object *ob);
void delete_key(struct Object *ob);
void move_keys(struct Object *ob);
void make_rvk_slider(struct uiBlock *block, struct Key *key, int i,
void make_rvk_slider(struct uiBlock *block, struct Object *ob, int keynum,
int x, int y, int w, int h, char *tip);
#endif

View File

@@ -68,7 +68,7 @@ void scale_editipo(void);
unsigned int ipo_rainbow(int cur, int tot);
void test_editipo(void);
void test_editipo(int doit);
void get_status_editipo(void);
void update_editipo_flags(void);
void set_editflag_editipo(void);

View File

@@ -43,7 +43,7 @@ typedef struct KeyBlock {
struct KeyBlock *next, *prev;
float pos;
int pad;
float curval;
short type, adrcode;
int totelem;

View File

@@ -1429,10 +1429,13 @@ static void editing_panel_shapes(Object *ob)
if( uiNewPanel(curarea, block, "Shapes", "Editing", 640, 0, 318, 204)==0) return;
uiDefBut(block, BUT, B_ADDKEY, "Add Shape Key" , 10, 180, 150, 20, NULL, 0.0, 0.0, 0, 0, "Add new Shape Key");
key= ob_get_key(ob);
if(key==NULL)
if(key==NULL) {
/* label aligns add button */
uiDefBut(block, LABEL, 0, "", 170, 180,140,20, NULL, 0, 0, 0, 0, "");
return;
}
uiDefButS(block, TOG, B_RELKEY, "Relative", 170, 180,140,20, &key->type, 0, 0, 0, 0, "Makes Shape Keys relative");
@@ -1458,7 +1461,7 @@ static void editing_panel_shapes(Object *ob)
if(key->type && (ob->shapeflag & OB_SHAPE_LOCK)==0 && ob->shapenr!=1) {
uiBlockBeginAlign(block);
make_rvk_slider(block, key, ob->shapenr-1, 10, 120, 150, 20, "Key value, when used it inserts an animation curve point");
make_rvk_slider(block, ob, ob->shapenr-1, 10, 120, 150, 20, "Key value, when used it inserts an animation curve point");
uiDefButF(block, NUM, B_REDR, "Min ", 160,120, 75, 20, &kb->slidermin, -10.0, 10.0, 100, 1, "Minumum for slider");
uiDefButF(block, NUM, B_REDR, "Max ", 235,120, 75, 20, &kb->slidermax, -10.0, 10.0, 100, 1, "Maximum for slider");
uiBlockEndAlign(block);

View File

@@ -88,28 +88,18 @@
/* local functions ----------------------------------------------------- */
void drawactionspace(ScrArea *sa, void *spacedata);
static void draw_channel_names(void);
static void draw_channel_strips(SpaceAction *saction);
int count_action_levels(bAction *act);
static BezTriple **ipo_to_keylist(Ipo *ipo, int flags, int *totvert);
static BezTriple **action_to_keylist(bAction *act, int flags, int *totvert);
static BezTriple **ob_to_keylist(Object *ob, int flags, int *totvert);
static BezTriple **icu_to_keylist(IpoCurve *icu, int flags, int *totvert);
static void draw_keylist(gla2DDrawInfo *di, int totvert, BezTriple **blist, float ypos);
void draw_icu_channel(gla2DDrawInfo *di, IpoCurve *icu, int flags, float ypos);
static void draw_action_mesh_names(Key *key);
/* missing local prototypes -------------------------------------------- */
void meshactionbuts(SpaceAction *saction, Key *key);
void do_actionbuts(unsigned short event);
/* implementation ------------------------------------------------------ */
extern short showsliders; /* editaction .c */
extern short ACTWIDTH;
void meshactionbuts(SpaceAction *saction, Key *key)
static void meshactionbuts(SpaceAction *saction, Object *ob, Key *key)
{
int i;
char str[64];
@@ -176,7 +166,7 @@ void meshactionbuts(SpaceAction *saction, Key *key)
glRects(NAMEWIDTH, 0, NAMEWIDTH+SLIDERWIDTH, curarea->winy);
uiBlockSetEmboss(block, UI_EMBOSS);
for (i=1 ; i < key->totkey ; ++ i) {
make_rvk_slider(block, key, i,
make_rvk_slider(block, ob, i,
x, y, SLIDERWIDTH-2, CHANNELHEIGHT-1, "Slider to control Shape Keys");
y-=CHANNELHEIGHT+CHANNELSKIP;
@@ -670,7 +660,7 @@ void drawactionspace(ScrArea *sa, void *spacedata)
/* if there is a mesh with rvk's selected,
* then draw the key frames in the action window
*/
meshactionbuts(G.saction, key);
meshactionbuts(G.saction, OBACT, key);
}
}
}

View File

@@ -1990,7 +1990,7 @@ void drawipospace(ScrArea *sa, void *spacedata)
}
}
test_editipo(); /* test if current editipo is correct, make_editipo sets v2d->cur */
test_editipo(0); /* test if current editipo is correct, make_editipo sets v2d->cur */
myortho2(v2d->cur.xmin, v2d->cur.xmax, v2d->cur.ymin, v2d->cur.ymax);

View File

@@ -1180,7 +1180,7 @@ void transform_meshchannel_keys(char mode, Key *key)
* future
*/
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA);
DAG_object_flush_update(G.scene, OBACT, OB_RECALC_OB|OB_RECALC_DATA);
allqueue (REDRAWVIEW3D, 0);
allqueue (REDRAWACTION, 0);
allqueue (REDRAWIPO, 0);

View File

@@ -196,20 +196,23 @@ EditIpo *get_active_editipo(void)
static void set_active_key(int index)
{
if(G.sipo->blocktype==ID_KE && G.sipo->from) {
Key *key= (Key *)G.sipo->from;
KeyBlock *curkb;
Object *ob= OBACT;
Object *ob= (Object *)G.sipo->from;
Key *key= ob_get_key(ob);
curkb= BLI_findlink(&key->block, index-1);
if(curkb) {
ob->shapenr= index;
ob->shapeflag |= OB_SHAPE_TEMPLOCK;
if(key) {
KeyBlock *curkb;
/* calc keypos */
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
}
curkb= BLI_findlink(&key->block, index-1);
if(curkb) {
ob->shapenr= index;
ob->shapeflag |= OB_SHAPE_TEMPLOCK;
/* calc keypos */
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWBUTSEDIT, 0);
}
}
}
}
@@ -251,7 +254,7 @@ void editipo_changed(SpaceIpo *si, int doredraw)
/* keylines? */
if(si->blocktype==ID_KE) {
key= (Key *)si->from;
key= ob_get_key((Object *)G.sipo->from);
if(key && key->block.first) {
kb= key->block.first;
if(kb->pos < v2d->tot.ymin) v2d->tot.ymin= kb->pos;
@@ -484,7 +487,7 @@ static void make_key_editipo(SpaceIpo *si)
EditIpo *ei;
int a;
key= (Key *)G.sipo->from;
key= ob_get_key((Object *)G.sipo->from);
if(key==NULL) return;
si->totipo= BLI_countlist(&key->block);
@@ -998,8 +1001,19 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname
else if(blocktype==ID_KE) {
if(ob) {
Key *key= ob_get_key(ob);
*from= (ID *)key;
if(key) *ipo= key->ipo;
if(ob->ipoflag & OB_ACTION_KEY) {
if (ob->action) {
bActionChannel *achan= get_action_channel(ob->action, "Shape");
if(achan) {
*ipo= achan->ipo;
BLI_strncpy(actname, achan->name, 32);
}
}
}
else if(key) *ipo= key->ipo;
*from= (ID *)ob;
}
}
else if(blocktype==ID_CU) {
@@ -1034,9 +1048,9 @@ static void get_ipo_context(short blocktype, ID **from, Ipo **ipo, char *actname
}
/* called on each redraw, check if editipo data has to be remade */
void test_editipo(void)
/* if doit already set, it always makes (in case no ipo exists, we need to see the channels */
void test_editipo(int doit)
{
int doit= 0;
if(G.sipo->pin==0) {
Ipo *ipo;
@@ -1292,8 +1306,7 @@ static short findnearest_ipovert(IpoCurve **icu, BezTriple **bezt)
void mouse_select_ipo(void)
{
Object *ob;
Key *key;
KeyBlock *kb, *actkb=NULL, *curkb;
KeyBlock *actkb=NULL;
EditIpo *ei, *actei= 0;
IpoCurve *icu;
IpoKey *ik, *actik;
@@ -1377,10 +1390,12 @@ void mouse_select_ipo(void)
/* vertex keys ? */
if(G.sipo->blocktype==ID_KE && G.sipo->from) {
Key *key;
KeyBlock *kb, *curkb;
int i, index= 1;
key= (Key *)G.sipo->from;
ob= OBACT;
ob= (Object *)G.sipo->from;
key= ob_get_key(ob);
curkb= BLI_findlink(&key->block, ob->shapenr-1);
ei= G.sipo->editipo;
@@ -1634,6 +1649,17 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname)
}
return ob->ipo;
}
else if(blocktype==ID_KE) {
Key *key= ob_get_key((Object *)G.sipo->from);
if(key) {
if(key->ipo==NULL) {
key->ipo= add_ipo("KeyIpo", ID_KE);
}
return key->ipo;
}
return NULL;
}
}
break;
case ID_MA:
@@ -1678,16 +1704,6 @@ Ipo *verify_ipo(ID *from, short blocktype, char *actname, char *constname)
return cu->ipo;
}
break;
case ID_KE:
{
Key *key= (Key *)from;
if(key->ipo==NULL) {
key->ipo= add_ipo("KeyIpo", ID_KE);
}
return key->ipo;
}
break;
case ID_WO:
{
World *wo= (World *)from;
@@ -1853,10 +1869,11 @@ void add_vert_ipo(void)
if(mval[0]>G.v2d->mask.xmax) return;
ei= get_active_editipo();
if(ei==0) {
if(ei==NULL) {
error("No active Ipo curve");
return;
}
ei->flag |= IPO_VISIBLE; /* can happen it is active but not visible */
areamouseco_to_ipoco(G.v2d, mval, &x, &y);
@@ -4084,9 +4101,6 @@ void ipo_record(void)
if(anim < 1) return;
if(anim!=2) anim= 0;
// ipo= verify_ipo(G.sipo->from, G.sipo->blocktype, G.sipo->actname, G.sipo->constname);
// test_editipo();
ob= OBACT;
/* find the curves... */

View File

@@ -44,19 +44,21 @@
#include "BLI_blenlib.h"
#include "BLI_arithb.h"
#include "DNA_action_types.h"
#include "DNA_curve_types.h"
#include "DNA_ipo_types.h"
#include "DNA_key_types.h"
#include "DNA_lattice_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
#include "DNA_view2d_types.h"
#include "DNA_lattice_types.h"
#include "DNA_scene_types.h"
#include "BKE_action.h"
#include "BKE_anim.h"
#include "BKE_curve.h"
#include "BKE_depsgraph.h"
@@ -96,7 +98,7 @@ float meshslidervals[64] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
static IpoCurve *get_key_icu(Key *key, int keynum)
static IpoCurve *get_key_icu(Ipo *ipo, int keynum)
{
/* return the Ipocurve that has the specified
* keynum as ardcode -- return NULL if no such
@@ -104,13 +106,10 @@ static IpoCurve *get_key_icu(Key *key, int keynum)
*/
IpoCurve *icu;
/* why this? (ton) */
if (!(key->ipo)) {
key->ipo= add_ipo("KeyIpo", ID_KE);
if (!ipo)
return NULL;
}
for (icu = key->ipo->curve.first; icu ; icu = icu->next) {
for (icu = ipo->curve.first; icu ; icu = icu->next) {
if (!icu->adrcode) continue;
if (icu->adrcode == keynum) return icu;
}
@@ -144,23 +143,26 @@ static BezTriple *get_bezt_icu_time(IpoCurve *icu, float *frame, float *val) {
return bezt;
}
static void rvk_slider_func(void *voidkey, void *voidkeynum)
static void rvk_slider_func(void *voidob, void *voidkeynum)
{
/* the callback for the rvk sliders ... copies the
* value from the temporary array into a bezier at the
* right frame on the right ipo curve (creating both the
* ipo curve and the bezier if needed).
*/
Object *ob= voidob;
IpoCurve *icu=NULL;
BezTriple *bezt=NULL;
Key *key = (Key *) voidkey;
Object *ob= OBACT;
float cfra, rvkval;
int keynum = (int) voidkeynum;
cfra = frame_to_float(CFRA);
icu = verify_ipocurve(&key->id, ID_KE, NULL, NULL, keynum);
/* ipo on action or ob? */
if(ob->ipoflag & OB_ACTION_KEY)
icu = verify_ipocurve(&ob->id, ID_KE, "Shape", NULL, keynum);
else
icu = verify_ipocurve(&ob->id, ID_KE, NULL, NULL, keynum);
if (icu) {
/* if the ipocurve exists, try to get a bezier
@@ -184,8 +186,6 @@ static void rvk_slider_func(void *voidkey, void *voidkeynum)
*/
sort_time_ipocurve(icu);
testhandles_ipocurve(icu);
do_ipo(key->ipo);
ob->shapeflag &= ~OB_SHAPE_TEMPLOCK;
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
@@ -195,10 +195,9 @@ static void rvk_slider_func(void *voidkey, void *voidkeynum)
allqueue (REDRAWNLA, 0);
allqueue (REDRAWIPO, 0);
allspace(REMAKEIPO, 0);
}
static float getrvkval(Key *key, int keynum)
static float getrvkval(Ipo *ipo, int keynum)
{
/* get the value of the rvk from the
* ipo curve at the current time -- return 0
@@ -210,7 +209,7 @@ static float getrvkval(Key *key, int keynum)
float cfra;
cfra = frame_to_float(CFRA);
icu = get_key_icu(key, keynum);
icu = get_key_icu(ipo, keynum);
if (icu) {
bezt = get_bezt_icu_time(icu, &cfra, &rvkval);
if (!bezt) {
@@ -222,17 +221,32 @@ static float getrvkval(Key *key, int keynum)
}
void make_rvk_slider(uiBlock *block, Key *key, int keynum,
void make_rvk_slider(uiBlock *block, Object *ob, int keynum,
int x, int y, int w, int h, char *tip)
{
/* create a slider for the rvk */
uiBut *but;
uiBut *but;
Ipo *ipo= NULL;
Key *key= ob_get_key(ob);
KeyBlock *kb;
float min, max;
int i;
if(key==NULL) return;
/* ipo on action or ob? */
if(ob->ipoflag & OB_ACTION_KEY) {
if(ob->action) {
bActionChannel *achan;
achan= get_action_channel(ob->action, "Shape");
if(achan) ipo= achan->ipo;
}
}
else ipo= key->ipo;
/* global array */
meshslidervals[keynum] = getrvkval(key, keynum);
meshslidervals[keynum] = getrvkval(ipo, keynum);
kb= key->block.first;
for (i=0; i<keynum; ++i) kb = kb->next;
@@ -252,7 +266,7 @@ void make_rvk_slider(uiBlock *block, Key *key, int keynum,
x, y , w, h,
meshslidervals+keynum, min, max, 10, 2, tip);
uiButSetFunc(but, rvk_slider_func, key, (void *)keynum);
uiButSetFunc(but, rvk_slider_func, ob, (void *)keynum);
// no hilite, the winmatrix is not correct later on...
uiButSetFlag(but, UI_NO_HILITE);

View File

@@ -897,16 +897,13 @@ void deselectall(void) /* is toggle */
void selectswap(void)
{
Base *base;
int a=0;
base= FIRSTBASE;
while(base) {
for(base= FIRSTBASE; base; base= base->next) {
if(base->lay & G.vd->lay) {
if TESTBASE(base) base->flag &= ~SELECT;
else base->flag |= SELECT;
base->object->flag= base->flag;
}
base= base->next;
}
allqueue(REDRAWVIEW3D, 0);

View File

@@ -64,6 +64,7 @@
#include "BKE_action.h"
#include "BKE_constraint.h"
#include "BKE_global.h"
#include "BKE_key.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_texture.h"
@@ -336,7 +337,7 @@ static void do_ipo_editmenu_keymenu(void *arg, int event)
Object *ob= OBACT;
if(G.sipo->blocktype==ID_KE && totipo_edit==0 && totipo_sel==0) {
key= (Key *)G.sipo->from;
key= ob_get_key((Object *)G.sipo->from);
if(key==NULL) return;
kb= BLI_findlink(&key->block, ob->shapenr-1);
@@ -925,6 +926,8 @@ void do_ipo_buttons(short event)
set_exprap_ipo(IPO_CYCLX);
break;
case B_IPOMAIN:
/* pass 1 to enforce a refresh when there's no Ipo */
test_editipo(1);
scrarea_queue_winredraw(curarea);
scrarea_queue_headredraw(curarea);
if(ob) ob->ipowin= G.sipo->blocktype;
@@ -986,8 +989,38 @@ void do_ipo_buttons(short event)
allqueue(REDRAWNLA, 0);
}
break;
case B_IPO_ACTION_KEY:
case B_IPO_ACTION_KEY:
if(ob && G.sipo->from && G.sipo->pin==0) {
Key *key= ob_get_key(ob);
if(key) {
if(ob->ipoflag & OB_ACTION_KEY) { /* check if channel exists, and flip ipo link */
bActionChannel *achan;
if(ob->action==NULL)
ob->action= add_empty_action(ID_KE);
achan= verify_action_channel(ob->action, "Shape");
if(achan->ipo==NULL && key->ipo) {
achan->ipo= key->ipo;
key->ipo= NULL;
}
}
else if(ob->action) {
bActionChannel *achan= get_action_channel(ob->action, "Shape");
if(achan) {
if(achan->ipo && key->ipo==NULL) {
key->ipo= achan->ipo;
achan->ipo= NULL;
}
}
}
allqueue(REDRAWVIEW3D, 0);
allqueue(REDRAWIPO, 0);
allqueue(REDRAWACTION, 0);
allqueue(REDRAWOOPS, 0);
allqueue(REDRAWNLA, 0);
}
}
break;
}
}
@@ -1013,7 +1046,7 @@ void ipo_buttons(void)
uiDefIconTextButC(block, ICONTEXTROW,B_NEWSPACE, ICON_VIEW3D, windowtype_pup(), xco,0,XIC+10,YIC, &(curarea->butspacetype), 1.0, SPACEICONMAX, 0, 0, "Displays Current Window Type. Click for menu of available types.");
xco+= XIC+14;
test_editipo(); /* test if current editipo is OK, make_editipo sets v2d->cur */
test_editipo(0); /* test if current editipo is OK, make_editipo sets v2d->cur */
uiBlockSetEmboss(block, UI_EMBOSSN);
if(curarea->flag & HEADER_NO_PULLDOWN) {

View File

@@ -1156,7 +1156,16 @@ static int tree_element_active_ipo(SpaceOops *soops, TreeElement *te, int set)
tselems= TREESTORE(tes);
if(set) {
ob->ipowin= tes->idcode;
if(tes->idcode==ID_AC) {
if(ob->ipoflag & OB_ACTION_OB)
ob->ipowin= ID_OB;
else if(ob->ipoflag & OB_ACTION_KEY)
ob->ipowin= ID_KE;
else
ob->ipowin= ID_PO;
}
else ob->ipowin= tes->idcode;
if(ob->ipowin==ID_MA) tree_element_active_material(soops, tes, 1);
else if(ob->ipowin==ID_AC) {
bActionChannel *chan;
@@ -1173,21 +1182,29 @@ static int tree_element_active_ipo(SpaceOops *soops, TreeElement *te, int set)
allqueue(REDRAWIPO, ob->ipowin);
}
else if(ob->ipowin==tes->idcode) {
if(ob->ipowin==ID_MA) {
Material *ma= give_current_material(ob, ob->actcol);
if(ma==(Material *)tselems->id) return 1;
}
else if(ob->ipowin==ID_AC) {
bActionChannel *chan;
short a=0;
for(chan=ob->action->chanbase.first; chan; chan= chan->next) {
if(a==te->index) break;
if(chan->ipo) a++;
else {
if(tes->idcode==ID_AC) {
if(ob->ipoflag & OB_ACTION_OB)
return ob->ipowin==ID_OB;
else if(ob->ipoflag & OB_ACTION_KEY)
return ob->ipowin==ID_KE;
else if(ob->ipowin==ID_AC) {
bActionChannel *chan;
short a=0;
for(chan=ob->action->chanbase.first; chan; chan= chan->next) {
if(a==te->index) break;
if(chan->ipo) a++;
}
if(chan==get_hilighted_action_channel(ob->action)) return 1;
}
if(chan==get_hilighted_action_channel(ob->action)) return 1;
}
else return 1;
else if(ob->ipowin==tes->idcode) {
if(ob->ipowin==ID_MA) {
Material *ma= give_current_material(ob, ob->actcol);
if(ma==(Material *)tselems->id) return 1;
}
else return 1;
}
}
return 0;
}