bugfix: [#36786] customdata layers are not merging taken the names into consideration
authorDalai Felinto <dfelinto@gmail.com>
Sat, 21 Sep 2013 05:42:34 +0000 (05:42 +0000)
committerDalai Felinto <dfelinto@gmail.com>
Sat, 21 Sep 2013 05:42:34 +0000 (05:42 +0000)
(which is also "[#36749] Joining objects with more than one uv map depends on list order")

Thanks Bastien Montagne and Brecht van Lommel for reviewing and some advice.

source/blender/blenkernel/BKE_customdata.h
source/blender/blenkernel/intern/customdata.c
source/blender/editors/mesh/meshtools.c

index d47d03fe903cf4cf8fc941af1db510a4a6c4c322..5a2839227075d4e717d03aca0175c6ba4badf48a 100644 (file)
@@ -192,6 +192,9 @@ void CustomData_set_only_copy(const struct CustomData *data,
 void CustomData_copy_data(const struct CustomData *source,
                           struct CustomData *dest, int source_index,
                           int dest_index, int count);
+void CustomData_copy_data_named(const struct CustomData *source,
+                          struct CustomData *dest, int source_index,
+                          int dest_index, int count);
 void CustomData_copy_elements(int type, void *source, void *dest, int count);
 void CustomData_bmesh_copy_data(const struct CustomData *source, 
                                 struct CustomData *dest, void *src_block, 
index 03dfee4b57c497c3382140a6e96a305ee27efa03..c386d72a8bd15ca6435629aa0b29908937632cab 100644 (file)
@@ -1313,7 +1313,7 @@ bool CustomData_merge(const struct CustomData *source, struct CustomData *dest,
 
                if (lastflag & CD_FLAG_NOCOPY) continue;
                else if (!(mask & CD_TYPE_AS_MASK(type))) continue;
-               else if (number < CustomData_number_of_layers(dest, type)) continue;
+               else if (CustomData_get_layer_named(dest, type, layer->name)) continue;
 
                switch (alloctype) {
                        case CD_ASSIGN:
@@ -1457,8 +1457,10 @@ int CustomData_get_named_layer_index(const CustomData *data, int type, const cha
        int i;
 
        for (i = 0; i < data->totlayer; ++i)
-               if (data->layers[i].type == type && strcmp(data->layers[i].name, name) == 0)
-                       return i;
+               if (data->layers[i].type == type)
+                       if ((!name && !data->layers[i].name) ||
+                           (strcmp(data->layers[i].name, name) == 0))
+                               return i;
 
        return -1;
 }
@@ -1947,13 +1949,61 @@ void CustomData_copy_elements(int type, void *source, void *dest, int count)
                memcpy(dest, source, typeInfo->size * count);
 }
 
+static void CustomData_copy_data_layer(const CustomData *source, CustomData *dest,
+                                       int src_i, int dest_i,
+                                       int source_index, int dest_index, int count) {
+       const LayerTypeInfo *typeInfo;
+       int src_offset;
+       int dest_offset;
+
+       char *src_data = source->layers[src_i].data;
+       char *dest_data = dest->layers[dest_i].data;
+
+       typeInfo = layerType_getInfo(source->layers[src_i].type);
+
+       src_offset = source_index * typeInfo->size;
+       dest_offset = dest_index * typeInfo->size;
+
+       if (!src_data || !dest_data) {
+               if (src_data != NULL && dest_data != NULL) {
+                       printf("%s: warning null data for %s type (%p --> %p), skipping\n",
+                              __func__, layerType_getName(source->layers[src_i].type),
+                              (void *)src_data, (void *)dest_data);
+               }
+               return;
+       }
+
+       if (typeInfo->copy)
+               typeInfo->copy(src_data + src_offset,
+                              dest_data + dest_offset,
+                              count);
+       else
+               memcpy(dest_data + dest_offset,
+                      src_data + src_offset,
+                      count * typeInfo->size);
+}
+
+void CustomData_copy_data_named(const CustomData *source, CustomData *dest,
+                                int source_index, int dest_index, int count)
+{
+       int src_i, dest_i;
+
+       /* copies a layer at a time */
+       for (src_i = 0; src_i < source->totlayer; ++src_i) {
+
+               dest_i = CustomData_get_named_layer_index(dest, source->layers[src_i].type, source->layers[src_i].name);
+
+               /* if we found a matching layer, copy the data */
+               if (dest_i > -1) {
+                       CustomData_copy_data_layer(source, dest, src_i, dest_i, source_index, dest_index, count);
+               }
+       }
+}
+
 void CustomData_copy_data(const CustomData *source, CustomData *dest,
                           int source_index, int dest_index, int count)
 {
-       const LayerTypeInfo *typeInfo;
        int src_i, dest_i;
-       int src_offset;
-       int dest_offset;
 
        /* copies a layer at a time */
        dest_i = 0;
@@ -1971,32 +2021,8 @@ void CustomData_copy_data(const CustomData *source, CustomData *dest,
 
                /* if we found a matching layer, copy the data */
                if (dest->layers[dest_i].type == source->layers[src_i].type) {
-                       char *src_data = source->layers[src_i].data;
-                       char *dest_data = dest->layers[dest_i].data;
-
-                       typeInfo = layerType_getInfo(source->layers[src_i].type);
-
-                       src_offset = source_index * typeInfo->size;
-                       dest_offset = dest_index * typeInfo->size;
+                       CustomData_copy_data_layer(source, dest, src_i, dest_i, source_index, dest_index, count);
                        
-                       if (!src_data || !dest_data) {
-                               if (src_data != NULL && dest_data != NULL) {
-                                       printf("%s: warning null data for %s type (%p --> %p), skipping\n",
-                                              __func__, layerType_getName(source->layers[src_i].type),
-                                              (void *)src_data, (void *)dest_data);
-                               }
-                               continue;
-                       }
-                       
-                       if (typeInfo->copy)
-                               typeInfo->copy(src_data + src_offset,
-                                              dest_data + dest_offset,
-                                              count);
-                       else
-                               memcpy(dest_data + dest_offset,
-                                      src_data + src_offset,
-                                      count * typeInfo->size);
-
                        /* if there are multiple source & dest layers of the same type,
                         * we don't want to copy all source layers to the same dest, so
                         * increment dest_i
index efa619bd10c35bb3b5b5654bc684c150d50aa800..5ee980ef5cb11ac1daabaa8e497d0ac4bac321ec 100644 (file)
@@ -314,7 +314,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
 
                                /* standard data */
                                CustomData_merge(&me->vdata, &vdata, CD_MASK_MESH, CD_DEFAULT, totvert);
-                               CustomData_copy_data(&me->vdata, &vdata, 0, vertofs, me->totvert);
+                               CustomData_copy_data_named(&me->vdata, &vdata, 0, vertofs, me->totvert);
                                
                                /* vertex groups */
                                dvert = CustomData_get(&vdata, vertofs, CD_MDEFORMVERT);
@@ -415,7 +415,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
                        
                        if (me->totedge) {
                                CustomData_merge(&me->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
-                               CustomData_copy_data(&me->edata, &edata, 0, edgeofs, me->totedge);
+                               CustomData_copy_data_named(&me->edata, &edata, 0, edgeofs, me->totedge);
                                
                                for (a = 0; a < me->totedge; a++, medge++) {
                                        medge->v1 += vertofs;
@@ -437,7 +437,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
                                }
                                
                                CustomData_merge(&me->ldata, &ldata, CD_MASK_MESH, CD_DEFAULT, totloop);
-                               CustomData_copy_data(&me->ldata, &ldata, 0, loopofs, me->totloop);
+                               CustomData_copy_data_named(&me->ldata, &ldata, 0, loopofs, me->totloop);
                                
                                for (a = 0; a < me->totloop; a++, mloop++) {
                                        mloop->v += vertofs;
@@ -461,7 +461,7 @@ int join_mesh_exec(bContext *C, wmOperator *op)
                                }
 
                                CustomData_merge(&me->pdata, &pdata, CD_MASK_MESH, CD_DEFAULT, totpoly);
-                               CustomData_copy_data(&me->pdata, &pdata, 0, polyofs, me->totpoly);
+                               CustomData_copy_data_named(&me->pdata, &pdata, 0, polyofs, me->totpoly);
                                
                                for (a = 0; a < me->totpoly; a++, mpoly++) {
                                        mpoly->loopstart += loopofs;