svn merge ^/trunk/blender -r42521:42550
authorCampbell Barton <ideasman42@gmail.com>
Sat, 10 Dec 2011 05:38:00 +0000 (05:38 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Sat, 10 Dec 2011 05:38:00 +0000 (05:38 +0000)
17 files changed:
1  2 
intern/cycles/blender/blender_mesh.cpp
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/deform.c
source/blender/blenkernel/intern/editderivedmesh.c
source/blender/blenkernel/intern/mesh_validate.c
source/blender/blenkernel/intern/particle.c
source/blender/editors/armature/editarmature.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_ops.c
source/blender/editors/object/object_vgroup.c
source/blender/editors/sculpt_paint/paint_vertex.c
source/blender/editors/space_view3d/drawmesh.c
source/blender/editors/space_view3d/drawobject.c
source/blender/modifiers/intern/MOD_hook.c
source/blender/modifiers/intern/MOD_mask.c
source/blender/render/intern/source/render_texture.c

index 98a5154c256ebf730a24a6cb9d372bce712ba814,5f451ce78217dc7df8331290d5a1e9a6a82cc2ce..139119ee87339c5df100c434a5eed3c926226899
@@@ -128,13 -94,8 +128,14 @@@ struct DerivedMesh 
        BVHCache bvhCache;
        struct GPUDrawObject *drawObject;
        DerivedMeshType type;
+       float auto_bump_scale;
  
 +      /* calculate vert and face normals */
 +      void (*calcNormals)(DerivedMesh *dm);
 +
 +      /* recalculates mesh tesselation */
 +      void (*recalcTesselation)(DerivedMesh *dm);
 +
        /* Misc. Queries */
  
        /* Also called in Editmode */
index 64a802f225ff9bcb6d8c1a3e99cd0ccfbdf7e923,0087b91c6158f37858c90032e4df1f545a2c8d89..8405a3922e6b285113db76321a7f265516ab67dc
@@@ -953,139 -715,31 +956,139 @@@ void vDM_ColorBand_store(ColorBand *cob
  
  static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm, int const draw_flag)
  {
 -      Mesh *me = ob->data;
 -      MFace *mf = me->mface;
 +      // Mesh *me = ob->data; // UNUSED
 +      MFace *mf = dm->getTessFaceArray(dm);
 +      MLoop *mloop = dm->getLoopArray(dm), *ml;
 +      MPoly *mp = dm->getPolyArray(dm);
        ColorBand *coba= stored_cb;     /* warning, not a local var */
        unsigned char *wtcol;
 -      int i;
 -      
 +      unsigned char(*wlcol)[4] = NULL;
 +      BLI_array_declare(wlcol);
 +      int i, j, totface=dm->getNumTessFaces(dm), totloop;
 +      int *origIndex = dm->getVertDataArray(dm, CD_ORIGINDEX);
 +
-       int defbase_len = BLI_countlist(&ob->defbase);
-       char *defbase_sel = MEM_mallocN(defbase_len * sizeof(char), __func__);
-       int selected = get_selected_defgroups(ob, defbase_sel, defbase_len);
-       int unselected = defbase_len - selected;
+       int defbase_tot = BLI_countlist(&ob->defbase);
+       char *defbase_sel = MEM_mallocN(defbase_tot * sizeof(char), __func__);
+       int selected = get_selected_defgroups(ob, defbase_sel, defbase_tot);
+       int unselected = defbase_tot - selected;
  
 -      wtcol = MEM_callocN (sizeof (unsigned char) * me->totface*4*4, "weightmap");
 +      wtcol = MEM_callocN (sizeof (unsigned char) * totface*4*4, "weightmap");
        
 -      memset(wtcol, 0x55, sizeof (unsigned char) * me->totface*4*4);
 -      for (i=0; i<me->totface; i++, mf++) {
 +      /*first add colors to the tesselation faces*/
 +      memset(wtcol, 0x55, sizeof (unsigned char) * totface*4*4);
 +      for (i=0; i<totface; i++, mf++) {
 +              /*origindex being NULL means we're operating on original mesh data*/
-               calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4], defbase_sel, selected, unselected, draw_flag);
-               calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4], defbase_sel, selected, unselected, draw_flag);
-               calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4], defbase_sel, selected, unselected, draw_flag);
+               calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v1, &wtcol[(i*4 + 0)*4], defbase_sel, selected, unselected, draw_flag);
+               calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v2, &wtcol[(i*4 + 1)*4], defbase_sel, selected, unselected, draw_flag);
+               calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v3, &wtcol[(i*4 + 2)*4], defbase_sel, selected, unselected, draw_flag);
                if (mf->v4)
