forked from bartvdbraak/blender
joining mesh objects now keeps relative key setting of each keyblock. also joining absolute shapekeys now sorts by time.
This commit is contained in:
parent
0d5d2146eb
commit
15ce5f95b3
@ -69,6 +69,7 @@ struct KeyBlock *BKE_keyblock_add(struct Key *key, const char *name);
|
|||||||
struct KeyBlock *BKE_keyblock_add_ctime(struct Key *key, const char *name, const short do_force);
|
struct KeyBlock *BKE_keyblock_add_ctime(struct Key *key, const char *name, const short do_force);
|
||||||
struct KeyBlock *BKE_keyblock_from_key(struct Key *key, int index);
|
struct KeyBlock *BKE_keyblock_from_key(struct Key *key, int index);
|
||||||
struct KeyBlock *BKE_keyblock_find_name(struct Key *key, const char name[]);
|
struct KeyBlock *BKE_keyblock_find_name(struct Key *key, const char name[]);
|
||||||
|
void BKE_keyblock_copy_settings(struct KeyBlock *kb_dst, const struct KeyBlock *kb_src);
|
||||||
char *BKE_keyblock_curval_rnapath_get(struct Key *key, struct KeyBlock *kb);
|
char *BKE_keyblock_curval_rnapath_get(struct Key *key, struct KeyBlock *kb);
|
||||||
// needed for the GE
|
// needed for the GE
|
||||||
void BKE_key_evaluate_relative(const int start, int end, const int tot, char *basispoin, struct Key *key, struct KeyBlock *actkb, const int mode);
|
void BKE_key_evaluate_relative(const int start, int end, const int tot, char *basispoin, struct Key *key, struct KeyBlock *actkb, const int mode);
|
||||||
|
@ -1511,10 +1511,21 @@ KeyBlock *BKE_keyblock_from_key(Key *key, int index)
|
|||||||
/* get the appropriate KeyBlock given a name to search for */
|
/* get the appropriate KeyBlock given a name to search for */
|
||||||
KeyBlock *BKE_keyblock_find_name(Key *key, const char name[])
|
KeyBlock *BKE_keyblock_find_name(Key *key, const char name[])
|
||||||
{
|
{
|
||||||
if (key && name)
|
return BLI_findstring(&key->block, name, offsetof(KeyBlock, name));
|
||||||
return BLI_findstring(&key->block, name, offsetof(KeyBlock, name));
|
}
|
||||||
|
|
||||||
return NULL;
|
/**
|
||||||
|
* \brief copy shape-key attributes, but not key data.or name/uid
|
||||||
|
*/
|
||||||
|
void BKE_keyblock_copy_settings(KeyBlock *kb_dst, const KeyBlock *kb_src)
|
||||||
|
{
|
||||||
|
kb_dst->pos = kb_src->pos;
|
||||||
|
kb_dst->curval = kb_src->curval;
|
||||||
|
kb_dst->type = kb_src->type;
|
||||||
|
kb_dst->relative = kb_src->relative;
|
||||||
|
BLI_strncpy(kb_dst->vgroup, kb_src->vgroup, sizeof(kb_dst->vgroup));
|
||||||
|
kb_dst->slidermin = kb_src->slidermin;
|
||||||
|
kb_dst->slidermax = kb_src->slidermax;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get RNA-Path for 'value' setting of the given ShapeKey
|
/* Get RNA-Path for 'value' setting of the given ShapeKey
|
||||||
|
@ -6070,7 +6070,7 @@ void CURVE_OT_shade_flat(wmOperatorType *ot)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/************** join operator, to be used externally? ****************/
|
/************** join operator, to be used externally? ****************/
|
||||||
|
/* TODO: shape keys - as with meshes */
|
||||||
int join_curve_exec(bContext *C, wmOperator *UNUSED(op))
|
int join_curve_exec(bContext *C, wmOperator *UNUSED(op))
|
||||||
{
|
{
|
||||||
Main *bmain = CTX_data_main(C);
|
Main *bmain = CTX_data_main(C);
|
||||||
|
@ -243,19 +243,24 @@ int join_mesh_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
/* if this mesh has shapekeys, check if destination mesh already has matching entries too */
|
/* if this mesh has shapekeys, check if destination mesh already has matching entries too */
|
||||||
if (me->key && key) {
|
if (me->key && key) {
|
||||||
for (kb = me->key->block.first; kb; kb = kb->next) {
|
/* for remapping KeyBlock.relative */
|
||||||
|
int *index_map = MEM_mallocN(sizeof(int) * me->key->totkey, __func__);
|
||||||
|
KeyBlock **kb_map = MEM_mallocN(sizeof(KeyBlock *) * me->key->totkey, __func__);
|
||||||
|
|
||||||
|
for (kb = me->key->block.first, i = 0; kb; kb = kb->next, i++) {
|
||||||
|
BLI_assert(i < me->key->totkey);
|
||||||
|
|
||||||
|
kbn = BKE_keyblock_find_name(key, kb->name);
|
||||||
/* if key doesn't exist in destination mesh, add it */
|
/* if key doesn't exist in destination mesh, add it */
|
||||||
if (BKE_keyblock_find_name(key, kb->name) == NULL) {
|
if (kbn) {
|
||||||
|
index_map[i] = BLI_findindex(&key->block, kbn);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
index_map[i] = key->totkey;
|
||||||
|
|
||||||
kbn = BKE_keyblock_add(key, kb->name);
|
kbn = BKE_keyblock_add(key, kb->name);
|
||||||
|
|
||||||
/* copy most settings */
|
BKE_keyblock_copy_settings(kbn, kb);
|
||||||
kbn->pos = kb->pos;
|
|
||||||
kbn->curval = kb->curval;
|
|
||||||
kbn->type = kb->type;
|
|
||||||
kbn->relative = kb->relative;
|
|
||||||
BLI_strncpy(kbn->vgroup, kb->vgroup, sizeof(kbn->vgroup));
|
|
||||||
kbn->slidermin = kb->slidermin;
|
|
||||||
kbn->slidermax = kb->slidermax;
|
|
||||||
|
|
||||||
/* adjust settings to fit (allocate a new data-array) */
|
/* adjust settings to fit (allocate a new data-array) */
|
||||||
kbn->data = MEM_callocN(sizeof(float) * 3 * totvert, "joined_shapekey");
|
kbn->data = MEM_callocN(sizeof(float) * 3 * totvert, "joined_shapekey");
|
||||||
@ -270,13 +275,26 @@ int join_mesh_exec(bContext *C, wmOperator *op)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kb_map[i] = kbn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* remap relative index values */
|
||||||
|
for (kb = me->key->block.first, i = 0; kb; kb = kb->next, i++) {
|
||||||
|
if (LIKELY(kb->relative < me->key->totkey)) { /* sanity check, should always be true */
|
||||||
|
kb_map[i]->relative = index_map[kb->relative];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MEM_freeN(index_map);
|
||||||
|
MEM_freeN(kb_map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
CTX_DATA_END;
|
CTX_DATA_END;
|
||||||
|
|
||||||
|
|
||||||
/* setup new data for destination mesh */
|
/* setup new data for destination mesh */
|
||||||
memset(&vdata, 0, sizeof(vdata));
|
memset(&vdata, 0, sizeof(vdata));
|
||||||
memset(&edata, 0, sizeof(edata));
|
memset(&edata, 0, sizeof(edata));
|
||||||
@ -351,7 +369,8 @@ int join_mesh_exec(bContext *C, wmOperator *op)
|
|||||||
fp1 = ((float *)kb->data) + (vertofs * 3);
|
fp1 = ((float *)kb->data) + (vertofs * 3);
|
||||||
|
|
||||||
/* check if this mesh has such a shapekey */
|
/* check if this mesh has such a shapekey */
|
||||||
okb = BKE_keyblock_find_name(me->key, kb->name);
|
okb = me->key ? BKE_keyblock_find_name(me->key, kb->name) : NULL;
|
||||||
|
|
||||||
if (okb) {
|
if (okb) {
|
||||||
/* copy this mesh's shapekey to the destination shapekey (need to transform first) */
|
/* copy this mesh's shapekey to the destination shapekey (need to transform first) */
|
||||||
fp2 = ((float *)(okb->data));
|
fp2 = ((float *)(okb->data));
|
||||||
@ -422,8 +441,8 @@ int join_mesh_exec(bContext *C, wmOperator *op)
|
|||||||
|
|
||||||
if ((mmd = get_multires_modifier(scene, base->object, TRUE))) {
|
if ((mmd = get_multires_modifier(scene, base->object, TRUE))) {
|
||||||
ED_object_iter_other(bmain, base->object, TRUE,
|
ED_object_iter_other(bmain, base->object, TRUE,
|
||||||
ED_object_multires_update_totlevels_cb,
|
ED_object_multires_update_totlevels_cb,
|
||||||
&mmd->totlvl);
|
&mmd->totlvl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -543,6 +562,12 @@ int join_mesh_exec(bContext *C, wmOperator *op)
|
|||||||
MEM_freeN(nkey);
|
MEM_freeN(nkey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ensure newly inserted keys are time sorted */
|
||||||
|
if (key && (key->type != KEY_RELATIVE)) {
|
||||||
|
BKE_key_sort(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
DAG_scene_sort(bmain, scene); // removed objects, need to rebuild dag before editmode call
|
DAG_scene_sort(bmain, scene); // removed objects, need to rebuild dag before editmode call
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
Loading…
Reference in New Issue
Block a user