merge with trunk at r31523
[blender.git] / source / blender / blenkernel / intern / DerivedMesh.c
index de7b962e38a59105a0ad449d9944720d9ede0509..950ac6f3f4fa3f1ee83fd512b1c7aa7e33485cf8 100644 (file)
@@ -42,6 +42,7 @@
 #include "BLI_editVert.h"
 #include "BLI_math.h"
 #include "BLI_memarena.h"
+#include "BLI_array.h"
 #include "BLI_pbvh.h"
 
 #include "BKE_cdderivedmesh.h"
@@ -53,6 +54,9 @@
 #include "BKE_paint.h"
 #include "BKE_texture.h"
 #include "BKE_utildefines.h"
+#include "BKE_particle.h"
+#include "BKE_tessmesh.h"
+#include "BKE_bvhutils.h"
 
 #include "BLO_sys_types.h" // for intptr_t support
 
@@ -101,9 +105,9 @@ static MFace *dm_getFaceArray(DerivedMesh *dm)
 
        if (!mface) {
                mface = CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL,
-                       dm->getNumFaces(dm));
+                       dm->getNumTessFaces(dm));
                CustomData_set_layer_flag(&dm->faceData, CD_MFACE, CD_FLAG_TEMPORARY);
-               dm->copyFaceArray(dm, mface);
+               dm->copyTessFaceArray(dm, mface);
        }
 
        return mface;
@@ -131,41 +135,74 @@ static MEdge *dm_dupEdgeArray(DerivedMesh *dm)
 
 static MFace *dm_dupFaceArray(DerivedMesh *dm)
 {
-       MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumFaces(dm),
+       MFace *tmp = MEM_callocN(sizeof(*tmp) * dm->getNumTessFaces(dm),
                                                         "dm_dupFaceArray tmp");
 
-       if(tmp) dm->copyFaceArray(dm, tmp);
+       if(tmp) dm->copyTessFaceArray(dm, tmp);
 
        return tmp;
 }
 
+CustomData *dm_getVertCData(DerivedMesh *dm)
+{
+       return &dm->vertData;
+}
+
+CustomData *dm_getEdgeCData(DerivedMesh *dm)
+{
+       return &dm->edgeData;
+}
+
+CustomData *dm_getFaceCData(DerivedMesh *dm)
+{
+       return &dm->faceData;
+}
+
+CustomData *dm_getLoopCData(DerivedMesh *dm)
+{
+       return &dm->loopData;
+}
+
+CustomData *dm_getPolyCData(DerivedMesh *dm)
+{
+       return &dm->polyData;
+}
+
 void DM_init_funcs(DerivedMesh *dm)
 {
        /* default function implementations */
        dm->getVertArray = dm_getVertArray;
        dm->getEdgeArray = dm_getEdgeArray;
-       dm->getFaceArray = dm_getFaceArray;
+       dm->getTessFaceArray = dm_getFaceArray;
        dm->dupVertArray = dm_dupVertArray;
        dm->dupEdgeArray = dm_dupEdgeArray;
-       dm->dupFaceArray = dm_dupFaceArray;
+       dm->dupTessFaceArray = dm_dupFaceArray;
+
+       dm->getVertDataLayout = dm_getVertCData;
+       dm->getEdgeDataLayout = dm_getEdgeCData;
+       dm->getTessFaceDataLayout = dm_getFaceCData;
+       dm->getLoopDataLayout = dm_getLoopCData;
+       dm->getFaceDataLayout = dm_getPolyCData;
 
        dm->getVertData = DM_get_vert_data;
        dm->getEdgeData = DM_get_edge_data;
-       dm->getFaceData = DM_get_face_data;
+       dm->getTessFaceData = DM_get_face_data;
        dm->getVertDataArray = DM_get_vert_data_layer;
        dm->getEdgeDataArray = DM_get_edge_data_layer;
-       dm->getFaceDataArray = DM_get_face_data_layer;
+       dm->getTessFaceDataArray = DM_get_tessface_data_layer;
 
        bvhcache_init(&dm->bvhCache);
 }
 
-void DM_init(DerivedMesh *dm, DerivedMeshType type,
-                        int numVerts, int numEdges, int numFaces)
+void DM_init(DerivedMesh *dm, DerivedMeshType type, int numVerts, int numEdges,
+            int numFaces, int numLoops, int numPoly)
 {
        dm->type = type;
        dm->numVertData = numVerts;
        dm->numEdgeData = numEdges;
        dm->numFaceData = numFaces;
+       dm->numLoopData = numLoops;
+       dm->numPolyData = numPoly;
 
        DM_init_funcs(dm);
        
@@ -173,7 +210,8 @@ void DM_init(DerivedMesh *dm, DerivedMeshType type,
 }
 
 void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type,
-                                         int numVerts, int numEdges, int numFaces)
+                      int numVerts, int numEdges, int numFaces,
+                     int numLoops, int numPolys)
 {
        CustomData_copy(&source->vertData, &dm->vertData, CD_MASK_DERIVEDMESH,
                                        CD_CALLOC, numVerts);
@@ -181,11 +219,17 @@ void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type
                                        CD_CALLOC, numEdges);
        CustomData_copy(&source->faceData, &dm->faceData, CD_MASK_DERIVEDMESH,
                                        CD_CALLOC, numFaces);
+       CustomData_copy(&source->loopData, &dm->loopData, CD_MASK_DERIVEDMESH,
+                       CD_CALLOC, numLoops);
+       CustomData_copy(&source->polyData, &dm->polyData, CD_MASK_DERIVEDMESH,
+                       CD_CALLOC, numPolys);
 
        dm->type = type;
        dm->numVertData = numVerts;
        dm->numEdgeData = numEdges;
        dm->numFaceData = numFaces;
+       dm->numLoopData = numLoops;
+       dm->numPolyData = numPolys;
 
        DM_init_funcs(dm);
 
@@ -200,6 +244,8 @@ int DM_release(DerivedMesh *dm)
                CustomData_free(&dm->vertData, dm->numVertData);
                CustomData_free(&dm->edgeData, dm->numEdgeData);
                CustomData_free(&dm->faceData, dm->numFaceData);
+               CustomData_free(&dm->loopData, dm->numLoopData);
+               CustomData_free(&dm->polyData, dm->numPolyData);
 
                return 1;
        }
@@ -207,28 +253,139 @@ int DM_release(DerivedMesh *dm)
                CustomData_free_temporary(&dm->vertData, dm->numVertData);
                CustomData_free_temporary(&dm->edgeData, dm->numEdgeData);
                CustomData_free_temporary(&dm->faceData, dm->numFaceData);
+               CustomData_free_temporary(&dm->loopData, dm->numLoopData);
+               CustomData_free_temporary(&dm->polyData, dm->numPolyData);
 
                return 0;
        }
 }
 
