Cleanup: remove unused EditDerivedBMesh
authorCampbell Barton <ideasman42@gmail.com>
Tue, 9 Oct 2018 04:57:38 +0000 (15:57 +1100)
committerCampbell Barton <ideasman42@gmail.com>
Tue, 9 Oct 2018 04:57:38 +0000 (15:57 +1100)
source/blender/blenkernel/BKE_DerivedMesh.h
source/blender/blenkernel/BKE_editmesh.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/editderivedmesh.c

index 5a60fc25241f53249bdf7b20c53522472646e428..3db032da1b14e197a43a25057d73127f2d00b3e1 100644 (file)
@@ -526,10 +526,6 @@ DerivedMesh *mesh_create_derived_render(
         struct Depsgraph *depsgraph, struct Scene *scene,
         struct Object *ob, CustomDataMask dataMask);
 
         struct Depsgraph *depsgraph, struct Scene *scene,
         struct Object *ob, CustomDataMask dataMask);
 
-DerivedMesh *getEditDerivedBMesh(
-        struct BMEditMesh *em, struct Object *ob, CustomDataMask data_mask,
-        float (*vertexCos)[3]);
-
 /* same as above but wont use render settings */
 DerivedMesh *mesh_create_derived(struct Mesh *me, float (*vertCos)[3]);
 DerivedMesh *mesh_create_derived_no_deform(
 /* same as above but wont use render settings */
 DerivedMesh *mesh_create_derived(struct Mesh *me, float (*vertCos)[3]);
 DerivedMesh *mesh_create_derived_no_deform(
index 09f9c3dfbcfb497541fe2eafe5af3721475a44ee..65c2caa4d78f07f7e3b2eab0ebffeaee6d249b43 100644 (file)
@@ -41,6 +41,7 @@ struct Scene;
 struct DerivedMesh;
 struct MeshStatVis;
 struct Depsgraph;
 struct DerivedMesh;
 struct MeshStatVis;
 struct Depsgraph;
+struct EditMeshData;
 
 /**
  * This structure is used for mesh edit-mode.
 
 /**
  * This structure is used for mesh edit-mode.
@@ -97,8 +98,8 @@ void        BKE_editmesh_lnorspace_update(BMEditMesh *em);
 
 /* editderivedmesh.c */
 /* should really be defined in editmesh.c, but they use 'EditDerivedBMesh' */
 
 /* editderivedmesh.c */
 /* should really be defined in editmesh.c, but they use 'EditDerivedBMesh' */
-void        BKE_editmesh_statvis_calc(BMEditMesh *em, struct DerivedMesh *dm,
-                                      const struct MeshStatVis *statvis);
+void BKE_editmesh_statvis_calc(
+        BMEditMesh *em, struct EditMeshData *emd, const struct MeshStatVis *statvis);
 
 float (*BKE_editmesh_vertexCos_get(
            struct Depsgraph *depsgraph, struct BMEditMesh *em, struct Scene *scene, int *r_numVerts))[3];
 
 float (*BKE_editmesh_vertexCos_get(
            struct Depsgraph *depsgraph, struct BMEditMesh *em, struct Scene *scene, int *r_numVerts))[3];
index e5b12b97033bd01c63a80c643646c45e3928d6d1..72823e7b1b491cd4e91303a1499fd3a0c7254d72 100644 (file)
@@ -1259,11 +1259,12 @@ static void add_orco_mesh(
        }
 }
 
        }
 }
 
-static void UNUSED_FUNCTION(DM_update_statvis_color)(const Scene *scene, Object *ob, DerivedMesh *dm)
+static void UNUSED_FUNCTION(DM_update_statvis_color)(const Scene *scene, Object *ob)
 {
        BMEditMesh *em = BKE_editmesh_from_object(ob);
 {
        BMEditMesh *em = BKE_editmesh_from_object(ob);
-
-       BKE_editmesh_statvis_calc(em, dm, &scene->toolsettings->statvis);
+       Mesh *me = ob->data;
+       BKE_mesh_runtime_ensure_edit_data(me);
+       BKE_editmesh_statvis_calc(em, me->runtime.edit_data, &scene->toolsettings->statvis);
 }
 
 static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid)
 }
 
 static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid)
@@ -2129,7 +2130,7 @@ static void editbmesh_calc_modifiers(
 #if 0
                /* In this case, we should never have weight-modifying modifiers in stack... */
                if (do_init_statvis) {
 #if 0
                /* In this case, we should never have weight-modifying modifiers in stack... */
                if (do_init_statvis) {
-                       DM_update_statvis_color(scene, ob, *r_final);
+                       DM_update_statvis_color(scene, ob);
                }
 #endif
        }
                }
 #endif
        }
@@ -2148,7 +2149,7 @@ static void editbmesh_calc_modifiers(
 #if 0
                /* In this case, we should never have weight-modifying modifiers in stack... */
                if (do_init_statvis) {
 #if 0
                /* In this case, we should never have weight-modifying modifiers in stack... */
                if (do_init_statvis) {
-                       DM_update_statvis_color(scene, ob, *r_final);
+                       DM_update_statvis_color(scene, ob);
                }
 #endif
        }
                }
 #endif
        }
