svn merge -r39878:39890 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender-staging.git] / source / blender / blenkernel / intern / customdata.c
index 346fb5dd85d65ddae223a5dc1f0d4348dc7771c6..f47e38f6d17e59f00352ee62aaaf9959f8884a17 100644 (file)
 *
 * BKE_customdata.h contains the function prototypes for this file.
 *
-*/ 
+*/
+
+/** \file blender/blenkernel/intern/customdata.c
+ *  \ingroup bke
+ */
 
 #include <math.h>
 #include <string.h>
-
 #include <assert.h>
 
 #include "MEM_guardedalloc.h"
@@ -42,6 +46,7 @@
 #include "DNA_meshdata_types.h"
 #include "DNA_ID.h"
 
+#include "BLI_utildefines.h"
 #include "BLI_blenlib.h"
 #include "BLI_path_util.h"
 #include "BLI_linklist.h"
@@ -54,7 +59,6 @@
 #include "BKE_customdata_file.h"
 #include "BKE_global.h"
 #include "BKE_main.h"
-#include "BKE_utildefines.h"
 #include "BKE_multires.h"
 
 #include "bmesh.h"
@@ -293,7 +297,6 @@ static void layerInterp_tface(void **sources, float *weights,
        }
 
        *tf = *(MTFace *)sources[0];
-
        for(j = 0; j < 4; ++j) {
                tf->uv[j][0] = uv[j][0];
                tf->uv[j][1] = uv[j][1];
@@ -345,6 +348,24 @@ static void layerDefault_tface(void *data, int count)
                tf[i] = default_tf;
 }
 
+static void layerCopy_propFloat(const void *source, void *dest,
+                                                                 int count)
+{
+       memcpy(dest, source, sizeof(MFloatProperty)*count);
+}
+
+static void layerCopy_propInt(const void *source, void *dest,
+                                                                 int count)
+{
+       memcpy(dest, source, sizeof(MIntProperty)*count);
+}
+
+static void layerCopy_propString(const void *source, void *dest,
+                                                                 int count)
+{
+       memcpy(dest, source, sizeof(MStringProperty)*count);
+}
+
 static void layerCopy_origspace_face(const void *source, void *dest, int count)
 {
        const OrigSpaceFace *source_tf = (const OrigSpaceFace*)source;
@@ -449,6 +470,23 @@ static void layerSwap_mdisps(void *data, const int *ci)
        }
 }
 
+#if 1 /* BMESH_TODO: place holder function, dont actually interp */
+static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
+                               float *UNUSED(sub_weights), int UNUSED(count), void *dest)
+{
+       MDisps *d = dest;
+
+       /* happens when flipping normals of newly created mesh */
+       if(!d->totdisp) {
+               d->totdisp = ((MDisps*)sources[0])->totdisp;
+       }
+
+       if (!d->disps && d->totdisp)
+               d->disps = BLI_cellalloc_calloc(sizeof(float)*3*d->totdisp, "blank mdisps in layerInterp_mdisps");
+}
+
+#else // BMESH_TODO
+
 static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
                                float *sub_weights, int count, void *dest)
 {
@@ -462,13 +500,9 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
        float (*disps)[3], (*out)[3];
 
        /* happens when flipping normals of newly created mesh */
-       if(!d->totdisp) {
-               d->totdisp = ((MDisps*)sources[0])->totdisp;
-       }
-       
-       if (!d->disps && d->totdisp)
-               d->disps = BLI_cellalloc_calloc(sizeof(float)*3*d->totdisp, "blank mdisps in layerInterp_mdisps");
-#if 0  
+       if(!d->totdisp)
+               return;
+
        s = sources[0];
        dst_corners = multires_mdisp_corners(d);
        src_corners = multires_mdisp_corners(s);
@@ -481,7 +515,6 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
                        MDisps tris[2];
                        int vindex[4] = {0};
 
-                       S = 0;
                        for(i = 0; i < 2; i++)
                                for(y = 0; y < 4; y++)
                                        for(x = 0; x < 4; x++)
@@ -500,14 +533,14 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
                                                sw_m4[2][x] = 1;
 
                                tris[i] = *((MDisps*)sources[i]);
-                               tris[i].disps = BLI_cellalloc_dupalloc(tris[i].disps);
+                               tris[i].disps = MEM_dupallocN(tris[i].disps);
                                layerInterp_mdisps(&sources[i], NULL, (float*)sw_m4, 1, &tris[i]);
                        }
 
                        mdisp_join_tris(d, &tris[0], &tris[1]);
 
                        for(i = 0; i < 2; i++)
-                               BLI_cellalloc_free(tris[i].disps);
+                               MEM_freeN(tris[i].disps);
 
                        return;
                }
@@ -522,7 +555,7 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
        }
 
        /* Initialize the destination */
-       out = disps = BLI_cellalloc_calloc(3*d->totdisp*sizeof(float), "iterp disps");
+       disps = MEM_callocN(3*d->totdisp*sizeof(float), "iterp disps");
 
        side = sqrt(d->totdisp / dst_corners);
        st = (side<<1)-1;
@@ -555,7 +588,7 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
                                float face_u, face_v, crn_u, crn_v;
 
                                mdisp_apply_weight(S, dst_corners, x, y, st, crn_weight, &face_u, &face_v);
-                               crn = mdisp_rot_face_to_crn(src_corners, st, face_u, face_v, &crn_u, &crn_v);
+                               crn = mdisp_rot_face_to_quad_crn(src_corners, st, face_u, face_v, &crn_u, &crn_v);
 
                                old_mdisps_bilinear((*out), &s->disps[crn*side*side], side, crn_u, crn_v);
                                mdisp_flip_disp(crn, dst_corners, axis_x, axis_y, *out);
@@ -563,10 +596,10 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
                }
        }
 
-       BLI_cellalloc_free(d->disps);
+       MEM_freeN(d->disps);
        d->disps = disps;
-#endif
 }
+#endif // BMESH_TODO
 
 static void layerCopy_mdisps(const void *source, void *dest, int count)
 {
@@ -589,6 +622,10 @@ static void layerCopy_mdisps(const void *source, void *dest, int count)
 
 static void layerValidate_mdisps(void *data, int sub_elements)
 {
+#if 1 /*BMESH_TODO*/
+       (void)data;
+       (void)sub_elements;
+#else
        MDisps *disps = data;
        if(disps->disps) {
                int corners = multires_mdisp_corners(disps);
@@ -599,6 +636,7 @@ static void layerValidate_mdisps(void *data, int sub_elements)
                        disps->disps = BLI_cellalloc_calloc(3*disps->totdisp*sizeof(float), "layerValidate_mdisps");
                }
        }
+#endif
 }
 
 static void layerFree_mdisps(void *data, int count, int UNUSED(size))
@@ -739,7 +777,6 @@ static void layerDefault_mloopcol(void *data, int count)
        MLoopCol default_mloopcol = {255,255,255,255};
        MLoopCol *mlcol = (MLoopCol*)data;
        int i;
-
        for(i = 0; i < count; i++)
                mlcol[i] = default_mloopcol;
 
@@ -947,10 +984,10 @@ static void layerDefault_mcol(void *data, int count)
 }
 
 static void layerInterp_bweight(void **sources, float *weights,
-                             float *sub_weights, int count, void *dest)
+                             float *UNUSED(sub_weights), int count, void *dest)
 {
        float *f = dest, *src;
-       float **in = sources;
+       float **in = (float **)sources;
        int i;
        
        if(count <= 0) return;
@@ -966,11 +1003,11 @@ static void layerInterp_bweight(void **sources, float *weights,
 }
 
 static void layerInterp_shapekey(void **sources, float *weights,
-                             float *sub_weights, int count, void *dest)
+                             float *UNUSED(sub_weights), int count, void *dest)
 {
        float *co = dest, *src;
-       float **in = sources;
-       int i, j, k;
+       float **in = (float **)sources;
+       int i;
 
        if(count <= 0) return;
 
@@ -986,46 +1023,70 @@ static void layerInterp_shapekey(void **sources, float *weights,
        }
 }
 
+/* note, these numbered comments below are copied from trunk,
+ * while _most_ match, some at the end need adding and are out of sync */
+
 static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