+void dm_add_polys_from_iter(CustomData *ldata, CustomData *pdata, DerivedMesh *dm, int totloop)
+{
+       DMFaceIter *iter = dm->newFaceIter(dm);
+       DMLoopIter *liter;
+       CustomData *oldata, *opdata;
+       MPoly *mpoly;
+       MLoop *mloop;
+       int p, l, i, j, lasttype;
+
+       oldata = dm->getLoopDataLayout(dm);
+       opdata = dm->getFaceDataLayout(dm);
+
+       CustomData_copy(oldata, ldata, CD_MASK_DERIVEDMESH, CD_CALLOC, totloop);
+       CustomData_copy(opdata, pdata, CD_MASK_DERIVEDMESH, CD_CALLOC, dm->getNumFaces(dm));
+
+       mloop = MEM_callocN(sizeof(MLoop)*totloop, "MLoop from dm_add_polys_from_iter");
+       CustomData_add_layer(ldata, CD_MLOOP, CD_ASSIGN, mloop, totloop);
+       mpoly = MEM_callocN(sizeof(MPoly)*dm->getNumFaces(dm), "MPoly from dm_add_polys_from_iter");
+       CustomData_add_layer(pdata, CD_MPOLY, CD_ASSIGN, mpoly, dm->getNumFaces(dm));
+
+       l = 0;
+       for (p=0; !iter->done; iter->step(iter), mpoly++, p++) {
+               mpoly->flag = iter->flags;
+               mpoly->loopstart = l;
+               mpoly->totloop = iter->len;
+               mpoly->mat_nr = iter->mat_nr;
+               
+               j = 0;
+               lasttype = -1;
+               for (i=0; i<opdata->totlayer; i++) {
+                       void *e1, *e2;
+
+                       if (opdata->layers[i].type == lasttype)
+                               j++;
+                       else
+                               j = 0;
+
+                       if (opdata->layers[i].type == CD_MPOLY)
+                               continue;
+                       
+                       e1 = iter->getCDData(iter, opdata->layers[i].type, j);
+                       e2 = (char*)CustomData_get_n(pdata, opdata->layers[i].type, p, j);
+                       
+                       if (!e2)
+                               continue;
+
+                       CustomData_copy_elements(opdata->layers[i].type, e1, e2, 1);
+                       
+                       lasttype = opdata->layers[i].type;                              
+               }
+
+               liter = iter->getLoopsIter(iter);
+               for (; !liter->done; liter->step(liter), mloop++, l++) {
+                       mloop->v = liter->vindex;
+                       mloop->e = liter->eindex;
+
+                       j = 0;
+                       lasttype = -1;
+                       for (i=0; i<oldata->totlayer; i++) {
+                               void *e1, *e2;
+
+                               if (oldata->layers[i].type == CD_MLOOP)
+                                       continue;
+                               
+                               if (oldata->layers[i].type == lasttype)
+                                       j++;
+                               else
+                                       j = 0;
+
+                               e1 = liter->getLoopCDData(liter, oldata->layers[i].type, j);
+                               e2 = CustomData_get_n(ldata, oldata->layers[i].type, l, j);
+                               
+                               if (!e2)
+                                       continue;
+
+                               CustomData_copy_elements(oldata->layers[i].type, e1, e2, 1);
+                               lasttype = oldata->layers[i].type;                              
+                       }
+               }
+       }
+       iter->free(iter);
+}
+
+void DM_DupPolys(DerivedMesh *source, DerivedMesh *target)
+{
+       DMFaceIter *iter = source->newFaceIter(source);
+       DMLoopIter *liter;
+       int totloop = source->numLoopData;
+
+       dm_add_polys_from_iter(&target->loopData, &target->polyData, source, totloop);
+
+       target->numLoopData = totloop;
+       target->numPolyData = source->getNumFaces(source);
+}
+
 void DM_to_mesh(DerivedMesh *dm, Mesh *me)
 {
        /* dm might depend on me, so we need to do everything with a local copy */
        Mesh tmp = *me;
-       int totvert, totedge, totface;
+       DMFaceIter *iter;
+       int totvert, totedge, totface, totloop, totpoly;
 
        memset(&tmp.vdata, 0, sizeof(tmp.vdata));
        memset(&tmp.edata, 0, sizeof(tmp.edata));
        memset(&tmp.fdata, 0, sizeof(tmp.fdata));
+       memset(&tmp.ldata, 0, sizeof(tmp.ldata));
+       memset(&tmp.pdata, 0, sizeof(tmp.pdata));
 
        totvert = tmp.totvert = dm->getNumVerts(dm);
        totedge = tmp.totedge = dm->getNumEdges(dm);
-       totface = tmp.totface = dm->getNumFaces(dm);
+       totface = tmp.totface = dm->getNumTessFaces(dm);
+       totpoly = tmp.totpoly = dm->getNumFaces(dm);
+       
+       totloop = 0;
+       for (iter=dm->newFaceIter(dm); !iter->done; iter->step(iter)) {
+               totloop += iter->len;
+       }
+       iter->free(iter);
+       
+       tmp.totloop = totloop;
 
        CustomData_copy(&dm->vertData, &tmp.vdata, CD_MASK_MESH, CD_DUPLICATE, totvert);
        CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge);
        CustomData_copy(&dm->faceData, &tmp.fdata, CD_MASK_MESH, CD_DUPLICATE, totface);
+       CustomData_copy(&dm->loopData, &tmp.ldata, CD_MASK_MESH, CD_DUPLICATE, totloop);
+       CustomData_copy(&dm->polyData, &tmp.pdata, CD_MASK_MESH, CD_DUPLICATE, totpoly);
 
        /* not all DerivedMeshes store their verts/edges/faces in CustomData, so
           we set them here in case they are missing */
@@ -237,16 +394,23 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me)
        if(!CustomData_has_layer(&tmp.edata, CD_MEDGE))
                CustomData_add_layer(&tmp.edata, CD_MEDGE, CD_ASSIGN, dm->dupEdgeArray(dm), totedge);
        if(!CustomData_has_layer(&tmp.fdata, CD_MFACE))
-               CustomData_add_layer(&tmp.fdata, CD_MFACE, CD_ASSIGN, dm->dupFaceArray(dm), totface);
+               CustomData_add_layer(&tmp.fdata, CD_MFACE, CD_ASSIGN, dm->dupTessFaceArray(dm), totface);
+       if(!CustomData_has_layer(&tmp.pdata, CD_MPOLY))
+               dm_add_polys_from_iter(&tmp.ldata, &tmp.pdata, dm, totloop);
 
        mesh_update_customdata_pointers(&tmp);
 
        CustomData_free(&me->vdata, me->totvert);
        CustomData_free(&me->edata, me->totedge);
        CustomData_free(&me->fdata, me->totface);
+       CustomData_free(&me->ldata, me->totloop);
+       CustomData_free(&me->pdata, me->totpoly);
 
-       /* if the number of verts has changed, remove invalid data */
+       /* BMESH_TODO/XXX: ok, this should use new CD shapekey data,
+                          which shouuld be fed through the modifier 
+                                          stack*/
        if(tmp.totvert != me->totvert) {
+               printf("YEEK! this should be recoded! Shape key loss!!!\n");
                if(tmp.key) tmp.key->id.us--;
                tmp.key = NULL;
        }
@@ -291,11 +455,21 @@ void DM_add_edge_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
        CustomData_add_layer(&dm->edgeData, type, alloctype, layer, dm->numEdgeData);
 }
 
-void DM_add_face_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
+void DM_add_tessface_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
 {
        CustomData_add_layer(&dm->faceData, type, alloctype, layer, dm->numFaceData);
 }
 
+void DM_add_loop_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
+{
+       CustomData_add_layer(&dm->loopData, type, alloctype, layer, dm->numLoopData);
+}
+
+void DM_add_face_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
+{
+       CustomData_add_layer(&dm->polyData, type, alloctype, layer, dm->numPolyData);
+}
+
 void *DM_get_vert_data(DerivedMesh *dm, int index, int type)
 {
        return CustomData_get(&dm->vertData, index, type);
@@ -327,14 +501,19 @@ void *DM_get_edge_data_layer(DerivedMesh *dm, int type)
        return CustomData_get_layer(&dm->edgeData, type);
 }
 
-void *DM_get_face_data_layer(DerivedMesh *dm, int type)
+void *DM_get_tessface_data_layer(DerivedMesh *dm, int type)
 {
        if(type == CD_MFACE)
-               return dm->getFaceArray(dm);
+               return dm->getTessFaceArray(dm);
 
        return CustomData_get_layer(&dm->faceData, type);
 }
 
+void *DM_get_face_data_layer(DerivedMesh *dm, int type)
+{
+       return CustomData_get_layer(&dm->polyData, type);
+}
+
 void DM_set_vert_data(DerivedMesh *dm, int index, int type, void *data)
 {
        CustomData_set(&dm->vertData, index, type, data);
@@ -364,13 +543,27 @@ void DM_copy_edge_data(DerivedMesh *source, DerivedMesh *dest,
                                                 source_index, dest_index, count);
 }
 
-void DM_copy_face_data(DerivedMesh *source, DerivedMesh *dest,
+void DM_copy_tessface_data(DerivedMesh *source, DerivedMesh *dest,
                                           int source_index, int dest_index, int count)
 {
        CustomData_copy_data(&source->faceData, &dest->faceData,
                                                 source_index, dest_index, count);
 }
 
+void DM_copy_loop_data(DerivedMesh *source, DerivedMesh *dest,
+                       int source_index, int dest_index, int count)
+{
+       CustomData_copy_data(&source->loopData, &dest->loopData,
+                            source_index, dest_index, count);
+}
+
+void DM_copy_face_data(DerivedMesh *source, DerivedMesh *dest,
+                       int source_index, int dest_index, int count)
+{
+       CustomData_copy_data(&source->polyData, &dest->polyData,
+                            source_index, dest_index, count);
+}
+
 void DM_free_vert_data(struct DerivedMesh *dm, int index, int count)
 {
        CustomData_free_elem(&dm->vertData, index, count);
@@ -381,11 +574,21 @@ void DM_free_edge_data(struct DerivedMesh *dm, int index, int count)
        CustomData_free_elem(&dm->edgeData, index, count);
 }
 
-void DM_free_face_data(struct DerivedMesh *dm, int index, int count)
+void DM_free_tessface_data(struct DerivedMesh *dm, int index, int count)
 {
        CustomData_free_elem(&dm->faceData, index, count);
 }
 
+void DM_free_loop_data(struct DerivedMesh *dm, int index, int count)
+{
+       CustomData_free_elem(&dm->loopData, index, count);
+}
+
+void DM_free_face_data(struct DerivedMesh *dm, int index, int count)
+{
+       CustomData_free_elem(&dm->polyData, index, count);
+}
+
 void DM_interp_vert_data(DerivedMesh *source, DerivedMesh *dest,
                                                 int *src_indices, float *weights,
                                                 int count, int dest_index)
@@ -403,7 +606,7 @@ void DM_interp_edge_data(DerivedMesh *source, DerivedMesh *dest,
                                          weights, (float*)vert_weights, count, dest_index);
 }
 