@@ -2953,7 +2954,6 @@ char *DM_debug_info(DerivedMesh *dm)
        BLI_dynstr_appendf(dynstr, "    'ptr': '%p',\n", (void *)dm);
        switch (dm->type) {
                case DM_TYPE_CDDM:     tstr = "DM_TYPE_CDDM";     break;
        BLI_dynstr_appendf(dynstr, "    'ptr': '%p',\n", (void *)dm);
        switch (dm->type) {
                case DM_TYPE_CDDM:     tstr = "DM_TYPE_CDDM";     break;
-               case DM_TYPE_EDITBMESH: tstr = "DM_TYPE_EDITMESH";  break;
                case DM_TYPE_CCGDM:    tstr = "DM_TYPE_CCGDM";     break;
                default:               tstr = "UNKNOWN";           break;
        }
                case DM_TYPE_CCGDM:    tstr = "DM_TYPE_CCGDM";     break;
                default:               tstr = "UNKNOWN";           break;
        }
index 38a6556dc21e1e34274407aca501b6da67b3acd6..5ca8bcfd74d0750111cf8ca43b6b0118ec500a4f 100644 (file)
 
 #include "MEM_guardedalloc.h"
 
 
 #include "MEM_guardedalloc.h"
 
-typedef struct EditDerivedBMesh {
-       DerivedMesh dm;
-
-       BMEditMesh *em;
-
-       EditMeshData emd;
-} EditDerivedBMesh;
-
-/* -------------------------------------------------------------------- */
-/* Lazy initialize datastructures */
-
-static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm);
-
-static void emDM_ensureVertNormals(EditDerivedBMesh *bmdm)
-{
-       BKE_editmesh_cache_ensure_vert_normals(bmdm->em, &bmdm->emd);
-}
-
-static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm)
-{
-       BKE_editmesh_cache_ensure_poly_normals(bmdm->em, &bmdm->emd);
-}
-
-static void emDM_ensurePolyCenters(EditDerivedBMesh *bmdm)
-{
-       BKE_editmesh_cache_ensure_poly_centers(bmdm->em, &bmdm->emd);
-}
-
-static void emDM_calcNormals(DerivedMesh *dm)
-{
-       /* Nothing to do: normals are already calculated and stored on the
-        * BMVerts and BMFaces */
-       dm->dirty &= ~DM_DIRTY_NORMALS;
-}
-
-static void emDM_calcLoopNormalsSpaceArray(
-        DerivedMesh *dm, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr);
-
-static void emDM_calcLoopNormals(DerivedMesh *dm, const bool use_split_normals, const float split_angle)
-{
-       emDM_calcLoopNormalsSpaceArray(dm, use_split_normals, split_angle, NULL);
-}
-
-/* #define DEBUG_CLNORS */
-
-static void emDM_calcLoopNormalsSpaceArray(
-        DerivedMesh *dm, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-       const float (*vertexCos)[3], (*vertexNos)[3], (*polyNos)[3];
-       float (*loopNos)[3];
-       short (*clnors_data)[2];
-       int cd_loop_clnors_offset;
-
-       /* calculate loop normals from poly and vertex normals */
-       emDM_ensureVertNormals(bmdm);
-       emDM_ensurePolyNormals(bmdm);
-       dm->dirty &= ~DM_DIRTY_NORMALS;
-
-       vertexCos = bmdm->emd.vertexCos;
-       vertexNos = bmdm->emd.vertexNos;
-       polyNos = bmdm->emd.polyNos;
-
-       loopNos = dm->getLoopDataArray(dm, CD_NORMAL);
-       if (!loopNos) {
-               DM_add_loop_layer(dm, CD_NORMAL, CD_CALLOC, NULL);
-               loopNos = dm->getLoopDataArray(dm, CD_NORMAL);
-       }
-
-       /* We can have both, give priority to dm's data, and fallback to bm's ones. */
-       clnors_data = dm->getLoopDataArray(dm, CD_CUSTOMLOOPNORMAL);
-       cd_loop_clnors_offset = clnors_data ? -1 : CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
-
-       BM_loops_calc_normal_vcos(bm, vertexCos, vertexNos, polyNos, use_split_normals, split_angle, loopNos,
-                                 r_lnors_spacearr, clnors_data, cd_loop_clnors_offset, false);
-#ifdef DEBUG_CLNORS
-       if (r_lnors_spacearr) {
-               int i;
-               for (i = 0; i < numLoops; i++) {
-                       if (r_lnors_spacearr->lspacearr[i]->ref_alpha != 0.0f) {
-                               LinkNode *loops = r_lnors_spacearr->lspacearr[i]->loops;
-                               printf("Loop %d uses lnor space %p:\n", i, r_lnors_spacearr->lspacearr[i]);
-                               print_v3("\tfinal lnor:", loopNos[i]);
-                               print_v3("\tauto lnor:", r_lnors_spacearr->lspacearr[i]->vec_lnor);
-                               print_v3("\tref_vec:", r_lnors_spacearr->lspacearr[i]->vec_ref);
-                               printf("\talpha: %f\n\tbeta: %f\n\tloops: %p\n", r_lnors_spacearr->lspacearr[i]->ref_alpha,
-                                      r_lnors_spacearr->lspacearr[i]->ref_beta, r_lnors_spacearr->lspacearr[i]->loops);
-                               printf("\t\t(shared with loops");
-                               while (loops) {
-                                       printf(" %d", POINTER_AS_INT(loops->link));
-                                       loops = loops->next;
-                               }
-                               printf(")\n");
-                       }
-                       else {
-                               printf("Loop %d has no lnor space\n", i);
-                       }
-               }
-       }
-#endif
-}
-
-static void emDM_calc_loop_tangents(
-        DerivedMesh *dm, bool calc_active_tangent,
-        const char (*tangent_names)[MAX_NAME], int tangent_names_len)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMEditMesh *em = bmdm->em;
-
-       if (CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPUV) == 0) {
-               return;
-       }
-
-       const float (*poly_normals)[3] = bmdm->emd.polyNos;
-       const float (*loop_normals)[3] = CustomData_get_layer(&dm->loopData, CD_NORMAL);
-       const float (*vert_orco)[3] = dm->getVertDataArray(dm, CD_ORCO);  /* can be NULL */
-       BKE_editmesh_loop_tangent_calc(
-               em, calc_active_tangent,
-               tangent_names, tangent_names_len,
-               poly_normals, loop_normals,
-               vert_orco,
-               &dm->loopData, dm->numLoopData,
-               &dm->tangent_mask);
-}
-
-
-static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm))
-{
-       /* do nothing */
-}
-
-static void emDM_recalcLoopTri(DerivedMesh *dm)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMLoop *(*looptris)[3] = bmdm->em->looptris;
-       MLoopTri *mlooptri;
-       const int tottri = bmdm->em->tottri;
-       int i;
-
-       DM_ensure_looptri_data(dm);
-       mlooptri = dm->looptris.array_wip;
-
-       BLI_assert(tottri == 0 || mlooptri != NULL);
-       BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
-       BLI_assert(tottri == dm->looptris.num);
-
-       BM_mesh_elem_index_ensure(bmdm->em->bm, BM_FACE | BM_LOOP);
-
-       for (i = 0; i < tottri; i++) {
-               BMLoop **ltri = looptris[i];
-               MLoopTri *lt = &mlooptri[i];
-
-               ARRAY_SET_ITEMS(
-                       lt->tri,
-                       BM_elem_index_get(ltri[0]),
-                       BM_elem_index_get(ltri[1]),
-                       BM_elem_index_get(ltri[2]));
-               lt->poly = BM_elem_index_get(ltri[0]->f);
-       }
-
-       BLI_assert(dm->looptris.array == NULL);
-       atomic_cas_ptr((void **)&dm->looptris.array, dm->looptris.array, dm->looptris.array_wip);
-       dm->looptris.array_wip = NULL;
-}
-
-static void emDM_foreachMappedVert(
-        DerivedMesh *dm,
-        void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
-        void *userData,
-        DMForeachFlag flag)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-       BMVert *eve;
-       BMIter iter;
-       int i;
-
-       if (bmdm->emd.vertexCos) {
-               const float (*vertexCos)[3] = bmdm->emd.vertexCos;
-               const float (*vertexNos)[3];
-
-               if (flag & DM_FOREACH_USE_NORMAL) {
-                       emDM_ensureVertNormals(bmdm);
-                       vertexNos = bmdm->emd.vertexNos;
-               }
-               else {
-                       vertexNos = NULL;
-               }
-
-               BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
-                       const float *no = (flag & DM_FOREACH_USE_NORMAL) ? vertexNos[i] : NULL;
-                       func(userData, i, vertexCos[i], no, NULL);
-               }
-       }
-       else {
-               BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
-                       const float *no = (flag & DM_FOREACH_USE_NORMAL) ? eve->no : NULL;
-                       func(userData, i, eve->co, no, NULL);
-               }
-       }
-}
-static void emDM_foreachMappedEdge(
-        DerivedMesh *dm,
-        void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
-        void *userData)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-       BMEdge *eed;
-       BMIter iter;
-       int i;
-
-       if (bmdm->emd.vertexCos) {
-
-               BM_mesh_elem_index_ensure(bm, BM_VERT);
-
-               BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
-                       func(userData, i,
-                            bmdm->emd.vertexCos[BM_elem_index_get(eed->v1)],
-                            bmdm->emd.vertexCos[BM_elem_index_get(eed->v2)]);
-               }
-       }
-       else {
-               BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
-                       func(userData, i, eed->v1->co, eed->v2->co);
-               }
-       }
-}
-
-static void emDM_foreachMappedLoop(
-        DerivedMesh *dm,
-        void (*func)(void *userData, int vertex_index, int face_index, const float co[3], const float no[3]),
-        void *userData,
-        DMForeachFlag flag)
-{
-       /* We can't use dm->getLoopDataLayout(dm) here, we want to always access dm->loopData, EditDerivedBMesh would
-        * return loop data from bmesh itself. */
-       const float (*lnors)[3] = (flag & DM_FOREACH_USE_NORMAL) ? DM_get_loop_data_layer(dm, CD_NORMAL) : NULL;
-
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-       BMFace *efa;
-       BMIter iter;
-
-       const float (*vertexCos)[3] = bmdm->emd.vertexCos;
-       int f_idx;
-
-       BM_mesh_elem_index_ensure(bm, BM_VERT);
-
-       BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, f_idx) {
-               BMLoop *l_iter, *l_first;
-
-               l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
-               do {
-                       const BMVert *eve = l_iter->v;
-                       const int v_idx = BM_elem_index_get(eve);
-                       const float *no = lnors ? *lnors++ : NULL;
-                       func(userData, v_idx, f_idx, vertexCos ? vertexCos[v_idx] : eve->co, no);
-               } while ((l_iter = l_iter->next) != l_first);
-       }
-}
-
-static void emDM_foreachMappedFaceCenter(
-        DerivedMesh *dm,
-        void (*func)(void *userData, int index, const float co[3], const float no[3]),
-        void *userData,
-        DMForeachFlag flag)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-       const float (*polyNos)[3];
-       const float (*polyCos)[3];
-       BMFace *efa;
-       BMIter iter;
-       int i;
-
-       emDM_ensurePolyCenters(bmdm);
-       polyCos = bmdm->emd.polyCos;  /* always set */
-
-       if (flag & DM_FOREACH_USE_NORMAL) {
-               emDM_ensurePolyNormals(bmdm);
-               polyNos = bmdm->emd.polyNos;  /* maybe NULL */
-       }
-       else {
-               polyNos = NULL;
-       }
-
-       if (polyNos) {
-               BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
-                       const float *no = polyNos[i];
-                       func(userData, i, polyCos[i], no);
-               }
-       }
-       else {
-               BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
-                       const float *no = (flag & DM_FOREACH_USE_NORMAL) ? efa->no : NULL;
-                       func(userData, i, polyCos[i], no);
-               }
-       }
-}
-
-static void emDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-       BMVert *eve;
-       BMIter iter;
-       int i;
-
-       if (bm->totvert) {
-               if (bmdm->emd.vertexCos) {
-                       BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
-                               minmax_v3v3_v3(r_min, r_max, bmdm->emd.vertexCos[i]);
-                       }
-               }
-               else {
-                       BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
-                               minmax_v3v3_v3(r_min, r_max, eve->co);
-                       }
-               }
-       }
-       else {
-               zero_v3(r_min);
-               zero_v3(r_max);
-       }
-}
-static int emDM_getNumVerts(DerivedMesh *dm)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-
-       return bmdm->em->bm->totvert;
-}
-
-static int emDM_getNumEdges(DerivedMesh *dm)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-
-       return bmdm->em->bm->totedge;
-}
-
-static int emDM_getNumTessFaces(DerivedMesh *dm)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-
-       return bmdm->em->tottri;
-}
-
-static int emDM_getNumLoops(DerivedMesh *dm)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-
-       return bmdm->em->bm->totloop;
-}
-
-static int emDM_getNumPolys(DerivedMesh *dm)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-
-       return bmdm->em->bm->totface;
-}
-
-static void bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *r_vert)
-{
-       const float *f;
-
-       copy_v3_v3(r_vert->co, ev->co);
-
-       normal_float_to_short_v3(r_vert->no, ev->no);
-
-       r_vert->flag = BM_vert_flag_to_mflag(ev);
-
-       if ((f = CustomData_bmesh_get(&bm->vdata, ev->head.data, CD_BWEIGHT))) {
-               r_vert->bweight = (unsigned char)((*f) * 255.0f);
-       }
-}
-
-static void emDM_getVert(DerivedMesh *dm, int index, MVert *r_vert)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-       BMVert *ev;
-
-       if (UNLIKELY(index < 0 || index >= bm->totvert)) {
-               BLI_assert(!"error in emDM_getVert");
-               return;
-       }
-
-       BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
-       ev = bm->vtable[index];  /* should be BM_vert_at_index() */
-       // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
-
-       bmvert_to_mvert(bm, ev, r_vert);
-       if (bmdm->emd.vertexCos)
-               copy_v3_v3(r_vert->co, bmdm->emd.vertexCos[index]);
-}
-
-static void emDM_getVertCo(DerivedMesh *dm, int index, float r_co[3])
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-
-       if (UNLIKELY(index < 0 || index >= bm->totvert)) {
-               BLI_assert(!"error in emDM_getVertCo");
-               return;
-       }
-
-       if (bmdm->emd.vertexCos) {
-               copy_v3_v3(r_co, bmdm->emd.vertexCos[index]);
-       }
-       else {
-               BMVert *ev;
-
-               BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
-               ev = bm->vtable[index];  /* should be BM_vert_at_index() */
-               // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
-               copy_v3_v3(r_co, ev->co);
-       }
-}
-
-static void emDM_getVertNo(DerivedMesh *dm, int index, float r_no[3])
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-
-       if (UNLIKELY(index < 0 || index >= bm->totvert)) {
-               BLI_assert(!"error in emDM_getVertNo");
-               return;
-       }
-
-
-       if (bmdm->emd.vertexCos) {
-               emDM_ensureVertNormals(bmdm);
-               copy_v3_v3(r_no, bmdm->emd.vertexNos[index]);
-       }
-       else {
-               BMVert *ev;
-
-               BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
-               ev = bm->vtable[index];  /* should be BM_vert_at_index() */
-               // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
-               copy_v3_v3(r_no, ev->no);
-       }
-}
-
-static void emDM_getPolyNo(DerivedMesh *dm, int index, float r_no[3])
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-
-       if (UNLIKELY(index < 0 || index >= bm->totface)) {
-               BLI_assert(!"error in emDM_getPolyNo");
-               return;
-       }
-
-       if (bmdm->emd.vertexCos) {
-               emDM_ensurePolyNormals(bmdm);
-               copy_v3_v3(r_no, bmdm->emd.polyNos[index]);
-       }
-       else {
-               BMFace *efa;
-
-               BLI_assert((bm->elem_table_dirty & BM_FACE) == 0);
-               efa = bm->ftable[index];  /* should be BM_vert_at_index() */
-               // efa = BM_face_at_index(bm, index); /* warning, does list loop, _not_ ideal */
-               copy_v3_v3(r_no, efa->no);
-       }
-}
-
-static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *r_edge)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-       BMEdge *e;
-       const float *f;
-
-       if (UNLIKELY(index < 0 || index >= bm->totedge)) {
-               BLI_assert(!"error in emDM_getEdge");
-               return;
-       }
-
-       BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0);
-       e = bm->etable[index];  /* should be BM_edge_at_index() */
-       // e = BM_edge_at_index(bm, index); /* warning, does list loop, _not_ ideal */
-
-       r_edge->flag = BM_edge_flag_to_mflag(e);
-
-       r_edge->v1 = BM_elem_index_get(e->v1);
-       r_edge->v2 = BM_elem_index_get(e->v2);
-
-       if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT))) {
-               r_edge->bweight = (unsigned char)((*f) * 255.0f);
-       }
-       if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE))) {
-               r_edge->crease = (unsigned char)((*f) * 255.0f);
-       }
-}
-
-static void emDM_getTessFace(DerivedMesh *dm, int index, MFace *r_face)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMFace *ef;
-       BMLoop **ltri;
-
-       if (UNLIKELY(index < 0 || index >= bmdm->em->tottri)) {
-               BLI_assert(!"error in emDM_getTessFace");
-               return;
-       }
-
-       ltri = bmdm->em->looptris[index];
-
-       ef = ltri[0]->f;
-
-       r_face->mat_nr = (unsigned char) ef->mat_nr;
-       r_face->flag = BM_face_flag_to_mflag(ef);
-
-       r_face->v1 = BM_elem_index_get(ltri[0]->v);
-       r_face->v2 = BM_elem_index_get(ltri[1]->v);
-       r_face->v3 = BM_elem_index_get(ltri[2]->v);
-       r_face->v4 = 0;
-
-       test_index_face(r_face, NULL, 0, 3);
-}
-
-static void emDM_copyVertArray(DerivedMesh *dm, MVert *r_vert)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-       BMVert *eve;
-       BMIter iter;
-       const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
-
-       if (bmdm->emd.vertexCos) {
-               int i;
-
-               BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
-                       copy_v3_v3(r_vert->co, bmdm->emd.vertexCos[i]);
-                       normal_float_to_short_v3(r_vert->no, eve->no);
-                       r_vert->flag = BM_vert_flag_to_mflag(eve);
-
-                       r_vert->bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset) : 0;
-
-                       r_vert++;
-               }
-       }
-       else {
-               BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
-                       copy_v3_v3(r_vert->co, eve->co);
-                       normal_float_to_short_v3(r_vert->no, eve->no);
-                       r_vert->flag = BM_vert_flag_to_mflag(eve);
-
-                       r_vert->bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset) : 0;
-
-                       r_vert++;
-               }
-       }
-}
-
-static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *r_edge)
-{
-       BMesh *bm = ((EditDerivedBMesh *)dm)->em->bm;
-       BMEdge *eed;
-       BMIter iter;
-
-       const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
-       const int cd_edge_crease_offset  = CustomData_get_offset(&bm->edata, CD_CREASE);
-
-       BM_mesh_elem_index_ensure(bm, BM_VERT);
-
-       BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
-               r_edge->v1 = BM_elem_index_get(eed->v1);
-               r_edge->v2 = BM_elem_index_get(eed->v2);
-
-               r_edge->flag = BM_edge_flag_to_mflag(eed);
-
-               r_edge->crease  = (cd_edge_crease_offset  != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset)  : 0;
-               r_edge->bweight = (cd_edge_bweight_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset) : 0;
-
-               r_edge++;
-       }
-}
-
-static void emDM_copyTessFaceArray(DerivedMesh *dm, MFace *r_face)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-       struct BMLoop *(*looptris)[3] = bmdm->em->looptris;
-       BMFace *ef;
-       int i;
-
-       BM_mesh_elem_index_ensure(bm, BM_VERT);
-
-       for (i = 0; i < bmdm->em->tottri; i++, r_face++) {
-               BMLoop **ltri = looptris[i];
-               ef = ltri[0]->f;
-
-               r_face->mat_nr = (unsigned char) ef->mat_nr;
-
-               r_face->flag = BM_face_flag_to_mflag(ef);
-               r_face->edcode = 0;
-
-               r_face->v1 = BM_elem_index_get(ltri[0]->v);
-               r_face->v2 = BM_elem_index_get(ltri[1]->v);
-               r_face->v3 = BM_elem_index_get(ltri[2]->v);
-               r_face->v4 = 0;
-
-               test_index_face(r_face, NULL, 0, 3);
-       }
-}
-
-static void emDM_copyLoopArray(DerivedMesh *dm, MLoop *r_loop)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-       BMIter iter;
-       BMFace *efa;
-
-       BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE);
-
-       BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
-               BMLoop *l_iter, *l_first;
-               l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
-               do {
-                       r_loop->v = BM_elem_index_get(l_iter->v);
-                       r_loop->e = BM_elem_index_get(l_iter->e);
-                       r_loop++;
-               } while ((l_iter = l_iter->next) != l_first);
-       }
-}
-
-static void emDM_copyPolyArray(DerivedMesh *dm, MPoly *r_poly)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-       BMIter iter;
-       BMFace *efa;
-       int i;
-
-       i = 0;
-       BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
-               r_poly->flag = BM_face_flag_to_mflag(efa);
-               r_poly->loopstart = i;
-               r_poly->totloop = efa->len;
-               r_poly->mat_nr = efa->mat_nr;
-
-               r_poly++;
-               i += efa->len;
-       }
-}
-
-static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-       void *datalayer;
-
-       datalayer = DM_get_tessface_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) {
-               const char *bmdata;
-               char *data;
-
-               bool has_type_source = CustomData_has_layer(&bm->ldata, (type == CD_MTFACE) ? CD_MLOOPUV : CD_MLOOPCOL);
-
-               if (has_type_source) {
-                       /* offset = bm->pdata.layers[index].offset; */ /* UNUSED */
-                       BMLoop *(*looptris)[3] = bmdm->em->looptris;
-                       const int size = CustomData_sizeof(type);
-                       int i, j;
-
-                       DM_add_tessface_layer(dm, type, CD_CALLOC, NULL);
-                       const int index = CustomData_get_layer_index(&dm->faceData, type);
-                       dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
-
-                       data = datalayer = DM_get_tessface_data_layer(dm, type);
-
-                       if (type == CD_MTFACE) {
-                               const int cd_loop_uv_offset  = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
-
-                               for (i = 0; i < bmdm->em->tottri; i++, data += size) {
-                                       for (j = 0; j < 3; j++) {
-                                               // bmdata = CustomData_bmesh_get(&bm->ldata, looptris[i][j]->head.data, CD_MLOOPUV);
-                                               bmdata = BM_ELEM_CD_GET_VOID_P(looptris[i][j], cd_loop_uv_offset);
-                                               copy_v2_v2(((MTFace *)data)->uv[j], ((const MLoopUV *)bmdata)->uv);
-                                       }
-                               }
-                       }
-                       else {
-                               const int cd_loop_color_offset  = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
-                               for (i = 0; i < bmdm->em->tottri; i++, data += size) {
-                                       for (j = 0; j < 3; j++) {
-                                               // bmdata = CustomData_bmesh_get(&bm->ldata, looptris[i][j]->head.data, CD_MLOOPCOL);
-                                               bmdata = BM_ELEM_CD_GET_VOID_P(looptris[i][j], cd_loop_color_offset);
-                                               MESH_MLOOPCOL_TO_MCOL(((const MLoopCol *)bmdata), (((MCol *)data) + j));
-                                       }
-                               }
-                       }
-               }
-       }
-
-       /* Special handling for CD_TESSLOOPNORMAL, we generate it on demand as well. */
-       if (type == CD_TESSLOOPNORMAL) {
-               const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
-
-               if (lnors) {
-                       BMLoop *(*looptris)[3] = bmdm->em->looptris;
-                       short (*tlnors)[4][3], (*tlnor)[4][3];
-                       int index, i, j;
-
-                       DM_add_tessface_layer(dm, type, CD_CALLOC, NULL);
-                       index = CustomData_get_layer_index(&dm->faceData, type);
-                       dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
-
-                       tlnor = tlnors = DM_get_tessface_data_layer(dm, type);
-
-                       BM_mesh_elem_index_ensure(bm, BM_LOOP);
-
-                       for (i = 0; i < bmdm->em->tottri; i++, tlnor++, looptris++) {
-                               for (j = 0; j < 3; j++) {
-                                       normal_float_to_short_v3((*tlnor)[j], lnors[BM_elem_index_get((*looptris)[j])]);
-                               }
-                       }
-               }
-       }
-
-       return datalayer;
-}
-
-static void emDM_getVertCos(DerivedMesh *dm, float (*r_cos)[3])
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BMesh *bm = bmdm->em->bm;
-       BMVert *eve;
-       BMIter iter;
-       int i;
-
-       if (bmdm->emd.vertexCos) {
-               BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
-                       copy_v3_v3(r_cos[i], bmdm->emd.vertexCos[i]);
-               }
-       }
-       else {
-               BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
-                       copy_v3_v3(r_cos[i], eve->co);
-               }
-       }
-}
-
-static void emDM_release(DerivedMesh *dm)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-
-       if (DM_release(dm)) {
-               if (bmdm->emd.vertexCos) {
-                       MEM_freeN((void *)bmdm->emd.vertexCos);
-                       if (bmdm->emd.vertexNos) {
-                               MEM_freeN((void *)bmdm->emd.vertexNos);
-                       }
-                       if (bmdm->emd.polyNos) {
-                               MEM_freeN((void *)bmdm->emd.polyNos);
-                       }
-               }
-
-               if (bmdm->emd.polyCos) {
-                       MEM_freeN((void *)bmdm->emd.polyCos);
-               }
-
-               MEM_freeN(bmdm);
-       }
-}
-
-static CustomData *bmDm_getVertDataLayout(DerivedMesh *dm)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-
-       return &bmdm->em->bm->vdata;
-}
-
-static CustomData *bmDm_getEdgeDataLayout(DerivedMesh *dm)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-
-       return &bmdm->em->bm->edata;
-}
-
-static CustomData *bmDm_getTessFaceDataLayout(DerivedMesh *dm)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-
-       return &bmdm->dm.faceData;
-}
-
-static CustomData *bmDm_getLoopDataLayout(DerivedMesh *dm)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-
-       return &bmdm->em->bm->ldata;
-}
-
-static CustomData *bmDm_getPolyDataLayout(DerivedMesh *dm)
-{
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-
-       return &bmdm->em->bm->pdata;
-}
-
-/**
- * \note This may be called per-draw,
- * avoid allocating large arrays where possible and keep this a thin wrapper for #BMesh.
- */
-DerivedMesh *getEditDerivedBMesh(
-        BMEditMesh *em, struct Object *UNUSED(ob),
-        CustomDataMask data_mask,
-        float (*vertexCos)[3])
-{
-       EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), __func__);
-       BMesh *bm = em->bm;
-
-       bmdm->em = em;
-
-       DM_init((DerivedMesh *)bmdm, DM_TYPE_EDITBMESH, bm->totvert,
-               bm->totedge, em->tottri, bm->totloop, bm->totface);
-
-       /* could also get from the objects mesh directly */
-       bmdm->dm.cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
-
-       bmdm->dm.getVertCos = emDM_getVertCos;
-       bmdm->dm.getMinMax = emDM_getMinMax;
-
-       bmdm->dm.getVertDataLayout = bmDm_getVertDataLayout;
-       bmdm->dm.getEdgeDataLayout = bmDm_getEdgeDataLayout;
-       bmdm->dm.getTessFaceDataLayout = bmDm_getTessFaceDataLayout;
-       bmdm->dm.getLoopDataLayout = bmDm_getLoopDataLayout;
-       bmdm->dm.getPolyDataLayout = bmDm_getPolyDataLayout;
-
-       bmdm->dm.getNumVerts = emDM_getNumVerts;
-       bmdm->dm.getNumEdges = emDM_getNumEdges;
-       bmdm->dm.getNumTessFaces = emDM_getNumTessFaces;
-       bmdm->dm.getNumLoops = emDM_getNumLoops;
-       bmdm->dm.getNumPolys = emDM_getNumPolys;
-
-       bmdm->dm.getVert = emDM_getVert;
-       bmdm->dm.getVertCo = emDM_getVertCo;
-       bmdm->dm.getVertNo = emDM_getVertNo;
-       bmdm->dm.getPolyNo = emDM_getPolyNo;
-       bmdm->dm.getEdge = emDM_getEdge;
-       bmdm->dm.getTessFace = emDM_getTessFace;
-       bmdm->dm.copyVertArray = emDM_copyVertArray;
-       bmdm->dm.copyEdgeArray = emDM_copyEdgeArray;
-       bmdm->dm.copyTessFaceArray = emDM_copyTessFaceArray;
-       bmdm->dm.copyLoopArray = emDM_copyLoopArray;
-       bmdm->dm.copyPolyArray = emDM_copyPolyArray;
-
-       bmdm->dm.getTessFaceDataArray = emDM_getTessFaceDataArray;
-
-       bmdm->dm.calcNormals = emDM_calcNormals;
-       bmdm->dm.calcLoopNormals = emDM_calcLoopNormals;
-       bmdm->dm.calcLoopNormalsSpaceArray = emDM_calcLoopNormalsSpaceArray;
-       bmdm->dm.calcLoopTangents = emDM_calc_loop_tangents;
-       bmdm->dm.recalcTessellation = emDM_recalcTessellation;
-       bmdm->dm.recalcLoopTri = emDM_recalcLoopTri;
-
-       bmdm->dm.foreachMappedVert = emDM_foreachMappedVert;
-       bmdm->dm.foreachMappedLoop = emDM_foreachMappedLoop;
-       bmdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
-       bmdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
-
-       bmdm->dm.release = emDM_release;
-
-       bmdm->emd.vertexCos = (const float (*)[3])vertexCos;
-       bmdm->dm.deformedOnly = (vertexCos != NULL);
-
-       const int cd_dvert_offset = (data_mask & CD_MASK_MDEFORMVERT) ?
-               CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT) : -1;
-
-       if (cd_dvert_offset != -1) {
-               BMIter iter;
-               BMVert *eve;
-               int i;
-
-               DM_add_vert_layer(&bmdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
-
-               BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
-                       DM_set_vert_data(&bmdm->dm, i, CD_MDEFORMVERT,
-                                        BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset));
-               }
-       }
-
-       const int cd_skin_offset = (data_mask & CD_MASK_MVERT_SKIN) ?
-               CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN) : -1;
-
-       if (cd_skin_offset != -1) {
-               BMIter iter;
-               BMVert *eve;
-               int i;
-
-               DM_add_vert_layer(&bmdm->dm, CD_MVERT_SKIN, CD_CALLOC, NULL);
-
-               BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
-                       DM_set_vert_data(&bmdm->dm, i, CD_MVERT_SKIN,
-                                        BM_ELEM_CD_GET_VOID_P(eve, cd_skin_offset));
-               }
-       }
-
-       return (DerivedMesh *)bmdm;
-}
-
-
-
 /* -------------------------------------------------------------------- */
 /* StatVis Functions */
 
 /* -------------------------------------------------------------------- */
 /* StatVis Functions */
 
