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:
parent
b06640c583
commit
3ffb695b10
|
@ -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"
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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++;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue