svn merge -r39878:39890 https://svn.blender.org/svnroot/bf-blender/trunk/blender
[blender-staging.git] / source / blender / blenkernel / intern / customdata.c
index 7276e4eb246ac1ad2f77663a43f1c9efd06e5aee..f47e38f6d17e59f00352ee62aaaf9959f8884a17 100644 (file)
@@ -39,7 +39,6 @@
 
 #include <math.h>
 #include <string.h>
-
 #include <assert.h>
 
 #include "MEM_guardedalloc.h"
@@ -47,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"
@@ -59,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"
@@ -298,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];
@@ -350,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;
@@ -454,8 +470,9 @@ 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 *sub_weights, int count, void *dest)
+                               float *UNUSED(sub_weights), int UNUSED(count), void *dest)
 {
        MDisps *d = dest;
 
@@ -463,11 +480,127 @@ static void layerInterp_mdisps(void **sources, float *UNUSED(weights),
        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)
+{
+       MDisps *d = dest;
+       MDisps *s = NULL;
+       int st, stl;
+       int i, x, y;
+       int side, S, dst_corners, src_corners;
+       float crn_weight[4][2];
+       float (*sw)[4] = (void*)sub_weights;
+       float (*disps)[3], (*out)[3];
+
+       /* happens when flipping normals of newly created mesh */
+       if(!d->totdisp)
+               return;
+
+       s = sources[0];
+       dst_corners = multires_mdisp_corners(d);
+       src_corners = multires_mdisp_corners(s);
+
+       if(sub_weights && count == 2 && src_corners == 3) {
+               src_corners = multires_mdisp_corners(sources[1]);
+
+               /* special case -- converting two triangles to quad */
+               if(src_corners == 3 && dst_corners == 4) {
+                       MDisps tris[2];
+                       int vindex[4] = {0};
+
+                       for(i = 0; i < 2; i++)
+                               for(y = 0; y < 4; y++)
+                                       for(x = 0; x < 4; x++)
+                                               if(sw[x+i*4][y])
+                                                       vindex[x] = y;
+
+                       for(i = 0; i < 2; i++) {
+                               float sw_m4[4][4] = {{0}};
+                               int a = 7 & ~(1 << vindex[i*2] | 1 << vindex[i*2+1]);
+
+                               sw_m4[0][vindex[i*2+1]] = 1;
+                               sw_m4[1][vindex[i*2]] = 1;
+
+                               for(x = 0; x < 3; x++)
+                                       if(a & (1 << x))
+                                               sw_m4[2][x] = 1;
+
+                               tris[i] = *((MDisps*)sources[i]);
+                               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++)
+                               MEM_freeN(tris[i].disps);
+
+                       return;
+               }
+       }
+
+       /* For now, some restrictions on the input */
+       if(count != 1 || !sub_weights) {
+               for(i = 0; i < d->totdisp; ++i)
+                       zero_v3(d->disps[i]);
+
+               return;
+       }
+
+       /* Initialize the destination */
+       disps = MEM_callocN(3*d->totdisp*sizeof(float), "iterp disps");
+
+       side = sqrt(d->totdisp / dst_corners);
+       st = (side<<1)-1;
+       stl = st - 1;
+
+       sw= (void*)sub_weights;
+       for(i = 0; i < 4; ++i) {
+               crn_weight[i][0] = 0 * sw[i][0] + stl * sw[i][1] + stl * sw[i][2] + 0 * sw[i][3];
+               crn_weight[i][1] = 0 * sw[i][0] + 0 * sw[i][1] + stl * sw[i][2] + stl * sw[i][3];
+       }
+
+       multires_mdisp_smooth_bounds(s);
+
+       out = disps;
+       for(S = 0; S < dst_corners; S++) {
+               float base[2], axis_x[2], axis_y[2];
+
+               mdisp_apply_weight(S, dst_corners, 0, 0, st, crn_weight, &base[0], &base[1]);
+               mdisp_apply_weight(S, dst_corners, side-1, 0, st, crn_weight, &axis_x[0], &axis_x[1]);
+               mdisp_apply_weight(S, dst_corners, 0, side-1, st, crn_weight, &axis_y[0], &axis_y[1]);
+
+               sub_v2_v2(axis_x, base);
+               sub_v2_v2(axis_y, base);
+               normalize_v2(axis_x);
+               normalize_v2(axis_y);
+
+               for(y = 0; y < side; ++y) {
+                       for(x = 0; x < side; ++x, ++out) {
+                               int crn;
+                               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_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);
+                       }
+               }
+       }
+
+       MEM_freeN(d->disps);
+       d->disps = disps;
+}
+#endif // BMESH_TODO
+
 static void layerCopy_mdisps(const void *source, void *dest, int count)
 {
        int i;
@@ -489,7 +622,10 @@ static void layerCopy_mdisps(const void *source, void *dest, int count)
 
 static void layerValidate_mdisps(void *data, int sub_elements)
 {
-#if 0
+#if 1 /*BMESH_TODO*/
+       (void)data;
+       (void)sub_elements;
+#else
        MDisps *disps = data;
        if(disps->disps) {
                int corners = multires_mdisp_corners(disps);
@@ -641,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;
 
@@ -849,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;
@@ -868,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;
 
@@ -888,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,
@@ -997,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;
 
@@ -1019,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*/
@@ -1040,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,
@@ -1060,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,
@@ -1125,7 +1284,7 @@ static void customData_update_offsets(CustomData *data)
        }
 
        data->totsize = offset;
-       customData_update_typemap(data);
+       CustomData_update_typemap(data);
 }
 
 int CustomData_get_layer_index(const CustomData *data, int type)
@@ -1355,9 +1514,8 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
        int size = typeInfo->size * totelem, flag = 0, index = data->totlayer;
        void *newlayerdata;
 
-       if (!typeInfo->defaultname && CustomData_has_layer(data, type)) {
+       if (!typeInfo->defaultname && CustomData_has_layer(data, type))
                return &data->layers[CustomData_get_layer_index(data, type)];
-       }
 
        if((alloctype == CD_ASSIGN) || (alloctype == CD_REFERENCE)) {
                newlayerdata = layerdata;
@@ -1431,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;
@@ -1447,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;
@@ -1486,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;
 }
@@ -1571,10 +1729,10 @@ void CustomData_free_temporary(CustomData *data, int totelem)
 
                if (i != j)
                        data->layers[j] = data->layers[i];
-               
-               if ((layer->flag & CD_FLAG_TEMPORARY) == CD_FLAG_TEMPORARY) {
+
+               if ((layer->flag & CD_FLAG_TEMPORARY) == CD_FLAG_TEMPORARY)
                        customData_free_layer__internal(layer, totelem);
-               else
+               else
                        j++;
        }
 
@@ -1810,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 */
@@ -2148,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);
        }
 }
 
@@ -2184,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) {