svn merge -r39878:39890 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorCampbell Barton <ideasman42@gmail.com>
Sat, 3 Sep 2011 12:57:33 +0000 (12:57 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 3 Sep 2011 12:57:33 +0000 (12:57 +0000)
1  2 
source/blender/blenkernel/intern/customdata.c
source/blender/editors/object/object_edit.c

index 9fe07834750edbe669826a988301a528a99b4907,c342bbc917f5b96ee850515d949fa3f422404057..f47e38f6d17e59f00352ee62aaaf9959f8884a17
  #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"
  #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
  
@@@ -108,14 -102,6 +108,14 @@@ typedef struct LayerTypeInfo 
           default is assumed to be all zeros */
        void (*set_default)(void *data, int count);
  
 +    /* functions necassary for geometry collapse*/
 +      int (*equal)(void *data1, void *data2);
 +      void (*multiply)(void *data, float fac);
 +      void (*initminmax)(void *min, void *max);
 +      void (*add)(void *data1, void *data2);
 +      void (*dominmax)(void *data1, void *min, void *max);
 +      void (*copyvalue)(void *source, void *dest);
 +
        /* a function to read data from a cdf file */
        int (*read)(CDataFile *cdf, void *data, int count);
  
@@@ -142,7 -128,7 +142,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));
@@@ -161,7 -147,7 +161,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;
  
@@@ -348,24 -334,6 +348,24 @@@ static void layerDefault_tface(void *da
                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,39 -422,22 +454,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;
        }