@@ -1352,18 +439,15 @@ static void statvis_calc_sharp(
 }
 
 void BKE_editmesh_statvis_calc(
 }
 
 void BKE_editmesh_statvis_calc(
-        BMEditMesh *em, DerivedMesh *dm,
+        BMEditMesh *em, EditMeshData *emd,
         const MeshStatVis *statvis)
 {
         const MeshStatVis *statvis)
 {
-       EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
-       BLI_assert(dm == NULL || dm->type == DM_TYPE_EDITBMESH);
-
        switch (statvis->type) {
                case SCE_STATVIS_OVERHANG:
                {
                        BKE_editmesh_color_ensure(em, BM_FACE);
                        statvis_calc_overhang(
        switch (statvis->type) {
                case SCE_STATVIS_OVERHANG:
                {
                        BKE_editmesh_color_ensure(em, BM_FACE);
                        statvis_calc_overhang(
-                                   em, bmdm ? bmdm->emd.polyNos : NULL,
+                                   em, emd ? emd->polyNos : NULL,
                                    statvis->overhang_min / (float)M_PI,
                                    statvis->overhang_max / (float)M_PI,
                                    statvis->overhang_axis,
                                    statvis->overhang_min / (float)M_PI,
                                    statvis->overhang_max / (float)M_PI,
                                    statvis->overhang_axis,
@@ -1375,7 +459,7 @@ void BKE_editmesh_statvis_calc(
                        const float scale = 1.0f / mat4_to_scale(em->ob->obmat);
                        BKE_editmesh_color_ensure(em, BM_FACE);
                        statvis_calc_thickness(
                        const float scale = 1.0f / mat4_to_scale(em->ob->obmat);
                        BKE_editmesh_color_ensure(em, BM_FACE);
                        statvis_calc_thickness(
-                                   em, bmdm ? bmdm->emd.vertexCos : NULL,
+                                   em, emd ? emd->vertexCos : NULL,
                                    statvis->thickness_min * scale,
                                    statvis->thickness_max * scale,
                                    statvis->thickness_samples,
                                    statvis->thickness_min * scale,
                                    statvis->thickness_max * scale,
                                    statvis->thickness_samples,
@@ -1386,7 +470,7 @@ void BKE_editmesh_statvis_calc(
                {
                        BKE_editmesh_color_ensure(em, BM_FACE);
                        statvis_calc_intersect(
                {
                        BKE_editmesh_color_ensure(em, BM_FACE);
                        statvis_calc_intersect(
-                                   em, bmdm ? bmdm->emd.vertexCos : NULL,
+                                   em, emd ? emd->vertexCos : NULL,
                                    em->derivedFaceColor);
                        break;
                }
                                    em->derivedFaceColor);
                        break;
                }
@@ -1394,11 +478,12 @@ void BKE_editmesh_statvis_calc(
                {
                        BKE_editmesh_color_ensure(em, BM_FACE);
 
                {
                        BKE_editmesh_color_ensure(em, BM_FACE);
 
-                       if (bmdm)
-                               emDM_ensurePolyNormals(bmdm);
+                       if (emd) {
+                               BKE_editmesh_cache_ensure_poly_normals(em, emd);
+                       }
 
                        statvis_calc_distort(
 
                        statvis_calc_distort(
-                               em, bmdm ? bmdm->emd.vertexCos : NULL, bmdm ? bmdm->emd.polyNos : NULL,
+                               em, emd ? emd->vertexCos : NULL, emd ? emd->polyNos : NULL,
                                statvis->distort_min,
                                statvis->distort_max,
                                em->derivedFaceColor);
                                statvis->distort_min,
                                statvis->distort_max,
                                em->derivedFaceColor);
@@ -1408,7 +493,7 @@ void BKE_editmesh_statvis_calc(
                {
                        BKE_editmesh_color_ensure(em, BM_VERT);
                        statvis_calc_sharp(
                {
                        BKE_editmesh_color_ensure(em, BM_VERT);
                        statvis_calc_sharp(
-                               em, bmdm ? bmdm->emd.vertexCos : NULL,
+                               em, emd ? emd->vertexCos : NULL,
                                statvis->sharp_min,
                                statvis->sharp_max,
                                /* in this case they are vertex colors */
                                statvis->sharp_min,
                                statvis->sharp_max,
                                /* in this case they are vertex colors */