From 15ce5f95b3933eaa2be7cbf1e3dcc211138b0f0b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 19 Sep 2012 12:11:28 +0000 Subject: joining mesh objects now keeps relative key setting of each keyblock. also joining absolute shapekeys now sorts by time. --- source/blender/blenkernel/BKE_key.h | 1 + source/blender/blenkernel/intern/key.c | 19 ++++++++--- source/blender/editors/curve/editcurve.c | 2 +- source/blender/editors/mesh/meshtools.c | 55 +++++++++++++++++++++++--------- 4 files changed, 57 insertions(+), 20 deletions(-) (limited to 'source') diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index 7283cd389e9..01baf8feb2a 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -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_from_key(struct Key *key, int index); 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); // 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); diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c index ba8008d2abd..5b05ce02104 100644 --- a/source/blender/blenkernel/intern/key.c +++ b/source/blender/blenkernel/intern/key.c @@ -1511,10 +1511,21 @@ KeyBlock *BKE_keyblock_from_key(Key *key, int index) /* get the appropriate KeyBlock given a name to search for */ KeyBlock *BKE_keyblock_find_name(Key *key, const char name[]) { - if (key && name) - return BLI_findstring(&key->block, name, offsetof(KeyBlock, name)); - - return NULL; + return BLI_findstring(&key->block, name, offsetof(KeyBlock, name)); +} + +/** + * \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 diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index e50bc2741e1..39cb2d98783 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -6070,7 +6070,7 @@ void CURVE_OT_shade_flat(wmOperatorType *ot) } /************** join operator, to be used externally? ****************/ - +/* TODO: shape keys - as with meshes */ int join_curve_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index d2c42e82065..191c831bd79 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.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 (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 (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); - - /* copy most settings */ - 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; + + BKE_keyblock_copy_settings(kbn, kb); /* adjust settings to fit (allocate a new data-array) */ kbn->data = MEM_callocN(sizeof(float) * 3 * totvert, "joined_shapekey"); @@ -270,13 +275,26 @@ int join_mesh_exec(bContext *C, wmOperator *op) } #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; - + + /* setup new data for destination mesh */ memset(&vdata, 0, sizeof(vdata)); memset(&edata, 0, sizeof(edata)); @@ -351,7 +369,8 @@ int join_mesh_exec(bContext *C, wmOperator *op) fp1 = ((float *)kb->data) + (vertofs * 3); /* 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) { /* copy this mesh's shapekey to the destination shapekey (need to transform first) */ 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))) { ED_object_iter_other(bmain, base->object, TRUE, - ED_object_multires_update_totlevels_cb, - &mmd->totlvl); + ED_object_multires_update_totlevels_cb, + &mmd->totlvl); } } @@ -543,6 +562,12 @@ int join_mesh_exec(bContext *C, wmOperator *op) 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 #if 0 -- cgit v1.2.3