@@@ -659,7 -604,7 +659,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);
@@@ -698,83 -643,10 +698,83 @@@ static size_t layerFilesize_mdisps(CDat
  }
  
  /* --------- */
 +static void layerCopyValue_mloopcol(void *source, void *dest)
 +{
 +      MLoopCol *m1 = source, *m2 = dest;
 +      
 +      m2->r = m1->r;
 +      m2->g = m1->g;
 +      m2->b = m1->b;
 +      m2->a = m1->a;
 +}
 +
 +static int layerEqual_mloopcol(void *data1, void *data2)
 +{
 +      MLoopCol *m1 = data1, *m2 = data2;
 +      float r, g, b, a;
 +
 +      r = m1->r - m2->r;
 +      g = m1->g - m2->g;
 +      b = m1->b - m2->b;
 +      a = m1->a - m2->a;
 +
 +      return r*r + g*g + b*b + a*a < 0.001;
 +}
 +
 +static void layerMultiply_mloopcol(void *data, float fac)
 +{
 +      MLoopCol *m = data;
 +
 +      m->r = (float)m->r * fac;
 +      m->g = (float)m->g * fac;
 +      m->b = (float)m->b * fac;
 +      m->a = (float)m->a * fac;
 +}
 +
 +static void layerAdd_mloopcol(void *data1, void *data2)
 +{
 +      MLoopCol *m = data1, *m2 = data2;
 +
 +      m->r += m2->r;
 +      m->g += m2->g;
 +      m->b += m2->b;
 +      m->a += m2->a;
 +}
 +
 +static void layerDoMinMax_mloopcol(void *data, void *vmin, void *vmax)
 +{
 +      MLoopCol *m = data;
 +      MLoopCol *min = vmin, *max = vmax;
 +
 +      if (m->r < min->r) min->r = m->r;
 +      if (m->g < min->g) min->g = m->g;
 +      if (m->b < min->b) min->b = m->b;
 +      if (m->a < min->a) min->a = m->a;
 +      
 +      if (m->r > max->r) max->r = m->r;
 +      if (m->g > max->g) max->g = m->g;
 +      if (m->b > max->b) max->b = m->b;
 +      if (m->a > max->a) max->a = m->a;
 +}
 +
 +static void layerInitMinMax_mloopcol(void *vmin, void *vmax)
 +{
 +      MLoopCol *min = vmin, *max = vmax;
 +
 +      min->r = 255;
 +      min->g = 255;
 +      min->b = 255;
 +      min->a = 255;
 +
 +      max->r = 0;
 +      max->g = 0;
 +      max->b = 0;
 +      max->a = 0;
 +}
  
  static void layerDefault_mloopcol(void *data, int count)
  {
 -      static MLoopCol default_mloopcol = {255,255,255,255};
 +      MLoopCol default_mloopcol = {255,255,255,255};
        MLoopCol *mlcol = (MLoopCol*)data;
        int i;
        for(i = 0; i < count; i++)
@@@ -826,56 -698,6 +826,56 @@@ static void layerInterp_mloopcol(void *
        mc->g = (int)col.g;
        mc->b = (int)col.b;
  }
 +
 +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];
 +}
 +
 +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;
 +}
 +
 +static void layerMultiply_mloopuv(void *data, float fac)
 +{
 +      MLoopUV *luv = data;
 +
 +      luv->uv[0] *= fac;
 +      luv->uv[1] *= fac;
 +}
 +
 +static void layerInitMinMax_mloopuv(void *vmin, void *vmax)
 +{
 +      MLoopUV *min = vmin, *max = vmax;
 +
 +      INIT_MINMAX2(min->uv, max->uv);
 +}
 +
 +static void layerDoMinMax_mloopuv(void *data, void *vmin, void *vmax)
 +{
 +      MLoopUV *min = vmin, *max = vmax, *luv = data;
 +
 +      DO_MINMAX2(luv->uv, min->uv, max->uv);
 +}
 +
 +static void layerAdd_mloopuv(void *data1, void *data2)
 +{
 +      MLoopUV *l1 = data1, *l2 = data2;
 +
 +      l1->uv[0] += l2->uv[0];
 +      l1->uv[1] += l2->uv[1];
 +}
 +
  static void layerInterp_mloopuv(void **sources, float *weights,
                                float *sub_weights, int count, void *dest)
  {
@@@ -983,135 -805,99 +983,159 @@@ static void layerDefault_mcol(void *dat
                mcol[i] = default_mcol;
  }
  
 +static void layerInterp_bweight(void **sources, float *weights,
 +                             float *UNUSED(sub_weights), int count, void *dest)
 +{
 +      float *f = dest, *src;
 +      float **in = (float **)sources;
 +      int i;
 +      
 +      if(count <= 0) return;
 +
 +      *f = 0.0f;
 +      
 +      for(i = 0; i < count; ++i) {
 +              float weight = weights ? weights[i] : 1.0f;
 +              
 +              src = in[i];
 +              *f += *src * weight;
 +      }
 +}
 +
 +static void layerInterp_shapekey(void **sources, float *weights,
 +                             float *UNUSED(sub_weights), int count, void *dest)
 +{
 +      float *co = dest, *src;
 +      float **in = (float **)sources;
 +      int i;
 +
 +      if(count <= 0) return;
 +
 +      memset(co, 0, sizeof(float)*3);
 +      
 +      for(i = 0; i < count; ++i) {
 +              float weight = weights ? weights[i] : 1.0f;
 +              
 +              src = in[i];
 +              co[0] += src[0] * weight;
 +              co[1] += src[1] * weight;
 +              co[2] += src[2] * weight;
 +      }
 +}
  
++/* 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, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
 +      {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},
+       /* 10: CD_PROP_FLT */
 -      {sizeof(MIntProperty), "MIntProperty",1,"Int",NULL,NULL,NULL,NULL},
 +      {sizeof(MFloatProperty), "MFloatProperty",1,"Float", layerCopy_propFloat,NULL,NULL,NULL},
+       /* 11: CD_PROP_INT */
 -      {sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL},
 +      {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},
 -      {sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL},
+       /* 16: CD_MLOOPUV */
 -      {sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol},
 -      /* 18: CD_TANGENT */
 +      {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, layerRead_mdisps, layerWrite_mdisps,
 -       layerFilesize_mdisps, layerValidate_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},
 -      /* 22: CD_TEXTURE_MCOL */
 -      {sizeof(MCol)*4, "MCol", 4, "TexturedCol", NULL, NULL, layerInterp_mcol,
 +      {sizeof(MCol)*4, "MCol", 4, "TextureCol", NULL, NULL, layerInterp_mcol,
         layerSwap_mcol, layerDefault_mcol},
 -      /* 23: CD_CLOTH_ORCO */
 -      {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}
 +      {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
 +      {sizeof(float)*3, "", 0, "ShapeKey", NULL, NULL, layerInterp_shapekey},
 +      {sizeof(float), "", 0, "BevelWeight", NULL, NULL, layerInterp_bweight},
 +      {sizeof(float), "", 0, "SubSurfCrease", NULL, NULL, layerInterp_bweight},
 +      {sizeof(MLoopCol), "MLoopCol", 1, "WeightLoopCol", NULL, NULL, layerInterp_mloopcol, NULL,
 +       layerDefault_mloopcol, layerEqual_mloopcol, layerMultiply_mloopcol, layerInitMinMax_mloopcol,
 +       layerAdd_mloopcol, layerDoMinMax_mloopcol, layerCopyValue_mloopcol},
  };
  
  static const char *LAYERTYPENAMES[CD_NUMTYPES] = {
 -      /*   0-4 */ "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace",
 -      /*   5-9 */ "CDMTFace", "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags",
 -      /* 10-14 */ "CDMFloatProperty", "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco",
 -      /* 15-19 */ "CDMTexPoly", "CDMLoopUV", "CDMloopCol", "CDTangent", "CDMDisps",
 -      /* 20-23 */"CDWeightMCol", "CDIDMCol", "CDTextureMCol", "CDClothOrco"
 +      "CDMVert", "CDMSticky", "CDMDeformVert", "CDMEdge", "CDMFace", "CDMTFace",
 +      "CDMCol", "CDOrigIndex", "CDNormal", "CDFlags","CDMFloatProperty",
 +      "CDMIntProperty","CDMStringProperty", "CDOrigSpace", "CDOrco", "CDMTexPoly", "CDMLoopUV",
 +      "CDMloopCol", "CDTangent", "CDMDisps", "CDWeightMCol", "CDMPoly", 
 +      "CDMLoop", "CDMClothOrco", "CDMLoopCol", "CDIDCol", "CDTextureCol",
 +      "CDShapeKeyIndex", "CDShapeKey", "CDBevelWeight", "CDSubSurfCrease"
  };
  
 +
  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_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;
  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_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;
  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;
 -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_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;
 +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;
  
 -
  static const LayerTypeInfo *layerType_getInfo(int type)
  {
        if(type < 0 || type >= CD_NUMTYPES) return NULL;
@@@ -1132,22 -918,6 +1156,22 @@@ static void customData_update_offsets(C
  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)
 +{
 +      int i, lasttype = -1;
 +
 +      for (i=0; i<CD_NUMTYPES; i++) {
 +              data->typemap[i] = -1;
 +      }
 +
 +      for (i=0; i<data->totlayer; i++) {
 +              if (data->layers[i].type != lasttype) {
 +                      data->typemap[data->layers[i].type] = i;
 +              }
 +              lasttype = data->layers[i].type;
 +      }
 +}
 +
  void CustomData_merge(const struct CustomData *source, struct CustomData *dest,
                                          CustomDataMask mask, int alloctype, int totelem)
  {
                                layer->data, totelem, layer->name);
                
                if(newlayer) {
 +                      newlayer->uid = layer->uid;
 +                      
                        newlayer->active = lastactive;
                        newlayer->active_rnd = lastrender;
                        newlayer->active_clone = lastclone;
                        newlayer->flag |= lastflag & (CD_FLAG_EXTERNAL|CD_FLAG_IN_MEMORY);
                }
        }
 +
 +      CustomData_update_typemap(dest);
  }
  
  void CustomData_copy(const struct CustomData *source, struct CustomData *dest,
@@@ -1260,7 -1026,6 +1284,7 @@@ static void customData_update_offsets(C
        }
  
        data->totsize = offset;
 +      CustomData_update_typemap(data);
  }
  
  int CustomData_get_layer_index(const CustomData *data, int type)
        return -1;
  }
  
 +int CustomData_get_layer_index_n(const struct CustomData *data, int type, int n)
 +{
 +      int i; 
 +
 +      for(i=0; i < data->totlayer; ++i)
 +              if(data->layers[i].type == type)
 +                      return i + n;
 +
 +      return -1;      
 +}
 +
  int CustomData_get_named_layer_index(const CustomData *data, int type, const char *name)
  {
        int i;
  
  int CustomData_get_active_layer_index(const CustomData *data, int type)
  {
 -      int i;
 +      if (!data->totlayer)
 +              return -1;
  
 -      for(i=0; i < data->totlayer; ++i)
 -              if(data->layers[i].type == type)
 -                      return i + data->layers[i].active;
 +      if (data->typemap[type] != -1) {
 +              return data->typemap[type] + data->layers[data->typemap[type]].active;
 +      }
  
        return -1;
  }
@@@ -1502,7 -1255,7 +1526,7 @@@ static CustomDataLayer *customData_add_
                        return NULL;
        }
  
 -      if (alloctype == CD_DUPLICATE) {
 +      if (alloctype == CD_DUPLICATE && layerdata) {
                if(typeInfo->copy)
                        typeInfo->copy(layerdata, newlayerdata, totelem);
                else
        data->layers[index].type = type;
        data->layers[index].flag = flag;
        data->layers[index].data = newlayerdata;
 +
        if(name || (name=typeInfo->defaultname)) {
                BLI_strncpy(data->layers[index].name, name, 32);
                CustomData_set_layer_unique_name(data, index);
@@@ -1565,7 -1317,6 +1589,7 @@@ void *CustomData_add_layer(CustomData *
        
        layer = customData_add_layer__internal(data, type, alloctype, layerdata,
                                                                                   totelem, typeInfo->defaultname);
 +      CustomData_update_typemap(data);
  
        if(layer)
                return layer->data;
@@@ -1581,7 -1332,6 +1605,7 @@@ void *CustomData_add_layer_named(Custom
        
        layer = customData_add_layer__internal(data, type, alloctype, layerdata,
                                                                                   totelem, name);
 +      CustomData_update_typemap(data);
  
        if(layer)
                return layer->data;
@@@ -1620,7 -1370,6 +1644,7 @@@ int CustomData_free_layer(CustomData *d
                customData_resize(data, -CUSTOMDATA_GROW);
  
        customData_update_offsets(data);
 +      CustomData_update_typemap(data);
  
        return 1;
  }
@@@ -1730,16 -1479,6 +1754,16 @@@ void CustomData_set_only_copy(const str
                        data->layers[i].flag |= CD_FLAG_NOCOPY;
  }
  
 +void CustomData_copy_elements(int type, void *source, void *dest, int count)
 +{
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(type);
 +
 +      if (typeInfo->copy)
 +              typeInfo->copy(source, dest, count);
 +      else
 +              memcpy(dest, source, typeInfo->size*count);
 +}
 +
  void CustomData_copy_data(const CustomData *source, CustomData *dest,
                                                  int source_index, int dest_index, int count)
  {
  
                        src_offset = source_index * typeInfo->size;
                        dest_offset = dest_index * typeInfo->size;
 -
 +                      
 +                      if (!src_data || !dest_data) {
 +                              printf("eek! null data in CustomData_copy_data!\n");
 +                              continue;
 +                      }
 +                      
                        if(typeInfo->copy)
                                typeInfo->copy(src_data + src_offset,
                                                                dest_data + dest_offset,
@@@ -1904,19 -1638,6 +1928,19 @@@ void *CustomData_get(const CustomData *
        return (char *)data->layers[layer_index].data + offset;
  }
  
 +void *CustomData_get_n(const CustomData *data, int type, int index, int n)
 +{
 +      int layer_index;
 +      int offset;
 +
 +      /* get the layer index of the first layer of type */
 +      layer_index = data->typemap[type];
 +      if(layer_index < 0) return NULL;
 +      
 +      offset = layerType_getInfo(type)->size * index;
 +      return (char *)data->layers[layer_index+n].data + offset;
 +}
 +
  void *CustomData_get_layer(const CustomData *data, int type)
  {
        /* get the layer index of the active layer of type */
@@@ -1944,20 -1665,6 +1968,20 @@@ void *CustomData_get_layer_named(const 
        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 */
@@@ -2277,89 -1984,33 +2301,89 @@@ 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);
 +                      CustomData_add_layer(pdata, CD_MTEXPOLY, CD_CALLOC, &(fdata->layers[i].name), totpoly);
 +                      CustomData_add_layer(ldata, CD_MLOOPUV, CD_CALLOC, &(fdata->layers[i].name), totloop);
                }
                else if(fdata->layers[i].type == CD_MCOL)
 -                      CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), 0);
 -      }               
 +                      CustomData_add_layer(ldata, CD_MLOOPCOL, CD_CALLOC, &(fdata->layers[i].name), totloop);
 +              else if(fdata->layers[i].type == CD_MDISPS) 
 +                      CustomData_add_layer(ldata, CD_MDISPS, CD_CALLOC, &(fdata->layers[i].name), totloop);
 +      }
  }
  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);
 +                      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_named(fdata, CD_WEIGHT_MCOL, CD_CALLOC, NULL, total, ldata->layers[i].name);
        }
  }
  
  
  void CustomData_bmesh_init_pool(CustomData *data, int allocsize){
 -      if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, 0);
 +      if(data->totlayer)data->pool = BLI_mempool_create(data->totsize, allocsize, allocsize, 1, 0);
 +}
 +
 +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;
  }
  