-void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest,
+void DM_interp_tessface_data(DerivedMesh *source, DerivedMesh *dest,
                                                 int *src_indices,
                                                 float *weights, FaceVertWeight *vert_weights,
                                                 int count, int dest_index)
@@ -412,13 +615,28 @@ void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest,
                                          weights, (float*)vert_weights, count, dest_index);
 }
 
-void DM_swap_face_data(DerivedMesh *dm, int index, const int *corner_indices)
+void DM_swap_tessface_data(DerivedMesh *dm, int index, const int *corner_indices)
 {
        CustomData_swap(&dm->faceData, index, corner_indices);
 }
 
-///
+void DM_interp_loop_data(DerivedMesh *source, DerivedMesh *dest,
+                         int *src_indices,
+                         float *weights, int count, int dest_index)
+{
+       CustomData_interp(&source->loopData, &dest->loopData, src_indices,
+                         weights, NULL, count, dest_index);
+}
+
+void DM_interp_face_data(DerivedMesh *source, DerivedMesh *dest,
+                         int *src_indices,
+                         float *weights, int count, int dest_index)
+{
+       CustomData_interp(&source->polyData, &dest->polyData, src_indices,
+                         weights, NULL, count, dest_index);
+}
 
+///
 static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3])
 {
        DerivedMesh *dm = CDDM_from_mesh(me, ob);
@@ -434,987 +652,6 @@ static DerivedMesh *getMeshDerivedMesh(Mesh *me, Object *ob, float (*vertCos)[3]
        return dm;
 }
 
-///
-
-typedef struct {
-       DerivedMesh dm;
-
-       EditMesh *em;
-       float (*vertexCos)[3];
-       float (*vertexNos)[3];
-       float (*faceNos)[3];
-} EditMeshDerivedMesh;
-
-static void emDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditVert *eve;
-       int i;
-
-       for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
-               if (emdm->vertexCos) {
-                       func(userData, i, emdm->vertexCos[i], emdm->vertexNos[i], NULL);
-               } else {
-                       func(userData, i, eve->co, eve->no, NULL);
-               }
-       }
-}
-static void emDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditEdge *eed;
-       int i;
-
-       if (emdm->vertexCos) {
-               EditVert *eve;
-
-               for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
-                       eve->tmp.l = (intptr_t) i++;
-               for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
-                       func(userData, i, emdm->vertexCos[(int) eed->v1->tmp.l], emdm->vertexCos[(int) eed->v2->tmp.l]);
-       } else {
-               for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
-                       func(userData, i, eed->v1->co, eed->v2->co);
-       }
-}
-static void emDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData) 
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditEdge *eed;
-       int i;
-
-       if (emdm->vertexCos) {
-               EditVert *eve;
-
-               for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
-                       eve->tmp.l = (intptr_t) i++;
-
-               glBegin(GL_LINES);
-               for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
-                       if(!setDrawOptions || setDrawOptions(userData, i)) {
-                               glVertex3fv(emdm->vertexCos[(int) eed->v1->tmp.l]);
-                               glVertex3fv(emdm->vertexCos[(int) eed->v2->tmp.l]);
-                       }
-               }
-               glEnd();
-       } else {
-               glBegin(GL_LINES);
-               for(i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
-                       if(!setDrawOptions || setDrawOptions(userData, i)) {
-                               glVertex3fv(eed->v1->co);
-                               glVertex3fv(eed->v2->co);
-                       }
-               }
-               glEnd();
-       }
-}
-static void emDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges)
-{
-       emDM_drawMappedEdges(dm, NULL, NULL);
-}
-static void emDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData) 
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditEdge *eed;
-       int i;
-
-       if (emdm->vertexCos) {
-               EditVert *eve;
-
-               for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
-                       eve->tmp.l = (intptr_t) i++;
-
-               glBegin(GL_LINES);
-               for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
-                       if(!setDrawOptions || setDrawOptions(userData, i)) {
-                               setDrawInterpOptions(userData, i, 0.0);
-                               glVertex3fv(emdm->vertexCos[(int) eed->v1->tmp.l]);
-                               setDrawInterpOptions(userData, i, 1.0);
-                               glVertex3fv(emdm->vertexCos[(int) eed->v2->tmp.l]);
-                       }
-               }
-               glEnd();
-       } else {
-               glBegin(GL_LINES);
-               for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
-                       if(!setDrawOptions || setDrawOptions(userData, i)) {
-                               setDrawInterpOptions(userData, i, 0.0);
-                               glVertex3fv(eed->v1->co);
-                               setDrawInterpOptions(userData, i, 1.0);
-                               glVertex3fv(eed->v2->co);
-                       }
-               }
-               glEnd();
-       }
-}
-
-static void emDM_drawUVEdges(DerivedMesh *dm)
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditFace *efa;
-       MTFace *tf;
-
-       glBegin(GL_LINES);
-       for(efa= emdm->em->faces.first; efa; efa= efa->next) {
-               tf = CustomData_em_get(&emdm->em->fdata, efa->data, CD_MTFACE);
-
-               if(tf && !(efa->h)) {
-                       glVertex2fv(tf->uv[0]);
-                       glVertex2fv(tf->uv[1]);
-
-                       glVertex2fv(tf->uv[1]);
-                       glVertex2fv(tf->uv[2]);
-
-                       if (!efa->v4) {
-                               glVertex2fv(tf->uv[2]);
-                               glVertex2fv(tf->uv[0]);
-                       } else {
-                               glVertex2fv(tf->uv[2]);
-                               glVertex2fv(tf->uv[3]);
-                               glVertex2fv(tf->uv[3]);
-                               glVertex2fv(tf->uv[0]);
-                       }
-               }
-       }
-       glEnd();
-}
-
-static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[3])
-{
-       if (vertexCos) {
-               VECCOPY(cent, vertexCos[(int) efa->v1->tmp.l]);
-               add_v3_v3(cent, vertexCos[(int) efa->v2->tmp.l]);
-               add_v3_v3(cent, vertexCos[(int) efa->v3->tmp.l]);
-               if (efa->v4) add_v3_v3(cent, vertexCos[(int) efa->v4->tmp.l]);
-       } else {
-               VECCOPY(cent, efa->v1->co);
-               add_v3_v3(cent, efa->v2->co);
-               add_v3_v3(cent, efa->v3->co);
-               if (efa->v4) add_v3_v3(cent, efa->v4->co);
-       }
-
-       if (efa->v4) {
-               mul_v3_fl(cent, 0.25f);
-       } else {
-               mul_v3_fl(cent, 0.33333333333f);
-       }
-}
-static void emDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditVert *eve;
-       EditFace *efa;
-       float cent[3];
-       int i;
-
-       if (emdm->vertexCos) {
-               for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
-                       eve->tmp.l = (intptr_t) i++;
-       }
-
-       for(i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
-               emDM__calcFaceCent(efa, cent, emdm->vertexCos);
-               func(userData, i, cent, emdm->vertexCos?emdm->faceNos[i]:efa->n);
-       }
-}
-static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditFace *efa;
-       int i, draw;
-
-       if (emdm->vertexCos) {
-               EditVert *eve;
-
-               for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
-                       eve->tmp.l = (intptr_t) i++;
-
-               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);
-                       if(draw) {
-                               if (draw==2) { /* enabled with stipple */
-                                         glEnable(GL_POLYGON_STIPPLE);
-                                         glPolygonStipple(stipple_quarttone);
-                               }
-                               
-                               glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
-
-                               glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
-                               if (!drawSmooth) {
-                                       glNormal3fv(emdm->faceNos[i]);
-                                       glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]);
-                                       glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]);
-                                       glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]);
-                                       if(efa->v4) glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]);
-                               } else {
-                                       glNormal3fv(emdm->vertexNos[(int) efa->v1->tmp.l]);
-                                       glVertex3fv(emdm->vertexCos[(int) efa->v1->tmp.l]);
-                                       glNormal3fv(emdm->vertexNos[(int) efa->v2->tmp.l]);
-                                       glVertex3fv(emdm->vertexCos[(int) efa->v2->tmp.l]);
-                                       glNormal3fv(emdm->vertexNos[(int) efa->v3->tmp.l]);
-                                       glVertex3fv(emdm->vertexCos[(int) efa->v3->tmp.l]);
-                                       if(efa->v4) {
-                                               glNormal3fv(emdm->vertexNos[(int) efa->v4->tmp.l]);
-                                               glVertex3fv(emdm->vertexCos[(int) efa->v4->tmp.l]);
-                                       }
-                               }
-                               glEnd();
-                               
-                               if (draw==2)
-                                       glDisable(GL_POLYGON_STIPPLE);
-                       }
-               }
-       } 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);
-                       if(draw) {
-                               if (draw==2) { /* enabled with stipple */
-                                       glEnable(GL_POLYGON_STIPPLE);
-                                       glPolygonStipple(stipple_quarttone);
-                               }
-                               glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
-
-                               glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
-                               if (!drawSmooth) {
-                                       glNormal3fv(efa->n);
-                                       glVertex3fv(efa->v1->co);
-                                       glVertex3fv(efa->v2->co);
-                                       glVertex3fv(efa->v3->co);
-                                       if(efa->v4) glVertex3fv(efa->v4->co);
-                               } else {
-                                       glNormal3fv(efa->v1->no);
-                                       glVertex3fv(efa->v1->co);
-                                       glNormal3fv(efa->v2->no);
-                                       glVertex3fv(efa->v2->co);
-                                       glNormal3fv(efa->v3->no);
-                                       glVertex3fv(efa->v3->co);
-                                       if(efa->v4) {
-                                               glNormal3fv(efa->v4->no);
-                                               glVertex3fv(efa->v4->co);
-                                       }
-                               }
-                               glEnd();
-                               
-                               if (draw==2)
-                                       glDisable(GL_POLYGON_STIPPLE);
-                       }
-               }
-       }
-}
-
-static void emDM_drawFacesTex_common(DerivedMesh *dm,
-                          int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
-                          int (*drawParamsMapped)(void *userData, int index),
-                          void *userData) 
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditMesh *em= emdm->em;
-       float (*vertexCos)[3]= emdm->vertexCos;
-       float (*vertexNos)[3]= emdm->vertexNos;
-       EditFace *efa;
-       int i;
-
-       /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
-       glShadeModel(GL_SMOOTH);
-       
-       if (vertexCos) {
-               EditVert *eve;
-
-               for (i=0,eve=em->verts.first; eve; eve= eve->next)
-                       eve->tmp.l = (intptr_t) i++;
-
-               for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
-                       MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                       MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
-                       unsigned char *cp= NULL;
-                       int drawSmooth= (efa->flag & ME_SMOOTH);
-                       int flag;
-
-                       if(drawParams)
-                               flag= drawParams(tf, mcol, efa->mat_nr);
-                       else if(drawParamsMapped)
-                               flag= drawParamsMapped(userData, i);
-                       else
-                               flag= 1;
-
-                       if(flag != 0) { /* flag 0 == the face is hidden or invisible */
-                               
-                               /* we always want smooth here since otherwise vertex colors dont interpolate */
-                               if (mcol) {
-                                       if (flag==1) {
-                                               cp= (unsigned char*)mcol;
-                                       }
-                               } else {
-                                       glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
-                               } 
-                               
-                               glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
-                               if (!drawSmooth) {
-                                       glNormal3fv(emdm->faceNos[i]);
-
-                                       if(tf) glTexCoord2fv(tf->uv[0]);
-                                       if(cp) glColor3ub(cp[3], cp[2], cp[1]);
-                                       glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
-
-                                       if(tf) glTexCoord2fv(tf->uv[1]);
-                                       if(cp) glColor3ub(cp[7], cp[6], cp[5]);
-                                       glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
-
-                                       if(tf) glTexCoord2fv(tf->uv[2]);
-                                       if(cp) glColor3ub(cp[11], cp[10], cp[9]);
-                                       glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
-
-                                       if(efa->v4) {
-                                               if(tf) glTexCoord2fv(tf->uv[3]);
-                                               if(cp) glColor3ub(cp[15], cp[14], cp[13]);
-                                               glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
-                                       }
-                               } else {
-                                       if(tf) glTexCoord2fv(tf->uv[0]);
-                                       if(cp) glColor3ub(cp[3], cp[2], cp[1]);
-                                       glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
-                                       glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
-
-                                       if(tf) glTexCoord2fv(tf->uv[1]);
-                                       if(cp) glColor3ub(cp[7], cp[6], cp[5]);
-                                       glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
-                                       glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
-
-                                       if(tf) glTexCoord2fv(tf->uv[2]);
-                                       if(cp) glColor3ub(cp[11], cp[10], cp[9]);
-                                       glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
-                                       glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
-
-                                       if(efa->v4) {
-                                               if(tf) glTexCoord2fv(tf->uv[3]);
-                                               if(cp) glColor3ub(cp[15], cp[14], cp[13]);
-                                               glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
-                                               glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
-                                       }
-                               }
-                               glEnd();
-                       }
-               }
-       } else {
-               for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
-                       MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
-                       MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
-                       unsigned char *cp= NULL;
-                       int drawSmooth= (efa->flag & ME_SMOOTH);
-                       int flag;
-
-                       if(drawParams)
-                               flag= drawParams(tf, mcol, efa->mat_nr);
-                       else if(drawParamsMapped)
-                               flag= drawParamsMapped(userData, i);
-                       else
-                               flag= 1;
-
-                       if(flag != 0) { /* flag 0 == the face is hidden or invisible */
-                               /* we always want smooth here since otherwise vertex colors dont interpolate */
-                               if (mcol) {
-                                       if (flag==1) {
-                                               cp= (unsigned char*)mcol;
-                                       }
-                               } else {
-                                       glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
-                               } 
-
-                               glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
-                               if (!drawSmooth) {
-                                       glNormal3fv(efa->n);
-
-                                       if(tf) glTexCoord2fv(tf->uv[0]);
-                                       if(cp) glColor3ub(cp[3], cp[2], cp[1]);
-                                       glVertex3fv(efa->v1->co);
-
-                                       if(tf) glTexCoord2fv(tf->uv[1]);
-                                       if(cp) glColor3ub(cp[7], cp[6], cp[5]);
-                                       glVertex3fv(efa->v2->co);
-
-                                       if(tf) glTexCoord2fv(tf->uv[2]);
-                                       if(cp) glColor3ub(cp[11], cp[10], cp[9]);
-                                       glVertex3fv(efa->v3->co);
-
-                                       if(efa->v4) {
-                                               if(tf) glTexCoord2fv(tf->uv[3]);
-                                               if(cp) glColor3ub(cp[15], cp[14], cp[13]);
-                                               glVertex3fv(efa->v4->co);
-                                       }
-                               } else {
-                                       if(tf) glTexCoord2fv(tf->uv[0]);
-                                       if(cp) glColor3ub(cp[3], cp[2], cp[1]);
-                                       glNormal3fv(efa->v1->no);
-                                       glVertex3fv(efa->v1->co);
-
-                                       if(tf) glTexCoord2fv(tf->uv[1]);
-                                       if(cp) glColor3ub(cp[7], cp[6], cp[5]);
-                                       glNormal3fv(efa->v2->no);
-                                       glVertex3fv(efa->v2->co);
-
-                                       if(tf) glTexCoord2fv(tf->uv[2]);
-                                       if(cp) glColor3ub(cp[11], cp[10], cp[9]);
-                                       glNormal3fv(efa->v3->no);
-                                       glVertex3fv(efa->v3->co);
-
-                                       if(efa->v4) {
-                                               if(tf) glTexCoord2fv(tf->uv[3]);
-                                               if(cp) glColor3ub(cp[15], cp[14], cp[13]);
-                                               glNormal3fv(efa->v4->no);
-                                               glVertex3fv(efa->v4->co);
-                                       }
-                               }
-                               glEnd();
-                       }
-               }
-       }
-}
-
-static void emDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
-{
-       emDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
-}
-
-static void emDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
-{
-       emDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
-}
-
-static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
-                          int (*setMaterial)(int, void *attribs),
-                          int (*setDrawOptions)(void *userData, int index), void *userData) 
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditMesh *em= emdm->em;
-       float (*vertexCos)[3]= emdm->vertexCos;
-       float (*vertexNos)[3]= emdm->vertexNos;
-       EditVert *eve;
-       EditFace *efa;
-       DMVertexAttribs attribs;
-       GPUVertexAttribs gattribs;
-       MTFace *tf;
-       int transp, new_transp, orig_transp, tfoffset;
-       int i, b, matnr, new_matnr, dodraw, layer;
-
-       dodraw = 0;
-       matnr = -1;
-
-       transp = GPU_get_material_blend_mode();
-       orig_transp = transp;
-       layer = CustomData_get_layer_index(&em->fdata, CD_MTFACE);
-       tfoffset = (layer == -1)? -1: em->fdata.layers[layer].offset;
-
-       memset(&attribs, 0, sizeof(attribs));
-
-       /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
-       glShadeModel(GL_SMOOTH);
-
-       for (i=0,eve=em->verts.first; eve; eve= eve->next)
-               eve->tmp.l = (intptr_t) i++;
-
-#define PASSATTRIB(efa, eve, vert) {                                                                                   \
-       if(attribs.totorco) {                                                                                                           \
-               float *orco = attribs.orco.array[eve->tmp.l];                                                   \
-               glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                               \
-       }                                                                                                                                                       \
-       for(b = 0; b < attribs.tottface; b++) {                                                                         \
-               MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset);  \
-               glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]);                  \
-       }                                                                                                                                                       \
-       for(b = 0; b < attribs.totmcol; b++) {                                                                          \
-               MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset);                \
-               GLubyte col[4];                                                                                                                 \
-               col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
-               glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
-       }                                                                                                                                                       \
-       if(attribs.tottang) {                                                                                                           \
-               float *tang = attribs.tang.array[i*4 + vert];                                                   \
-               glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
-       }                                                                                                                                                       \
-}
-
-       for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
-               int drawSmooth= (efa->flag & ME_SMOOTH);
-
-               if(setDrawOptions && !setDrawOptions(userData, i))
-                       continue;
-
-               new_matnr = efa->mat_nr + 1;
-               if(new_matnr != matnr) {
-                       dodraw = setMaterial(matnr = new_matnr, &gattribs);
-                       if(dodraw)
-                               DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
-               }
-
-               if(tfoffset != -1) {
-                       tf = (MTFace*)((char*)efa->data)+tfoffset;
-                       new_transp = tf->transp;
-
-                       if(new_transp != transp) {
-                               if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
-                                       GPU_set_material_blend_mode(orig_transp);
-                               else
-                                       GPU_set_material_blend_mode(new_transp);
-                               transp = new_transp;
-                       }
-               }
-
-               if(dodraw) {
-                       glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
-                       if (!drawSmooth) {
-                               if(vertexCos) glNormal3fv(emdm->faceNos[i]);
-                               else glNormal3fv(efa->n);
-
-                               PASSATTRIB(efa, efa->v1, 0);
-                               if(vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
-                               else glVertex3fv(efa->v1->co);
-
-                               PASSATTRIB(efa, efa->v2, 1);
-                               if(vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
-                               else glVertex3fv(efa->v2->co);
-
-                               PASSATTRIB(efa, efa->v3, 2);
-                               if(vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
-                               else glVertex3fv(efa->v3->co);
-
-                               if(efa->v4) {
-                                       PASSATTRIB(efa, efa->v4, 3);
-                                       if(vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
-                                       else glVertex3fv(efa->v4->co);
-                               }
-                       } else {
-                               PASSATTRIB(efa, efa->v1, 0);
-                               if(vertexCos) {
-                                       glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
-                                       glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
-                               }
-                               else {
-                                       glNormal3fv(efa->v1->no);
-                                       glVertex3fv(efa->v1->co);
-                               }
-
-                               PASSATTRIB(efa, efa->v2, 1);
-                               if(vertexCos) {
-                                       glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
-                                       glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
-                               }
-                               else {
-                                       glNormal3fv(efa->v2->no);
-                                       glVertex3fv(efa->v2->co);
-                               }
-
-                               PASSATTRIB(efa, efa->v3, 2);
-                               if(vertexCos) {
-                                       glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
-                                       glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
-                               }
-                               else {
-                                       glNormal3fv(efa->v3->no);
-                                       glVertex3fv(efa->v3->co);
-                               }
-
-                               if(efa->v4) {
-                                       PASSATTRIB(efa, efa->v4, 3);
-                                       if(vertexCos) {
-                                               glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
-                                               glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
-                                       }
-                                       else {
-                                               glNormal3fv(efa->v4->no);
-                                               glVertex3fv(efa->v4->co);
-                                       }
-                               }
-                       }
-                       glEnd();
-               }
-       }
-}
-
-static void emDM_drawFacesGLSL(DerivedMesh *dm,
-                          int (*setMaterial)(int, void *attribs))
-{
-       dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
-}
-
-static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditVert *eve;
-       int i;
-
-       if (emdm->em->verts.first) {
-               for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) {
-                       if (emdm->vertexCos) {
-                               DO_MINMAX(emdm->vertexCos[i], min_r, max_r);
-                       } else {
-                               DO_MINMAX(eve->co, min_r, max_r);
-                       }
-               }
-       } else {
-               min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
-       }
-}
-static int emDM_getNumVerts(DerivedMesh *dm)
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-
-       return BLI_countlist(&emdm->em->verts);
-}
-
-static int emDM_getNumEdges(DerivedMesh *dm)
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-
-       return BLI_countlist(&emdm->em->edges);
-}
-
-static int emDM_getNumFaces(DerivedMesh *dm)
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-
-       return BLI_countlist(&emdm->em->faces);
-}
-
-static void emDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditVert *eve;
-       int i;
-
-       for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
-               if (emdm->vertexCos) {
-                       copy_v3_v3(cos_r[i], emdm->vertexCos[i]);
-               } else {
-                       copy_v3_v3(cos_r[i], eve->co);
-               }
-       }
-}
-
-static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
-{
-       EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
-       int i;
-
-       for(i = 0; i < index; ++i) ev = ev->next;
-
-       VECCOPY(vert_r->co, ev->co);
-
-       vert_r->no[0] = ev->no[0] * 32767.0;
-       vert_r->no[1] = ev->no[1] * 32767.0;
-       vert_r->no[2] = ev->no[2] * 32767.0;
-
-       /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
-       vert_r->mat_nr = 0;
-       vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
-}
-
-static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
-{
-       EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
-       EditEdge *ee = em->edges.first;
-       EditVert *ev, *v1, *v2;
-       int i;
-
-       for(i = 0; i < index; ++i) ee = ee->next;
-
-       edge_r->crease = (unsigned char) (ee->crease*255.0f);
-       edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
-       /* TODO what to do with edge_r->flag? */
-       edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
-       if (ee->seam) edge_r->flag |= ME_SEAM;
-       if (ee->sharp) edge_r->flag |= ME_SHARP;
-#if 0
-       /* this needs setup of f2 field */
-       if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
-#endif
-
-       /* goddamn, we have to search all verts to find indices */
-       v1 = ee->v1;
-       v2 = ee->v2;
-       for(i = 0, ev = em->verts.first; v1 || v2; i++, ev = ev->next) {
-               if(ev == v1) {
-                       edge_r->v1 = i;
-                       v1 = NULL;
-               }
-               if(ev == v2) {
-                       edge_r->v2 = i;
-                       v2 = NULL;
-               }
-       }
-}
-
-static void emDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
-{
-       EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
-       EditFace *ef = em->faces.first;
-       EditVert *ev, *v1, *v2, *v3, *v4;
-       int i;
-
-       for(i = 0; i < index; ++i) ef = ef->next;
-
-       face_r->mat_nr = ef->mat_nr;
-       face_r->flag = ef->flag;
-
-       /* goddamn, we have to search all verts to find indices */
-       v1 = ef->v1;
-       v2 = ef->v2;
-       v3 = ef->v3;
-       v4 = ef->v4;
-       if(!v4) face_r->v4 = 0;
-
-       for(i = 0, ev = em->verts.first; v1 || v2 || v3 || v4;
-               i++, ev = ev->next) {
-               if(ev == v1) {
-                       face_r->v1 = i;
-                       v1 = NULL;
-               }
-               if(ev == v2) {
-                       face_r->v2 = i;
-                       v2 = NULL;
-               }
-               if(ev == v3) {
-                       face_r->v3 = i;
-                       v3 = NULL;
-               }
-               if(ev == v4) {
-                       face_r->v4 = i;
-                       v4 = NULL;
-               }
-       }
-
-       test_index_face(face_r, NULL, 0, ef->v4?4:3);
-}
-
-static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditVert *ev = emdm->em->verts.first;
-       int i;
-
-       for(i=0; ev; ev = ev->next, ++vert_r, ++i) {
-               if(emdm->vertexCos)
-                       copy_v3_v3(vert_r->co, emdm->vertexCos[i]);
-               else
-                       copy_v3_v3(vert_r->co, ev->co);
-
-               vert_r->no[0] = ev->no[0] * 32767.0;
-               vert_r->no[1] = ev->no[1] * 32767.0;
-               vert_r->no[2] = ev->no[2] * 32767.0;
-
-               /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
-               vert_r->mat_nr = 0;
-               vert_r->flag = 0;
-               vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
-       }
-}
-
-static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
-{
-       EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
-       EditEdge *ee = em->edges.first;
-       EditVert *ev;
-       int i;
-
-       /* store vertex indices in tmp union */
-       for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
-               ev->tmp.l = (intptr_t) i;
-
-       for( ; ee; ee = ee->next, ++edge_r) {
-               edge_r->crease = (unsigned char) (ee->crease*255.0f);
-               edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
-               /* TODO what to do with edge_r->flag? */
-               edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
-               if (ee->seam) edge_r->flag |= ME_SEAM;
-               if (ee->sharp) edge_r->flag |= ME_SHARP;
-#if 0
-               /* this needs setup of f2 field */
-               if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
-#endif
-
-               edge_r->v1 = (int)ee->v1->tmp.l;
-               edge_r->v2 = (int)ee->v2->tmp.l;
-       }
-}
-
-static void emDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
-{
-       EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
-       EditFace *ef = em->faces.first;
-       EditVert *ev;
-       int i;
-
-       /* store vertexes indices in tmp union */
-       for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
-               ev->tmp.l = (intptr_t) i;
-
-       for( ; ef; ef = ef->next, ++face_r) {
-               face_r->mat_nr = ef->mat_nr;
-               face_r->flag = ef->flag;
-
-               face_r->v1 = (int)ef->v1->tmp.l;
-               face_r->v2 = (int)ef->v2->tmp.l;
-               face_r->v3 = (int)ef->v3->tmp.l;
-               if(ef->v4) face_r->v4 = (int)ef->v4->tmp.l;
-               else face_r->v4 = 0;
-
-               test_index_face(face_r, NULL, 0, ef->v4?4:3);
-       }
-}
-
-static void *emDM_getFaceDataArray(DerivedMesh *dm, int type)
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-       EditMesh *em= emdm->em;
-       EditFace *efa;
-       char *data, *emdata;
-       void *datalayer;
-       int index, offset, size;
-
-       datalayer = DM_get_face_data_layer(dm, type);
-       if(datalayer)
-               return datalayer;
-
-       /* layers are store per face for editmesh, we convert to a temporary
-        * data layer array in the derivedmesh when these are requested */
-       if(type == CD_MTFACE || type == CD_MCOL) {
-               index = CustomData_get_layer_index(&em->fdata, type);
-
-               if(index != -1) {
-                       offset = em->fdata.layers[index].offset;
-                       size = CustomData_sizeof(type);
-
-                       DM_add_face_layer(dm, type, CD_CALLOC, NULL);
-                       index = CustomData_get_layer_index(&dm->faceData, type);
-                       dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
-
-                       data = datalayer = DM_get_face_data_layer(dm, type);
-                       for(efa=em->faces.first; efa; efa=efa->next, data+=size) {
-                               emdata = CustomData_em_get(&em->fdata, efa->data, type);
-                               memcpy(data, emdata, size);
-                       }
-               }
-       }
-
-       return datalayer;
-}
-
-static void emDM_release(DerivedMesh *dm)
-{
-       EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
-
-       if (DM_release(dm)) {
-               if (emdm->vertexCos) {
-                       MEM_freeN(emdm->vertexCos);
-                       MEM_freeN(emdm->vertexNos);
-                       MEM_freeN(emdm->faceNos);
-               }
-
-               MEM_freeN(emdm);
-       }
-}
-
-static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
-                                                                                  float (*vertexCos)[3])
-{
-       EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
-
-       DM_init(&emdm->dm, DM_TYPE_EDITMESH, BLI_countlist(&em->verts),
-                                        BLI_countlist(&em->edges), BLI_countlist(&em->faces));
-
-       emdm->dm.getMinMax = emDM_getMinMax;
-
-       emdm->dm.getNumVerts = emDM_getNumVerts;
-       emdm->dm.getNumEdges = emDM_getNumEdges;
-       emdm->dm.getNumFaces = emDM_getNumFaces;
-
-       emdm->dm.getVertCos = emDM_getVertCos;
-
-       emdm->dm.getVert = emDM_getVert;
-       emdm->dm.getEdge = emDM_getEdge;
-       emdm->dm.getFace = emDM_getFace;
-       emdm->dm.copyVertArray = emDM_copyVertArray;
-       emdm->dm.copyEdgeArray = emDM_copyEdgeArray;
-       emdm->dm.copyFaceArray = emDM_copyFaceArray;
-       emdm->dm.getFaceDataArray = emDM_getFaceDataArray;
-
-       emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
-       emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
-       emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
-
-       emdm->dm.drawEdges = emDM_drawEdges;
-       emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
-       emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
-       emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
-       emdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
-       emdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
-       emdm->dm.drawFacesTex = emDM_drawFacesTex;
-       emdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
-       emdm->dm.drawUVEdges = emDM_drawUVEdges;
-
-       emdm->dm.release = emDM_release;
-       
-       emdm->em = em;
-       emdm->vertexCos = vertexCos;
-
-       if(CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
-               EditVert *eve;
-               int i;
-
-               DM_add_vert_layer(&emdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
-
-               for(eve = em->verts.first, i = 0; eve; eve = eve->next, ++i)
-                       DM_set_vert_data(&emdm->dm, i, CD_MDEFORMVERT,
-                                                        CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT));
-       }
-
-       if(vertexCos) {
-               EditVert *eve;
-               EditFace *efa;
-               int totface = BLI_countlist(&em->faces);
-               int i;
-
-               for (i=0,eve=em->verts.first; eve; eve= eve->next)
-                       eve->tmp.l = (intptr_t) i++;
-
-               emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
-               emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
-
-               for(i=0, efa= em->faces.first; efa; i++, efa=efa->next) {
-                       float *v1 = vertexCos[(int) efa->v1->tmp.l];
-                       float *v2 = vertexCos[(int) efa->v2->tmp.l];
-                       float *v3 = vertexCos[(int) efa->v3->tmp.l];
-                       float *no = emdm->faceNos[i];
-                       
-                       if(efa->v4) {
-                               float *v4 = vertexCos[(int) efa->v4->tmp.l];
-
-                               normal_quad_v3( no,v1, v2, v3, v4);
-                               add_v3_v3(emdm->vertexNos[(int) efa->v4->tmp.l], no);
-                       }
-                       else {
-                               normal_tri_v3( no,v1, v2, v3);
-                       }
-
-                       add_v3_v3(emdm->vertexNos[(int) efa->v1->tmp.l], no);
-                       add_v3_v3(emdm->vertexNos[(int) efa->v2->tmp.l], no);
-                       add_v3_v3(emdm->vertexNos[(int) efa->v3->tmp.l], no);
-               }
-
-               for(i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
-                       float *no = emdm->vertexNos[i];
-                       /* following Mesh convention; we use vertex coordinate itself
-                        * for normal in this case */
-                       if (normalize_v3(no)==0.0) {
-                               normalize_v3_v3(no, vertexCos[i]);
-                       }
-               }
-       }
-
-       return (DerivedMesh*) emdm;
-}
-
 /***/
 
 DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, ModifierData *md)