+       /* 0: CD_MVERT */
        {sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
+       /* 1: CD_MSTICKY */
        {sizeof(MSticky), "MSticky", 1, NULL, NULL, NULL, layerInterp_msticky, NULL,
         NULL},
+       /* 2: CD_MDEFORMVERT */
        {sizeof(MDeformVert), "MDeformVert", 1, NULL, layerCopy_mdeformvert,
         layerFree_mdeformvert, layerInterp_mdeformvert, NULL, NULL},
+       /* 3: CD_MEDGE */
        {sizeof(MEdge), "MEdge", 1, NULL, NULL, NULL, NULL, NULL, NULL},
+       /* 4: CD_MFACE */
        {sizeof(MFace), "MFace", 1, NULL, NULL, NULL, NULL, NULL, NULL},
+       /* 5: CD_MTFACE */
        {sizeof(MTFace), "MTFace", 1, "UVTex", layerCopy_tface, NULL,
         layerInterp_tface, layerSwap_tface, layerDefault_tface},
+       /* 6: CD_MCOL */
        /* 4 MCol structs per face */
        {sizeof(MCol)*4, "MCol", 4, "Col", NULL, NULL, layerInterp_mcol,
         layerSwap_mcol, layerDefault_mcol},
+       /* 7: CD_ORIGINDEX */
        {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+       /* 8: CD_NORMAL */
        /* 3 floats per normal vector */
        {sizeof(float)*3, "vec3f", 1, NULL, NULL, NULL, NULL, NULL, NULL},
+       /* 9: CD_FLAGS */
        {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
-       {sizeof(MFloatProperty), "MFloatProperty",1,"Float",NULL,NULL,NULL,NULL},
-       {sizeof(MIntProperty), "MIntProperty",1,"Int",NULL,NULL,NULL,NULL},
-       {sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL},
+       /* 10: CD_PROP_FLT */
+       {sizeof(MFloatProperty), "MFloatProperty",1,"Float", layerCopy_propFloat,NULL,NULL,NULL},
+       /* 11: CD_PROP_INT */
+       {sizeof(MIntProperty), "MIntProperty",1,"Int",layerCopy_propInt,NULL,NULL,NULL},
+       /* 12: CD_PROP_STR */
+       {sizeof(MStringProperty), "MStringProperty",1,"String",layerCopy_propString,NULL,NULL,NULL},
+       /* 13: CD_ORIGSPACE */
        {sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL,
         layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
+       /* 14: CD_ORCO */
        {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+       /* 15: CD_MTEXPOLY */
        {sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL},
+       /* 16: CD_MLOOPUV */
        {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL,
         layerEqual_mloopuv, layerMultiply_mloopuv, layerInitMinMax_mloopuv, 
         layerAdd_mloopuv, layerDoMinMax_mloopuv, layerCopyValue_mloopuv},
+       /* 17: CD_MLOOPCOL */
        {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, 
         layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol, 
         layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
        {sizeof(float)*4*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+       /* 19: CD_MDISPS */
        {sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps,
         layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL, 
         NULL, NULL, NULL, NULL, NULL, NULL, 
         layerRead_mdisps, layerWrite_mdisps, layerFilesize_mdisps, layerValidate_mdisps},
+       /* 20: CD_WEIGHT_MCOL */
        {sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol,
         layerSwap_mcol, layerDefault_mcol},
        {sizeof(MPoly), "MPoly", 1, "NGon Face", NULL, NULL, NULL, NULL, NULL},
        {sizeof(MLoop), "MLoop", 1, "NGon Face-Vertex", NULL, NULL, NULL, NULL, NULL},
        {sizeof(float)*3, "", 0, "ClothOrco", NULL, NULL, layerInterp_shapekey},
+       /* 21: CD_ID_MCOL */
        {sizeof(MCol)*4, "MCol", 4, "IDCol", NULL, NULL, layerInterp_mcol,
         layerSwap_mcol, layerDefault_mcol},
        {sizeof(MCol)*4, "MCol", 4, "TextureCol", NULL, NULL, layerInterp_mcol,
@@ -1067,7 +1128,7 @@ const CustomDataMask CD_MASK_DERIVEDMESH =
        CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
        CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_WEIGHT_MLOOPCOL |
        CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | 
-       CD_MASK_WEIGHT_MCOL | CD_MASK_NORMAL;
+       CD_MASK_WEIGHT_MCOL | CD_MASK_NORMAL | CD_MASK_SHAPEKEY;
 const CustomDataMask CD_MASK_BMESH = CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY |
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | 
        CD_MASK_PROP_STR | CD_MASK_SHAPEKEY | CD_MASK_SHAPE_KEYINDEX | CD_MASK_MDISPS;
@@ -1095,7 +1156,7 @@ static void customData_update_offsets(CustomData *data);
 static CustomDataLayer *customData_add_layer__internal(CustomData *data,
        int type, int alloctype, void *layerdata, int totelem, const char *name);
 
-void customData_update_typemap(CustomData *data)
+void CustomData_update_typemap(CustomData *data)
 {
        int i, lasttype = -1;
 
@@ -1117,7 +1178,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
        /*const LayerTypeInfo *typeInfo;*/
        CustomDataLayer *layer, *newlayer;
        int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0, lastflag = 0;
-       
+
        for(i = 0; i < source->totlayer; ++i) {
                layer = &source->layers[i];
                /*typeInfo = layerType_getInfo(layer->type);*/ /*UNUSED*/
@@ -1138,7 +1199,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
 
                if(lastflag & CD_FLAG_NOCOPY) continue;
                else if(!((int)mask & (int)(1 << (int)type))) continue;
-               else if(number+1 < CustomData_number_of_layers(dest, type)) continue;
+               else if(number < CustomData_number_of_layers(dest, type)) continue;
 
                if((alloctype == CD_ASSIGN) && (lastflag & CD_FLAG_NOFREE))
                        newlayer = customData_add_layer__internal(dest, type, CD_REFERENCE,
@@ -1148,6 +1209,8 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
                                layer->data, totelem, layer->name);
                
                if(newlayer) {
+                       newlayer->uid = layer->uid;
+                       
                        newlayer->active = lastactive;
                        newlayer->active_rnd = lastrender;
                        newlayer->active_clone = lastclone;
@@ -1156,7 +1219,7 @@ void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
                }
        }
 
-       customData_update_typemap(dest);
+       CustomData_update_typemap(dest);
 }
 
 void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
@@ -1221,6 +1284,7 @@ static void customData_update_offsets(CustomData *data)
        }
 
        data->totsize = offset;
+       CustomData_update_typemap(data);
 }
 
 int CustomData_get_layer_index(const CustomData *data, int type)
@@ -1525,7 +1589,7 @@ void *CustomData_add_layer(CustomData *data, int type, int alloctype,
        
        layer = customData_add_layer__internal(data, type, alloctype, layerdata,
                                                                                   totelem, typeInfo->defaultname);
-       customData_update_typemap(data);
+       CustomData_update_typemap(data);
 
        if(layer)
                return layer->data;
@@ -1541,7 +1605,7 @@ void *CustomData_add_layer_named(CustomData *data, int type, int alloctype,
        
        layer = customData_add_layer__internal(data, type, alloctype, layerdata,
                                                                                   totelem, name);
-       customData_update_typemap(data);
+       CustomData_update_typemap(data);
 
        if(layer)
                return layer->data;
@@ -1580,7 +1644,7 @@ int CustomData_free_layer(CustomData *data, int type, int totelem, int index)
                customData_resize(data, -CUSTOMDATA_GROW);
 
        customData_update_offsets(data);
-       customData_update_typemap(data);
+       CustomData_update_typemap(data);
 
        return 1;
 }
@@ -1904,6 +1968,20 @@ void *CustomData_get_layer_named(const struct CustomData *data, int type,
        return data->layers[layer_index].data;
 }
 
+
+int CustomData_set_layer_name(const CustomData *data, int type, int n, const char *name)
+{
+       /* get the layer index of the first layer of type */
+       int layer_index = CustomData_get_layer_index_n(data, type, n);
+
+       if(layer_index < 0) return 0;
+       if (!name) return 0;
+       
+       strcpy(data->layers[layer_index].name, name);
+       
+       return 1;
+}
+
 void *CustomData_set_layer(const CustomData *data, int type, void *ptr)
 {
        /* get the layer index of the first layer of type */
@@ -2242,13 +2320,13 @@ void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData
        int i;
        for(i=0; i < pdata->totlayer; i++){
                if(pdata->layers[i].type == CD_MTEXPOLY)
-                       CustomData_add_layer(fdata, CD_MTFACE, CD_CALLOC, &(pdata->layers[i].name), total);
+                       CustomData_add_layer_named(fdata, CD_MTFACE, CD_CALLOC, NULL, total, pdata->layers[i].name);
        }
        for(i=0; i < ldata->totlayer; i++){
                if(ldata->layers[i].type == CD_MLOOPCOL)
-                       CustomData_add_layer(fdata, CD_MCOL, CD_CALLOC, &(ldata->layers[i].name), total);
+                       CustomData_add_layer_named(fdata, CD_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
                if (ldata->layers[i].type == CD_WEIGHT_MLOOPCOL)
-                       CustomData_add_layer(fdata, CD_WEIGHT_MCOL, CD_CALLOC, &(ldata->layers[i].name), total);
+                       CustomData_add_layer_named(fdata, CD_WEIGHT_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
        }
 }
 
@@ -2278,6 +2356,9 @@ void CustomData_bmesh_merge(CustomData *source, CustomData *dest,
                        t = BM_LOOPS_OF_FACE; break;
                case BM_FACE:
                        t = BM_FACES_OF_MESH; break;
+               default: /* should never happen */
+                       BLI_assert(!"invalid type given");
+                       t = BM_VERTS_OF_MESH;
        }
 
        if (t != BM_LOOPS_OF_FACE) {