-                       calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4], defbase_sel, selected, unselected, draw_flag);
+                       calc_weightpaint_vert_color(ob, defbase_tot, coba, mf->v4, &wtcol[(i*4 + 3)*4], defbase_sel, selected, unselected, draw_flag);
        }
        
-                       calc_weightpaint_vert_color(ob, coba, origIndex ? origIndex[ml->v] : ml->v,
 +      CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, totface);
 +
 +      /*now add to loops, so the data can be passed through the modifier stack*/
 +      totloop = 0;
 +      for (i=0; i<dm->numPolyData; i++, mp++) {
 +              ml = mloop + mp->loopstart;
 +
 +              for (j=0; j<mp->totloop; j++, ml++, totloop++) {
 +                      BLI_array_growone(wlcol);
 +
++                      calc_weightpaint_vert_color(ob, defbase_tot, coba, origIndex ? origIndex[ml->v] : ml->v,
 +                                                                              (unsigned char *)&wlcol[totloop], defbase_sel, selected, unselected, draw_flag);
 +              }
 +      }
 +
        MEM_freeN(defbase_sel);
  
 -      CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData);
 +      CustomData_add_layer(&dm->loopData, CD_WEIGHT_MLOOPCOL, CD_ASSIGN, wlcol, totloop);
 +}
 +
 +
 +static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid)
 +{
 +      KeyBlock *kb;
 +      int i, j, tot;
 +      
 +      if (!me->key)
 +              return; 
 +      
 +      tot = CustomData_number_of_layers(&dm->vertData, CD_SHAPEKEY);
 +      for (i=0; i<tot; i++) {
 +              CustomDataLayer *layer = &dm->vertData.layers[CustomData_get_layer_index_n(&dm->vertData, CD_SHAPEKEY, i)];
 +              float (*cos)[3], (*kbcos)[3];
 +              
 +              for (kb=me->key->block.first; kb; kb=kb->next) {
 +                      if (kb->uid == layer->uid)
 +                              break;
 +              }
 +              
 +              if (!kb) {
 +                      kb = add_keyblock(me->key, layer->name);
 +                      kb->uid = layer->uid;
 +              }
 +              
 +              if (kb->data)
 +                      MEM_freeN(kb->data);
 +              
 +              cos = CustomData_get_layer_n(&dm->vertData, CD_SHAPEKEY, i);
 +              kb->totelem = dm->numVertData;
 +
 +              kb->data = kbcos = MEM_mallocN(sizeof(float)*3*kb->totelem, "kbcos DerivedMesh.c");
 +              if (kb->uid == actshape_uid) {
 +                      MVert *mvert = dm->getVertArray(dm);
 +                      
 +                      for (j=0; j<dm->numVertData; j++, kbcos++, mvert++) {
 +                              copy_v3_v3(*kbcos, mvert->co);
 +                      }
 +              } else {
 +                      for (j=0; j<kb->totelem; j++, cos++, kbcos++) {
 +                              copy_v3_v3(*kbcos, *cos);
 +                      }
 +              }
 +      }
 +      
 +      for (kb=me->key->block.first; kb; kb=kb->next) {
 +              if (kb->totelem != dm->numVertData) {
 +                      if (kb->data)
 +                              MEM_freeN(kb->data);
 +                      
 +                      kb->totelem = dm->numVertData;
 +                      kb->data = MEM_callocN(sizeof(float)*3*kb->totelem, "kb->data derivedmesh.c");
 +                      fprintf(stderr, "%s: lost a shapekey layer! (bmesh internal error)\n", __func__);
 +              }
 +      }
 +}
 +
 +static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *UNUSED(ob))
 +{
 +      KeyBlock *kb;
 +      Key *key = me->key;
 +      int a, b;
 +      
 +      if (!me->key)
 +              return;
 +      
 +      if (dm->numVertData != me->totvert) {
 +              printf("error in add_shapekey_layers: dm isn't the same size as me\n");
 +              return;
 +      }
 +              
 +      for (a=0, kb=key->block.first; kb; kb=kb->next, a++) {
 +              float (*cos)[3] = CustomData_add_layer_named(&dm->vertData, CD_SHAPEKEY, CD_CALLOC, NULL, dm->numVertData, kb->name);
 +              int ci = CustomData_get_layer_index_n(&dm->vertData, CD_SHAPEKEY, a);
 +              
 +              dm->vertData.layers[ci].uid = kb->uid;
 +              if (kb->totelem != dm->numVertData) {
 +                      printf("error in add_shapekey_layers: totelem and totvert don't match");
 +                      continue;
 +              }
 +              
 +              for (b=0; b<kb->totelem; b++, cos++) {
 +                      copy_v3_v3((float *)cos, ((float*)kb->data)+b*3);
 +              }
 +      }
  }
  
  /* new value for useDeform -1  (hack for the gameengine):
@@@ -2222,6 -1832,159 +2225,159 @@@ void DM_add_tangent_layer(DerivedMesh *
        MEM_freeN(vtangents);
  }
  
 -      int totface= dm->getNumFaces(dm);
+ void DM_calc_auto_bump_scale(DerivedMesh *dm)
+ {
+       /* int totvert= dm->getNumVerts(dm); */ /* UNUSED */
 -      MFace * mface = dm->getFaceArray(dm);
 -      MTFace * mtface = dm->getFaceDataArray(dm, CD_MTFACE);
