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.
This commit is contained in:
Brecht Van Lommel 2009-10-22 16:35:51 +00:00
parent b06640c583
commit 3ffb695b10
18 changed files with 275 additions and 139 deletions

View File

@ -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"

View File

@ -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
};

View File

@ -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);

View File

@ -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

View File

@ -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);
}

View File

@ -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 */

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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++;
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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;
}