@@@ -2392,7 -2041,7 +2416,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;
  }
@@@ -2465,82 -2114,6 +2489,82 @@@ void *CustomData_bmesh_get_n(const Cust
        return (char *)block + data->layers[layer_index+n].offset;
  }
  
 +/*gets from the layer at physical index n, note: doesn't check type.*/
 +void *CustomData_bmesh_get_layer_n(const CustomData *data, void *block, int n)
 +{
 +      if(n < 0 || n >= data->totlayer) return NULL;
 +
 +      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)
  {
        void *dest = CustomData_bmesh_get(data, block, type);
@@@ -2567,19 -2140,6 +2591,19 @@@ void CustomData_bmesh_set_n(CustomData 
                memcpy(dest, source, typeInfo->size);
  }
  
 +void CustomData_bmesh_set_layer_n(CustomData *data, void *block, int n, void *source)
 +{
 +      void *dest = CustomData_bmesh_get_layer_n(data, block, n);
 +      const LayerTypeInfo *typeInfo = layerType_getInfo(data->layers[n].type);
 +
 +      if(!dest) return;
 +
 +      if(typeInfo->copy)
 +              typeInfo->copy(source, dest, 1);
 +      else
 +              memcpy(dest, source, typeInfo->size);
 +}
 +
  void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights,
                                                  float *sub_weights, int count, void *dest_block)
  {
@@@ -2625,7 -2185,6 +2649,7 @@@ void CustomData_bmesh_set_default(Custo
  
                if(typeInfo->set_default)
                        typeInfo->set_default((char*)*block + offset, 1);
 +              else memset((char*)*block + offset, 0, typeInfo->size);
        }
  }
  
