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
path: root/source
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
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')
-rw-r--r--source/blender/blenkernel/BKE_key.h2
-rw-r--r--source/blender/blenkernel/BKE_modifier.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c15
-rw-r--r--source/blender/blenkernel/intern/displist.c4
-rw-r--r--source/blender/blenkernel/intern/key.c130
-rw-r--r--source/blender/blenkernel/intern/lattice.c3
-rw-r--r--source/blender/blenkernel/intern/modifier.c100
-rw-r--r--source/blender/blenkernel/intern/particle.c1
-rw-r--r--source/blender/editors/interface/interface_layout.c4
-rw-r--r--source/blender/editors/interface/interface_templates.c51
-rw-r--r--source/blender/editors/object/object_shapekey.c15
-rw-r--r--source/blender/editors/transform/transform_conversions.c2
-rw-r--r--source/blender/makesdna/DNA_modifier_types.h5
-rw-r--r--source/blender/makesdna/DNA_object_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_object.c6
-rw-r--r--source/blender/makesrna/intern/rna_ui.c2
-rw-r--r--source/gameengine/Converter/BL_ShapeDeformer.cpp2
17 files changed, 233 insertions, 112 deletions
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index 59d7f99112e..b70801a9edd 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -64,7 +64,7 @@ struct KeyBlock *key_get_keyblock(struct Key *key, int index);
struct KeyBlock *key_get_named_keyblock(struct Key *key, const char name[]);
char *key_get_curValue_rnaPath(struct Key *key, struct KeyBlock *kb);
// needed for the GE
-void do_rel_key(int start, int end, int tot, char *basispoin, struct Key *key, int mode);
+void do_rel_key(int start, int end, int tot, char *basispoin, struct Key *key, struct KeyBlock *actkb, int mode);
#ifdef __cplusplus
};
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 9957ced9555..245db7e35ff 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -293,7 +293,7 @@ void modifiers_foreachIDLink(struct Object *ob,
struct ModifierData *modifiers_findByType(struct Object *ob, ModifierType type);
void modifiers_clearErrors(struct Object *ob);
int modifiers_getCageIndex(struct Object *ob,
- int *lastPossibleCageIndex_r);
+ int *lastPossibleCageIndex_r, int virtual_);
int modifiers_isSoftbodyEnabled(struct Object *ob);
int modifiers_isClothEnabled(struct Object *ob);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 59cf786af1e..11e58203bb3 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1755,9 +1755,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
*final_r = NULL;
if(useDeform) {
- if(useDeform > 0)
- deformedVerts= (float(*)[3])do_ob_key(scene, ob); /* shape key makes deform verts */
- else if(inputVertexCos)
+ if(inputVertexCos)
deformedVerts = inputVertexCos;
/* Apply all leading deforming modifiers */
@@ -2013,7 +2011,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
float (*deformedVerts)[3] = NULL;
CustomDataMask mask;
DerivedMesh *dm, *orcodm = NULL;
- int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL);
+ int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL, 1);
LinkNode *datamasks, *curr;
int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
@@ -2024,16 +2022,13 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
}
dm = NULL;
- md = ob->modifiers.first;
+ md = modifiers_getVirtualModifierList(ob);
/* we always want to keep original indices */
dataMask |= CD_MASK_ORIGINDEX;
datamasks = modifiers_calcDataMasks(ob, md, dataMask, required_mode);
- /* doesn't work, shape keys are not updated from editmesh.
- deformedVerts= (float(*)[3])do_ob_key(scene, ob); */
-
curr = datamasks;
for(i = 0; md; i++, md = md->next, curr = curr->next) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -2463,13 +2458,13 @@ int editmesh_get_first_deform_matrices(Object *ob, EditMesh *em, float (**deform
ModifierData *md;
DerivedMesh *dm;
int i, a, numleft = 0, numVerts = 0;
- int cageIndex = modifiers_getCageIndex(ob, NULL);
+ int cageIndex = modifiers_getCageIndex(ob, NULL, 1);
float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL;
modifiers_clearErrors(ob);
dm = NULL;
- md = ob->modifiers.first;
+ md = modifiers_getVirtualModifierList(ob);
/* compute the deformation matrices and coordinates for the first
modifiers with on cage editing that are enabled and support computing
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index 39b07cae2ab..64af08d6f6a 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -1260,7 +1260,9 @@ static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, fl
if(keyVerts) {
/* split coords from key data, the latter also includes
- tilts, which is passed through in the modifier stack */
+ tilts, which is passed through in the modifier stack.
+ this is also the reason curves do not use a virtual
+ shape key modifier yet. */
deformedVerts= curve_getKeyVertexCos(cu, nurb, keyVerts);
originalVerts= MEM_dupallocN(deformedVerts);
}
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 */
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 128d3229a3c..c53101299c6 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -995,9 +995,6 @@ void lattice_calc_modifiers(Scene *scene, Object *ob)
freedisplist(&ob->disp);
- if (!editmode)
- vertexCos= (float(*)[3])do_ob_key(scene, ob);
-
for (; md; md=md->next) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index c4de67014b4..a445b6986f6 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -60,6 +60,7 @@
#include "DNA_curve_types.h"
#include "DNA_effect_types.h"
#include "DNA_group_types.h"
+#include "DNA_key_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
@@ -92,6 +93,7 @@
#include "BKE_fluidsim.h"
#include "BKE_global.h"
#include "BKE_multires.h"
+#include "BKE_key.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_material.h"
@@ -8341,6 +8343,52 @@ static void simpledeformModifier_deformVertsEM(ModifierData *md, Object *ob, Edi
dm->release(dm);
}
+/* Shape Key */
+
+static void shapekeyModifier_deformVerts(
+ ModifierData *md, Object *ob, DerivedMesh *derivedData,
+ float (*vertexCos)[3], int numVerts, int useRenderParams, int isFinalCalc)
+{
+ KeyBlock *kb= ob_get_keyblock(ob);
+ float (*deformedVerts)[3];
+
+ if(kb && kb->totelem == numVerts) {
+ deformedVerts= (float(*)[3])do_ob_key(md->scene, ob);
+ if(deformedVerts) {
+ memcpy(vertexCos, deformedVerts, sizeof(float)*3*numVerts);
+ MEM_freeN(deformedVerts);
+ }
+ }
+}
+
+static void shapekeyModifier_deformVertsEM(
+ ModifierData *md, Object *ob, EditMesh *editData,
+ DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
+{
+ Key *key= ob_get_key(ob);
+
+ if(key && key->type == KEY_RELATIVE)
+ shapekeyModifier_deformVerts(md, ob, derivedData, vertexCos, numVerts, 0, 0);
+}
+
+static void shapekeyModifier_deformMatricesEM(
+ ModifierData *md, Object *ob, EditMesh *editData,
+ DerivedMesh *derivedData, float (*vertexCos)[3],
+ float (*defMats)[3][3], int numVerts)
+{
+ Key *key= ob_get_key(ob);
+ KeyBlock *kb= ob_get_keyblock(ob);
+ float scale[3][3];
+ int a;
+
+ if(kb && kb->totelem==numVerts && kb!=key->refkey) {
+ Mat3Scale(scale, kb->curval);
+
+ for(a=0; a<numVerts; a++)
+ Mat3CpyMat3(defMats[a], scale);
+ }
+}
+
/***/
static ModifierTypeInfo typeArr[NUM_MODIFIER_TYPES];
@@ -8745,6 +8793,14 @@ ModifierTypeInfo *modifierType_getInfo(ModifierType type)
mti->copyData = multiresModifier_copyData;
mti->applyModifier = multiresModifier_applyModifier;
+ mti = INIT_TYPE(ShapeKey);
+ mti->type = eModifierTypeType_OnlyDeform;
+ mti->flags = eModifierTypeFlag_AcceptsCVs
+ | eModifierTypeFlag_SupportsEditmode;
+ mti->deformVerts = shapekeyModifier_deformVerts;
+ mti->deformVertsEM = shapekeyModifier_deformVertsEM;
+ mti->deformMatricesEM = shapekeyModifier_deformMatricesEM;
+
typeArrInit = 0;
#undef INIT_TYPE
}
@@ -8909,9 +8965,9 @@ void modifier_setError(ModifierData *md, char *format, ...)
* also used in transform_conversion.c, to detect CrazySpace [tm] (2nd arg
* then is NULL)
*/
-int modifiers_getCageIndex(Object *ob, int *lastPossibleCageIndex_r)
+int modifiers_getCageIndex(Object *ob, int *lastPossibleCageIndex_r, int virtual_)
{
- ModifierData *md = ob->modifiers.first;
+ ModifierData *md = (virtual_)? modifiers_getVirtualModifierList(ob): ob->modifiers.first;
int i, cageIndex = -1;
/* Find the last modifier acting on the cage. */
@@ -9020,11 +9076,11 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob)
static ArmatureModifierData amd;
static CurveModifierData cmd;
static LatticeModifierData lmd;
+ static ShapeKeyModifierData smd;
static int init = 1;
+ ModifierData *md;
if (init) {
- ModifierData *md;
-
md = modifier_new(eModifierType_Armature);
amd = *((ArmatureModifierData*) md);
modifier_free(md);
@@ -9037,32 +9093,50 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob)
lmd = *((LatticeModifierData*) md);
modifier_free(md);
+ md = modifier_new(eModifierType_ShapeKey);
+ smd = *((ShapeKeyModifierData*) md);
+ modifier_free(md);
+
amd.modifier.mode |= eModifierMode_Virtual;
cmd.modifier.mode |= eModifierMode_Virtual;
lmd.modifier.mode |= eModifierMode_Virtual;
+ smd.modifier.mode |= eModifierMode_Virtual;
init = 0;
}
- if (ob->parent) {
+ md = ob->modifiers.first;
+
+ if(ob->parent) {
if(ob->parent->type==OB_ARMATURE && ob->partype==PARSKEL) {
amd.object = ob->parent;
- amd.modifier.next = ob->modifiers.first;
+ amd.modifier.next = md;
amd.deformflag= ((bArmature *)(ob->parent->data))->deformflag;
- return &amd.modifier;
+ md = &amd.modifier;
} else if(ob->parent->type==OB_CURVE && ob->partype==PARSKEL) {
cmd.object = ob->parent;
cmd.defaxis = ob->trackflag + 1;
- cmd.modifier.next = ob->modifiers.first;
- return &cmd.modifier;
+ cmd.modifier.next = md;
+ md = &cmd.modifier;
} else if(ob->parent->type==OB_LATTICE && ob->partype==PARSKEL) {
lmd.object = ob->parent;
- lmd.modifier.next = ob->modifiers.first;
- return &lmd.modifier;
+ lmd.modifier.next = md;
+ md = &lmd.modifier;
}
}
- return ob->modifiers.first;
+ /* shape key modifier, not yet for curves */
+ if(ELEM(ob->type, OB_MESH, OB_LATTICE) && ob_get_key(ob)) {
+ if(ob->type == OB_MESH && (ob->shapeflag & OB_SHAPE_EDIT_MODE))
+ smd.modifier.mode |= eModifierMode_Editmode|eModifierMode_OnCage;
+ else
+ smd.modifier.mode &= ~eModifierMode_Editmode|eModifierMode_OnCage;
+
+ smd.modifier.next = md;
+ md = &smd.modifier;
+ }
+
+ return md;
}
/* Takes an object and returns its first selected armature, else just its
* armature
@@ -9139,6 +9213,8 @@ int modifier_isDeformer(ModifierData *md)
return 1;
if (md->type==eModifierType_Lattice)
return 1;
+ if (md->type==eModifierType_ShapeKey)
+ return 1;
return 0;
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 322904136ea..feec4866a18 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -3828,6 +3828,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
pind.keyed = keyed;
pind.cache = cached ? psys->pointcache : NULL;
pind.epoint = NULL;
+ pind.bspline = (psys->part->flag & PART_HAIR_BSPLINE);
pind.dm = psys->hair_out_dm;
init_particle_interpolation(sim->ob, psys, pa, &pind);
do_particle_interpolation(psys, p, pa, t, frs_sec, &pind, state);
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 10449a1133e..41a0ad7d4b0 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1503,11 +1503,11 @@ static void ui_litem_layout_row(uiLayout *litem)
/* align right/center */
offset= 0;
if(litem->alignment == UI_LAYOUT_ALIGN_RIGHT) {
- if(fixedw == 0 && freew < w-fixedw)
+ if(freew > 0 && freew < w-fixedw)
offset= (w - fixedw) - freew;
}
else if(litem->alignment == UI_LAYOUT_ALIGN_CENTER) {
- if(fixedw == 0 && freew < w-fixedw)
+ if(freew > 0 && freew < w-fixedw)
offset= ((w - fixedw) - freew)/2;
}
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 960574ae8a9..75ae475435a 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -506,7 +506,7 @@ static void modifiers_setOnCage(bContext *C, void *ob_v, void *md_v)
{
Object *ob = ob_v;
ModifierData *md= md_v;
- int i, cageIndex = modifiers_getCageIndex(ob, NULL );
+ int i, cageIndex = modifiers_getCageIndex(ob, NULL, 0);
/* undo button operation */
md->mode ^= eModifierMode_OnCage;
@@ -715,7 +715,7 @@ uiLayout *uiTemplateModifier(uiLayout *layout, PointerRNA *ptr)
uiBlockSetButLock(uiLayoutGetBlock(layout), (ob && ob->id.lib), ERROR_LIBDATA_MESSAGE);
/* find modifier and draw it */
- cageIndex = modifiers_getCageIndex(ob, &lastCageIndex);
+ cageIndex = modifiers_getCageIndex(ob, &lastCageIndex, 0);
// XXX virtual modifiers are not accesible for python
vmd = modifiers_getVirtualModifierList(ob);
@@ -1955,13 +1955,30 @@ static int list_item_icon_get(bContext *C, PointerRNA *itemptr, int rnaicon)
return rnaicon;
}
-static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *itemptr, int i, int rnaicon)
+static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, PointerRNA *itemptr, int i, int rnaicon, PointerRNA *activeptr, char *activepropname)
{
+ Object *ob;
uiBlock *block= uiLayoutGetBlock(layout);
- uiLayout *split;
+ uiBut *but;
+ uiLayout *split, *overlap, *sub;
char *name, *namebuf;
int icon;
+ overlap= uiLayoutOverlap(layout);
+
+ /* list item behind label & other buttons */
+ sub= uiLayoutRow(overlap, 0);
+
+ if(itemptr->type == &RNA_ShapeKey) {
+ ob= (Object*)activeptr->data;
+ uiLayoutSetEnabled(sub, ob->mode != OB_MODE_EDIT);
+ }
+
+ but= uiDefButR(block, LISTROW, 0, "", 0,0, UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
+ uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
+
+ sub= uiLayoutRow(overlap, 0);
+
/* retrieve icon and name */
icon= list_item_icon_get(C, itemptr, rnaicon);
if(!icon || icon == ICON_DOT)
@@ -1974,24 +1991,28 @@ static void list_item_row(bContext *C, uiLayout *layout, PointerRNA *ptr, Pointe
uiBlockSetEmboss(block, UI_EMBOSSN);
if(itemptr->type == &RNA_MeshTextureFaceLayer || itemptr->type == &RNA_MeshColorLayer) {
- uiItemL(layout, name, icon);
+ uiItemL(sub, name, icon);
uiDefIconButR(block, TOG, 0, ICON_SCENE, 0, 0, UI_UNIT_X, UI_UNIT_Y, itemptr, "active_render", 0, 0, 0, 0, 0, NULL);
}
else if(itemptr->type == &RNA_MaterialTextureSlot) {
- uiItemL(layout, name, icon);
+ uiItemL(sub, name, icon);
uiDefButR(block, OPTION, 0, "", 0, 0, UI_UNIT_X, UI_UNIT_Y, ptr, "use_textures", i, 0, 0, 0, 0, NULL);
}
else if(itemptr->type == &RNA_ShapeKey) {
- split= uiLayoutSplit(layout, 0.75f);
+ ob= (Object*)activeptr->data;
+
+ split= uiLayoutSplit(sub, 0.75f);
uiItemL(split, name, icon);
if(i == 0) uiItemL(split, "", 0);
else uiItemR(split, "", 0, itemptr, "value", 0);
+ if(ob->mode == OB_MODE_EDIT && !(ob->shapeflag & OB_SHAPE_EDIT_MODE))
+ uiLayoutSetEnabled(split, 0);
//uiItemR(split, "", ICON_MUTE_IPO_OFF, itemptr, "mute", 0);
}
else
- uiItemL(layout, name, icon);
+ uiItemL(sub, name, icon);
uiBlockSetEmboss(block, UI_EMBOSS);
@@ -2006,7 +2027,7 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propna
PropertyRNA *prop= NULL, *activeprop;
PropertyType type, activetype;
StructRNA *ptype;
- uiLayout *box, *row, *col, *subrow, *overlap;
+ uiLayout *box, *row, *col;
uiBlock *block;
uiBut *but;
Panel *pa;
@@ -2151,16 +2172,8 @@ void uiTemplateList(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propna
if(ptr->data && prop) {
/* create list items */
RNA_PROP_BEGIN(ptr, itemptr, prop) {
- if(i >= pa->list_scroll && i<pa->list_scroll+items) {
- overlap= uiLayoutOverlap(col);
-
- subrow= uiLayoutRow(overlap, 0);
- but= uiDefButR(block, LISTROW, 0, "", 0,0, UI_UNIT_X*10,UI_UNIT_Y, activeptr, activepropname, 0, 0, i, 0, 0, "");
- uiButSetFlag(but, UI_BUT_NO_TOOLTIP);
-
- subrow= uiLayoutRow(overlap, 0);
- list_item_row(C, subrow, ptr, &itemptr, i, rnaicon);
- }
+ if(i >= pa->list_scroll && i<pa->list_scroll+items)
+ list_item_row(C, col, ptr, &itemptr, i, rnaicon, activeptr, activepropname);
i++;
}
diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c
index 5f3d73ec348..4d4dd7a0738 100644
--- a/source/blender/editors/object/object_shapekey.c
+++ b/source/blender/editors/object/object_shapekey.c
@@ -544,6 +544,13 @@ static int ED_object_shape_key_mirror(bContext *C, Scene *scene, Object *ob)
/********************** shape key operators *********************/
+static int shape_key_mode_poll(bContext *C)
+{
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ ID *data= (ob)? ob->data: NULL;
+ return (ob && !ob->id.lib && data && !data->lib && ob->mode != OB_MODE_EDIT);
+}
+
static int shape_key_poll(bContext *C)
{
Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
@@ -569,7 +576,7 @@ void OBJECT_OT_shape_key_add(wmOperatorType *ot)
ot->idname= "OBJECT_OT_shape_key_add";
/* api callbacks */
- ot->poll= shape_key_poll;
+ ot->poll= shape_key_mode_poll;
ot->exec= shape_key_add_exec;
/* flags */
@@ -594,7 +601,7 @@ void OBJECT_OT_shape_key_remove(wmOperatorType *ot)
ot->idname= "OBJECT_OT_shape_key_remove";
/* api callbacks */
- ot->poll= shape_key_poll;
+ ot->poll= shape_key_mode_poll;
ot->exec= shape_key_remove_exec;
/* flags */
@@ -652,7 +659,7 @@ void OBJECT_OT_shape_key_mirror(wmOperatorType *ot)
ot->idname= "OBJECT_OT_shape_key_mirror";
/* api callbacks */
- ot->poll= shape_key_poll;
+ ot->poll= shape_key_mode_poll;
ot->exec= shape_key_mirror_exec;
/* flags */
@@ -710,7 +717,7 @@ void OBJECT_OT_shape_key_move(wmOperatorType *ot)
ot->idname= "OBJECT_OT_shape_key_move";
/* api callbacks */
- ot->poll= shape_key_poll;
+ ot->poll= shape_key_mode_poll;
ot->exec= shape_key_move_exec;
/* flags */
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index cdfdcaffb0d..cefb7741658 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -2199,7 +2199,7 @@ static void createTransEditVerts(bContext *C, TransInfo *t)
/* detect CrazySpace [tm] */
if(propmode==0) {
- if(modifiers_getCageIndex(t->obedit, NULL)>=0) {
+ if(modifiers_getCageIndex(t->obedit, NULL, 1)>=0) {
if(modifiers_isDeformed(t->scene, t->obedit)) {
/* check if we can use deform matrices for modifier from the
start up to stack, they are more accurate than quats */
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 7c76a5c099d..db1c261556b 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -63,6 +63,7 @@ typedef enum ModifierType {
eModifierType_Multires,
eModifierType_Surface,
eModifierType_Smoke,
+ eModifierType_ShapeKey,
NUM_MODIFIER_TYPES
} ModifierType;
@@ -663,4 +664,8 @@ typedef struct SimpleDeformModifierData {
#define MOD_UVPROJECT_MAX 10
+typedef struct ShapeKeyModifierData {
+ ModifierData modifier;
+} ShapeKeyModifierData;
+
#endif
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 4cf78c83cd0..267e0192247 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -500,6 +500,7 @@ extern Object workob;
/* ob->shapeflag */
#define OB_SHAPE_LOCK 1
#define OB_SHAPE_TEMPLOCK 2 // deprecated
+#define OB_SHAPE_EDIT_MODE 4
/* ob->nlaflag */
// XXX depreceated - old animation system
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 3fb132b24fd..f81e3d5d665 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -1642,6 +1642,12 @@ static void rna_def_object(BlenderRNA *brna)
RNA_def_property_ui_icon(prop, ICON_UNPINNED, 1);
RNA_def_property_update(prop, 0, "rna_Object_update_data");
+ prop= RNA_def_property(srna, "shape_key_edit_mode", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "shapeflag", OB_SHAPE_EDIT_MODE);
+ RNA_def_property_ui_text(prop, "Shape Key Edit Mode", "Apply shape keys in edit mode (for Meshes only).");
+ RNA_def_property_ui_icon(prop, ICON_EDITMODE_HLT, 0);
+ RNA_def_property_update(prop, 0, "rna_Object_update_data");
+
prop= RNA_def_property(srna, "active_shape_key", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ShapeKey");
RNA_def_property_pointer_funcs(prop, "rna_Object_active_shape_key_get", NULL, NULL);
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index 0a661e9aaf3..8d6a18dd9c2 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -500,7 +500,7 @@ static void rna_def_ui_layout(BlenderRNA *brna)
{UI_LAYOUT_ALIGN_EXPAND, "EXPAND", 0, "Expand", ""},
{UI_LAYOUT_ALIGN_LEFT, "LEFT", 0, "Left", ""},
{UI_LAYOUT_ALIGN_CENTER, "CENTER", 0, "Center", ""},
- {UI_LAYOUT_ALIGN_RIGHT, "RIGHT", 0, "RIght", ""},
+ {UI_LAYOUT_ALIGN_RIGHT, "RIGHT", 0, "Right", ""},
{0, NULL, 0, NULL, NULL}};
/* see WM_types.h */
diff --git a/source/gameengine/Converter/BL_ShapeDeformer.cpp b/source/gameengine/Converter/BL_ShapeDeformer.cpp
index 41ff3cc3274..125e91e0e0a 100644
--- a/source/gameengine/Converter/BL_ShapeDeformer.cpp
+++ b/source/gameengine/Converter/BL_ShapeDeformer.cpp
@@ -154,7 +154,7 @@ bool BL_ShapeDeformer::Update(void)
/* store verts locally */
VerifyStorage();
- do_rel_key(0, m_bmesh->totvert, m_bmesh->totvert, (char *)(float *)m_transverts, m_bmesh->key, 0);
+ do_rel_key(0, m_bmesh->totvert, m_bmesh->totvert, (char *)(float *)m_transverts, m_bmesh->key, NULL, 0);
m_bDynamic = true;
}