@@ -1446,30 +683,29 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob, Modifier
        return dm;
 }
 
-static float *get_editmesh_orco_verts(EditMesh *em)
+static float *get_editbmesh_orco_verts(BMEditMesh *em)
 {
-       EditVert *eve;
+       BMIter iter;
+       BMVert *eve;
        float *orco;
        int a, totvert;
 
        /* these may not really be the orco's, but it's only for preview.
         * could be solver better once, but isn't simple */
 
-       totvert= 0;
-       for(eve=em->verts.first; eve; eve=eve->next)
-               totvert++;
+       totvert= em->bm->totvert;
        
        orco = MEM_mallocN(sizeof(float)*3*totvert, "EditMesh Orco");
 
-       for(a=0, eve=em->verts.first; eve; eve=eve->next, a+=3)
+       eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
+       for (a=0; eve; eve=BMIter_Step(&iter), a+=3)
                VECCOPY(orco+a, eve->co);
        
        return orco;
 }
 
 /* orco custom data layer */
-
-static void *get_orco_coords_dm(Object *ob, EditMesh *em, int layer, int *free)
+static void *get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free)
 {
        *free= 0;
 
@@ -1478,7 +714,7 @@ static void *get_orco_coords_dm(Object *ob, EditMesh *em, int layer, int *free)
                *free= 1;
 
                if(em)
-                       return (float(*)[3])get_editmesh_orco_verts(em);
+                       return (float(*)[3])get_editbmesh_orco_verts(em);
                else
                        return (float(*)[3])get_mesh_orco_verts(ob);
        }
