diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-10-22 20:35:51 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-10-22 20:35:51 +0400 |
commit | 3ffb695b10bd85f7cd431f6144dbc2c427a365ee (patch) | |
tree | 008509058f8da92056c567e50951d48438a35c82 /source/blender/blenkernel | |
parent | b06640c583ed9900223855004d8e9cd6947adf21 (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')
-rw-r--r-- | source/blender/blenkernel/BKE_key.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_modifier.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/DerivedMesh.c | 15 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist.c | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/key.c | 130 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/lattice.c | 3 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 100 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/particle.c | 1 |
8 files changed, 173 insertions, 84 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); |