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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-10-22 20:35:51 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-10-22 20:35:51 +0400
commit3ffb695b10bd85f7cd431f6144dbc2c427a365ee (patch)
tree008509058f8da92056c567e50951d48438a35c82 /source/blender/blenkernel/intern/key.c
parentb06640c583ed9900223855004d8e9cd6947adf21 (diff)
Shape Keys
Blended shape keys can now be displayed & edited in edit mode. This is much like showing an armature modifier in edit mode, and shape keys now are a applied as a virtual modifier (for mesh & lattice only, curve doesn't fit in the stack well due to tilt). The main thing missing still is being able to switch between the active shape key in edit mode, that's more complicated.. but the weights of other shapes can be edited while in edit mode. One thing to be careful about is that this does automatic crazyspace correction, which means that if you edit a shape key with a low value, the actual vertices will be moved to correct for that and actually move a (potentially much) longer distance. Also includes some UI tweaks, mainly placing some buttons horizontally since the vertical list was getting too long.
Diffstat (limited to 'source/blender/blenkernel/intern/key.c')
-rw-r--r--source/blender/blenkernel/intern/key.c130
1 files changed, 74 insertions, 56 deletions
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 78b9c04e4d2..61f51d61e0b 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -36,6 +36,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_editVert.h"
#include "DNA_anim_types.h"
#include "DNA_curve_types.h"
@@ -497,38 +498,41 @@ static void rel_flerp(int aantal, float *in, float *ref, float *out, float fac)
}
}
-static void *key_block_get_data(Key *key, KeyBlock *kb)
+static char *key_block_get_data(Key *key, KeyBlock *actkb, KeyBlock *kb, char **freedata)
{
- /* editmode shape key apply test */
-#if 0
- EditVert *eve;
- Mesh *me;
- float (*co)[3];
- int a;
-
- if(kb != key->refkey) {
+ if(kb == actkb) {
+ /* this hack makes it possible to edit shape keys in
+ edit mode with shape keys blending applied */
if(GS(key->from->name) == ID_ME) {
+ Mesh *me;
+ EditVert *eve;
+ float (*co)[3];
+ int a;
+
me= (Mesh*)key->from;
- if(me->edit_mesh) {
+ if(me->edit_mesh && me->edit_mesh->totvert == kb->totelem) {
a= 0;
- co= kb->data;
+ co= MEM_callocN(sizeof(float)*3*me->edit_mesh->totvert, "key_block_get_data");
for(eve=me->edit_mesh->verts.first; eve; eve=eve->next, a++)
VECCOPY(co[a], eve->co);
+
+ *freedata= (char*)co;
+ return (char*)co;
}
}
}
-#endif
+ *freedata= NULL;
return kb->data;
}
-static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *kb, float *weights, int mode)
+static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *actkb, KeyBlock *kb, float *weights, int mode)
{
float ktot = 0.0, kd = 0.0;
int elemsize, poinsize = 0, a, *ofsp, ofs[32], flagflo=0;
- char *k1, *kref;
+ char *k1, *kref, *freek1, *freekref;
char *cp, elemstr[8];
if(key->from==NULL) return;
@@ -553,9 +557,6 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
if(end>tot) end= tot;
- k1= key_block_get_data(key, kb);
- kref= key_block_get_data(key, key->refkey);
-
if(tot != kb->totelem) {
ktot= 0.0;
flagflo= 1;
@@ -565,6 +566,9 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
else return;
}
+ k1= key_block_get_data(key, actkb, kb, &freek1);
+ kref= key_block_get_data(key, actkb, key->refkey, &freekref);
+
/* this exception is needed for slurphing */
if(start!=0) {
@@ -638,9 +642,12 @@ static void cp_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
if(mode==KEY_BEZTRIPLE) a+=2;
}
+
+ if(freek1) MEM_freeN(freek1);
+ if(freekref) MEM_freeN(freekref);
}
-static void cp_cu_key(Curve *cu, KeyBlock *kb, int start, int end, char *out, int tot)
+static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, int start, int end, char *out, int tot)
{
Nurb *nu;
char *poin;
@@ -655,7 +662,7 @@ static void cp_cu_key(Curve *cu, KeyBlock *kb, int start, int end, char *out, in
a1= MAX2(a, start);
a2= MIN2(a+step, end);
- if(a1<a2) cp_key(a1, a2, tot, poin, cu->key, kb, NULL, KEY_BPOINT);
+ if(a1<a2) cp_key(a1, a2, tot, poin, key, actkb, kb, NULL, KEY_BPOINT);
}
else if(nu->bezt) {
step= 3*nu->pntsu;
@@ -664,7 +671,7 @@ static void cp_cu_key(Curve *cu, KeyBlock *kb, int start, int end, char *out, in
a1= MAX2(a, start);
a2= MIN2(a+step, end);
- if(a1<a2) cp_key(a1, a2, tot, poin, cu->key, kb, NULL, KEY_BEZTRIPLE);
+ if(a1<a2) cp_key(a1, a2, tot, poin, key, actkb, kb, NULL, KEY_BEZTRIPLE);
}
else
step= 0;
@@ -672,11 +679,12 @@ static void cp_cu_key(Curve *cu, KeyBlock *kb, int start, int end, char *out, in
}
-void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode)
+void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, KeyBlock *actkb, int mode)
{
KeyBlock *kb;
int *ofsp, ofs[3], elemsize, b;
char *cp, *poin, *reffrom, *from, elemstr[8];
+ char *freefrom, *freereffrom;
if(key->from==NULL) return;
@@ -707,7 +715,7 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode
if(mode==KEY_BEZTRIPLE) elemsize*= 3;
/* step 1 init */
- cp_key(start, end, tot, basispoin, key, key->refkey, NULL, mode);
+ cp_key(start, end, tot, basispoin, key, actkb, key->refkey, NULL, mode);
/* step 2: do it */
@@ -719,13 +727,14 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode
if(!(kb->flag & KEYBLOCK_MUTE) && icuval!=0.0f && kb->totelem==tot) {
KeyBlock *refb;
float weight, *weights= kb->weights;
-
- poin= basispoin;
- from= key_block_get_data(key, kb);
+
/* reference now can be any block */
refb= BLI_findlink(&key->block, kb->relative);
if(refb==NULL) continue;
- reffrom= key_block_get_data(key, refb);
+
+ poin= basispoin;
+ from= key_block_get_data(key, actkb, kb, &freefrom);
+ reffrom= key_block_get_data(key, actkb, refb, &freereffrom);
poin+= start*ofs[0];
reffrom+= key->elemsize*start; // key elemsize yes!
@@ -769,19 +778,22 @@ void do_rel_key(int start, int end, int tot, char *basispoin, Key *key, int mode
if(mode==KEY_BEZTRIPLE) b+= 2;
if(weights) weights++;
}
+
+ if(freefrom) MEM_freeN(freefrom);
+ if(freereffrom) MEM_freeN(freereffrom);
}
}
}
}
-static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock **k, float *t, int mode)
+static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, int mode)
{
float k1tot = 0.0, k2tot = 0.0, k3tot = 0.0, k4tot = 0.0;
float k1d = 0.0, k2d = 0.0, k3d = 0.0, k4d = 0.0;
int a, ofs[32], *ofsp;
int flagdo= 15, flagflo=0, elemsize, poinsize=0;
- char *k1, *k2, *k3, *k4;
+ char *k1, *k2, *k3, *k4, *freek1, *freek2, *freek3, *freek4;
char *cp, elemstr[8];;
if(key->from==0) return;
@@ -806,10 +818,10 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
if(end>tot) end= tot;
- k1= key_block_get_data(key, k[0]);
- k2= key_block_get_data(key, k[1]);
- k3= key_block_get_data(key, k[2]);
- k4= key_block_get_data(key, k[3]);
+ k1= key_block_get_data(key, actkb, k[0], &freek1);
+ k2= key_block_get_data(key, actkb, k[1], &freek2);
+ k3= key_block_get_data(key, actkb, k[2], &freek3);
+ k4= key_block_get_data(key, actkb, k[3], &freek4);
/* test for more or less points (per key!) */
if(tot != k[0]->totelem) {
@@ -975,6 +987,11 @@ static void do_key(int start, int end, int tot, char *poin, Key *key, KeyBlock *
if(mode==KEY_BEZTRIPLE) a+= 2;
}
+
+ if(freek1) MEM_freeN(freek1);
+ if(freek2) MEM_freeN(freek2);
+ if(freek3) MEM_freeN(freek3);
+ if(freek4) MEM_freeN(freek4);
}
static float *get_weights_array(Object *ob, char *vgroup)
@@ -1026,7 +1043,7 @@ static float *get_weights_array(Object *ob, char *vgroup)
static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
{
- KeyBlock *k[4];
+ KeyBlock *k[4], *actkb= ob_get_keyblock(ob);
float cfra, ctime, t[4], delta;
int a, flag = 0, step;
@@ -1059,9 +1076,9 @@ static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
flag= setkeys(ctime, &key->block, k, t, 0);
if(flag==0)
- do_key(a, a+step, tot, (char *)out, key, k, t, 0);
+ do_key(a, a+step, tot, (char *)out, key, actkb, k, t, 0);
else
- cp_key(a, a+step, tot, (char *)out, key, k[2], NULL, 0);
+ cp_key(a, a+step, tot, (char *)out, key, actkb, k[2], NULL, 0);
}
}
else {
@@ -1071,7 +1088,7 @@ static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
for(kb= key->block.first; kb; kb= kb->next)
kb->weights= get_weights_array(ob, kb->vgroup);
- do_rel_key(0, tot, tot, (char *)out, key, 0);
+ do_rel_key(0, tot, tot, (char *)out, key, actkb, 0);
for(kb= key->block.first; kb; kb= kb->next) {
if(kb->weights) MEM_freeN(kb->weights);
@@ -1094,14 +1111,14 @@ static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
flag= setkeys(ctime, &key->block, k, t, 0);
if(flag==0)
- do_key(0, tot, tot, (char *)out, key, k, t, 0);
+ do_key(0, tot, tot, (char *)out, key, actkb, k, t, 0);
else
- cp_key(0, tot, tot, (char *)out, key, k[2], NULL, 0);
+ cp_key(0, tot, tot, (char *)out, key, actkb, k[2], NULL, 0);
}
}
}
-static void do_cu_key(Curve *cu, KeyBlock **k, float *t, char *out, int tot)
+static void do_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock **k, float *t, char *out, int tot)
{
Nurb *nu;
char *poin;
@@ -1111,19 +1128,19 @@ static void do_cu_key(Curve *cu, KeyBlock **k, float *t, char *out, int tot)
if(nu->bp) {
step= nu->pntsu*nu->pntsv;
poin= out - a*sizeof(float)*4;
- do_key(a, a+step, tot, poin, cu->key, k, t, KEY_BPOINT);
+ do_key(a, a+step, tot, poin, key, actkb, k, t, KEY_BPOINT);
}
else if(nu->bezt) {
step= 3*nu->pntsu;
poin= out - a*sizeof(float)*10;
- do_key(a, a+step, tot, poin, cu->key, k, t, KEY_BEZTRIPLE);
+ do_key(a, a+step, tot, poin, key, actkb, k, t, KEY_BEZTRIPLE);
}
else
step= 0;
}
}
-static void do_rel_cu_key(Curve *cu, float ctime, char *out, int tot)
+static void do_rel_cu_key(Curve *cu, Key *key, KeyBlock *actkb, float ctime, char *out, int tot)
{
Nurb *nu;
char *poin;
@@ -1133,12 +1150,12 @@ static void do_rel_cu_key(Curve *cu, float ctime, char *out, int tot)
if(nu->bp) {
step= nu->pntsu*nu->pntsv;
poin= out - a*sizeof(float)*3;
- do_rel_key(a, a+step, tot, out, cu->key, KEY_BPOINT);
+ do_rel_key(a, a+step, tot, out, key, actkb, KEY_BPOINT);
}
else if(nu->bezt) {
step= 3*nu->pntsu;
poin= out - a*sizeof(float)*10;
- do_rel_key(a, a+step, tot, poin, cu->key, KEY_BEZTRIPLE);
+ do_rel_key(a, a+step, tot, poin, key, actkb, KEY_BEZTRIPLE);
}
else
step= 0;
@@ -1148,7 +1165,7 @@ static void do_rel_cu_key(Curve *cu, float ctime, char *out, int tot)
static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
{
Curve *cu= ob->data;
- KeyBlock *k[4];
+ KeyBlock *k[4], *actkb= ob_get_keyblock(ob);
float cfra, ctime, t[4], delta;
int a, flag = 0, step = 0;
@@ -1187,7 +1204,7 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
ctime= bsystem_time(scene, NULL, (float)scene->r.cfra, 0.0);
if(key->type==KEY_RELATIVE) {
- do_rel_cu_key(cu, ctime, out, tot);
+ do_rel_cu_key(cu, cu->key, actkb, ctime, out, tot);
}
else {
#if 0 // XXX old animation system
@@ -1199,8 +1216,8 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
flag= setkeys(ctime, &key->block, k, t, 0);
- if(flag==0) do_cu_key(cu, k, t, out, tot);
- else cp_cu_key(cu, k[2], 0, tot, out, tot);
+ if(flag==0) do_cu_key(cu, key, actkb, k, t, out, tot);
+ else cp_cu_key(cu, key, actkb, k[2], 0, tot, out, tot);
}
}
}
@@ -1208,7 +1225,7 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
{
Lattice *lt= ob->data;
- KeyBlock *k[4];
+ KeyBlock *k[4], *actkb= ob_get_keyblock(ob);
float delta, cfra, ctime, t[4];
int a, flag;
@@ -1231,9 +1248,9 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
flag= setkeys(ctime, &key->block, k, t, 0);
if(flag==0)
- do_key(a, a+1, tot, (char *)out, key, k, t, 0);
+ do_key(a, a+1, tot, (char *)out, key, actkb, k, t, 0);
else
- cp_key(a, a+1, tot, (char *)out, key, k[2], NULL, 0);
+ cp_key(a, a+1, tot, (char *)out, key, actkb, k[2], NULL, 0);
}
}
else {
@@ -1243,7 +1260,7 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
for(kb= key->block.first; kb; kb= kb->next)
kb->weights= get_weights_array(ob, kb->vgroup);
- do_rel_key(0, tot, tot, (char *)out, key, 0);
+ do_rel_key(0, tot, tot, (char *)out, key, actkb, 0);
for(kb= key->block.first; kb; kb= kb->next) {
if(kb->weights) MEM_freeN(kb->weights);
@@ -1263,9 +1280,9 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
flag= setkeys(ctime, &key->block, k, t, 0);
if(flag==0)
- do_key(0, tot, tot, (char *)out, key, k, t, 0);
+ do_key(0, tot, tot, (char *)out, key, actkb, k, t, 0);
else
- cp_key(0, tot, tot, (char *)out, key, k[2], NULL, 0);
+ cp_key(0, tot, tot, (char *)out, key, actkb, k[2], NULL, 0);
}
}
@@ -1276,6 +1293,7 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, int tot)
float *do_ob_key(Scene *scene, Object *ob)
{
Key *key= ob_get_key(ob);
+ KeyBlock *actkb= ob_get_keyblock(ob);
char *out;
int tot= 0, size= 0;
@@ -1336,12 +1354,12 @@ float *do_ob_key(Scene *scene, Object *ob)
if(ELEM(ob->type, OB_MESH, OB_LATTICE)) {
float *weights= get_weights_array(ob, kb->vgroup);
- cp_key(0, tot, tot, (char*)out, key, kb, weights, 0);
+ cp_key(0, tot, tot, (char*)out, key, actkb, kb, weights, 0);
if(weights) MEM_freeN(weights);
}
else if(ELEM(ob->type, OB_CURVE, OB_SURF))
- cp_cu_key(ob->data, kb, 0, tot, out, tot);
+ cp_cu_key(ob->data, key, actkb, kb, 0, tot, out, tot);
}
else {
/* do shapekey local drivers */