dont use tface hide or select anymore, since maintaining 2 sets of hide/select data...
[blender.git] / source / blender / blenkernel / intern / DerivedMesh.c
index db03a9581ac4c85df3db9b61bb42e868a379484f..fa8f76178d590d53a7e9a0a358edf00ffd2d7858 100644 (file)
 #include "DNA_object_force.h"
 #include "DNA_object_fluidsim.h" // N_T
 #include "DNA_scene_types.h" // N_T
+#include "DNA_view3d_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
 
 #include "BLI_arithb.h"
 #include "BLI_blenlib.h"
 #include "BLI_edgehash.h"
 #include "BLI_editVert.h"
+#include "BLI_linklist.h"
 
 #include "BKE_utildefines.h"
 #include "BKE_cdderivedmesh.h"
@@ -94,8 +98,9 @@ MVert *dm_getVertArray(DerivedMesh *dm)
        MVert *mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
 
        if (!mvert) {
-               mvert = CustomData_add_layer(&dm->vertData, CD_MVERT,
-                       CD_FLAG_TEMPORARY, NULL, dm->getNumVerts(dm));
+               mvert = CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL,
+                       dm->getNumVerts(dm));
+               CustomData_set_layer_flag(&dm->vertData, CD_MVERT, CD_FLAG_TEMPORARY);
                dm->copyVertArray(dm, mvert);
        }
 
@@ -107,8 +112,9 @@ MEdge *dm_getEdgeArray(DerivedMesh *dm)
        MEdge *medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
 
        if (!medge) {
-               medge = CustomData_add_layer(&dm->edgeData, CD_MEDGE,
-                       CD_FLAG_TEMPORARY, NULL, dm->getNumEdges(dm));
+               medge = CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL,
+                       dm->getNumEdges(dm));
+               CustomData_set_layer_flag(&dm->edgeData, CD_MEDGE, CD_FLAG_TEMPORARY);
                dm->copyEdgeArray(dm, medge);
        }
 
@@ -120,8 +126,9 @@ MFace *dm_getFaceArray(DerivedMesh *dm)
        MFace *mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
 
        if (!mface) {
-               mface = CustomData_add_layer(&dm->faceData, CD_MFACE,
-                       CD_FLAG_TEMPORARY, NULL, dm->getNumFaces(dm));
+               mface = CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL,
+                       dm->getNumFaces(dm));
+               CustomData_set_layer_flag(&dm->faceData, CD_MFACE, CD_FLAG_TEMPORARY);
                dm->copyFaceArray(dm, mface);
        }
 
@@ -179,9 +186,9 @@ void DM_init_funcs(DerivedMesh *dm)
 void DM_init(DerivedMesh *dm,
              int numVerts, int numEdges, int numFaces)
 {
-       CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, 0, NULL, numVerts);
-       CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, 0, NULL, numEdges);
-       CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, 0, NULL, numFaces);
+       CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
+       CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
+       CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
 
        dm->numVertData = numVerts;
        dm->numEdgeData = numEdges;
@@ -250,11 +257,11 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me)
        /* not all DerivedMeshes store their verts/edges/faces in CustomData, so
           we set them here in case they are missing */
        if(!CustomData_has_layer(&tmp.vdata, CD_MVERT))
-               CustomData_add_layer(&tmp.vdata, CD_MVERT, 0, dm->dupVertArray(dm), totvert);
+               CustomData_add_layer(&tmp.vdata, CD_MVERT, CD_ASSIGN, dm->dupVertArray(dm), totvert);
        if(!CustomData_has_layer(&tmp.edata, CD_MEDGE))
-               CustomData_add_layer(&tmp.edata, CD_MEDGE, 0, dm->dupEdgeArray(dm), totedge);
+               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, 0, dm->dupFaceArray(dm), totface);
+               CustomData_add_layer(&tmp.fdata, CD_MFACE, CD_ASSIGN, dm->dupFaceArray(dm), totface);
 
        mesh_update_customdata_pointers(&tmp);
 
@@ -271,19 +278,26 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me)
        *me = tmp;
 }
 
-void DM_add_vert_layer(DerivedMesh *dm, int type, int flag, void *layer)
+void DM_set_only_copy(DerivedMesh *dm, CustomDataMask mask)
 {
-       CustomData_add_layer(&dm->vertData, type, flag, layer, dm->numVertData);
+       CustomData_set_only_copy(&dm->vertData, mask);
+       CustomData_set_only_copy(&dm->edgeData, mask);
+       CustomData_set_only_copy(&dm->faceData, mask);
 }
 
-void DM_add_edge_layer(DerivedMesh *dm, int type, int flag, void *layer)
+void DM_add_vert_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
 {
-       CustomData_add_layer(&dm->edgeData, type, flag, layer, dm->numEdgeData);
+       CustomData_add_layer(&dm->vertData, type, alloctype, layer, dm->numVertData);
 }
 
-void DM_add_face_layer(DerivedMesh *dm, int type, int flag, void *layer)
+void DM_add_edge_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
 {
-       CustomData_add_layer(&dm->faceData, type, flag, layer, dm->numFaceData);
+       CustomData_add_layer(&dm->edgeData, type, alloctype, layer, dm->numEdgeData);
+}
+
+void DM_add_face_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
+{
+       CustomData_add_layer(&dm->faceData, type, alloctype, layer, dm->numFaceData);
 }
 
 void *DM_get_vert_data(DerivedMesh *dm, int index, int type)
