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:
authorTon Roosendaal <ton@blender.org>2005-10-28 12:11:15 +0400
committerTon Roosendaal <ton@blender.org>2005-10-28 12:11:15 +0400
commit595447a85ea2e388fa17b4a44dacf256ac97f343 (patch)
tree3461e1157f41cbe304f8e346cd2ac5c8333c395d
parent0dde486eeae6c563059bfab408f1ed5bd239ad85 (diff)
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).
-rw-r--r--source/blender/blenkernel/intern/action.c56
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c20
-rw-r--r--source/blender/blenkernel/intern/ipo.c26
-rw-r--r--source/blender/blenkernel/intern/key.c47
-rw-r--r--source/blender/blenkernel/intern/object.c1
-rw-r--r--source/blender/include/BIF_editkey.h2
-rw-r--r--source/blender/include/BSE_editipo.h2
-rw-r--r--source/blender/makesdna/DNA_key_types.h2
-rw-r--r--source/blender/src/buttons_editing.c9
-rw-r--r--source/blender/src/drawaction.c16
-rw-r--r--source/blender/src/drawipo.c2
-rw-r--r--source/blender/src/editaction.c2
-rw-r--r--source/blender/src/editipo.c86
-rw-r--r--source/blender/src/editkey.c56
-rw-r--r--source/blender/src/editview.c5
-rw-r--r--source/blender/src/header_ipo.c39
-rw-r--r--source/blender/src/outliner.c43
17 files changed, 259 insertions, 155 deletions
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 64d6d1f5abd..3e494721621 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -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);
}
}
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index c5f87a495f4..95add0e8ae0 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -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;
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index c6c99137761..842b30b4147 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -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);
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 79ef90c7bbd..0877751016c 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -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;
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 0cc09f9fac9..cc7ca11f81c 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -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);
diff --git a/source/blender/include/BIF_editkey.h b/source/blender/include/BIF_editkey.h
index ff78f78da2b..e5dae4fac3e 100644
--- a/source/blender/include/BIF_editkey.h
+++ b/source/blender/include/BIF_editkey.h
@@ -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
diff --git a/source/blender/include/BSE_editipo.h b/source/blender/include/BSE_editipo.h
index 5e3a4ec5562..4b3dbc283c4 100644
--- a/source/blender/include/BSE_editipo.h
+++ b/source/blender/include/BSE_editipo.h
@@ -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);
diff --git a/source/blender/makesdna/DNA_key_types.h b/source/blender/makesdna/DNA_key_types.h
index 91a45dba77d..3292e07f80e 100644
--- a/source/blender/makesdna/DNA_key_types.h
+++ b/source/blender/makesdna/DNA_key_types.h
@@ -43,7 +43,7 @@ typedef struct KeyBlock {
struct KeyBlock *next, *prev;
float pos;
- int pad;
+ float curval;
short type, adrcode;
int totelem;
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index 5fb2066836d..d464056bc90 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -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);
diff --git a/source/blender/src/drawaction.c b/source/blender/src/drawaction.c
index c1a4782b1fa..c6955955c09 100644
--- a/source/blender/src/drawaction.c
+++ b/source/blender/src/drawaction.c
@@ -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);
}
}
}
diff --git a/source/blender/src/drawipo.c b/source/blender/src/drawipo.c
index 22017ee9d8c..a108492a5a3 100644
--- a/source/blender/src/drawipo.c
+++ b/source/blender/src/drawipo.c
@@ -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);
diff --git a/source/blender/src/editaction.c b/source/blender/src/editaction.c
index 335f8ee9c72..981d92fe5ff 100644
--- a/source/blender/src/editaction.c
+++ b/source/blender/src/editaction.c
@@ -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);
diff --git a/source/blender/src/editipo.c b/source/blender/src/editipo.c
index 853b069f484..3aa9bb83639 100644
--- a/source/blender/src/editipo.c
+++ b/source/blender/src/editipo.c
@@ -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... */
diff --git a/source/blender/src/editkey.c b/source/blender/src/editkey.c
index 2262d3298cf..32adf6289ac 100644
--- a/source/blender/src/editkey.c
+++ b/source/blender/src/editkey.c
@@ -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);
diff --git a/source/blender/src/editview.c b/source/blender/src/editview.c
index 7c343058d8a..c1da247120a 100644
--- a/source/blender/src/editview.c
+++ b/source/blender/src/editview.c
@@ -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);
diff --git a/source/blender/src/header_ipo.c b/source/blender/src/header_ipo.c
index 73439ec22bf..1bfef7a6567 100644
--- a/source/blender/src/header_ipo.c
+++ b/source/blender/src/header_ipo.c
@@ -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) {
diff --git a/source/blender/src/outliner.c b/source/blender/src/outliner.c
index 64d4d77cc43..417bf489eae 100644
--- a/source/blender/src/outliner.c
+++ b/source/blender/src/outliner.c
@@ -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(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;
+ }
}
- 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(ob->ipowin==tes->idcode) {
+ if(ob->ipowin==ID_MA) {
+ Material *ma= give_current_material(ob, ob->actcol);
+ if(ma==(Material *)tselems->id) return 1;
}
- if(chan==get_hilighted_action_channel(ob->action)) return 1;
+ else return 1;
}
- else return 1;
}
return 0;
}