index 7f1355af801a408f42724ac20f3d8510b80c3b44,79cbfb6574be67471ceb2440066f20e7bd64dcd3..4ceb3547462c733734905426dd90bb235dc88d29
@@@ -81,7 -81,6 +81,7 @@@
  #include "BKE_sca.h"
  #include "BKE_softbody.h"
  #include "BKE_modifier.h"
 +#include "BKE_tessmesh.h"
  
  #include "ED_armature.h"
  #include "ED_curve.h"
@@@ -322,24 -321,22 +322,24 @@@ void ED_object_exit_editmode(bContext *
  //            if(retopo_mesh_paint_check())
  //                    retopo_end_okee();
                
 -              if(me->edit_mesh->totvert>MESH_MAX_VERTS) {
 +              if(me->edit_btmesh->bm->totvert>MESH_MAX_VERTS) {
                        error("Too many vertices");
                        return;
                }
 -              load_editMesh(scene, obedit);
 +              
 +              EDBM_LoadEditBMesh(scene, obedit);
                
                if(freedata) {
 -                      free_editMesh(me->edit_mesh);
 -                      MEM_freeN(me->edit_mesh);
 -                      me->edit_mesh= NULL;
 +                      EDBM_FreeEditBMesh(me->edit_btmesh);
 +                      MEM_freeN(me->edit_btmesh);
 +                      me->edit_btmesh= NULL;
                }
 -              
 +#if 0 //BMESH_TODO            
                if(obedit->restore_mode & OB_MODE_WEIGHT_PAINT) {
                        mesh_octree_table(NULL, NULL, NULL, 'e');
                        mesh_mirrtopo_table(NULL, 'e');
                }
 +#endif
        }
        else if (obedit->type==OB_ARMATURE) {   
                ED_armature_from_edit(obedit);
                }
                BLI_freelistN(&pidlist);
                
 -              BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_OUTDATED);
 +              BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_DEPSGRAPH);
  
                /* also flush ob recalc, doesn't take much overhead, but used for particles */
                DAG_id_tag_update(&obedit->id, OB_RECALC_OB|OB_RECALC_DATA);
