joining mesh objects now keeps relative key setting of each keyblock. also joining...
authorCampbell Barton <ideasman42@gmail.com>
Wed, 19 Sep 2012 12:11:28 +0000 (12:11 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Wed, 19 Sep 2012 12:11:28 +0000 (12:11 +0000)
source/blender/blenkernel/BKE_key.h
source/blender/blenkernel/intern/key.c
source/blender/editors/curve/editcurve.c
source/blender/editors/mesh/meshtools.c

index 7283cd3..01baf8f 100644 (file)
@@ -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);
index ba8008d..5b05ce0 100644 (file)
@@ -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 
index e50bc27..39cb2d9 100644 (file)
@@ -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);
index d2c42e8..191c831 100644 (file)
@@ -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