@@ -1499,13 +735,13 @@ static void *get_orco_coords_dm(Object *ob, EditMesh *em, int layer, int *free)
        return NULL;
 }
 
-static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em, int layer)
+static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, BMEditMesh *em, int layer)
 {
        DerivedMesh *dm;
        float (*orco)[3];
        int free;
 
-       if(em) dm= CDDM_from_editmesh(em, me);
+       if(em) dm= CDDM_from_BMEditMesh(em, me);
        else dm= CDDM_from_mesh(me, ob);
 
        orco= get_orco_coords_dm(ob, em, layer, &free);
@@ -1520,7 +756,8 @@ static DerivedMesh *create_orco_dm(Object *ob, Mesh *me, EditMesh *em, int layer
        return dm;
 }
 
-static void add_orco_dm(Object *ob, EditMesh *em, DerivedMesh *dm, DerivedMesh *orcodm, int layer)
+static void add_orco_dm(Object *ob, BMEditMesh *em, DerivedMesh *dm,
+                                               DerivedMesh *orcodm, int layer)
 {
        float (*orco)[3], (*layerorco)[3];
        int totvert, free;
@@ -1624,15 +861,21 @@ void vDM_ColorBand_store(ColorBand *coba)
 static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm)
 {
        Mesh *me = ob->data;
-       MFace *mf = me->mface;
+       MFace *mf = dm->getTessFaceArray(dm);
+       DMFaceIter *dfiter;
+       DMLoopIter *dliter;
        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, totface=dm->getNumTessFaces(dm), totpoly=dm->getNumFaces, totloop;
+       int *origIndex = dm->getVertDataArray(dm, CD_ORIGINDEX);
        
-       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++) {
                calc_weightpaint_vert_color(ob, coba, mf->v1, &wtcol[(i*4 + 0)*4]); 
                calc_weightpaint_vert_color(ob, coba, mf->v2, &wtcol[(i*4 + 1)*4]); 
                calc_weightpaint_vert_color(ob, coba, mf->v3, &wtcol[(i*4 + 2)*4]); 
@@ -1640,7 +883,23 @@ static void add_weight_mcol_dm(Object *ob, DerivedMesh *dm)
                        calc_weightpaint_vert_color(ob, coba, mf->v4, &wtcol[(i*4 + 3)*4]); 
        }
        
-       CustomData_add_layer(&dm->faceData, CD_WEIGHT_MCOL, CD_ASSIGN, wtcol, dm->numFaceData);
+       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;
+       dfiter = dm->newFaceIter(dm);
+       for (; !dfiter->done; dfiter->step(dfiter)) {
+               dliter = dfiter->getLoopsIter(dfiter);
+               for (; !dliter->done; dliter->step(dliter), totloop++) {
+                       BLI_array_growone(wlcol);
+                       calc_weightpaint_vert_color(ob, coba, dliter->vindex, (unsigned
+char *)&wlcol[totloop]);                        
+               }
+       }
+
+       CustomData_add_layer(&dm->loopData, CD_WEIGHT_MLOOPCOL, CD_ASSIGN, wlcol, totloop);
+
+       dfiter->free(dfiter);
 }
 
 /* new value for useDeform -1  (hack for the gameengine):
@@ -1785,7 +1044,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                        /* apply vertex coordinates or build a DerivedMesh as necessary */
                        if(dm) {
                                if(deformedVerts) {
-                                       DerivedMesh *tdm = CDDM_copy(dm);
+                                       DerivedMesh *tdm = CDDM_copy(dm, 0);
                                        dm->release(dm);
                                        dm = tdm;
 
@@ -1837,7 +1096,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                        /* add an origspace layer if needed */
                        if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE)
                                if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
-                                       DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
+                                       DM_add_tessface_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
 
                        ndm = mti->applyModifier(md, ob, dm, useRenderParams, useCache);
 
@@ -1901,7 +1160,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
         * DerivedMesh then we need to build one.
         */
        if(dm && deformedVerts) {
-               finaldm = CDDM_copy(dm);
+               finaldm = CDDM_copy(dm, 0);
 
                dm->release(dm);
 
@@ -1945,21 +1204,24 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
        BLI_linklist_free(datamasks, NULL);
 }
 
-static float (*editmesh_getVertexCos(EditMesh *em, int *numVerts_r))[3]
+static float (*editbmesh_getVertexCos(BMEditMesh *em, int *numVerts_r))[3]
 {
-       int i, numVerts = *numVerts_r = BLI_countlist(&em->verts);
+       int i, numVerts = *numVerts_r = em->bm->totvert;
        float (*cos)[3];
-       EditVert *eve;
+       BMIter iter;
+       BMVert *eve;
 
        cos = MEM_mallocN(sizeof(*cos)*numVerts, "vertexcos");
-       for (i=0,eve=em->verts.first; i<numVerts; i++,eve=eve->next) {
+
+       eve = BMIter_New(&iter, em->bm, BM_VERTS_OF_MESH, NULL);
+       for (i=0; eve; eve=BMIter_Step(&iter), i++) {
                VECCOPY(cos[i], eve->co);
        }
 
        return cos;
 }
 
-static int editmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *dm)
+static int editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *dm)
 {
        ModifierTypeInfo *mti = modifierType_getInfo(md->type);
        int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
@@ -1973,7 +1235,7 @@ static int editmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedM
        return 1;
 }
 
