svn merge ^/trunk/blender -r42967:42973
authorCampbell Barton <ideasman42@gmail.com>
Thu, 29 Dec 2011 12:17:45 +0000 (12:17 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 29 Dec 2011 12:17:45 +0000 (12:17 +0000)
1  2 
source/blender/blenkernel/intern/customdata.c
source/blender/editors/curve/editfont.c

index 3fc6445d102c12f51bfa03c14504c02c2e2547cd,35b2499bea5d6f4eac9b913dc6723a62df957164..2f557ae38422fb61c5449ea9e4901023b6a4b0b3
  #include "DNA_meshdata_types.h"
  #include "DNA_ID.h"
  
 +#include "BLI_utildefines.h"
  #include "BLI_blenlib.h"
  #include "BLI_linklist.h"
  #include "BLI_math.h"
  #include "BLI_mempool.h"
 +#include "BLI_cellalloc.h"
  #include "BLI_utildefines.h"
  
  #include "BKE_customdata.h"
  #include "BKE_customdata_file.h"
  #include "BKE_global.h"
  #include "BKE_main.h"
 -#include "BKE_utildefines.h"
  #include "BKE_multires.h"
  
 +#include "bmesh.h"
 +
 +#include <math.h>
 +#include <string.h>
 +
  /* number of layers to add when growing a CustomData object */
  #define CUSTOMDATA_GROW 5
  
@@@ -139,7 -133,7 +139,7 @@@ static void layerCopy_mdeformvert(cons
                MDeformVert *dvert = (MDeformVert *)((char *)dest + i * size);
  
                if(dvert->totweight) {
 -                      MDeformWeight *dw = MEM_callocN(dvert->totweight * sizeof(*dw),
 +                      MDeformWeight *dw = BLI_cellalloc_calloc(dvert->totweight * sizeof(*dw),
                                                                                        "layerCopy_mdeformvert dw");
  
                        memcpy(dw, dvert->dw, dvert->totweight * sizeof(*dw));
@@@ -158,7 -152,7 +158,7 @@@ static void layerFree_mdeformvert(void 
                MDeformVert *dvert = (MDeformVert *)((char *)data + i * size);
  
                if(dvert->dw) {
 -                      MEM_freeN(dvert->dw);
 +                      BLI_cellalloc_free(dvert->dw);
                        dvert->dw = NULL;
                        dvert->totweight = 0;
                }
  
  static void linklist_free_simple(void *link)
  {
 -      MEM_freeN(link);
 +      BLI_cellalloc_free(link);
  }
  
  static void layerInterp_mdeformvert(void **sources, float *weights,
  
                        /* if this def_nr is not in the list, add it */
                        if(!node) {
 -                              MDeformWeight *tmp_dw = MEM_callocN(sizeof(*tmp_dw),
 +                              MDeformWeight *tmp_dw = BLI_cellalloc_calloc(sizeof(*tmp_dw),
                                                                                        "layerInterp_mdeformvert tmp_dw");
                                tmp_dw->def_nr = dw->def_nr;
                                tmp_dw->weight = dw->weight * interp_weight;
        }
  
        /* now we know how many unique deform weights there are, so realloc */
 -      if(dvert->dw) MEM_freeN(dvert->dw);
 +      if(dvert->dw) BLI_cellalloc_free(dvert->dw);
  
        if(totweight) {
 -              dvert->dw = MEM_callocN(sizeof(*dvert->dw) * totweight,
 +              dvert->dw = BLI_cellalloc_calloc(sizeof(*dvert->dw) * totweight,
                                                                "layerInterp_mdeformvert dvert->dw");
                dvert->totweight = totweight;
  
@@@ -240,13 -234,11 +240,11 @@@ static void layerInterp_msticky(void **
                w = weights ? weights[i] : 1.0f;
                mst = (MSticky*)sources[i];
  
-               co[0] += w*mst->co[0];
-               co[1] += w*mst->co[1];
+               madd_v2_v2fl(co, mst->co, w);
        }
  
        mst = (MSticky*)dest;
-       mst->co[0] = co[0];
-       mst->co[1] = co[1];
+       copy_v2_v2(mst->co, co);
  }
  
  
@@@ -265,13 -257,11 +263,11 @@@ static void layerInterp_tface(void **so
  {
        MTFace *tf = dest;
        int i, j, k;
-       float uv[4][2];
+       float uv[4][2] = {{0.0f}};
        float *sub_weight;
  
        if(count <= 0) return;
  
-       memset(uv, 0, sizeof(uv));
        sub_weight = sub_weights;
        for(i = 0; i < count; ++i) {
                float weight = weights ? weights[i] : 1;
                for(j = 0; j < 4; ++j) {
                        if(sub_weights) {
                                for(k = 0; k < 4; ++k, ++sub_weight) {
-                                       float w = (*sub_weight) * weight;
-                                       float *tmp_uv = src->uv[k];
-                                       uv[j][0] += tmp_uv[0] * w;
-                                       uv[j][1] += tmp_uv[1] * w;
+                                       madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * weight);
                                }
-                       } else {
-                               uv[j][0] += src->uv[j][0] * weight;
-                               uv[j][1] += src->uv[j][1] * weight;
+                       }
+                       else {
+                               madd_v2_v2fl(uv[j], src->uv[j], weight);
                        }
                }
        }
  
-       *tf = *(MTFace *)sources[0];
-       for(j = 0; j < 4; ++j) {
-               tf->uv[j][0] = uv[j][0];
-               tf->uv[j][1] = uv[j][1];
-       }
+       *tf = *(MTFace *)(*sources);
+       memcpy(tf->uv, uv, sizeof(tf->uv));
  }
  
  static void layerSwap_tface(void *data, const int *corner_indices)
        int j;
  
        for(j = 0; j < 4; ++j) {
-               int source_index = corner_indices[j];
+               const int source_index = corner_indices[j];
  
-               uv[j][0] = tf->uv[source_index][0];
-               uv[j][1] = tf->uv[source_index][1];
+               copy_v2_v2(uv[j], tf->uv[source_index]);
  
                // swap pinning flags around
                if(tf->unwrap & pin_flags[source_index]) {
@@@ -378,13 -360,11 +366,11 @@@ static void layerInterp_origspace_face(
  {
        OrigSpaceFace *osf = dest;
        int i, j, k;
-       float uv[4][2];
+       float uv[4][2] = {{0.0f}};
        float *sub_weight;
  
        if(count <= 0) return;
  
-       memset(uv, 0, sizeof(uv));
        sub_weight = sub_weights;
        for(i = 0; i < count; ++i) {
                float weight = weights ? weights[i] : 1;
                for(j = 0; j < 4; ++j) {
                        if(sub_weights) {
                                for(k = 0; k < 4; ++k, ++sub_weight) {
-                                       float w = (*sub_weight) * weight;
-                                       float *tmp_uv = src->uv[k];
-                                       uv[j][0] += tmp_uv[0] * w;
-                                       uv[j][1] += tmp_uv[1] * w;
+                                       madd_v2_v2fl(uv[j], src->uv[k], (*sub_weight) * weight);
                                }
                        } else {
-                               uv[j][0] += src->uv[j][0] * weight;
-                               uv[j][1] += src->uv[j][1] * weight;
+                               madd_v2_v2fl(uv[j], src->uv[j], weight);
                        }
                }
        }
  
-       *osf = *(OrigSpaceFace *)sources[0];
-       for(j = 0; j < 4; ++j) {
-               osf->uv[j][0] = uv[j][0];
-               osf->uv[j][1] = uv[j][1];
-       }
+ #if 0 /* no need, this ONLY contains UV's */
+       *osf = *(OrigSpaceFace *)(*sources);
+ #endif
+       memcpy(osf->uv, uv, sizeof(osf->uv));
  }
  
  static void layerSwap_origspace_face(void *data, const int *corner_indices)
        int j;
  
        for(j = 0; j < 4; ++j) {
-               uv[j][0] = osf->uv[corner_indices[j]][0];
-               uv[j][1] = osf->uv[corner_indices[j]][1];
+               copy_v2_v2(uv[j], osf->uv[corner_indices[j]]);
        }
        memcpy(osf->uv, uv, sizeof(osf->uv));
  }
@@@ -451,39 -424,22 +430,39 @@@ static void layerSwap_mdisps(void *data
                        /* happens when face changed vertex count in edit mode
                           if it happened, just forgot displacement */
  
 -                      MEM_freeN(s->disps);
 +                      BLI_cellalloc_free(s->disps);
                        s->totdisp= (s->totdisp/corners)*nverts;
 -                      s->disps= MEM_callocN(s->totdisp*sizeof(float)*3, "mdisp swap");
 +                      s->disps= BLI_cellalloc_calloc(s->totdisp*sizeof(float)*3, "mdisp swap");
                        return;
                }
  
 -              d= MEM_callocN(sizeof(float) * 3 * s->totdisp, "mdisps swap");
 +              d= BLI_cellalloc_calloc(sizeof(float) * 3 * s->totdisp, "mdisps swap");
  
                for(S = 0; S < corners; S++)
                        memcpy(d + cornersize*S, s->disps + cornersize*ci[S], cornersize*3*sizeof(float));
                
 -              MEM_freeN(s->disps);
 +              BLI_cellalloc_free(s->disps);
                s->disps= d;
        }
  }
  
 +#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)
  {
        MEM_freeN(d->disps);
        d->disps = disps;
  }
 +#endif // BMESH_TODO
  
  static void layerCopy_mdisps(const void *source, void *dest, int count)
  {
  
        for(i = 0; i < count; ++i) {
                if(s[i].disps) {
 -                      d[i].disps = MEM_dupallocN(s[i].disps);
 +                      d[i].disps = BLI_cellalloc_dupalloc(s[i].disps);
                        d[i].totdisp = s[i].totdisp;
                }
                else {
  
  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);
                if(corners != sub_elements) {
                        MEM_freeN(disps->disps);
                        disps->totdisp = disps->totdisp / corners * sub_elements;
 -                      disps->disps = MEM_callocN(3*disps->totdisp*sizeof(float), "layerValidate_mdisps");
 +                      disps->disps = BLI_cellalloc_calloc(3*disps->totdisp*sizeof(float), "layerValidate_mdisps");
                }
        }
 +#endif
  }
  
  static void layerFree_mdisps(void *data, int count, int UNUSED(size))
  
        for(i = 0; i < count; ++i) {
                if(d[i].disps)
 -                      MEM_freeN(d[i].disps);
 +                      BLI_cellalloc_free(d[i].disps);
                d[i].disps = NULL;
                d[i].totdisp = 0;
        }
@@@ -656,7 -606,7 +635,7 @@@ static int layerRead_mdisps(CDataFile *
  
        for(i = 0; i < count; ++i) {
                if(!d[i].disps)
 -                      d[i].disps = MEM_callocN(sizeof(float)*3*d[i].totdisp, "mdisps read");
 +                      d[i].disps = BLI_cellalloc_calloc(sizeof(float)*3*d[i].totdisp, "mdisps read");
  
                if(!cdf_read_data(cdf, d[i].totdisp*3*sizeof(float), d[i].disps)) {
                        printf("failed to read multires displacement %d/%d %d\n", i, count, d[i].totdisp);
@@@ -802,7 -752,7 +781,7 @@@ static void layerInterp_mloopcol(void *
                        col.r += src->r * (*sub_weight) * weight;
                        col.g += src->g * (*sub_weight) * weight;
                        col.b += src->b * (*sub_weight) * weight;
-                       sub_weight++;           
+                       sub_weight++;
                } else {
                        col.a += src->a * weight;
                        col.r += src->r * weight;
  static void layerCopyValue_mloopuv(void *source, void *dest)
  {
        MLoopUV *luv1 = source, *luv2 = dest;
-       
-       luv2->uv[0] = luv1->uv[0];
-       luv2->uv[1] = luv1->uv[1];
+       copy_v2_v2(luv2->uv, luv1->uv);
  }
  
  static int layerEqual_mloopuv(void *data1, void *data2)
  {
        MLoopUV *luv1 = data1, *luv2 = data2;
-       float u, v;
-       u = luv1->uv[0] - luv2->uv[0];
-       v = luv1->uv[1] - luv2->uv[1];
  
-       return u*u + v*v < 0.00001;
+       return len_squared_v2v2(luv1->uv, luv2->uv) < 0.00001f;
  }
  
  static void layerMultiply_mloopuv(void *data, float fac)
  {
        MLoopUV *luv = data;
  
-       luv->uv[0] *= fac;
-       luv->uv[1] *= fac;
+       mul_v2_fl(luv->uv, fac);
  }
  
  static void layerInitMinMax_mloopuv(void *vmin, void *vmax)
@@@ -869,37 -813,34 +842,34 @@@ static void layerAdd_mloopuv(void *data
  {
        MLoopUV *l1 = data1, *l2 = data2;
  
-       l1->uv[0] += l2->uv[0];
-       l1->uv[1] += l2->uv[1];
+       add_v2_v2(l1->uv, l2->uv);
  }
  
  static void layerInterp_mloopuv(void **sources, float *weights,
-                               float *sub_weights, int count, void *dest)
+                                 float *sub_weights, int count, void *dest)
  {
        MLoopUV *mluv = dest;
+       float *uv= mluv->uv;
        int i;
-       float *sub_weight;
-       struct {
-               float u;
-               float v;
-       }uv;
-       uv.u = uv.v = 0.0;
  
-       sub_weight = sub_weights;
-       for(i = 0; i < count; ++i){
-               float weight = weights ? weights[i] : 1;
-               MLoopUV *src = sources[i];
-               if(sub_weights){
-                       uv.u += src->uv[0] * (*sub_weight) * weight;
-                       uv.v += src->uv[1] * (*sub_weight) * weight;
-                       sub_weight++;           
-               } else {
-                       uv.u += src->uv[0] * weight;
-                       uv.v += src->uv[1] * weight;
+       zero_v2(uv);
+       if (sub_weights) {
+               const float *sub_weight = sub_weights;
+               for(i = 0; i < count; i++) {
+                       float weight = weights ? weights[i] : 1.0f;
+                       MLoopUV *src = sources[i];
+                       madd_v2_v2fl(uv, src->uv, (*sub_weight) * weight);
+                       sub_weight++;
+               }
+       }
+       else {
+               for(i = 0; i < count; i++) {
+                       float weight = weights ? weights[i] : 1;
+                       MLoopUV *src = sources[i];
+                       madd_v2_v2fl(uv, src->uv, weight);
                }
        }
-       mluv->uv[0] = uv.u;
-       mluv->uv[1] = uv.v;
  }
  
  static void layerInterp_mcol(void **sources, float *weights,
                float r;
                float g;
                float b;
-       } col[4];
+       } col[4] = {{0.0f}};
        float *sub_weight;
  
        if(count <= 0) return;
-       memset(col, 0, sizeof(col));
        
        sub_weight = sub_weights;
        for(i = 0; i < count; ++i) {
                        if(sub_weights) {
                                MCol *src = sources[i];
                                for(k = 0; k < 4; ++k, ++sub_weight, ++src) {
-                                       col[j].a += src->a * (*sub_weight) * weight;
-                                       col[j].r += src->r * (*sub_weight) * weight;
-                                       col[j].g += src->g * (*sub_weight) * weight;
-                                       col[j].b += src->b * (*sub_weight) * weight;
+                                       const float w= (*sub_weight) * weight;
+                                       col[j].a += src->a * w;
+                                       col[j].r += src->r * w;
+                                       col[j].g += src->g * w;
+                                       col[j].b += src->b * w;
                                }
                        } else {
                                MCol *src = sources[i];
@@@ -1051,7 -992,7 +1021,7 @@@ static const LayerTypeInfo LAYERTYPEINF
        {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
        /* 8: CD_NORMAL */
        /* 3 floats per normal vector */
 -      {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
 +      {sizeof(float)*3, "vec3f", 1, NULL, NULL, NULL, NULL, NULL, NULL},
        /* 9: CD_POLYINDEX */
        {sizeof(int), "MIntProperty", 1, NULL, NULL, NULL, NULL, NULL, NULL},
        /* 10: CD_PROP_FLT */
        /* 24: CD_RECAST */
        {sizeof(MRecast), "MRecast", 1,"Recast",NULL,NULL,NULL,NULL}
  
 -#ifdef USE_BMESH_FORWARD_COMPAT
 -      ,
  /* BMESH ONLY */
 +      ,
        /* 25: CD_MPOLY */
        {sizeof(MPoly), "MPoly", 1, "NGon Face", NULL, NULL, NULL, NULL, NULL},
        /* 26: CD_MLOOP */
         layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
  /* END BMESH ONLY */
  
 -#endif /* USE_BMESH_FORWARD_COMPAT */
  
  };
  
 +/* note, numbers are from trunk and need updating for bmesh */
 +
  static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
        /*   0-4 */ "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace",
        /*   5-9 */ "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags",
        /* 15-19 */ "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent", "CDMDisps",
        /* 20-24 */"CDWeightMCol", "CDIDMCol", "CDTextureMCol", "CDClothOrco", "CDMRecast"
  
 -#ifdef USE_BMESH_FORWARD_COMPAT
 +/* BMESH ONLY */
        ,
        /* 25-29 */ "CDMPoly", "CDMLoop", "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight",
        /* 30-31 */ "CDSubSurfCrease", "CDWeightLoopCol"
 +/* END BMESH ONLY */
  
 -#endif /* USE_BMESH_FORWARD_COMPAT */
  };
  
 +
  const CustomDataMask CD_MASK_BAREMESH =
 -      CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE;
 +      CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE | CD_MASK_MLOOP | CD_MASK_MPOLY | CD_MASK_BWEIGHT;
  const CustomDataMask CD_MASK_MESH =
        CD_MASK_MVERT | CD_MASK_MEDGE | CD_MASK_MFACE |
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MCOL |
 -      CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS | CD_MASK_RECAST;
 +      CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS |
 +      CD_MASK_MLOOPUV | CD_MASK_MLOOPCOL | CD_MASK_MPOLY | CD_MASK_MLOOP |
 +      CD_MASK_MTEXPOLY | CD_MASK_NORMAL | CD_MASK_MDISPS | CD_MASK_RECAST;
  const CustomDataMask CD_MASK_EDITMESH =
 -      CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
 -      CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR | CD_MASK_MDISPS | CD_MASK_RECAST;
 +      CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE | CD_MASK_MLOOPUV |
 +      CD_MASK_MLOOPCOL | CD_MASK_MTEXPOLY | CD_MASK_SHAPE_KEYINDEX |
 +      CD_MASK_MCOL|CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR |
 +      CD_MASK_MDISPS | CD_MASK_SHAPEKEY | CD_MASK_RECAST;
  const CustomDataMask CD_MASK_DERIVEDMESH =
        CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_MTFACE |
 -      CD_MASK_MCOL | CD_MASK_ORIGINDEX | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_CLOTH_ORCO |
 -      CD_MASK_PROP_STR | CD_MASK_ORIGSPACE | CD_MASK_ORCO | CD_MASK_TANGENT | CD_MASK_WEIGHT_MCOL | CD_MASK_RECAST;
 -const CustomDataMask CD_MASK_BMESH = 
 -      CD_MASK_MSTICKY | CD_MASK_MDEFORMVERT | CD_MASK_PROP_FLT | CD_MASK_PROP_INT | CD_MASK_PROP_STR;
 +      CD_MASK_MCOL | 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_SHAPEKEY | CD_MASK_RECAST |
 +      CD_MASK_ORIGINDEX | CD_MASK_POLYINDEX;
 +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;
  const CustomDataMask CD_MASK_FACECORNERS =
        CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_MTEXPOLY | CD_MASK_MLOOPUV |
        CD_MASK_MLOOPCOL;
@@@ -1208,7 -1140,6 +1178,7 @@@ void CustomData_merge(const struct Cust
  {
        /*const LayerTypeInfo *typeInfo;*/
        CustomDataLayer *layer, *newlayer;
 +      void *data;
        int i, type, number = 0, lasttype = -1, lastactive = 0, lastrender = 0, lastclone = 0, lastmask = 0, lastflag = 0;
  
        for(i = 0; i < source->totlayer; ++i) {
                else if(!(mask & CD_TYPE_AS_MASK(type))) continue;
                else if(number < CustomData_number_of_layers(dest, type)) continue;
  
 +              switch (alloctype) {
 +                      case CD_ASSIGN:
 +                      case CD_REFERENCE:
 +                      case CD_DUPLICATE:
 +                              data = layer->data;
 +                              break;
 +                      default:
 +                              data = NULL;
 +                              break;
 +              }
 +
                if((alloctype == CD_ASSIGN) && (lastflag & CD_FLAG_NOFREE))
                        newlayer = customData_add_layer__internal(dest, type, CD_REFERENCE,
 -                              layer->data, totelem, layer->name);
 +                              data, totelem, layer->name);
                else
                        newlayer = customData_add_layer__internal(dest, type, alloctype,
 -                              layer->data, totelem, layer->name);
 +                              data, totelem, layer->name);
                
                if(newlayer) {
 +                      newlayer->uid = layer->uid;
 +                      
                        newlayer->active = lastactive;
                        newlayer->active_rnd = lastrender;
                        newlayer->active_clone = lastclone;
@@@ -1555,14 -1473,7 +1525,14 @@@ static CustomDataLayer *customData_add_
  {
        const LayerTypeInfo *typeInfo= layerType_getInfo(type);
        int size = typeInfo->size * totelem, flag = 0, index = data->totlayer;
 -      void *newlayerdata;
 +      void *newlayerdata = NULL;
 +
 +      /* Passing a layerdata to copy from with an alloctype that won't copy is
 +         most likely a bug */
 +      BLI_assert(!layerdata ||
 +                 (alloctype == CD_ASSIGN) ||
 +                 (alloctype == CD_DUPLICATE) ||
 +                 (alloctype == CD_REFERENCE));
  
        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;
        }
 -      else {
 +      else if (size > 0) {
                newlayerdata = MEM_callocN(size, layerType_getName(type));
                if(!newlayerdata)
                        return NULL;
        }
  
 -      if (alloctype == CD_DUPLICATE) {
 +      if (alloctype == CD_DUPLICATE && layerdata) {
                if(typeInfo->copy)
                        typeInfo->copy(layerdata, newlayerdata, totelem);
                else
@@@ -2393,139 -2304,35 +2363,139 @@@ void CustomData_from_em_block(const Cus
  
  /*Bmesh functions*/
  /*needed to convert to/from different face reps*/
 -void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata)
 +void CustomData_to_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata,
 +                           int totloop, int totpoly)
  {
        int i;
 -      for(i=0; i < fdata->totlayer; i++){
 -              if(fdata->layers[i].type == CD_MTFACE){
 -                      CustomData_add_layer(pdata, CD_MTEXPOLY, CD_CALLOC, &(fdata->layers[i].name), 0);
 -                      CustomData_add_layer(ldata, CD_MLOOPUV, CD_CALLOC, &(fdata->layers[i].name), 0);
 +      for(i=0; i < fdata->totlayer; i++) {
 +              if(fdata->layers[i].type == CD_MTFACE) {
 +                      CustomData_add_layer_named(pdata, CD_MTEXPOLY, CD_CALLOC, NULL, totpoly, fdata->layers[i].name);
 +                      CustomData_add_layer_named(ldata, CD_MLOOPUV, CD_CALLOC, NULL, totloop, fdata->layers[i].name);
 +              }
 +              else if (fdata->layers[i].type == CD_MCOL) {
 +                      CustomData_add_layer_named(ldata, CD_MLOOPCOL, CD_CALLOC, NULL, totloop, fdata->layers[i].name);
                }
 -              else if(fdata->layers[i].type == CD_MCOL)
 -                      CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), 0);
 -      }               
 +              else if (fdata->layers[i].type == CD_MDISPS) {
 +                      CustomData_add_layer_named(ldata, CD_MDISPS, CD_CALLOC, NULL, totloop, fdata->layers[i].name);
 +              }
 +      }
  }
 +
  void CustomData_from_bmeshpoly(CustomData *fdata, CustomData *pdata, CustomData *ldata, int total)
  {
        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);
 +      for(i=0; i < pdata->totlayer; i++) {
 +              if (pdata->layers[i].type == CD_MTEXPOLY) {
 +                      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);
 +      for(i=0; i < ldata->totlayer; i++) {
 +              if (ldata->layers[i].type == CD_MLOOPCOL) {
 +                      CustomData_add_layer_named(fdata, CD_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
 +              }
 +              else if (ldata->layers[i].type == CD_WEIGHT_MLOOPCOL) {
 +                      CustomData_add_layer_named(fdata, CD_WEIGHT_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
 +              }
        }
  }
  
 +void CustomData_bmesh_update_active_layers(CustomData *fdata, CustomData *pdata, CustomData *ldata)
 +{
 +      int act;
 +
 +      if (CustomData_has_layer(pdata, CD_MTEXPOLY)) {
 +              act = CustomData_get_active_layer(pdata, CD_MTEXPOLY);
 +              CustomData_set_layer_active(ldata, CD_MLOOPUV, act);
 +              CustomData_set_layer_active(fdata, CD_MTFACE, act);
 +
 +              act = CustomData_get_render_layer(pdata, CD_MTEXPOLY);
 +              CustomData_set_layer_render(ldata, CD_MLOOPUV, act);
 +              CustomData_set_layer_render(fdata, CD_MTFACE, act);
 +
 +              act = CustomData_get_clone_layer(pdata, CD_MTEXPOLY);
 +              CustomData_set_layer_clone(ldata, CD_MLOOPUV, act);
 +              CustomData_set_layer_clone(fdata, CD_MTFACE, act);
 +
 +              act = CustomData_get_stencil_layer(pdata, CD_MTEXPOLY);
 +              CustomData_set_layer_stencil(ldata, CD_MLOOPUV, act);
 +              CustomData_set_layer_stencil(fdata, CD_MTFACE, act);
 +      }
 +
 +      if (CustomData_has_layer(ldata, CD_MLOOPCOL)) {
 +              act = CustomData_get_active_layer(ldata, CD_MLOOPCOL);
 +              CustomData_set_layer_active(fdata, CD_MCOL, act);
 +
 +              act = CustomData_get_render_layer(ldata, CD_MLOOPCOL);
 +              CustomData_set_layer_render(fdata, CD_MCOL, act);
 +
 +              act = CustomData_get_clone_layer(ldata, CD_MLOOPCOL);
 +              CustomData_set_layer_clone(fdata, CD_MCOL, act);
 +
 +              act = CustomData_get_stencil_layer(ldata, CD_MLOOPCOL);
 +              CustomData_set_layer_stencil(fdata, CD_MCOL, act);
 +      }
 +}
  
  void CustomData_bmesh_init_pool(CustomData *data, int allocsize)
  {
 -      if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, FALSE, FALSE);
 +      /* Dispose old pools before calling here to avoid leaks */
 +      BLI_assert(data->pool == NULL);
 +
 +      /* If there are no layers, no pool is needed just yet */
 +      if (data->totlayer) {
 +              data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, TRUE, FALSE);
 +      }
 +}
 +
 +void CustomData_bmesh_merge(CustomData *source, CustomData *dest, 
 +                            int mask, int alloctype, BMesh *bm, int type)
 +{
 +      BMHeader *h;
 +      BMIter iter;
 +      CustomData destold = *dest;
 +      void *tmp;
 +      int t;
 +      
 +      CustomData_merge(source, dest, mask, alloctype, 0);
 +      CustomData_bmesh_init_pool(dest, 512);
 +
 +      switch (type) {
 +              case BM_VERT:
 +                      t = BM_VERTS_OF_MESH; break;
 +              case BM_EDGE:
 +                      t = BM_EDGES_OF_MESH; break;
 +              case BM_LOOP:
 +                      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) {
 +              /*ensure all current elements follow new customdata layout*/
 +              BM_ITER(h, &iter, bm, t, NULL) {
 +                      CustomData_bmesh_copy_data(&destold, dest, h->data, &tmp);
 +                      CustomData_bmesh_free_block(&destold, &h->data);
 +                      h->data = tmp;
 +              }
 +      } else {
 +              BMFace *f;
 +              BMLoop *l;
 +              BMIter liter;
 +
 +              /*ensure all current elements follow new customdata layout*/
 +              BM_ITER(f, &iter, bm, BM_FACES_OF_MESH, NULL) {
 +                      BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, f) {
 +                              CustomData_bmesh_copy_data(&destold, dest, l->head.data, &tmp);
 +                              CustomData_bmesh_free_block(&destold, &l->head.data);
 +                              l->head.data = tmp;
 +                      }
 +              }
 +      }
 +
 +      if (destold.pool) BLI_mempool_destroy(destold.pool);
  }
  
  void CustomData_bmesh_free_block(CustomData *data, void **block)
                }
        }
  
 -      BLI_mempool_free(data->pool, *block);
 +      if (data->totsize)
 +              BLI_mempool_free(data->pool, *block);
 +
        *block = NULL;
  }
  
@@@ -2558,7 -2363,7 +2528,7 @@@ static void CustomData_bmesh_alloc_bloc
                CustomData_bmesh_free_block(data, block);
  
        if (data->totsize > 0)
 -              *block = BLI_mempool_calloc(data->pool);
 +              *block = BLI_mempool_alloc(data->pool);
        else
                *block = NULL;
  }
@@@ -2639,73 -2444,6 +2609,73 @@@ void *CustomData_bmesh_get_layer_n(cons
        return (char *)block + data->layers[n].offset;
  }
  
 +int CustomData_layer_has_math(struct CustomData *data, int layern)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[layern].type);
 +      
 +      if (typeInfo->equal && typeInfo->add && typeInfo->multiply && 
 +          typeInfo->initminmax && typeInfo->dominmax) return 1;
 +      
 +      return 0;
 +}
 +
 +/*copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to
 +  another, while not overwriting anything else (e.g. flags)*/
 +void CustomData_data_copy_value(int type, void *source, void *dest)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(type);
 +
 +      if(!dest) return;
 +
 +      if(typeInfo->copyvalue)
 +              typeInfo->copyvalue(source, dest);
 +      else
 +              memcpy(dest, source, typeInfo->size);
 +}
 +
 +int CustomData_data_equals(int type, void *data1, void *data2)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(type);
 +
 +      if (typeInfo->equal)
 +              return typeInfo->equal(data1, data2);
 +      else return !memcmp(data1, data2, typeInfo->size);
 +}
 +
 +void CustomData_data_initminmax(int type, void *min, void *max)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(type);
 +
 +      if (typeInfo->initminmax)
 +              typeInfo->initminmax(min, max);
 +}
 +
 +
 +void CustomData_data_dominmax(int type, void *data, void *min, void *max)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(type);
 +
 +      if (typeInfo->dominmax)
 +              typeInfo->dominmax(data, min, max);
 +}
 +
 +
 +void CustomData_data_multiply(int type, void *data, float fac)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(type);
 +
 +      if (typeInfo->multiply)
 +              typeInfo->multiply(data, fac);
 +}
 +
 +
 +void CustomData_data_add(int type, void *data1, void *data2)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(type);
 +
 +      if (typeInfo->add)
 +              typeInfo->add(data1, data2);
 +}
  
  void CustomData_bmesh_set(const CustomData *data, void *block, int type, void *source)
  {
index 909be0504c9b22cdaaf6d0828bb02877bd50a31a,40812808d06732603a87747c4bf64346f7a15cd4..cd12cc78ad56a92fa0457d9cfdc1e0bd5eadce01
@@@ -425,51 -425,6 +425,6 @@@ void FONT_OT_file_paste(wmOperatorType 
        WM_operator_properties_filesel(ot, FOLDERFILE|TEXTFILE, FILE_SPECIAL, FILE_OPENFILE, WM_FILESEL_FILEPATH);
  }
  
- /******************* paste buffer operator ********************/
- static int paste_buffer_exec(bContext *C, wmOperator *UNUSED(op))
- {
-       const char *filename;
- #ifdef WIN32
-       filename= "C:\\windows\\temp\\cutbuf.txt";
- //    The following is more likely to work on all Win32 installations.
- //    suggested by Douglas Toltzman. Needs windows include files...
- /*
-       char tempFileName[MAX_PATH];
-       DWORD pathlen;
-       static const char cutbufname[]="cutbuf.txt";
-       if((pathlen=GetTempPath(sizeof(tempFileName),tempFileName)) > 0 &&
-               pathlen + sizeof(cutbufname) <= sizeof(tempFileName))
-       {
-               strcat(tempFileName,cutbufname);
-               filename= tempFilename;
-       }
- */
- #else
-       filename= "/tmp/.cutbuffer";
- #endif
-       return paste_file(C, NULL, filename);
- }
- void FONT_OT_buffer_paste(wmOperatorType *ot)
- {
-       /* identifiers */
-       ot->name= "Paste Buffer";
-       ot->description= "Paste text from OS buffer";
-       ot->idname= "FONT_OT_buffer_paste";
-       
-       /* api callbacks */
-       ot->exec= paste_buffer_exec;
-       ot->poll= ED_operator_editfont;
-       
-       /* flags */
-       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
- }
  /******************* text to object operator ********************/
  
  static void txt_add_object(bContext *C, TextLine *firstline, int totline, float offset[3])
@@@ -1784,7 -1739,7 +1739,7 @@@ void FONT_OT_unlink(wmOperatorType *ot
  
  /* **************** undo for font object ************** */
  
 -static void undoFont_to_editFont(void *strv, void *ecu)
 +static void undoFont_to_editFont(void *strv, void *ecu, void *UNUSED(obdata))
  {
        Curve *cu= (Curve *)ecu;
        EditFont *ef= cu->editfont;
        update_string(cu);
  }
  
 -static void *editFont_to_undoFont(void *ecu)
 +static void *editFont_to_undoFont(void *ecu, void *UNUSED(obdata))
  {
        Curve *cu= (Curve *)ecu;
        EditFont *ef= cu->editfont;