diff --git a/release/scripts/ui/buttons_data_mesh.py b/release/scripts/ui/buttons_data_mesh.py index 5ae004514bd..e29166a505f 100644 --- a/release/scripts/ui/buttons_data_mesh.py +++ b/release/scripts/ui/buttons_data_mesh.py @@ -71,9 +71,14 @@ class DATA_PT_vertex_groups(DataButtonsPanel): layout = self.layout ob = context.object + group = ob.active_vertex_group + + rows = 2 + if group: + rows= 5 row = layout.row() - row.template_list(ob, "vertex_groups", ob, "active_vertex_group_index", rows=2) + row.template_list(ob, "vertex_groups", ob, "active_vertex_group_index", rows=rows) col = row.column(align=True) col.itemO("object.vertex_group_add", icon='ICON_ZOOMIN', text="") @@ -83,7 +88,6 @@ class DATA_PT_vertex_groups(DataButtonsPanel): if ob.data.users > 1: col.itemO("object.vertex_group_copy_to_linked", icon='ICON_LINK_AREA', text="") - group = ob.active_vertex_group if group: row = layout.row() row.itemR(group, "name") @@ -114,8 +118,19 @@ class DATA_PT_shape_keys(DataButtonsPanel): key = ob.data.shape_keys kb = ob.active_shape_key + enable_edit = ob.mode != 'EDIT' + enable_edit_value = False + + if ob.shape_key_lock == False: + if enable_edit or (ob.type == 'MESH' and ob.shape_key_edit_mode): + enable_edit_value = True + row = layout.row() - row.template_list(key, "keys", ob, "active_shape_key_index", rows=2) + + rows = 2 + if kb: + rows= 5 + row.template_list(key, "keys", ob, "active_shape_key_index", rows=rows) col = row.column() @@ -124,57 +139,57 @@ class DATA_PT_shape_keys(DataButtonsPanel): subcol.itemO("object.shape_key_remove", icon='ICON_ZOOMOUT', text="") if kb: - subcol.itemO("object.shape_key_mirror", icon='ICON_MOD_MIRROR', text="") - col.itemS() subcol = col.column(align=True) subcol.item_enumO("object.shape_key_move", "type", 'UP', icon='ICON_TRIA_UP', text="") subcol.item_enumO("object.shape_key_move", "type", 'DOWN', icon='ICON_TRIA_DOWN', text="") - - col.itemS() - subcol = col.column(align=True) - subcol.itemR(ob, "shape_key_lock", icon='ICON_UNPINNED', text="") - subcol.itemR(kb, "mute", icon='ICON_MUTE_IPO_OFF', text="") + split = layout.split(percentage=0.4) + sub = split.row() + sub.enabled = enable_edit + sub.itemR(key, "relative") + + sub = split.row() + sub.alignment = 'RIGHT' + + subrow = sub.row(align=True) + subrow.itemR(ob, "shape_key_lock", icon='ICON_UNPINNED', text="") + subrow.itemR(kb, "mute", icon='ICON_MUTE_IPO_OFF', text="") + subrow.itemO("object.shape_key_clear", icon='ICON_X', text="") + + sub.itemO("object.shape_key_mirror", icon='ICON_MOD_MIRROR', text="") + + sub.itemR(ob, "shape_key_edit_mode", text="") + + row = layout.row() + row.enabled = enable_edit_value + row.itemR(kb, "name") if key.relative: - row = layout.row() - row.itemR(key, "relative") - row.itemL() - - row = layout.row() - row.itemR(kb, "name") - if ob.active_shape_key_index != 0: - row = layout.row() - row.enabled = ob.shape_key_lock == False + row.enabled = enable_edit_value row.itemR(kb, "value") - row.itemO("object.shape_key_clear", icon='ICON_X', text="") split = layout.split() sub = split.column(align=True) - sub.enabled = ob.shape_key_lock == False + sub.enabled = enable_edit_value sub.itemL(text="Range:") sub.itemR(kb, "slider_min", text="Min") sub.itemR(kb, "slider_max", text="Max") sub = split.column(align=True) + sub.enabled = enable_edit_value sub.itemL(text="Blend:") sub.item_pointerR(kb, "vertex_group", ob, "vertex_groups", text="") sub.item_pointerR(kb, "relative_key", key, "keys", text="") else: row = layout.row() - row.itemR(key, "relative") + row.enabled = enable_edit row.itemR(key, "slurph") - layout.itemR(kb, "name") - - if ob.mode == 'EDIT': - layout.enabled = False - class DATA_PT_uv_texture(DataButtonsPanel): __label__ = "UV Texture" 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(a1key, kb, NULL, KEY_BPOINT); + if(a1bezt) { 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(a1key, kb, NULL, KEY_BEZTRIPLE); + if(a1from==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; acopyData = 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 && ilist_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 && ilist_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; }