-static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, DerivedMesh **cage_r,
+static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, DerivedMesh **cage_r,
                                                                        DerivedMesh **final_r,
                                                                        CustomDataMask dataMask)
 {
@@ -1988,7 +1250,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
        modifiers_clearErrors(ob);
 
        if(cage_r && cageIndex == -1) {
-               *cage_r = getEditMeshDerivedMesh(em, ob, NULL);
+               *cage_r = getEditDerivedBMesh(em, ob, NULL);
        }
 
        dm = NULL;
@@ -2005,7 +1267,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
 
                md->scene= scene;
                
-               if(!editmesh_modifier_is_enabled(scene, md, dm))
+               if(!editbmesh_modifier_is_enabled(scene, md, dm))
                        continue;
 
                /* add an orco layer if needed by this modifier */
@@ -2033,7 +1295,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
                                                MEM_mallocN(sizeof(*deformedVerts) * numVerts, "dfmv");
                                        dm->getVertCos(dm, deformedVerts);
                                } else {
-                                       deformedVerts = editmesh_getVertexCos(em, &numVerts);
+                                       deformedVerts = editbmesh_getVertexCos(em, &numVerts);
                                }
                        }
 
@@ -2046,7 +1308,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
                        /* apply vertex coordinates or build a DerivedMesh as necessary */
                        if(dm) {
                                if(deformedVerts) {
-                                       DerivedMesh *tdm = CDDM_copy(dm);
+                                       DerivedMesh *tdm = CDDM_copy(dm, 0);
                                        if(!(cage_r && dm == *cage_r)) dm->release(dm);
                                        dm = tdm;
 
@@ -2055,11 +1317,11 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
                                } else if(cage_r && dm == *cage_r) {
                                        /* dm may be changed by this modifier, so we need to copy it
                                         */
-                                       dm = CDDM_copy(dm);
+                                       dm = CDDM_copy(dm, 0);
                                }
 
                        } else {
-                               dm = CDDM_from_editmesh(em, ob->data);
+                               dm = CDDM_from_BMEditMesh(em, ob->data);
 
                                if(deformedVerts) {
                                        CDDM_apply_vert_coords(dm, deformedVerts);
@@ -2093,7 +1355,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
 
                        if(((CustomDataMask)GET_INT_FROM_POINTER(curr->link)) & CD_MASK_ORIGSPACE)
                                if(!CustomData_has_layer(&dm->faceData, CD_ORIGSPACE))
-                                       DM_add_face_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
+                                       DM_add_tessface_layer(dm, CD_ORIGSPACE, CD_DEFAULT, NULL);
                        
                        if (mti->applyModifierEM)
                                ndm = mti->applyModifierEM(md, ob, em, dm);
@@ -2115,13 +1377,13 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
 
                if(cage_r && i == cageIndex) {
                        if(dm && deformedVerts) {
-                               *cage_r = CDDM_copy(dm);
+                               *cage_r = CDDM_copy(dm, 0);
                                CDDM_apply_vert_coords(*cage_r, deformedVerts);
                        } else if(dm) {
                                *cage_r = dm;
                        } else {
                                *cage_r =
-                                       getEditMeshDerivedMesh(em, ob,
+                                       getEditDerivedBMesh(em, ob,
                                                deformedVerts ? MEM_dupallocN(deformedVerts) : NULL);
                        }
                }
@@ -2134,7 +1396,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
         * then we need to build one.
         */
        if(dm && deformedVerts) {
-               *final_r = CDDM_copy(dm);
+               *final_r = CDDM_copy(dm, 0);
 
                if(!(cage_r && dm == *cage_r)) dm->release(dm);
 
@@ -2145,7 +1407,7 @@ static void editmesh_calc_modifiers(Scene *scene, Object *ob, EditMesh *em, Deri
        } else if (!deformedVerts && cage_r && *cage_r) {
                *final_r = *cage_r;
        } else {
-               *final_r = getEditMeshDerivedMesh(em, ob, deformedVerts);
+               *final_r = getEditDerivedBMesh(em, ob, deformedVerts);
                deformedVerts = NULL;
        }
 
@@ -2217,7 +1479,7 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask)
        ob->lastDataMask = dataMask;
 }
 
-static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask)
+static void editbmesh_build_data(Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask)
 {
        clear_mesh_caches(obedit);
 
@@ -2234,7 +1496,7 @@ static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, Cust
                em->derivedCage = NULL;
        }
 
-       editmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask);
+       editbmesh_calc_modifiers(scene, obedit, em, &em->derivedCage, &em->derivedFinal, dataMask);
        DM_set_object_boundbox (obedit, em->derivedFinal);
 
        em->lastDataMask = dataMask;