++      int totface= dm->getNumTessFaces(dm);
+       MVert * mvert = dm->getVertArray(dm);
++      MFace * mface = dm->getTessFaceArray(dm);
++      MTFace * mtface = dm->getTessFaceDataArray(dm, CD_MTFACE);
+       if(mtface)
+       {
+               double dsum = 0.0;
+               int nr_accumulated = 0;
+               int f;
+               for ( f=0; f<totface; f++ )
+               {
+                       {
+                               float * verts[4], * tex_coords[4];
+                               const int nr_verts = mface[f].v4!=0 ? 4 : 3;
+                               int i, is_degenerate;
+                               verts[0]=mvert[mface[f].v1].co; verts[1]=mvert[mface[f].v2].co; verts[2]=mvert[mface[f].v3].co;
+                               tex_coords[0]=mtface[f].uv[0]; tex_coords[1]=mtface[f].uv[1]; tex_coords[2]=mtface[f].uv[2];
+                               if(nr_verts==4)
+                               {
+                                       verts[3]=mvert[mface[f].v4].co;
+                                       tex_coords[3]=mtface[f].uv[3];
+                               }
+                               // discard degenerate faces
+                               is_degenerate = 0;
+                               if(     equals_v3v3(verts[0], verts[1]) || equals_v3v3(verts[0], verts[2]) || equals_v3v3(verts[1], verts[2]) ||
+                                       equals_v2v2(tex_coords[0], tex_coords[1]) || equals_v2v2(tex_coords[0], tex_coords[2]) || equals_v2v2(tex_coords[1], tex_coords[2]) )
+                               {
+                                       is_degenerate = 1;
+                               }
+                               // verify last vertex as well if this is a quad
+                               if ( is_degenerate==0 && nr_verts==4 )
+                               {
+                                       if(     equals_v3v3(verts[3], verts[0]) || equals_v3v3(verts[3], verts[1]) || equals_v3v3(verts[3], verts[2]) ||
+                                               equals_v2v2(tex_coords[3], tex_coords[0]) || equals_v2v2(tex_coords[3], tex_coords[1]) || equals_v2v2(tex_coords[3], tex_coords[2]) )
+                                       {
+                                               is_degenerate = 1;
+                                       }
+                                       // verify the winding is consistent
+                                       if ( is_degenerate==0 )
+                                       {
+                                               float prev_edge[2];
+                                               int is_signed = 0;
+                                               sub_v2_v2v2(prev_edge, tex_coords[0], tex_coords[3]);
+                                               i = 0;
+                                               while ( is_degenerate==0 && i<4 )
+                                               {
+                                                       float cur_edge[2], signed_area;
+                                                       sub_v2_v2v2(cur_edge, tex_coords[(i+1)&0x3], tex_coords[i]);
+                                                       signed_area = prev_edge[0]*cur_edge[1] - prev_edge[1]*cur_edge[0];
+                                                       if ( i==0 ) is_signed = signed_area<0.0f ? 1 : 0;
+                                                       else if((is_signed!=0)!=(signed_area<0.0f)) is_degenerate=1;
+                                                       if ( is_degenerate==0 )
+                                                       {
+                                                               copy_v2_v2(prev_edge, cur_edge);
+                                                               ++i;
+                                                       }
+                                               }
+                                       }
+                               }
+                               // proceed if not a degenerate face
+                               if ( is_degenerate==0 )
+                               {
+                                       int nr_tris_to_pile=0;
+                                       // quads split at shortest diagonal
+                                       int offs = 0;           // initial triangulation is 0,1,2 and 0, 2, 3
+                                       if ( nr_verts==4 )
+                                       {
+                                               float pos_len_diag0, pos_len_diag1;
+                                               float vtmp[3];
+                                               sub_v3_v3v3(vtmp, verts[2], verts[0]);
+                                               pos_len_diag0 = dot_v3v3(vtmp, vtmp);
+                                               sub_v3_v3v3(vtmp, verts[3], verts[1]);
+                                               pos_len_diag1 = dot_v3v3(vtmp, vtmp);
+                                               if(pos_len_diag1<pos_len_diag0)
+                                                       offs=1;         // alter split
+                                               else if(pos_len_diag0==pos_len_diag1)           // do UV check instead
+                                               {
+                                                       float tex_len_diag0, tex_len_diag1;
+                                                       sub_v2_v2v2(vtmp, tex_coords[2], tex_coords[0]);
+                                                       tex_len_diag0 = dot_v2v2(vtmp, vtmp);
+                                                       sub_v2_v2v2(vtmp, tex_coords[3], tex_coords[1]);
+                                                       tex_len_diag1 = dot_v2v2(vtmp, vtmp);
+                                                       if(tex_len_diag1<tex_len_diag0)
+                                                       {
+                                                               offs=1;         // alter split
+                                                       }
+                                               }
+                                       }
+                                       nr_tris_to_pile = nr_verts-2 ;
+                                       if ( nr_tris_to_pile==1 || nr_tris_to_pile==2 )
+                                       {
+                                               const int indices[] = {offs+0, offs+1, offs+2, offs+0, offs+2, (offs+3)&0x3 };
+                                               int t;
+                                               for ( t=0; t<nr_tris_to_pile; t++ )
+                                               {
+                                                       float f2x_area_uv;
+                                                       float * p0 = verts[indices[t*3+0]];
+                                                       float * p1 = verts[indices[t*3+1]];
+                                                       float * p2 = verts[indices[t*3+2]];
+                                                       float edge_t0[2], edge_t1[2];
+                                                       sub_v2_v2v2(edge_t0, tex_coords[indices[t*3+1]], tex_coords[indices[t*3+0]]);
+                                                       sub_v2_v2v2(edge_t1, tex_coords[indices[t*3+2]], tex_coords[indices[t*3+0]]);
+                                                       f2x_area_uv = fabsf(edge_t0[0]*edge_t1[1] - edge_t0[1]*edge_t1[0]);
+                                                       if ( f2x_area_uv>FLT_EPSILON )
+                                                       {
+                                                               float norm[3], v0[3], v1[3], f2x_surf_area, fsurf_ratio;
+                                                               sub_v3_v3v3(v0, p1, p0);
+                                                               sub_v3_v3v3(v1, p2, p0);
+                                                               cross_v3_v3v3(norm, v0, v1);
+                                                               f2x_surf_area = len_v3(norm);
+                                                               fsurf_ratio = f2x_surf_area/f2x_area_uv;        // tri area divided by texture area
+                                                               ++nr_accumulated;
+                                                               dsum += (double)(fsurf_ratio);
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+               // finalize
+               {
+                       const float avg_area_ratio = (nr_accumulated>0) ? ((float)(dsum / nr_accumulated)) : 1.0f;
+                       const float use_as_render_bump_scale = sqrtf(avg_area_ratio);           // use width of average surface ratio as your bump scale
+                       dm->auto_bump_scale = use_as_render_bump_scale;
+               }
+       }
+       else
+       {
+               dm->auto_bump_scale = 1.0f;
+       }
+ }
  void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs, DMVertexAttribs *attribs)
  {
        CustomData *vdata, *fdata, *tfdata = NULL;
        memset(attribs, 0, sizeof(DMVertexAttribs));
  
        vdata = &dm->vertData;
 -      fdata = &dm->faceData;
 -
 -      /* ugly hack, editmesh derivedmesh doesn't copy face data, this way we
 -       * can use offsets instead */
 -      if(dm->type == DM_TYPE_EDITMESH)
 -              tfdata = &((EditMeshDerivedMesh*)dm)->em->fdata;
 -      else
 -              tfdata = fdata;
 -
 +      fdata = tfdata = dm->getTessFaceDataLayout(dm);
 +      
+       /* calc auto bump scale if necessary */
+ #if 0
+       if(dm->auto_bump_scale<=0.0f)
+               DM_calc_auto_bump_scale(dm);
+ #else
+       dm->auto_bump_scale = 1.0f; // will revert this after release
+ #endif
        /* add a tangent layer if necessary */
        for(b = 0; b < gattribs->totlayer; b++)
                if(gattribs->layer[b].type == CD_TANGENT)
index 3297417eb8c27d367c5104c5a300f5d92007a4bb,bb1d20f0187a6fa55a57edbee275d8baa5324b9a..89bf06be07ebb87329070776ca955e73bac08840
@@@ -617,9 -271,9 +617,12 @@@ static void emDM_drawMappedFaces
                int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
                void *userData, int UNUSED(useColors))
  {
 -      EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
 -      EditFace *efa;
 +      EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
 +      BMFace *efa;
-       int i, draw;
++      struct BMLoop *(*looptris)[3]= bmdm->tc->looptris;
++      const int tottri= bmdm->tc->tottri;
++      const int lasttri= tottri - 1; /* compare agasint this a lot */
+       int i, draw, flush;
        const int skip_normals= !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */
  
        /* GL_ZERO is used to detect if drawing has started or not */
        /* currently unused -- each original face is handled separately */
        (void)compareDrawOptions;
  
 -      if (emdm->vertexCos) {
 +      if (bmdm->vertexCos) {
                /* add direct access */
 -              float (*vertexCos)[3]= emdm->vertexCos;
 -              float (*vertexNos)[3]= emdm->vertexNos;
 -              float (*faceNos)[3]=   emdm->faceNos;
 -              EditVert *eve;
 +              float (*vertexCos)[3]= bmdm->vertexCos;
 +              float (*vertexNos)[3]= bmdm->vertexNos;
 +              float (*faceNos)[3]=   bmdm->faceNos;
 +
 +              BM_ElemIndex_Ensure(bmdm->tc->bm, BM_VERT | BM_FACE);
  
-               for (i=0; i<bmdm->tc->tottri; i++) {
-                       BMLoop **l = bmdm->tc->looptris[i];
 -              for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
 -                      eve->tmp.l = (intptr_t) i++;
++              for (i=0; i < tottri; i++) {
++                      BMLoop **l = looptris[i];
 +                      int drawSmooth;
  
 -              for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
 -                      int drawSmooth = (efa->flag & ME_SMOOTH);
 -                      draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
 +                      efa = l[0]->f;
 +                      drawSmooth= BM_TestHFlag(efa, BM_SMOOTH);
 +
 +                      draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BM_GetIndex(efa), &drawSmooth);
                        if (draw) {
 -                              const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES;
 +                              const GLenum poly_type= GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
                                if (draw==2) { /* enabled with stipple */
  
                                        if (poly_prev != GL_ZERO) glEnd();
                                        }
                                }
  
-                               if (draw==2) {
+                               flush= (draw==2);
 -                              if (!skip_normals && !flush && efa->next)
 -                                      flush|= efa->mat_nr != efa->next->mat_nr;
++                              if (!skip_normals && !flush && (i != lasttri))
++                                      flush|= efa->mat_nr != looptris[i + 1][0]->f->mat_nr; /* TODO, make this neater */
+                               if (flush) {
                                        glEnd();
                                        poly_prev= GL_ZERO; /* force glBegin */
  
                }
        }
        else {
 -              for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
 -                      int drawSmooth = (efa->flag & ME_SMOOTH);
 -                      draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
 +              BM_ElemIndex_Ensure(bmdm->tc->bm, BM_FACE);
 +
-               for (i=0; i<bmdm->tc->tottri; i++) {
-                       BMLoop **l = bmdm->tc->looptris[i];
++              for (i=0; i < tottri; i++) {
++                      BMLoop **l = looptris[i];
 +                      int drawSmooth;
 +
 +                      efa = l[0]->f;
 +                      drawSmooth= BM_TestHFlag(efa, BM_SMOOTH);
 +
 +                      draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BM_GetIndex(efa), &drawSmooth);
                        if (draw) {
 -                              const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES;
 +                              const GLenum poly_type= GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
                                if (draw==2) { /* enabled with stipple */
  
                                        if (poly_prev != GL_ZERO) glEnd();
                                        }
                                }
  
 -                              if (!skip_normals && !flush && efa->next)
 -                                      flush|= efa->mat_nr != efa->next->mat_nr;
+                               flush= (draw==2);
++                              if (!skip_normals && !flush && (i != lasttri)) {
++                                      flush|= efa->mat_nr != looptris[i + 1][0]->f->mat_nr; /* TODO, make this neater */
++                              }
  
-                               if (draw==2) {
+                               if (flush) {
                                        glEnd();
                                        poly_prev= GL_ZERO; /* force glBegin */
  
index c6a6cf46257973fec9ac2e87442383eed5ebae42,408558a30eb87140395297c1f95dc7052ef27d56..dda33689180b1c35bca105caa3dcd2a8bb06c7c3
@@@ -2855,14 -2850,13 +2855,14 @@@ static int vgroup_do_remap(Object *ob, 
  
        if(ob->mode == OB_MODE_EDIT) {
                if(ob->type==OB_MESH) {
 -                      EditMesh *em = BKE_mesh_get_editmesh(ob->data);
 -                      EditVert *eve;
 +                      BMEditMesh *em = ((Mesh*)ob->data)->edit_btmesh;
 +                      BMIter iter;
 +                      BMVert *eve;
  
 -                      for(eve=em->verts.first; eve; eve=eve->next){
 -                              dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT);
 +                      BM_ITER(eve, &iter, em->bm, BM_VERTS_OF_MESH, NULL) {
 +                              dvert= CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT);
                                if(dvert && dvert->totweight){
-                                       defvert_remap(dvert, sort_map);
+                                       defvert_remap(dvert, sort_map, defbase_tot);
                                }
                        }
                }
index 05ae51b80fc8a36a162f10815d5ba5a83c349abe,fa791665eb89bf7155582fddb73ae59704e817c3..04ae926ee068e55b34434df1c96030c8f21eb0fb
@@@ -1047,11 -967,11 +1047,11 @@@ static EnumPropertyItem *weight_paint_s
                                index= view3d_sample_backbuf(&vc, win->eventstate->x - vc.ar->winrct.xmin, win->eventstate->y - vc.ar->winrct.ymin);
  
                                if(index && index<=me->totface) {
-                                       const int totgroup= BLI_countlist(&vc.obact->defbase);
-                                       if(totgroup) {
+                                       const int defbase_tot= BLI_countlist(&vc.obact->defbase);
+                                       if(defbase_tot) {
 -                                              MFace *mf= ((MFace *)me->mface) + index-1;
 -                                              unsigned int fidx= mf->v4 ? 3:2;
 +                                              MPoly *mf= ((MPoly *)me->mpoly) + index-1;
 +                                              unsigned int fidx= mf->totloop - 1;
-                                               int *groups= MEM_callocN(totgroup*sizeof(int), "groups");
+                                               int *groups= MEM_callocN(defbase_tot*sizeof(int), "groups");
                                                int found= FALSE;
  
                                                do {
index 76ff7c088603c668178e6d678b8d881df174d998,6dd362b827f6ec57508e048c54b05526368de512..2c0af90a4d6bd3851d23c9c0042bf7455cf43619
@@@ -531,30 -513,19 +531,30 @@@ static int draw_tface_mapped__set_draw(
  
  static int draw_em_tf_mapped__set_draw(void *userData, int index)
  {
-       struct {DerivedMesh *dm; BMEditMesh *em; short has_mcol; short has_mtface;} *data = userData;
 -      struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data = userData;
 -      EditMesh *em = data->em;
 -      EditFace *efa= EM_get_face_for_index(index);
 -      MTFace *tface;
 -      int matnr;
++      struct {BMEditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data = userData;
 +      BMEditMesh *em = data->em;
 +      BMFace *efa= EDBM_get_face_for_index(em, index);
  
 -      if (efa->h)
 +      if (efa==NULL || BM_TestHFlag(efa, BM_HIDDEN)) {
                return 0;
 +      }
 +      else {
 +              MTFace mtf= {{{0}}};
 +              int matnr = efa->mat_nr;
 +
 +              if (data->has_mtface) {
 +                      MTexPoly *tpoly = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY);
 +                      mtf.flag = tpoly->flag;
 +                      mtf.tpage = tpoly->tpage;
 +                      mtf.transp = tpoly->transp;
 +                      mtf.mode = tpoly->mode;
 +                      mtf.tile = tpoly->tile;
 +                      mtf.unwrap = tpoly->unwrap;
  
 -      tface = data->has_mtface ? CustomData_em_get(&em->fdata, efa->data, CD_MTFACE) : NULL;
 -      matnr = efa->mat_nr;
 +              }
  
 -      return draw_tface__set_draw_legacy(tface, data->has_mcol, matnr);
 +              return draw_tface__set_draw_legacy(&mtf, data->has_mcol, matnr);
 +      }
  }
  
  static int wpaint__setSolidDrawOptions(void *userData, int index, int *drawSmooth_r)
@@@ -675,14 -644,12 +673,12 @@@ static int compareDrawOptions(void *use
  
  static int compareDrawOptionsEm(void *userData, int cur_index, int next_index)
  {
-       struct {DerivedMesh *dm; EditMesh *em; short has_mcol; short has_mtface;} *data= userData;
-       MFace *mf = DM_get_tessface_data_layer(data->dm, CD_MFACE);
-       MTFace *tf = DM_get_tessface_data_layer(data->dm, CD_MTFACE);
 -      struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data= userData;
++      struct {BMEditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} *data= userData;
  
-       if(mf && mf[cur_index].mat_nr != mf[next_index].mat_nr)
+       if(data->mf && data->mf[cur_index].mat_nr != data->mf[next_index].mat_nr)
                return 0;
  
-       if(tf && tf[cur_index].tpage != tf[next_index].tpage)
+       if(data->tf && data->tf[cur_index].tpage != data->tf[next_index].tpage)
                return 0;
  
        return 1;
@@@ -702,12 -669,13 +698,13 @@@ void draw_mesh_textured_old(Scene *scen
        glColor4f(1.0f,1.0f,1.0f,1.0f);
  
        if(ob->mode & OB_MODE_EDIT) {
-               struct {DerivedMesh *dm; BMEditMesh *em; short has_mcol; short has_mtface;} data;
 -              struct {EditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} data;
++              struct {BMEditMesh *em; short has_mcol; short has_mtface; MFace *mf; MTFace *tf;} data;
  
-               data.dm = dm;
 -              data.em= me->edit_mesh;
 -              data.has_mcol= CustomData_has_layer(&me->edit_mesh->fdata, CD_MCOL);
 -              data.has_mtface= CustomData_has_layer(&me->edit_mesh->fdata, CD_MTFACE);
 -              data.mf= DM_get_face_data_layer(dm, CD_MFACE);
 -              data.tf= DM_get_face_data_layer(dm, CD_MTFACE);
 +              data.em= me->edit_btmesh;
 +              data.has_mcol= CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_MLOOPCOL);
 +              data.has_mtface= CustomData_has_layer(&me->edit_btmesh->bm->pdata, CD_MTEXPOLY);
++              data.mf= DM_get_tessface_data_layer(dm, CD_MFACE);
++              data.tf= DM_get_tessface_data_layer(dm, CD_MTFACE);
  
                dm->drawMappedFacesTex(dm, draw_em_tf_mapped__set_draw, compareDrawOptionsEm, &data);
        }
                        if(!CustomData_has_layer(&dm->faceData,CD_TEXTURE_MCOL))
                                add_tface_color_layer(dm);
  
-                       dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, dm);
 -                      userData.mf = DM_get_face_data_layer(dm, CD_MFACE);
 -                      userData.tf = DM_get_face_data_layer(dm, CD_MTFACE);
++                      userData.mf = DM_get_tessface_data_layer(dm, CD_MFACE);
++                      userData.tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
+                       dm->drawFacesTex(dm, draw_tface__set_draw, compareDrawOptions, &userData);
                }
        }
  
index dd6e31ef8c4b4ede49a3b30734e7d48033b3a7d2,b3eba8652b021b22585d0a5590bc13c49831cd82..edcfc42a7982515627d47fbfedc2354347ec8146
@@@ -2375,14 -2349,11 +2375,14 @@@ static void draw_dm_edges_sharp(BMEditM
         * return 2 for the active face so it renders with stipple enabled */
  static int draw_dm_faces_sel__setDrawOptions(void *userData, int index, int *UNUSED(drawSmooth_r))
  {
-       struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} *data = userData;
 -      struct { unsigned char *cols[3]; EditFace *efa_act; int *orig_index; } * data = userData;
 -      EditFace *efa = EM_get_face_for_index(index);
++      struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; int *orig_index;} *data = userData;
 +      BMFace *efa = EDBM_get_face_for_index(data->em, index);
        unsigned char *col;
        
 -      if (efa->h==0) {
 +      if (!efa)
 +              return 0;
 +      
 +      if (!BM_TestHFlag(efa, BM_HIDDEN)) {
                if (efa == data->efa_act) {
                        glColor4ubv(data->cols[2]);
                        return 2; /* stipple */
  
  static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int next_index)
  {
-       struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} * data = userData;
-       int *orig_index= DM_get_tessface_data_layer(data->dm, CD_ORIGINDEX);
 -      struct { unsigned char *cols[3]; EditFace *efa_act; int *orig_index; } *data = userData;
 -      EditFace *efa;
 -      EditFace *next_efa;
++
++      struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; int *orig_index; } * data = userData;
 +      BMFace *efa;
 +      BMFace *next_efa;
 +
        unsigned char *col, *next_col;
  
-       if(!orig_index)
+       if(!data->orig_index)
                return 0;
  
-       efa= EDBM_get_face_for_index(data->em, orig_index[index]);
-       next_efa= EDBM_get_face_for_index(data->em, orig_index[next_index]);
 -      efa= EM_get_face_for_index(data->orig_index[index]);
 -      next_efa= EM_get_face_for_index(data->orig_index[next_index]);
++      efa= EDBM_get_face_for_index(data->em, data->orig_index[index]);
++      next_efa= EDBM_get_face_for_index(data->em, data->orig_index[next_index]);
  
        if(efa == next_efa)
                return 1;
  }
  
  /* also draws the active face */
 -static void draw_dm_faces_sel(DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, EditFace *efa_act) 
 +static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, 
-                             unsigned char *selCol, unsigned char *actCol, BMFace *efa_act, Mesh *me) 
++                            unsigned char *selCol, unsigned char *actCol, BMFace *efa_act)
  {
-       struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; Mesh *me;} data;
 -      struct { unsigned char *cols[3]; EditFace *efa_act; int *orig_index; } data;
++      struct { DerivedMesh *dm; unsigned char *cols[3]; BMEditMesh *em; BMFace *efa_act; int *orig_index; } data;
 +      data.dm= dm;
        data.cols[0] = baseCol;
 +      data.em = em;
        data.cols[1] = selCol;
        data.cols[2] = actCol;
        data.efa_act = efa_act;
-       data.me = me;
 -      data.orig_index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
++      data.orig_index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
  
        dm->drawMappedFaces(dm, draw_dm_faces_sel__setDrawOptions, GPU_enable_material, draw_dm_faces_sel__compareDrawOptions, &data, 0);
  }
@@@ -2928,7 -2854,7 +2928,7 @@@ static void draw_em_fancy(Scene *scene
                if CHECK_OB_DRAWTEXTURE(v3d, dt)
                        col1[3] = 0;
                
-               draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act, me);
 -              draw_dm_faces_sel(cageDM, col1, col2, col3, efa_act);
++              draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act);
  
                glDisable(GL_BLEND);
                glDepthMask(1);         // restore write in zbuffer
                glEnable(GL_BLEND);
                glDepthMask(0);         // disable write in zbuffer, needed for nice transp
                
-               draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act, me);
 -              draw_dm_faces_sel(cageDM, col1, col2, col3, efa_act);
++              draw_dm_faces_sel(em, cageDM, col1, col2, col3, efa_act);
  
                glDisable(GL_BLEND);
                glDepthMask(1);         // restore write in zbuffer
index e04d511336433e8a334ca6647554e83dc9c516ed,b5cf289f4ce7ec5a17e147acfa0f2aad8561edbd..a6eb9ab1e48b394c9d077110dc8ff3303563f76b
@@@ -251,15 -249,11 +249,11 @@@ static void deformVerts(ModifierData *m
                          int UNUSED(useRenderParams), int UNUSED(isFinalCalc))
  {
        HookModifierData *hmd = (HookModifierData*) md;
-       DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, 0);
-       deformVerts_do(hmd, ob, dm, vertexCos, numVerts);
-       if(derivedData != dm)
-               dm->release(dm);
+       
+       deformVerts_do(hmd, ob, derivedData, vertexCos, numVerts);
  }
  
 -static void deformVertsEM(ModifierData *md, Object *ob, struct EditMesh *editData,
 +static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *editData,
                            DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
  {
        HookModifierData *hmd = (HookModifierData*) md;