@@ -558,7 +572,7 @@ static void emDM_drawUVEdges(DerivedMesh *dm)
        for(efa= emdm->em->faces.first; efa; efa= efa->next) {
                tf = CustomData_em_get(&emdm->em->fdata, efa->data, CD_MTFACE);
 
-               if(tf && !(tf->flag&TF_HIDE)) {
+               if(tf && !(efa->h)) {
                        glVertex2fv(tf->uv[0]);
                        glVertex2fv(tf->uv[1]);
 
@@ -872,7 +886,7 @@ void emDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
 
        /* store vertexes indices in tmp union */
        for(ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
-               ev->tmp.l = (long) i++;
+               ev->tmp.l = (long) i;
 
        for( ; ef; ef = ef->next, ++face_r) {
                face_r->mat_nr = ef->mat_nr;
@@ -943,7 +957,7 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
                EditVert *eve;
                int i;
 
-               DM_add_vert_layer(&emdm->dm, CD_MDEFORMVERT, 0, NULL);
+               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,
@@ -987,9 +1001,9 @@ static DerivedMesh *getEditMeshDerivedMesh(EditMesh *em, Object *ob,
                        float *no = emdm->vertexNos[i];
                        /* following Mesh convention; we use vertex coordinate itself
                         * for normal in this case */
-                       if (Normalise(no)==0.0) {
+                       if (Normalize(no)==0.0) {
                                VECCOPY(no, vertexCos[i]);
-                               Normalise(no);
+                               Normalize(no);
                        }
                }
        }
@@ -1005,7 +1019,8 @@ typedef struct {
        struct VNode *vnode;
        struct VLayer *vertex_layer;
        struct VLayer *polygon_layer;
-       float (*verts)[3];
+       struct ListBase *edges;
+       float (*vertexCos)[3];
 } VDerivedMesh;
 
 /* this function set up border points of verse mesh bounding box */
@@ -1020,7 +1035,7 @@ static void vDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
 
        if(vdm->vertex_layer->dl.da.count > 0) {
                while(vvert) {
-                       DO_MINMAX(vdm->verts ? vvert->cos : vvert->co, min_r, max_r);
+                       DO_MINMAX(vdm->vertexCos ? vvert->cos : vvert->co, min_r, max_r);
                        vvert = vvert->next;
                }
        }
@@ -1041,7 +1056,9 @@ static int vDM_getNumVerts(DerivedMesh *dm)
 /* this function return number of 'fake' edges */
 static int vDM_getNumEdges(DerivedMesh *dm)
 {
-       return 0;
+       VDerivedMesh *vdm = (VDerivedMesh*)dm;
+
+       return BLI_countlist(vdm->edges);
 }
 
 /* this function returns number of polygons in polygon layer */
@@ -1057,10 +1074,13 @@ static int vDM_getNumFaces(DerivedMesh *dm)
  * but it return 'indexth' vertex of dynamic list */
 void vDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
 {
-       VerseVert *vvert = ((VDerivedMesh*)dm)->vertex_layer->dl.lb.first;
+       VDerivedMesh *vdm = (VDerivedMesh*)dm;
+       struct VerseVert *vvert;
        int i;
 
-       for(i=0 ; i<index; i++) vvert = vvert->next;
+       if(!vdm->vertex_layer) return;
+
+       for(vvert = vdm->vertex_layer->dl.lb.first, i=0 ; i<index; i++) vvert = vvert->next;
 
        if(vvert) {
                VECCOPY(vert_r->co, vvert->co);
@@ -1075,25 +1095,59 @@ void vDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
        }
 }
 
-/* dummy function, because verse mesh doesn't store edges */
+/* this function returns fake verse edge */
 void vDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
 {
-       edge_r->flag = 0;
-       edge_r->crease = 0;
-       edge_r->v1 = 0;
-       edge_r->v2 = 0;
+       VDerivedMesh *vdm = (VDerivedMesh*)dm;
+       struct VerseEdge *vedge;
+       struct VLayer *vert_vlayer = vdm->vertex_layer;
+       struct VerseVert *vvert;
+       int j;
+
+       if(!vdm->vertex_layer || !vdm->edges) return;
+
+       if(vdm->edges->first) {
+               struct VerseVert *vvert1, *vvert2;
+
+               /* store vert indices in tmp union */
+               for(vvert = vdm->vertex_layer->dl.lb.first, j = 0; vvert; vvert = vvert->next, j++)
+                       vvert->tmp.index = j;
+
+               for(vedge = vdm->edges->first; vedge; vedge = vedge->next) {
+                       if(vedge->tmp.index==index) {
+                               vvert1 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v0);
+                               vvert2 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v1);
+                               
+                               if(vvert1 && vvert2) {
+                                       edge_r->v1 = vvert1->tmp.index;
+                                       edge_r->v2 = vvert2->tmp.index;
+                               }
+                               else {
+                                       edge_r->v1 = 0;
+                                       edge_r->v2 = 0;
+                               }
+                               /* not supported yet */
+                               edge_r->flag = 0;
+                               edge_r->crease = 0;
+                               break;
+                       }
+               }
+       }
 }
 
 /* this function doesn't return face with index of access array,
  * but it returns 'indexth' vertex of dynamic list */
 void vDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
 {
-       struct VerseFace *vface = ((VDerivedMesh*)dm)->polygon_layer->dl.lb.first;
-       struct VerseVert *vvert = ((VDerivedMesh*)dm)->vertex_layer->dl.lb.first;
+       VDerivedMesh *vdm = (VDerivedMesh*)dm;
+       struct VerseFace *vface;
+       struct VerseVert *vvert;
        struct VerseVert *vvert0, *vvert1, *vvert2, *vvert3;
        int i;
 
-       for(i = 0; i < index; ++i) vface = vface->next;
+       if(!vdm->vertex_layer || !vdm->polygon_layer) return;
+
+       for(vface = vdm->polygon_layer->dl.lb.first, i = 0; i < index; ++i) vface = vface->next;
 
        face_r->mat_nr = 0;
        face_r->flag = 0;
@@ -1105,7 +1159,7 @@ void vDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
        vvert3 = vface->vvert3;
        if(!vvert3) face_r->v4 = 0;
 
-       for(i = 0; vvert0 || vvert1 || vvert2 || vvert3; i++, vvert = vvert->next) {
+       for(vvert = vdm->vertex_layer->dl.lb.first, i = 0; vvert0 || vvert1 || vvert2 || vvert3; i++, vvert = vvert->next) {
                if(vvert == vvert0) {
                        face_r->v1 = i;
                        vvert0 = NULL;
@@ -1130,9 +1184,12 @@ void vDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
 /* fill array of mvert */
 void vDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
 {
-       VerseVert *vvert = ((VDerivedMesh *)dm)->vertex_layer->dl.lb.first;
+       VDerivedMesh *vdm = (VDerivedMesh*)dm;
+       struct VerseVert *vvert;
+
+       if(!vdm->vertex_layer) return;
 
-       for( ; vvert; vvert = vvert->next, ++vert_r) {
+       for(vvert = vdm->vertex_layer->dl.lb.first ; vvert; vvert = vvert->next, ++vert_r) {
                VECCOPY(vert_r->co, vvert->co);
 
                vert_r->no[0] = vvert->no[0] * 32767.0;
@@ -1147,20 +1204,56 @@ void vDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
 /* dummy function, edges arent supported in verse mesh */
 void vDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
 {
+       VDerivedMesh *vdm = (VDerivedMesh*)dm;
+
+       if(!vdm->vertex_layer || !vdm->edges) return;
+
+       if(vdm->edges->first) {
+               struct VerseEdge *vedge;
+               struct VLayer *vert_vlayer = vdm->vertex_layer;
+               struct VerseVert *vvert, *vvert1, *vvert2;
+               int j;
+
+               /* store vert indices in tmp union */
+               for(vvert = vdm->vertex_layer->dl.lb.first, j = 0; vvert; vvert = vvert->next, ++j)
+                       vvert->tmp.index = j;
+
+               for(vedge = vdm->edges->first, j=0 ; vedge; vedge = vedge->next, ++edge_r, j++) {
+                       /* create temporary edge index */
+                       vedge->tmp.index = j;
+                       vvert1 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v0);
+                       vvert2 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v1);
+                       if(vvert1 && vvert2) {
+                               edge_r->v1 = vvert1->tmp.index;
+                               edge_r->v2 = vvert2->tmp.index;
+                       }
+                       else {
+                               printf("error: vDM_copyEdgeArray: %d, %d\n", vedge->v0, vedge->v1);
+                               edge_r->v1 = 0;
+                               edge_r->v2 = 0;
+                       }
+                       /* not supported yet */
+                       edge_r->flag = 0;
+                       edge_r->crease = 0;
+               }
+       }
 }
 
 /* fill array of mfaces */
 void vDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
 {
-       VerseFace *vface = ((VDerivedMesh*)dm)->polygon_layer->dl.lb.first;
-       VerseVert *vvert = ((VDerivedMesh*)dm)->vertex_layer->dl.lb.first;
+       VDerivedMesh *vdm = (VDerivedMesh*)dm;
+       struct VerseFace *vface;
+       struct VerseVert *vvert;
        int i;
-
+       
+       if(!vdm->vertex_layer || !vdm->polygon_layer) return;
+       
        /* store vertexes indices in tmp union */
-       for(i = 0; vvert; vvert = vvert->next, ++i)
+       for(vvert = vdm->vertex_layer->dl.lb.first, i = 0; vvert; vvert = vvert->next, ++i)
                vvert->tmp.index = i;
 
-       for( ; vface; vface = vface->next, ++face_r) {
+       for(vface = vdm->polygon_layer->dl.lb.first; vface; vface = vface->next, ++face_r) {
                face_r->mat_nr = 0;
                face_r->flag = 0;
 
@@ -1174,8 +1267,7 @@ void vDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
        }
 }
 
-/* return coordination of vertex with index ... I suppose, that it will
- * be very hard to do, becuase there can be holes in access array */
+/* return coordination of vertex with index */
 static void vDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
 {
        VDerivedMesh *vdm = (VDerivedMesh*)dm;
@@ -1184,8 +1276,9 @@ static void vDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
        if(!vdm->vertex_layer) return;
 
        vvert = BLI_dlist_find_link(&(vdm->vertex_layer->dl), index);
+       
        if(vvert) {
-               VECCOPY(co_r, vdm->verts ? vvert->cos : vvert->co);
+               VECCOPY(co_r, vdm->vertexCos ? vvert->cos : vvert->co);
        }
        else {
                co_r[0] = co_r[1] = co_r[2] = 0.0;
@@ -1203,14 +1296,13 @@ static void vDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
 
        vvert = vdm->vertex_layer->dl.lb.first;
        while(vvert) {
-               VECCOPY(cos_r[i], vdm->verts ? vvert->cos : vvert->co);
+               VECCOPY(cos_r[i], vdm->vertexCos ? vvert->cos : vvert->co);
                i++;
                vvert = vvert->next;
        }
 }
 
-/* return normal of vertex with index ... again, it will be hard to
- * implemente, because access array */
+/* return normal of vertex with index */
 static void vDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
 {
        VDerivedMesh *vdm = (VDerivedMesh*)dm;
@@ -1239,7 +1331,7 @@ static void vDM_drawVerts(DerivedMesh *dm)
 
        bglBegin(GL_POINTS);
        while(vvert) {
-               bglVertex3fv(vdm->verts ? vvert->cos : vvert->co);
+               bglVertex3fv(vdm->vertexCos ? vvert->cos : vvert->co);
                vvert = vvert->next;
        }
        bglEnd();
@@ -1251,21 +1343,22 @@ static void vDM_drawVerts(DerivedMesh *dm)
 static void vDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
 {
        VDerivedMesh *vdm = (VDerivedMesh*)dm;
-       struct VerseFace *vface;
-
-       if(!vdm->polygon_layer) return;
+       struct VerseEdge *vedge;
+       struct VLayer *vert_vlayer = vdm->vertex_layer;
 
-       vface = vdm->polygon_layer->dl.lb.first;
+       if(vert_vlayer && vdm->edges && (BLI_countlist(vdm->edges) > 0)) {
+               struct VerseVert *vvert1, *vvert2;
 
-       while(vface) {
-               glBegin(GL_LINE_LOOP);
-               glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
-               glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
-               glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
-               if(vface->vvert3) glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
+               glBegin(GL_LINES);
+               for(vedge = vdm->edges->first; vedge; vedge = vedge->next) {
+                       vvert1 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v0);
+                       vvert2 = BLI_dlist_find_link(&(vert_vlayer->dl), (unsigned int)vedge->v1);
+                       if(vvert1 && vvert2) {
+                               glVertex3fv(vdm->vertexCos ? vvert1->cos : vvert1->co);
+                               glVertex3fv(vdm->vertexCos ? vvert2->cos : vvert2->co);
+                       }
+               }
                glEnd();
-
-               vface = vface->next;
        }
 }
 
@@ -1289,40 +1382,21 @@ static void vDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int))
 
        vface = vdm->polygon_layer->dl.lb.first;
 
+       glShadeModel(GL_FLAT);
        while(vface) {
-/*             if((vface->smooth) && (vface->smooth->value)){
-                       glShadeModel(GL_SMOOTH);
-                       glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
-                       glNormal3fv(vface->vvert0->no);
-                       glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
-                       glNormal3fv(vface->vvert1->no);
-                       glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
-                       glNormal3fv(vface->vvert2->no);
-                       glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
-                       if(vface->vvert3){
-                               glNormal3fv(vface->vvert3->no);
-                               glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
-                       }
-                       glEnd();
-               }
-               else { */
-                       glShadeModel(GL_FLAT);
-                       glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
-                       glNormal3fv(vface->no);
-                       glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
-                       glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
-                       glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
-                       if(vface->vvert3)
-                               glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
-                       glEnd();
-/*             } */
-
+               glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
+               glNormal3fv(vface->no);
+               glVertex3fv(vdm->vertexCos ? vface->vvert0->cos : vface->vvert0->co);
+               glVertex3fv(vdm->vertexCos ? vface->vvert1->cos : vface->vvert1->co);
+               glVertex3fv(vdm->vertexCos ? vface->vvert2->cos : vface->vvert2->co);
+               if(vface->vvert3)
+                       glVertex3fv(vdm->vertexCos ? vface->vvert3->cos : vface->vvert3->co);
+               glEnd();
                vface = vface->next;
        }
-       glShadeModel(GL_FLAT);
 }
 
-/* thsi function should draw mesh with mapped texture, but it isn't supported yet */
+/* this function should draw mesh with mapped texture, but it isn't supported yet */
 static void vDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
 {
        VDerivedMesh *vdm = (VDerivedMesh*)dm;
@@ -1334,11 +1408,11 @@ static void vDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tfac
 
        while(vface) {
                glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
-               glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
-               glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
-               glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
+               glVertex3fv(vdm->vertexCos ? vface->vvert0->cos : vface->vvert0->co);
+               glVertex3fv(vdm->vertexCos ? vface->vvert1->cos : vface->vvert1->co);
+               glVertex3fv(vdm->vertexCos ? vface->vvert2->cos : vface->vvert2->co);
                if(vface->vvert3)
-                       glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
+                       glVertex3fv(vdm->vertexCos ? vface->vvert3->cos : vface->vvert3->co);
                glEnd();
 
                vface = vface->next;
@@ -1358,11 +1432,11 @@ static void vDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char
 
        while(vface) {
                glBegin(vface->vvert3?GL_QUADS:GL_TRIANGLES);
-               glVertex3fv(vdm->verts ? vface->vvert0->cos : vface->vvert0->co);
-               glVertex3fv(vdm->verts ? vface->vvert1->cos : vface->vvert1->co);
-               glVertex3fv(vdm->verts ? vface->vvert2->cos : vface->vvert2->co);
+               glVertex3fv(vdm->vertexCos ? vface->vvert0->cos : vface->vvert0->co);
+               glVertex3fv(vdm->vertexCos ? vface->vvert1->cos : vface->vvert1->co);
+               glVertex3fv(vdm->vertexCos ? vface->vvert2->cos : vface->vvert2->co);
                if(vface->vvert3)
-                       glVertex3fv(vdm->verts ? vface->vvert3->cos : vface->vvert3->co);
+                       glVertex3fv(vdm->vertexCos ? vface->vvert3->cos : vface->vvert3->co);
                glEnd();
 
                vface = vface->next;
@@ -1433,7 +1507,7 @@ static void vDM_release(DerivedMesh *dm)
        VDerivedMesh *vdm = (VDerivedMesh*)dm;
 
        if (DM_release(dm)) {
-               if(vdm->verts) MEM_freeN(vdm->verts);
+               if(vdm->vertexCos) MEM_freeN(vdm->vertexCos);
                MEM_freeN(vdm);
        }
 }
@@ -1448,9 +1522,11 @@ DerivedMesh *derivedmesh_from_versemesh(VNode *vnode, float (*vertexCos)[3])
        vdm->vnode = vnode;
        vdm->vertex_layer = find_verse_layer_type((VGeomData*)vnode->data, VERTEX_LAYER);
        vdm->polygon_layer = find_verse_layer_type((VGeomData*)vnode->data, POLYGON_LAYER);
+       vdm->edges = &((VGeomData*)vnode->data)->edges;
 
+       /* vertex and polygon layer has to exist */
        if(vdm->vertex_layer && vdm->polygon_layer)
-               DM_init(&vdm->dm, vdm->vertex_layer->dl.da.count, 0, vdm->polygon_layer->dl.da.count);
+               DM_init(&vdm->dm, vdm->vertex_layer->dl.da.count, BLI_countlist(vdm->edges), vdm->polygon_layer->dl.da.count);
        else
                DM_init(&vdm->dm, 0, 0, 0);
        
@@ -1492,28 +1568,7 @@ DerivedMesh *derivedmesh_from_versemesh(VNode *vnode, float (*vertexCos)[3])
 
        vdm->dm.release = vDM_release;
 
-       if(vdm->vertex_layer) {
-               if(vertexCos) {
-                       int i;
-
-                       vdm->verts = MEM_mallocN(sizeof(float)*3*vdm->vertex_layer->dl.da.count, "verse mod vertexes");
-                       vvert = vdm->vertex_layer->dl.lb.first;
-
-                       for(i=0; i<vdm->vertex_layer->dl.da.count && vvert; i++, vvert = vvert->next) {
-                               VECCOPY(vdm->verts[i], vertexCos[i]);
-                               vvert->cos = vdm->verts[i];
-                       }
-               }
-               else {
-                       vdm->verts = NULL;
-                       vvert = vdm->vertex_layer->dl.lb.first;
-
-                       while(vvert) {
-                               vvert->cos = NULL;
-                               vvert = vvert->next;
-                       }
-               }
-       }
+       vdm->vertexCos = vertexCos;
 
        return (DerivedMesh*) vdm;
 }
@@ -1554,13 +1609,45 @@ DerivedMesh *mesh_create_derived_for_modifier(Object *ob, ModifierData *md)
        return dm;
 }
 
+CustomDataMask get_viewedit_datamask()
+{
+       CustomDataMask mask = CD_MASK_BAREMESH;
+       ScrArea *sa;
+
+       /* check if we need tfaces & mcols due to face select or texture paint */
+       if(G.f & G_FACESELECT || G.f & G_TEXTUREPAINT) {
+               mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
+       } else {
+               /* check if we need tfaces & mcols due to view mode */
+               for(sa = G.curscreen->areabase.first; sa; sa = sa->next) {
+                       if(sa->spacetype == SPACE_VIEW3D) {
+                               View3D *view = sa->spacedata.first;
+                               if(view->drawtype == OB_SHADED) {
+                                       /* this includes normals for mesh_create_shadedColors */
+                                       mask |= CD_MASK_MTFACE | CD_MASK_MCOL | CD_MASK_NORMAL;
+                               }
+                               if(view->drawtype == OB_TEXTURE) {
+                                       mask |= CD_MASK_MTFACE | CD_MASK_MCOL;
+                               }
+                       }
+               }
+       }
+
+       /* check if we need mcols due to vertex paint or weightpaint */
+       if(G.f & G_VERTEXPAINT || G.f & G_WEIGHTPAINT)
+               mask |= CD_MASK_MCOL;
+
+       return mask;
+}
+
 static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
                                 DerivedMesh **deform_r, DerivedMesh **final_r,
                                 int useRenderParams, int useDeform,
-                                int needMapping)
+                                int needMapping, CustomDataMask dataMask)
 {
        Mesh *me = ob->data;
        ModifierData *md = modifiers_getVirtualModifierList(ob);
+       LinkNode *datamasks, *curr;
        float (*deformedVerts)[3] = NULL;
        DerivedMesh *dm;
        int numVerts = me->totvert;
@@ -1569,6 +1656,12 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
 
        modifiers_clearErrors(ob);
 
+       /* we always want to keep original indices */
+       dataMask |= CD_MASK_ORIGINDEX;
+
+       datamasks = modifiers_calcDataMasks(md, dataMask);
+       curr = datamasks;
+
        if(deform_r) *deform_r = NULL;
        *final_r = NULL;
 
@@ -1596,7 +1689,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
                        deformedVerts = mesh_getVertexCos(me, &numVerts);
                
                /* Apply all leading deforming modifiers */
-               for(; md; md = md->next) {
+               for(; md; md = md->next, curr = curr->next) {
                        ModifierTypeInfo *mti = modifierType_getInfo(md->type);
 
                        if((md->mode & required_mode) != required_mode) continue;
@@ -1659,7 +1752,7 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
        if(me->vnode) dm = derivedmesh_from_versemesh(me->vnode, deformedVerts);
 #endif
 
-       for(; md; md = md->next) {
+       for(; md; md = md->next, curr = curr->next) {
                ModifierTypeInfo *mti = modifierType_getInfo(md->type);
 
                if((md->mode & required_mode) != required_mode) continue;
@@ -1717,6 +1810,9 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
                                }
                        }
 
+                       /* set the DerivedMesh to only copy needed data */
+                       DM_set_only_copy(dm, (CustomDataMask)curr->link);
+
                        ndm = mti->applyModifier(md, ob, dm, useRenderParams,
                                                 !inputVertexCos);
 
@@ -1772,6 +1868,8 @@ static void mesh_calc_modifiers(Object *ob, float (*inputVertexCos)[3],
        if(deformedVerts && deformedVerts != inputVertexCos)
                MEM_freeN(deformedVerts);
 
+       BLI_linklist_free(datamasks, NULL);
+
        /* restore mesh in any case */
        if(fluidsimMeshUsed) ob->data = ob->fluidsimSettings->orgMesh;
 }
@@ -1790,7 +1888,9 @@ static float (*editmesh_getVertexCos(EditMesh *em, int *numVerts_r))[3]
        return cos;
 }
 
-static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
+static void editmesh_calc_modifiers(DerivedMesh **cage_r,
+                                    DerivedMesh **final_r,
+                                    CustomDataMask dataMask)
 {
        Object *ob = G.obedit;
        EditMesh *em = G.editMesh;
@@ -1799,6 +1899,7 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
        DerivedMesh *dm;
        int i, numVerts = 0, cageIndex = modifiers_getCageIndex(ob, NULL);
        int required_mode = eModifierMode_Realtime | eModifierMode_Editmode;
+       LinkNode *datamasks, *curr;
 
        modifiers_clearErrors(ob);
 
@@ -1807,7 +1908,15 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
        }
 
        dm = NULL;
-       for(i = 0, md = ob->modifiers.first; md; i++, md = md->next) {
+       md = ob->modifiers.first;
+
+       /* we always want to keep original indices */
+       dataMask |= CD_MASK_ORIGINDEX;
+
+       datamasks = modifiers_calcDataMasks(md, dataMask);
+
+       curr = datamasks;
+       for(i = 0; md; i++, md = md->next, curr = curr->next) {
                ModifierTypeInfo *mti = modifierType_getInfo(md->type);
 
                if((md->mode & required_mode) != required_mode) continue;
@@ -1869,6 +1978,9 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
                                }
                        }
 
+                       /* set the DerivedMesh to only copy needed data */
+                       DM_set_only_copy(dm, (CustomDataMask)curr->link);
+
                        ndm = mti->applyModifierEM(md, ob, em, dm);
 
                        if (ndm) {
@@ -1898,6 +2010,8 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
                }
        }
 
+       BLI_linklist_free(datamasks, NULL);
+
        /* Yay, we are done. If we have a DerivedMesh and deformed vertices need
         * to apply these back onto the DerivedMesh. If we have no DerivedMesh
         * then we need to build one.
@@ -1909,13 +2023,17 @@ static void editmesh_calc_modifiers(DerivedMesh **cage_r, DerivedMesh **final_r)
 
                CDDM_apply_vert_coords(*final_r, deformedVerts);
                CDDM_calc_normals(*final_r);
-
-               MEM_freeN(deformedVerts);
        } else if (dm) {
                *final_r = dm;
+       } else if (cage_r && *cage_r) {
+               *final_r = *cage_r;
        } else {
                *final_r = getEditMeshDerivedMesh(em, ob, deformedVerts);
+               deformedVerts = NULL;
        }
+
+       if(deformedVerts)
+               MEM_freeN(deformedVerts);
 }
 
 /***/
@@ -2020,7 +2138,7 @@ static void clear_mesh_caches(Object *ob)
        }
 }
 
-static void mesh_build_data(Object *ob)
+static void mesh_build_data(Object *ob, CustomDataMask dataMask)
 {
        Mesh *me = ob->data;
        float min[3], max[3];
@@ -2033,31 +2151,23 @@ static void mesh_build_data(Object *ob)
                int needMapping = editing && (ob==obact);
 
                if( (G.f & G_WEIGHTPAINT) && ob==obact ) {
-                       MCol *mcol = me->mcol;
                        MCol *wpcol = (MCol*)calc_weightpaint_colors(ob);
+                       int layernum = CustomData_number_of_layers(&me->fdata, CD_MCOL);
 
-                       /* ugly hack here, we replace mcol with weight paint colors, then
-                          CDDM_from_mesh duplicates it, and uses that instead of mcol */
-                       if (mcol) {
-                               CustomData_set_layer(&me->fdata, CD_MCOL, NULL);
-                               CustomData_free_layer(&me->fdata, CD_MCOL, me->totface);
-                       }
-
-                       CustomData_add_layer(&me->fdata, CD_MCOL, CD_FLAG_NOFREE, wpcol, me->totface);
-                       me->mcol= wpcol;
+                       /* ugly hack here, we temporarily add a new active mcol layer with
+                          weightpaint colors in it, that is then duplicated in CDDM_from_mesh */
+                       CustomData_add_layer(&me->fdata, CD_MCOL, CD_ASSIGN, wpcol, me->totface);
+                       CustomData_set_layer_active(&me->fdata, CD_MCOL, layernum);
 
-                       mesh_calc_modifiers(ob, NULL, &ob->derivedDeform, &ob->derivedFinal, 0, 1,
-                                           needMapping);
-
-                       CustomData_free_layer(&me->fdata, CD_MCOL, me->totface);
-                       if (wpcol) MEM_freeN(wpcol);
+                       mesh_calc_modifiers(ob, NULL, &ob->derivedDeform,
+                                           &ob->derivedFinal, 0, 1,
+                                           needMapping, dataMask);
 
-                       if (mcol)
-                               me->mcol= CustomData_add_layer(&me->fdata, CD_MCOL, 0, mcol, me->totface);
-                       me->mcol= mcol;
+                       CustomData_free_layer_active(&me->fdata, CD_MCOL, me->totface);
                } else {
                        mesh_calc_modifiers(ob, NULL, &ob->derivedDeform,
-                                           &ob->derivedFinal, 0, 1, needMapping);
+                                           &ob->derivedFinal, 0, 1,
+                                           needMapping, dataMask);
                }
 
                INIT_MINMAX(min, max);
@@ -2068,10 +2178,11 @@ static void mesh_build_data(Object *ob)
 
                ob->derivedFinal->needsFree = 0;
                ob->derivedDeform->needsFree = 0;
+               ob->lastDataMask = dataMask;
        }
 }
 
-static void editmesh_build_data(void)
+static void editmesh_build_data(CustomDataMask dataMask)
 {
        float min[3], max[3];
 
@@ -2092,7 +2203,8 @@ static void editmesh_build_data(void)
                em->derivedCage = NULL;
        }
 
-       editmesh_calc_modifiers(&em->derivedCage, &em->derivedFinal);
+       editmesh_calc_modifiers(&em->derivedCage, &em->derivedFinal, dataMask);
+       em->lastDataMask = dataMask;
 
        INIT_MINMAX(min, max);
 
@@ -2104,14 +2216,14 @@ static void editmesh_build_data(void)
        em->derivedCage->needsFree = 0;
 }
 
-void makeDerivedMesh(Object *ob)
+void makeDerivedMesh(Object *ob, CustomDataMask dataMask)
 {
        if (ob==G.obedit) {
-               editmesh_build_data();
+               editmesh_build_data(dataMask);
        } else {
                PartEff *paf= give_parteff(ob);
                
-               mesh_build_data(ob);
+               mesh_build_data(ob, dataMask);
                
                if(paf) {
                        if((paf->flag & PAF_STATIC) || (ob->recalc & OB_RECALC_TIME)==0)
@@ -2122,96 +2234,168 @@ void makeDerivedMesh(Object *ob)
 
 /***/
 
-DerivedMesh *mesh_get_derived_final(Object *ob)
+DerivedMesh *mesh_get_derived_final(Object *ob, CustomDataMask dataMask)
 {
-       if (!ob->derivedFinal)
-               mesh_build_data(ob);
+       /* if there's no derived mesh or the last data mask used doesn't include
+        * the data we need, rebuild the derived mesh
+        */
+       if(!ob->derivedFinal || (dataMask & ob->lastDataMask) != dataMask)
+               mesh_build_data(ob, dataMask);
 
        return ob->derivedFinal;
 }
 
-DerivedMesh *mesh_get_derived_deform(Object *ob)
+DerivedMesh *mesh_get_derived_deform(Object *ob, CustomDataMask dataMask)
 {
-       if (!ob->derivedDeform)
-               mesh_build_data(ob);
+       /* if there's no derived mesh or the last data mask used doesn't include
+        * the data we need, rebuild the derived mesh
+        */
+       if(!ob->derivedDeform || (dataMask & ob->lastDataMask) != dataMask)
+               mesh_build_data(ob, dataMask);
 
        return ob->derivedDeform;
 }
 
-DerivedMesh *mesh_create_derived_render(Object *ob)
+/* Move to multires Pin level, returns a copy of the original vertex coords. */
+float *multires_render_pin(Object *ob, Mesh *me, int *orig_lvl)
 {
-       DerivedMesh *final;
-       Mesh *m= get_mesh(ob);
-       unsigned i;
+       float *vert_copy= NULL;
 
-       /* Goto the pin level for multires */
-       if(m->mr) {
-               m->mr->newlvl= m->mr->pinlvl;
-               multires_set_level(ob,m);
+       if(me->mr) {
+               MultiresLevel *lvl= NULL;
+               int i;
+               
+               /* Make sure all mesh edits are properly stored in the multires data*/
+               multires_update_levels(me, 1);
+       
+               /* Copy the highest level of multires verts */
+               *orig_lvl= me->mr->current;
+               lvl= multires_level_n(me->mr, BLI_countlist(&me->mr->levels));
+               vert_copy= MEM_callocN(sizeof(float)*3*lvl->totvert, "multires vert_copy");
+               for(i=0; i<lvl->totvert; ++i)
+                       VecCopyf(&vert_copy[i*3], lvl->verts[i].co);
+       
+               /* Goto the pin level for multires */
+               me->mr->newlvl= me->mr->pinlvl;
+               multires_set_level(ob, me, 1);
        }
+       
+       return vert_copy;
+}
 
-       mesh_calc_modifiers(ob, NULL, NULL, &final, 1, 1, 0);
+/* Propagate the changes to render level - fails if mesh topology changed */
+void multires_render_final(Object *ob, Mesh *me, DerivedMesh **dm, float *vert_copy, const int orig_lvl)
+{
+       if(me->mr) {
+               if((*dm)->getNumVerts(*dm) == me->totvert &&
+                  (*dm)->getNumFaces(*dm) == me->totface) {
+                       MultiresLevel *lvl= multires_level_n(me->mr, BLI_countlist(&me->mr->levels));
+                       DerivedMesh *old= NULL;
+                       int i;
 
-       /* Propagate the changes to render level - fails if mesh topology changed */
-       if(m->mr) {
-               if(final->getNumVerts(final) == m->totvert &&
-                  final->getNumFaces(final) == m->totface) {
-                       for(i=0; i<m->totvert; ++i)
-                               memcpy(&m->mvert[i], CustomData_get(&final->vertData, i, CD_MVERT), sizeof(MVert));
+                       (*dm)->copyVertArray(*dm, me->mvert);
+                       (*dm)->release(*dm);
 
-                       final->release(final);
-                       
-                       m->mr->newlvl= m->mr->renderlvl;
-                       multires_set_level(ob,m);
-                       final= getMeshDerivedMesh(m,ob,NULL);
+                       me->mr->newlvl= me->mr->renderlvl;
+                       multires_set_level(ob, me, 1);
+                       (*dm)= getMeshDerivedMesh(me, ob, NULL);
+
+                       /* Some of the data in dm is referenced externally, so make a copy */
+                       old= *dm;
+                       (*dm)= CDDM_copy(old);
+                       old->release(old);
+
+                       /* Restore the original verts */
+                       me->mr->newlvl= BLI_countlist(&me->mr->levels);
+                       multires_set_level(ob, me, 1);
+                       for(i=0; i<lvl->totvert; ++i)
+                               VecCopyf(me->mvert[i].co, &vert_copy[i*3]);
                }
+               
+               if(vert_copy)
+                       MEM_freeN(vert_copy);
+                       
+               me->mr->newlvl= orig_lvl;
+               multires_set_level(ob, me, 1);
        }
+}
+
+/* Multires note - if mesh has multires enabled, mesh is first set to the Pin level,
+   where all modifiers are applied, then if the topology hasn't changed, the changes
+   from modifiers are propagated up to the Render level. */
+DerivedMesh *mesh_create_derived_render(Object *ob, CustomDataMask dataMask)
+{
+       DerivedMesh *final;
+       Mesh *me= get_mesh(ob);
+       float *vert_copy= NULL;
+       int orig_lvl= 0;
+       
+       vert_copy= multires_render_pin(ob, me, &orig_lvl);
+       mesh_calc_modifiers(ob, NULL, NULL, &final, 1, 1, 0, dataMask);
+       multires_render_final(ob, me, &final, vert_copy, orig_lvl);
 
        return final;
 }
 
-DerivedMesh *mesh_create_derived_view(Object *ob)
+DerivedMesh *mesh_create_derived_view(Object *ob, CustomDataMask dataMask)
 {
        DerivedMesh *final;
 
-       mesh_calc_modifiers(ob, NULL, NULL, &final, 0, 1, 0);
+       mesh_calc_modifiers(ob, NULL, NULL, &final, 0, 1, 0, dataMask);
 
        return final;
 }
 
-DerivedMesh *mesh_create_derived_no_deform(Object *ob, float (*vertCos)[3])
+DerivedMesh *mesh_create_derived_no_deform(Object *ob, float (*vertCos)[3],
+                                           CustomDataMask dataMask)
 {
        DerivedMesh *final;
-
-       mesh_calc_modifiers(ob, vertCos, NULL, &final, 0, 0, 0);
+       
+       mesh_calc_modifiers(ob, vertCos, NULL, &final, 0, 0, 0, dataMask);
 
        return final;
 }
 
-DerivedMesh *mesh_create_derived_no_deform_render(Object *ob, float (*vertCos)[3])
+DerivedMesh *mesh_create_derived_no_deform_render(Object *ob,
+                                                  float (*vertCos)[3],
+                                                  CustomDataMask dataMask)
 {
        DerivedMesh *final;
+       Mesh *me= get_mesh(ob);
+       float *vert_copy= NULL;
+       int orig_lvl= 0;
 
-       mesh_calc_modifiers(ob, vertCos, NULL, &final, 1, 0, 0);
+       vert_copy= multires_render_pin(ob, me, &orig_lvl);
+       mesh_calc_modifiers(ob, vertCos, NULL, &final, 1, 0, 0, dataMask);
+       multires_render_final(ob, me, &final, vert_copy, orig_lvl);
 
        return final;
 }
 
 /***/
 
-DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r)
+DerivedMesh *editmesh_get_derived_cage_and_final(DerivedMesh **final_r,
+                                                 CustomDataMask dataMask)
 {
-       if (!G.editMesh->derivedCage)
-               editmesh_build_data();
+       /* if there's no derived mesh or the last data mask used doesn't include
+        * the data we need, rebuild the derived mesh
+        */
+       if(!G.editMesh->derivedCage ||
+          (G.editMesh->lastDataMask & dataMask) != dataMask)
+               editmesh_build_data(dataMask);
 
        *final_r = G.editMesh->derivedFinal;
        return G.editMesh->derivedCage;
 }
 
-DerivedMesh *editmesh_get_derived_cage(void)
+DerivedMesh *editmesh_get_derived_cage(CustomDataMask dataMask)
 {
-       if (!G.editMesh->derivedCage)
-               editmesh_build_data();
+       /* if there's no derived mesh or the last data mask used doesn't include
+        * the data we need, rebuild the derived mesh
+        */
+       if(!G.editMesh->derivedCage ||
+          (G.editMesh->lastDataMask & dataMask) != dataMask)
+               editmesh_build_data(dataMask);
 
        return G.editMesh->derivedCage;
 }
@@ -2258,7 +2442,7 @@ float *mesh_get_mapped_verts_nors(Object *ob)
        if(ob->type!=OB_MESH || me->totvert==0)
                return NULL;
        
-       dm= mesh_get_derived_final(ob);
+       dm= mesh_get_derived_final(ob, CD_MASK_BAREMESH);
        vertexcosnos= MEM_callocN(6*sizeof(float)*me->totvert, "vertexcosnos map");
        
        if(dm->foreachMappedVert) {
@@ -2322,7 +2506,7 @@ void writeBobjgz(char *filename, struct Object *ob, int useGlobalCoords, int app
                return;
        }
 
-       dm = mesh_create_derived_render(ob);
+       dm = mesh_create_derived_render(ob, CD_MASK_BAREMESH);
        //dm = mesh_create_derived_no_deform(ob,NULL);
 
        mvert = dm->getVertArray(dm);
@@ -2355,7 +2539,7 @@ void writeBobjgz(char *filename, struct Object *ob, int useGlobalCoords, int app
        EulToMat3(ob->rot, rotmat);
        for(i=0; i<wri;i++) {
                VECCOPY(vec, mvert[i].no);
-               Normalise(vec);
+               Normalize(vec);
                if(useGlobalCoords) { Mat3MulVecfl(rotmat, vec); }
                for(j=0; j<3; j++) {
                        wrf = vec[j];
@@ -2426,9 +2610,8 @@ void initElbeemMesh(struct Object *ob,
        float *verts;
        int *tris;
 
-       dm = mesh_create_derived_render(ob);
+       dm = mesh_create_derived_render(ob, CD_MASK_BAREMESH);
        //dm = mesh_create_derived_no_deform(ob,NULL);
-       if(!dm) { *numVertices = *numTriangles = 0; *triangles=NULL; *vertices=NULL; }
 
        mvert = dm->getVertArray(dm);
        mface = dm->getFaceArray(dm);
@@ -2532,7 +2715,7 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh, float* bbstart, float *bbsize) /
        //if(sizeof(wri)!=4) { snprintf(debugStrBuffer,256,"Reading GZ_BOBJ, Invalid int size %d...\n", wri); return NULL; } // paranoia check
        gotBytes = gzread(gzf, &wri, sizeof(wri));
        newmesh->totvert = wri;
-       newmesh->mvert = CustomData_add_layer(&newmesh->vdata, CD_MVERT, 0, NULL, newmesh->totvert);
+       newmesh->mvert = CustomData_add_layer(&newmesh->vdata, CD_MVERT, CD_CALLOC, NULL, newmesh->totvert);
        if(debugBobjRead){ snprintf(debugStrBuffer,256,"#vertices %d ", newmesh->totvert); elbeemDebugOut(debugStrBuffer); } //DEBUG
        for(i=0; i<newmesh->totvert;i++) {
                //if(debugBobjRead) snprintf(debugStrBuffer,256,"V %d = ",i);
@@ -2548,7 +2731,7 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh, float* bbstart, float *bbsize) /
        gotBytes = gzread(gzf, &wri, sizeof(wri));
        if(wri != newmesh->totvert) {
                // complain #vertices has to be equal to #normals, reset&abort
-               CustomData_free_layer(&newmesh->vdata, CD_MVERT, newmesh->totvert);
+               CustomData_free_layer_active(&newmesh->vdata, CD_MVERT, newmesh->totvert);
                MEM_freeN(newmesh);
                snprintf(debugStrBuffer,256,"Reading GZ_BOBJ, #normals=%d, #vertices=%d, aborting...\n", wri,newmesh->totvert );
                return NULL;
@@ -2568,7 +2751,7 @@ Mesh* readBobjgz(char *filename, Mesh *orgmesh, float* bbstart, float *bbsize) /
        /* compute no. of triangles */
        gotBytes = gzread(gzf, &wri, sizeof(wri));
        newmesh->totface = wri;
-       newmesh->mface = CustomData_add_layer(&newmesh->fdata, CD_MFACE, 0, NULL, newmesh->totface);
+       newmesh->mface = CustomData_add_layer(&newmesh->fdata, CD_MFACE, CD_CALLOC, NULL, newmesh->totface);
        if(debugBobjRead){ snprintf(debugStrBuffer,256,"#faces %d ", newmesh->totface); elbeemDebugOut(debugStrBuffer); } //DEBUG
        fsface = newmesh->mface;
        for(i=0; i<newmesh->totface; i++) {
@@ -2835,13 +3018,15 @@ void fluidsimGetAxisAlignedBB(struct Mesh *mesh, float obmat[][4],
                else {           newmesh = *bbmesh; }
 
                newmesh->totvert = 8;
-               if(!newmesh->mvert) newmesh->mvert = CustomData_add_layer(&newmesh->vdata, CD_MVERT, 0, NULL, newmesh->totvert);
+               if(!newmesh->mvert)
+                       newmesh->mvert = CustomData_add_layer(&newmesh->vdata, CD_MVERT, CD_CALLOC, NULL, newmesh->totvert);
                for(i=0; i<8; i++) {
                        for(j=0; j<3; j++) newmesh->mvert[i].co[j] = start[j]; 
                }
 
                newmesh->totface = 6;
-               if(!newmesh->mface) newmesh->mface = CustomData_add_layer(&newmesh->fdata, CD_MFACE, 0, NULL, newmesh->totface);
+               if(!newmesh->mface)
+                       newmesh->mface = CustomData_add_layer(&newmesh->fdata, CD_MFACE, CD_CALLOC, NULL, newmesh->totface);
 
                *bbmesh = newmesh;
        }