@@@ -448,7 -445,7 +448,7 @@@ void ED_object_enter_editmode(bContext 
                ok= 1;
                scene->obedit= ob;      // context sees this
                
 -              make_editMesh(scene, ob);
 +              EDBM_MakeEditBMesh(CTX_data_tool_settings(C), scene, ob);
  
                WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MESH, scene);
        }
@@@ -1414,6 -1411,8 +1414,8 @@@ static int forcefield_toggle_exec(bCont
        else
                ob->pd->forcefield = 0;
        
+       WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, NULL);
        return OPERATOR_FINISHED;
  }
  
@@@ -1831,16 -1830,11 +1833,16 @@@ static int object_mode_set_compat(bCont
  {
        ObjectMode mode = RNA_enum_get(op->ptr, "mode");
  
 -      if(ob) {
 -              if(mode == OB_MODE_OBJECT)
 -                      return 1;
 +      if(mode == OB_MODE_OBJECT)
 +              return 1;
  
 +      if(ob) {
                switch(ob->type) {
 +              case OB_EMPTY:
 +              case OB_LAMP:
 +              case OB_CAMERA:
 +                      return 0;
 +
                case OB_MESH:
                        if(mode & (OB_MODE_EDIT|OB_MODE_SCULPT|OB_MODE_VERTEX_PAINT|OB_MODE_WEIGHT_PAINT|OB_MODE_TEXTURE_PAINT|OB_MODE_PARTICLE_EDIT))
                                return 1;
                case OB_SURF:
                case OB_FONT:
                case OB_MBALL:
 -                      if(mode & (OB_MODE_EDIT))
 +                      if(mode & (OB_MODE_OBJECT|OB_MODE_EDIT))
                                return 1;
                        return 0;
                case OB_LATTICE:
 -                      if(mode & (OB_MODE_EDIT|OB_MODE_WEIGHT_PAINT))
 +                      if(mode & (OB_MODE_OBJECT|OB_MODE_EDIT|OB_MODE_WEIGHT_PAINT))
                                return 1;
                case OB_ARMATURE:
 -                      if(mode & (OB_MODE_EDIT|OB_MODE_POSE))
 +                      if(mode & (OB_MODE_OBJECT|OB_MODE_EDIT|OB_MODE_POSE))
                                return 1;
                }
        }
@@@ -1872,7 -1866,7 +1874,7 @@@ static int object_mode_set_exec(bContex
        int toggle = RNA_boolean_get(op->ptr, "toggle");
  
        if(!ob || !object_mode_set_compat(C, op, ob))
 -              return OPERATOR_PASS_THROUGH;
 +              return OPERATOR_CANCELLED;
  
        /* Exit current mode if it's not the mode we're setting */
        if(ob->mode != OB_MODE_OBJECT && ob->mode != mode)
@@@ -1913,7 -1907,7 +1915,7 @@@ void OBJECT_OT_mode_set(wmOperatorType 
        /* flags */
        ot->flag= 0; /* no register/undo here, leave it to operators being called */
        
 -      prop= RNA_def_enum(ot->srna, "mode", object_mode_items, OB_MODE_OBJECT, "Mode", "");
 +      prop= RNA_def_enum(ot->srna, "mode", object_mode_items, 0, "Mode", "");
        RNA_def_enum_funcs(prop, object_mode_set_itemsf);
  
        RNA_def_boolean(ot->srna, "toggle", 0, "Toggle", "");