@@ -2242,10 +1504,10 @@ static void editmesh_build_data(Scene *scene, Object *obedit, EditMesh *em, Cust
        em->derivedCage->needsFree = 0;
 }
 
-void makeDerivedMesh(Scene *scene, Object *ob, EditMesh *em, CustomDataMask dataMask)
+void makeDerivedMesh(Scene *scene, Object *ob, BMEditMesh *em, CustomDataMask dataMask)
 {
        if (em) {
-               editmesh_build_data(scene, ob, em, dataMask);
+               editbmesh_build_data(scene, ob, em, dataMask);
        } else {
                mesh_build_data(scene, ob, dataMask);
        }
@@ -2335,7 +1597,7 @@ DerivedMesh *mesh_create_derived_no_deform_render(Scene *scene, Object *ob,
 
 /***/
 
-DerivedMesh *editmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, EditMesh *em, DerivedMesh **final_r,
+DerivedMesh *editbmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, BMEditMesh *em, DerivedMesh **final_r,
                                                                                                 CustomDataMask dataMask)
 {
        /* if there's no derived mesh or the last data mask used doesn't include
@@ -2343,27 +1605,27 @@ DerivedMesh *editmesh_get_derived_cage_and_final(Scene *scene, Object *obedit, E
         */
        if(!em->derivedCage ||
           (em->lastDataMask & dataMask) != dataMask)
-               editmesh_build_data(scene, obedit, em, dataMask);
+               editbmesh_build_data(scene, obedit, em, dataMask);
 
        *final_r = em->derivedFinal;
        return em->derivedCage;
 }
 
-DerivedMesh *editmesh_get_derived_cage(Scene *scene, Object *obedit, EditMesh *em, CustomDataMask dataMask)
+DerivedMesh *editbmesh_get_derived_cage(Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask)
 {
        /* if there's no derived mesh or the last data mask used doesn't include
         * the data we need, rebuild the derived mesh
         */
        if(!em->derivedCage ||
           (em->lastDataMask & dataMask) != dataMask)
-               editmesh_build_data(scene, obedit, em, dataMask);
+               editbmesh_build_data(scene, obedit, em, dataMask);
 
        return em->derivedCage;
 }
 
-DerivedMesh *editmesh_get_derived_base(Object *obedit, EditMesh *em)
+DerivedMesh *editbmesh_get_derived_base(Object *obedit, BMEditMesh *em)
 {
-       return getEditMeshDerivedMesh(em, obedit, NULL);
+       return getEditDerivedBMesh(em, obedit, NULL);
 }
 
 
@@ -2425,7 +1687,7 @@ float *mesh_get_mapped_verts_nors(Scene *scene, Object *ob)
 
 /* ********* crazyspace *************** */
 
-int editmesh_get_first_deform_matrices(Scene *scene, Object *ob, EditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3])
+int editbmesh_get_first_deform_matrices(Scene *scene, Object *ob, BMEditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3])
 {
        ModifierData *md;
        DerivedMesh *dm;
@@ -2444,13 +1706,13 @@ int editmesh_get_first_deform_matrices(Scene *scene, Object *ob, EditMesh *em, f
        for(i = 0; md && i <= cageIndex; i++, md = md->next) {
                ModifierTypeInfo *mti = modifierType_getInfo(md->type);
 
-               if(!editmesh_modifier_is_enabled(scene, md, dm))
+               if(!editbmesh_modifier_is_enabled(scene, md, dm))
                        continue;
 
                if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) {
                        if(!defmats) {
-                               dm= getEditMeshDerivedMesh(em, ob, NULL);
-                               deformedVerts= editmesh_getVertexCos(em, &numVerts);
+                               dm= getEditDerivedBMesh(em, ob, NULL);
+                               deformedVerts= editbmesh_getVertexCos(em, &numVerts);
                                defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats");
 
                                for(a=0; a<numVerts; a++)
@@ -2465,7 +1727,7 @@ int editmesh_get_first_deform_matrices(Scene *scene, Object *ob, EditMesh *em, f
        }
 
        for(; md && i <= cageIndex; md = md->next, i++)
-               if(editmesh_modifier_is_enabled(scene, md, dm) && modifier_isCorrectableDeformed(md))
+               if(editbmesh_modifier_is_enabled(scene, md, dm) && modifier_isCorrectableDeformed(md))
                        numleft++;
 
        if(dm)
@@ -2497,11 +1759,11 @@ void DM_add_tangent_layer(DerivedMesh *dm)
 
        /* check we have all the needed layers */
        totvert= dm->getNumVerts(dm);
-       totface= dm->getNumFaces(dm);
+       totface= dm->getNumTessFaces(dm);
 
        mvert= dm->getVertArray(dm);
-       mface= dm->getFaceArray(dm);
-       mtface= dm->getFaceDataArray(dm, CD_MTFACE);
+       mface= dm->getTessFaceArray(dm);
+       mtface= dm->getTessFaceDataArray(dm, CD_MTFACE);
 
        if(!mtface) {
                orco= dm->getVertDataArray(dm, CD_ORCO);
@@ -2510,8 +1772,8 @@ void DM_add_tangent_layer(DerivedMesh *dm)
        }
        
        /* create tangent layer */
-       DM_add_face_layer(dm, CD_TANGENT, CD_CALLOC, NULL);
-       tangent= DM_get_face_data_layer(dm, CD_TANGENT);
+       DM_add_tessface_layer(dm, CD_TANGENT, CD_CALLOC, NULL);
+       tangent= DM_get_tessface_data_layer(dm, CD_TANGENT);
        
        /* allocate some space */
        arena= BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, "tangent layer arena");
@@ -2608,15 +1870,8 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
        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->release == emDM_release)
-               tfdata = &((EditMeshDerivedMesh*)dm)->em->fdata;
-       else
-               tfdata = fdata;
-
+       fdata = tfdata = dm->getTessFaceDataLayout(dm);
+       
        /* add a tangent layer if necessary */
        for(b = 0; b < gattribs->totlayer; b++)
                if(gattribs->layer[b].type == CD_TANGENT)