Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / mesh.c
index 770d482..e83f2d9 100644 (file)
 #include "BLI_string.h"
 
 #include "BKE_animsys.h"
+#include "BKE_idcode.h"
 #include "BKE_main.h"
 #include "BKE_DerivedMesh.h"
 #include "BKE_global.h"
 #include "BKE_mesh.h"
+#include "BKE_mesh_runtime.h"
 #include "BKE_library.h"
 #include "BKE_material.h"
 #include "BKE_modifier.h"
 #include "BKE_multires.h"
-#include "BKE_depsgraph.h"
 #include "BKE_object.h"
 #include "BKE_editmesh.h"
 
@@ -109,7 +110,7 @@ static int customdata_compare(CustomData *c1, CustomData *c2, Mesh *m1, Mesh *m2
        
        for (i = 0; i < c1->totlayer; i++) {
                if (ELEM(c1->layers[i].type, CD_MVERT, CD_MEDGE, CD_MPOLY,
-                        CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
+                        CD_MLOOPUV, CD_MLOOPCOL, CD_MDEFORMVERT))
                {
                        i1++;
                }
@@ -117,7 +118,7 @@ static int customdata_compare(CustomData *c1, CustomData *c2, Mesh *m1, Mesh *m2
 
        for (i = 0; i < c2->totlayer; i++) {
                if (ELEM(c2->layers[i].type, CD_MVERT, CD_MEDGE, CD_MPOLY,
-                        CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
+                        CD_MLOOPUV, CD_MLOOPCOL, CD_MDEFORMVERT))
                {
                        i2++;
                }
@@ -131,14 +132,14 @@ static int customdata_compare(CustomData *c1, CustomData *c2, Mesh *m1, Mesh *m2
        i1 = 0; i2 = 0;
        for (i = 0; i < tot; i++) {
                while (i1 < c1->totlayer && !ELEM(l1->type, CD_MVERT, CD_MEDGE, CD_MPOLY,
-                                                 CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
+                                                 CD_MLOOPUV, CD_MLOOPCOL, CD_MDEFORMVERT))
                {
                        i1++;
                        l1++;
                }
 
                while (i2 < c2->totlayer && !ELEM(l2->type, CD_MVERT, CD_MEDGE, CD_MPOLY,
-                                                 CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
+                                                 CD_MLOOPUV, CD_MLOOPCOL, CD_MDEFORMVERT))
                {
                        i2++;
                        l2++;
@@ -306,7 +307,7 @@ static void mesh_ensure_tessellation_customdata(Mesh *me)
                 * Callers could also check but safer to do here - campbell */
        }
        else {
-               const int tottex_original = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
+               const int tottex_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
                const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
 
                const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
@@ -317,7 +318,7 @@ static void mesh_ensure_tessellation_customdata(Mesh *me)
                {
                        BKE_mesh_tessface_clear(me);
 
-                       CustomData_from_bmeshpoly(&me->fdata, &me->pdata, &me->ldata, me->totface);
+                       CustomData_from_bmeshpoly(&me->fdata, &me->ldata, me->totface);
 
                        /* TODO - add some --debug-mesh option */
                        if (G.debug & G_DEBUG) {
@@ -326,7 +327,7 @@ static void mesh_ensure_tessellation_customdata(Mesh *me)
                                 * and check if there was any data to begin with, for now just print the warning with
                                 * some info to help troubleshoot whats going on - campbell */
                                printf("%s: warning! Tessellation uvs or vcol data got out of sync, "
-                                      "had to reset!\n    CD_MTFACE: %d != CD_MTEXPOLY: %d || CD_MCOL: %d != CD_MLOOPCOL: %d\n",
+                                      "had to reset!\n    CD_MTFACE: %d != CD_MLOOPUV: %d || CD_MCOL: %d != CD_MLOOPCOL: %d\n",
                                       __func__, tottex_tessface, tottex_original, totcol_tessface, totcol_original);
                        }
                }
@@ -370,6 +371,48 @@ void BKE_mesh_ensure_skin_customdata(Mesh *me)
        }
 }
 
+bool BKE_mesh_ensure_facemap_customdata(struct Mesh *me)
+{
+       BMesh *bm = me->edit_btmesh ? me->edit_btmesh->bm : NULL;
+       bool changed = false;
+       if (bm) {
+               if (!CustomData_has_layer(&bm->pdata, CD_FACEMAP)) {
+                       BM_data_layer_add(bm, &bm->pdata, CD_FACEMAP);
+                       changed = true;
+               }
+       }
+       else {
+               if (!CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
+                       CustomData_add_layer(&me->pdata,
+                                                 CD_FACEMAP,
+                                                 CD_DEFAULT,
+                                                 NULL,
+                                                 me->totpoly);
+                       changed = true;
+               }
+       }
+       return changed;
+}
+
+bool BKE_mesh_clear_facemap_customdata(struct Mesh *me)
+{
+       BMesh *bm = me->edit_btmesh ? me->edit_btmesh->bm : NULL;
+       bool changed = false;
+       if (bm) {
+               if (CustomData_has_layer(&bm->pdata, CD_FACEMAP)) {
+                       BM_data_layer_free(bm, &bm->pdata, CD_FACEMAP);
+                       changed = true;
+               }
+       }
+       else {
+               if (CustomData_has_layer(&me->pdata, CD_FACEMAP)) {
+                       CustomData_free_layers(&me->pdata, CD_FACEMAP, me->totpoly);
+                       changed = true;
+               }
+       }
+       return changed;
+}
+
 /* this ensures grouped customdata (e.g. mtexpoly and mloopuv and mtface, or
  * mloopcol and mcol) have the same relative active/render/clone/mask indices.
  *
@@ -378,14 +421,11 @@ void BKE_mesh_ensure_skin_customdata(Mesh *me)
  * versions of the mesh. - campbell*/
 static void mesh_update_linked_customdata(Mesh *me, const bool do_ensure_tess_cd)
 {
-       if (me->edit_btmesh)
-               BKE_editmesh_update_linked_customdata(me->edit_btmesh);
-
        if (do_ensure_tess_cd) {
                mesh_ensure_tessellation_customdata(me);
        }
 
-       CustomData_bmesh_update_active_layers(&me->fdata, &me->pdata, &me->ldata);
+       CustomData_bmesh_update_active_layers(&me->fdata, &me->ldata);
 }
 
 void BKE_mesh_update_customdata_pointers(Mesh *me, const bool do_ensure_tess_cd)
@@ -404,7 +444,6 @@ void BKE_mesh_update_customdata_pointers(Mesh *me, const bool do_ensure_tess_cd)
        me->mpoly = CustomData_get_layer(&me->pdata, CD_MPOLY);
        me->mloop = CustomData_get_layer(&me->ldata, CD_MLOOP);
 
-       me->mtpoly = CustomData_get_layer(&me->pdata, CD_MTEXPOLY);
        me->mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
        me->mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
 }
@@ -424,6 +463,8 @@ void BKE_mesh_free(Mesh *me)
 {
        BKE_animdata_free(&me->id, false);
 
+       BKE_mesh_runtime_clear_cache(me);
+
        CustomData_free(&me->vdata, me->totvert);
        CustomData_free(&me->edata, me->totedge);
        CustomData_free(&me->fdata, me->totface);
@@ -494,15 +535,22 @@ Mesh *BKE_mesh_add(Main *bmain, const char *name)
 void BKE_mesh_copy_data(Main *bmain, Mesh *me_dst, const Mesh *me_src, const int flag)
 {
        const bool do_tessface = ((me_src->totface != 0) && (me_src->totpoly == 0)); /* only do tessface if we have no polys */
+       CustomDataMask mask = CD_MASK_MESH;
+
+       if (me_src->id.tag & LIB_TAG_NO_MAIN) {
+               /* For copies in depsgraph, keep data like origindex and orco. */
+               mask |= CD_MASK_DERIVEDMESH;
+       }
 
        me_dst->mat = MEM_dupallocN(me_src->mat);
 
-       CustomData_copy(&me_src->vdata, &me_dst->vdata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totvert);
-       CustomData_copy(&me_src->edata, &me_dst->edata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totedge);
-       CustomData_copy(&me_src->ldata, &me_dst->ldata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totloop);
-       CustomData_copy(&me_src->pdata, &me_dst->pdata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totpoly);
+       const eCDAllocType alloc_type = (flag & LIB_ID_COPY_CD_REFERENCE) ? CD_REFERENCE : CD_DUPLICATE;
+       CustomData_copy(&me_src->vdata, &me_dst->vdata, mask, alloc_type, me_dst->totvert);
+       CustomData_copy(&me_src->edata, &me_dst->edata, mask, alloc_type, me_dst->totedge);
+       CustomData_copy(&me_src->ldata, &me_dst->ldata, mask, alloc_type, me_dst->totloop);
+       CustomData_copy(&me_src->pdata, &me_dst->pdata, mask, alloc_type, me_dst->totpoly);
        if (do_tessface) {
-               CustomData_copy(&me_src->fdata, &me_dst->fdata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totface);
+               CustomData_copy(&me_src->fdata, &me_dst->fdata, mask, alloc_type, me_dst->totface);
        }
        else {
                mesh_tessface_clear_intern(me_dst, false);
@@ -512,159 +560,262 @@ void BKE_mesh_copy_data(Main *bmain, Mesh *me_dst, const Mesh *me_src, const int
 
        me_dst->edit_btmesh = NULL;
 
+       /* Call BKE_mesh_runtime_reset? */
+       me_dst->runtime.batch_cache = NULL;
+       me_dst->runtime.looptris.array = NULL;
+       me_dst->runtime.bvh_cache = NULL;
+
+       if (me_src->id.tag & LIB_TAG_NO_MAIN) {
+               me_dst->runtime.deformed_only = me_src->runtime.deformed_only;
+       }
+       else {
+               /* This is a direct copy of a main mesh, so for now it has the same topology. */
+               me_dst->runtime.deformed_only = 1;
+       }
+
        me_dst->mselect = MEM_dupallocN(me_dst->mselect);
        me_dst->bb = MEM_dupallocN(me_dst->bb);
 
        /* TODO Do we want to add flag to prevent this? */
-       if (me_src->key) {
+       if (me_src->key && (flag & LIB_ID_COPY_SHAPEKEY)) {
                BKE_id_copy_ex(bmain, &me_src->key->id, (ID **)&me_dst->key, flag, false);
        }
 }
 
+/* Custom data layer functions; those assume that totXXX are set correctly. */
+static void mesh_ensure_cdlayers_primary(Mesh *mesh, bool do_tessface)
+{
+       if (!CustomData_get_layer(&mesh->vdata, CD_MVERT))
+               CustomData_add_layer(&mesh->vdata, CD_MVERT, CD_CALLOC, NULL, mesh->totvert);
+       if (!CustomData_get_layer(&mesh->edata, CD_MEDGE))
+               CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_CALLOC, NULL, mesh->totedge);
+       if (!CustomData_get_layer(&mesh->ldata, CD_MLOOP))
+               CustomData_add_layer(&mesh->ldata, CD_MLOOP, CD_CALLOC, NULL, mesh->totloop);
+       if (!CustomData_get_layer(&mesh->pdata, CD_MPOLY))
+               CustomData_add_layer(&mesh->pdata, CD_MPOLY, CD_CALLOC, NULL, mesh->totpoly);
+
+       if (do_tessface && !CustomData_get_layer(&mesh->fdata, CD_MFACE))
+               CustomData_add_layer(&mesh->fdata, CD_MFACE, CD_CALLOC, NULL, mesh->totface);
+}
+static void mesh_ensure_cdlayers_origindex(Mesh *mesh, bool do_tessface)
+{
+       if (!CustomData_get_layer(&mesh->vdata, CD_ORIGINDEX))
+               CustomData_add_layer(&mesh->vdata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totvert);
+       if (!CustomData_get_layer(&mesh->edata, CD_ORIGINDEX))
+               CustomData_add_layer(&mesh->edata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totedge);
+       if (!CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX))
+               CustomData_add_layer(&mesh->pdata, CD_ORIGINDEX, CD_CALLOC, NULL,  mesh->totpoly);
+
+       if (do_tessface && !CustomData_get_layer(&mesh->fdata, CD_ORIGINDEX))
+               CustomData_add_layer(&mesh->fdata, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totface);
+}
+
+Mesh *BKE_mesh_new_nomain(int verts_len, int edges_len, int tessface_len, int loops_len, int polys_len)
+{
+       Mesh *mesh = BKE_libblock_alloc(
+               NULL, ID_ME,
+               BKE_idcode_to_name(ID_ME),
+               LIB_ID_CREATE_NO_MAIN |
+               LIB_ID_CREATE_NO_USER_REFCOUNT |
+               LIB_ID_CREATE_NO_DEG_TAG);
+       BKE_libblock_init_empty(&mesh->id);
+
+       /* don't use CustomData_reset(...); because we dont want to touch customdata */
+       copy_vn_i(mesh->vdata.typemap, CD_NUMTYPES, -1);
+       copy_vn_i(mesh->edata.typemap, CD_NUMTYPES, -1);
+       copy_vn_i(mesh->fdata.typemap, CD_NUMTYPES, -1);
+       copy_vn_i(mesh->ldata.typemap, CD_NUMTYPES, -1);
+       copy_vn_i(mesh->pdata.typemap, CD_NUMTYPES, -1);
+
+       mesh->totvert = verts_len;
+       mesh->totedge = edges_len;
+       mesh->totface = tessface_len;
+       mesh->totloop = loops_len;
+       mesh->totpoly = polys_len;
+
+       mesh_ensure_cdlayers_primary(mesh, true);
+       mesh_ensure_cdlayers_origindex(mesh, true);
+       BKE_mesh_update_customdata_pointers(mesh, false);
+
+       return mesh;
+}
+
+static Mesh *mesh_new_nomain_from_template_ex(
+        const Mesh *me_src,
+        int verts_len, int edges_len, int tessface_len,
+        int loops_len, int polys_len,
+        CustomDataMask mask)
+{
+       const bool do_tessface = ((me_src->totface != 0) && (me_src->totpoly == 0)); /* only do tessface if we have no polys */
+
+       Mesh *me_dst = BKE_id_new_nomain(ID_ME, NULL);
+
+       me_dst->mat = MEM_dupallocN(me_src->mat);
+       me_dst->mselect = MEM_dupallocN(me_dst->mselect);
+
+       me_dst->totvert = verts_len;
+       me_dst->totedge = edges_len;
+       me_dst->totface = tessface_len;
+       me_dst->totloop = loops_len;
+       me_dst->totpoly = polys_len;
+
+       CustomData_copy(&me_src->vdata, &me_dst->vdata, mask, CD_CALLOC, verts_len);
+       CustomData_copy(&me_src->edata, &me_dst->edata, mask, CD_CALLOC, edges_len);
+       CustomData_copy(&me_src->ldata, &me_dst->ldata, mask, CD_CALLOC, loops_len);
+       CustomData_copy(&me_src->pdata, &me_dst->pdata, mask, CD_CALLOC, polys_len);
+       if (do_tessface) {
+               CustomData_copy(&me_src->fdata, &me_dst->fdata, mask, CD_CALLOC, tessface_len);
+       }
+       else {
+               mesh_tessface_clear_intern(me_dst, false);
+       }
+
+       /* The destination mesh should at least have valid primary CD layers,
+        * even in cases where the source mesh does not. */
+       mesh_ensure_cdlayers_primary(me_dst, do_tessface);
+       mesh_ensure_cdlayers_origindex(me_dst, false);
+       BKE_mesh_update_customdata_pointers(me_dst, false);
+
+       return me_dst;
+}
+
+Mesh * BKE_mesh_new_nomain_from_template(
+        const Mesh *me_src,
+        int verts_len, int edges_len, int tessface_len,
+        int loops_len, int polys_len)
+{
+       return mesh_new_nomain_from_template_ex(
+               me_src,
+               verts_len, edges_len, tessface_len,
+               loops_len, polys_len,
+               CD_MASK_EVERYTHING);
+}
+
 Mesh *BKE_mesh_copy(Main *bmain, const Mesh *me)
 {
        Mesh *me_copy;
-       BKE_id_copy_ex(bmain, &me->id, (ID **)&me_copy, 0, false);
+       BKE_id_copy_ex(bmain, &me->id, (ID **)&me_copy, LIB_ID_COPY_SHAPEKEY, false);
        return me_copy;
 }
 
-BMesh *BKE_mesh_to_bmesh(
-        Mesh *me, Object *ob,
-        const bool add_key_index, const struct BMeshCreateParams *params)
+BMesh *BKE_mesh_to_bmesh_ex(
+        Mesh *me,
+        const struct BMeshCreateParams *create_params,
+        const struct BMeshFromMeshParams *convert_params)
 {
        BMesh *bm;
        const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me);
 
-       bm = BM_mesh_create(&allocsize, params);
-
-       BM_mesh_bm_from_me(
-               bm, me, (&(struct BMeshFromMeshParams){
-                   .add_key_index = add_key_index, .use_shapekey = true, .active_shapekey = ob->shapenr,
-               }));
+       bm = BM_mesh_create(&allocsize, create_params);
+       BM_mesh_bm_from_me(bm, me, convert_params);
 
        return bm;
 }
 
+BMesh *BKE_mesh_to_bmesh(
+        Mesh *me, Object *ob,
+        const bool add_key_index, const struct BMeshCreateParams *params)
+{
+       return BKE_mesh_to_bmesh_ex(
+               me, params,
+               &(struct BMeshFromMeshParams){
+                   .calc_face_normal = false,
+                   .add_key_index = add_key_index,
+                   .use_shapekey = true,
+                   .active_shapekey = ob->shapenr,
+               });
+}
+
+Mesh *BKE_bmesh_to_mesh_nomain(BMesh *bm, const struct BMeshToMeshParams *params)
+{
+       BLI_assert(params->calc_object_remap == false);
+       Mesh *mesh = BKE_id_new_nomain(ID_ME, NULL);
+       BM_mesh_bm_to_me(NULL, bm, mesh, params);
+       return mesh;
+}
+
 void BKE_mesh_make_local(Main *bmain, Mesh *me, const bool lib_local)
 {
        BKE_id_make_local_generic(bmain, &me->id, true, lib_local);
 }
 
-bool BKE_mesh_uv_cdlayer_rename_index(Mesh *me, const int poly_index, const int loop_index, const int face_index,
-                                      const char *new_name, const bool do_tessface)
+bool BKE_mesh_uv_cdlayer_rename_index(
+        Mesh *me, const int loop_index, const int face_index,
+        const char *new_name, const bool do_tessface)
 {
-       CustomData *pdata, *ldata, *fdata;
-       CustomDataLayer *cdlp, *cdlu, *cdlf;
-       const int step = do_tessface ? 3 : 2;
-       int i;
+       CustomData *ldata, *fdata;
+       CustomDataLayer *cdlu, *cdlf;
 
        if (me->edit_btmesh) {
-               pdata = &me->edit_btmesh->bm->pdata;
                ldata = &me->edit_btmesh->bm->ldata;
                fdata = NULL;  /* No tessellated data in BMesh! */
        }
        else {
-               pdata = &me->pdata;
                ldata = &me->ldata;
                fdata = &me->fdata;
        }
-       cdlp = &pdata->layers[poly_index];
+
        cdlu = &ldata->layers[loop_index];
-       cdlf = fdata && do_tessface ? &fdata->layers[face_index] : NULL;
+       cdlf = (face_index != -1) && fdata && do_tessface ? &fdata->layers[face_index] : NULL;
 
-       if (cdlp->name != new_name) {
+       if (cdlu->name != new_name) {
                /* Mesh validate passes a name from the CD layer as the new name,
                 * Avoid memcpy from self to self in this case.
                 */
-               BLI_strncpy(cdlp->name, new_name, sizeof(cdlp->name));
-               CustomData_set_layer_unique_name(pdata, cdlp - pdata->layers);
+               BLI_strncpy(cdlu->name, new_name, sizeof(cdlu->name));
+               CustomData_set_layer_unique_name(ldata, loop_index);
        }
 
-       /* Loop until we do have exactly the same name for all layers! */
-       for (i = 1; !STREQ(cdlp->name, cdlu->name) || (cdlf && !STREQ(cdlp->name, cdlf->name)); i++) {
-               switch (i % step) {
-                       case 0:
-                               BLI_strncpy(cdlp->name, cdlu->name, sizeof(cdlp->name));
-                               CustomData_set_layer_unique_name(pdata, cdlp - pdata->layers);
-                               break;
-                       case 1:
-                               BLI_strncpy(cdlu->name, cdlp->name, sizeof(cdlu->name));
-                               CustomData_set_layer_unique_name(ldata, cdlu - ldata->layers);
-                               break;
-                       case 2:
-                               if (cdlf) {
-                                       BLI_strncpy(cdlf->name, cdlp->name, sizeof(cdlf->name));
-                                       CustomData_set_layer_unique_name(fdata, cdlf - fdata->layers);
-                               }
-                               break;
-               }
+       if (cdlf == NULL) {
+               return false;
        }
 
+       BLI_strncpy(cdlf->name, cdlu->name, sizeof(cdlf->name));
+       CustomData_set_layer_unique_name(fdata, face_index);
+
        return true;
 }
 
 bool BKE_mesh_uv_cdlayer_rename(Mesh *me, const char *old_name, const char *new_name, bool do_tessface)
 {
-       CustomData *pdata, *ldata, *fdata;
+       CustomData *ldata, *fdata;
        if (me->edit_btmesh) {
-               pdata = &me->edit_btmesh->bm->pdata;
                ldata = &me->edit_btmesh->bm->ldata;
                /* No tessellated data in BMesh! */
                fdata = NULL;
                do_tessface = false;
        }
        else {
-               pdata = &me->pdata;
                ldata = &me->ldata;
                fdata = &me->fdata;
                do_tessface = (do_tessface && fdata->totlayer);
        }
 
        {
-               const int pidx_start = CustomData_get_layer_index(pdata, CD_MTEXPOLY);
                const int lidx_start = CustomData_get_layer_index(ldata, CD_MLOOPUV);
                const int fidx_start = do_tessface ? CustomData_get_layer_index(fdata, CD_MTFACE) : -1;
-               int pidx = CustomData_get_named_layer(pdata, CD_MTEXPOLY, old_name);
                int lidx = CustomData_get_named_layer(ldata, CD_MLOOPUV, old_name);
                int fidx = do_tessface ? CustomData_get_named_layer(fdata, CD_MTFACE, old_name) : -1;
 
                /* None of those cases should happen, in theory!
                 * Note this assume we have the same number of mtexpoly, mloopuv and mtface layers!
                 */
-               if (pidx == -1) {
-                       if (lidx == -1) {
-                               if (fidx == -1) {
-                                       /* No layer found with this name! */
-                                       return false;
-                               }
-                               else {
-                                       lidx = fidx;
-                               }
+               if (lidx == -1) {
+                       if (fidx == -1) {
+                               /* No layer found with this name! */
+                               return false;
                        }
-                       pidx = lidx;
-               }
-               else {
-                       if (lidx == -1) {
-                               lidx = pidx;
-                       }
-                       if (fidx == -1 && do_tessface) {
-                               fidx = pidx;
+                       else {
+                               lidx = fidx;
                        }
                }
-#if 0
-               /* For now, we do not consider mismatch in indices (i.e. same name leading to (relative) different indices). */
-               else if (pidx != lidx) {
-                       lidx = pidx;
-               }
-#endif
 
                /* Go back to absolute indices! */
-               pidx += pidx_start;
                lidx += lidx_start;
                if (fidx != -1)
                        fidx += fidx_start;
 
-               return BKE_mesh_uv_cdlayer_rename_index(me, pidx, lidx, fidx, new_name, do_tessface);
+               return BKE_mesh_uv_cdlayer_rename_index(me, lidx, fidx, new_name, do_tessface);
        }
 }
 
@@ -742,6 +893,18 @@ void BKE_mesh_texspace_get(Mesh *me, float r_loc[3], float r_rot[3], float r_siz
        if (r_size) copy_v3_v3(r_size, me->size);
 }
 
+void BKE_mesh_texspace_get_reference(Mesh *me, short **r_texflag,  float **r_loc, float **r_rot, float **r_size)
+{
+       if (me->bb == NULL || (me->bb->flag & BOUNDBOX_DIRTY)) {
+               BKE_mesh_texspace_calc(me);
+       }
+
+       if (r_texflag != NULL) *r_texflag = &me->texflag;
+       if (r_loc != NULL) *r_loc = me->loc;
+       if (r_rot != NULL) *r_rot = me->rot;
+       if (r_size != NULL) *r_size = me->size;
+}
+
 void BKE_mesh_texspace_copy_from_object(Mesh *me, Object *ob)
 {
        float *texloc, *texrot, *texsize;
@@ -901,7 +1064,6 @@ void BKE_mesh_assign_object(Main *bmain, Object *ob, Mesh *me)
        test_object_modifiers(ob);
 }
 
-
 void BKE_mesh_material_index_remove(Mesh *me, short index)
 {
        MPoly *mp;
@@ -996,15 +1158,15 @@ void BKE_mesh_smooth_flag_set(Object *meshOb, int enableSmooth)
 
 /**
  * Return a newly MEM_malloc'd array of all the mesh vertex locations
- * \note \a r_numVerts may be NULL
+ * \note \a r_verts_len may be NULL
  */
-float (*BKE_mesh_vertexCos_get(const Mesh *me, int *r_numVerts))[3]
+float (*BKE_mesh_vertexCos_get(const Mesh *me, int *r_verts_len))[3]
 {
-       int i, numVerts = me->totvert;
-       float (*cos)[3] = MEM_malloc_arrayN(numVerts, sizeof(*cos), "vertexcos1");
+       int i, verts_len = me->totvert;
+       float (*cos)[3] = MEM_malloc_arrayN(verts_len, sizeof(*cos), "vertexcos1");
 
-       if (r_numVerts) *r_numVerts = numVerts;
-       for (i = 0; i < numVerts; i++)
+       if (r_verts_len) *r_verts_len = verts_len;
+       for (i = 0; i < verts_len; i++)
                copy_v3_v3(cos[i], me->mvert[i].co);
 
        return cos;
@@ -1135,13 +1297,13 @@ void BKE_mesh_ensure_navmesh(Mesh *me)
 {
        if (!CustomData_has_layer(&me->pdata, CD_RECAST)) {
                int i;
-               int numFaces = me->totpoly;
+               int polys_len = me->totpoly;
                int *recastData;
-               recastData = (int *)MEM_malloc_arrayN(numFaces, sizeof(int), __func__);
-               for (i = 0; i < numFaces; i++) {
+               recastData = (int *)MEM_malloc_arrayN(polys_len, sizeof(int), __func__);
+               for (i = 0; i < polys_len; i++) {
                        recastData[i] = i + 1;
                }
-               CustomData_add_layer_named(&me->pdata, CD_RECAST, CD_ASSIGN, recastData, numFaces, "recastData");
+               CustomData_add_layer_named(&me->pdata, CD_RECAST, CD_ASSIGN, recastData, polys_len, "recastData");
        }
 }
 
@@ -1332,6 +1494,22 @@ void BKE_mesh_mselect_active_set(Mesh *me, int index, int type)
                   (me->mselect[me->totselect - 1].type  == type));
 }
 
+
+void BKE_mesh_apply_vert_coords(Mesh *mesh, float (*vertCoords)[3])
+{
+       MVert *vert;
+       int i;
+
+       /* this will just return the pointer if it wasn't a referenced layer */
+       vert = CustomData_duplicate_referenced_layer(&mesh->vdata, CD_MVERT, mesh->totvert);
+       mesh->mvert = vert;
+
+       for (i = 0; i < mesh->totvert; ++i, ++vert)
+               copy_v3_v3(vert->co, vertCoords[i]);
+
+       mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
+}
+
 /**
  * Compute 'split' (aka loop, or per face corner's) normals.
  *
@@ -1383,6 +1561,8 @@ void BKE_mesh_calc_normals_split_ex(Mesh *mesh, MLoopNorSpaceArray *r_lnors_spac
        if (free_polynors) {
                MEM_freeN(polynors);
        }
+
+       mesh->runtime.cd_dirty_vert &= ~CD_MASK_NORMAL;
 }
 
 void BKE_mesh_calc_normals_split(Mesh *mesh)
@@ -1416,25 +1596,25 @@ static int split_faces_prepare_new_verts(
         * dealing with smooth/flat faces one can find cases that no simple algorithm can handle properly. */
        BLI_assert(lnors_spacearr != NULL);
 
-       const int num_loops = mesh->totloop;
-       int num_verts = mesh->totvert;
+       const int loops_len = mesh->totloop;
+       int verts_len = mesh->totvert;
        MVert *mvert = mesh->mvert;
        MLoop *mloop = mesh->mloop;
 
-       BLI_bitmap *verts_used = BLI_BITMAP_NEW(num_verts, __func__);
-       BLI_bitmap *done_loops = BLI_BITMAP_NEW(num_loops, __func__);
+       BLI_bitmap *verts_used = BLI_BITMAP_NEW(verts_len, __func__);
+       BLI_bitmap *done_loops = BLI_BITMAP_NEW(loops_len, __func__);
 
        MLoop *ml = mloop;
        MLoopNorSpace **lnor_space = lnors_spacearr->lspacearr;
 
        BLI_assert(lnors_spacearr->data_type == MLNOR_SPACEARR_LOOP_INDEX);
 
-       for (int loop_idx = 0; loop_idx < num_loops; loop_idx++, ml++, lnor_space++) {
+       for (int loop_idx = 0; loop_idx < loops_len; loop_idx++, ml++, lnor_space++) {
                if (!BLI_BITMAP_TEST(done_loops, loop_idx)) {
                        const int vert_idx = ml->v;
                        const bool vert_used = BLI_BITMAP_TEST_BOOL(verts_used, vert_idx);
                        /* If vert is already used by another smooth fan, we need a new vert for this one. */
-                       const int new_vert_idx = vert_used ? num_verts++ : vert_idx;
+                       const int new_vert_idx = vert_used ? verts_len++ : vert_idx;
 
                        BLI_assert(*lnor_space);
 
@@ -1479,7 +1659,7 @@ static int split_faces_prepare_new_verts(
        MEM_freeN(done_loops);
        MEM_freeN(verts_used);
 
-       return num_verts - mesh->totvert;
+       return verts_len - mesh->totvert;
 }
 
 /* Detect needed new edges, and update accordingly loops' edge indices.
@@ -1547,12 +1727,12 @@ static int split_faces_prepare_new_edges(
 static void split_faces_split_new_verts(
         Mesh *mesh, SplitFaceNewVert *new_verts, const int num_new_verts)
 {
-       const int num_verts = mesh->totvert - num_new_verts;
+       const int verts_len = mesh->totvert - num_new_verts;
        MVert *mvert = mesh->mvert;
 
        /* Remember new_verts is a single linklist, so its items are in reversed order... */
        MVert *new_mv = &mvert[mesh->totvert - 1];
-       for (int i = mesh->totvert - 1; i >= num_verts ; i--, new_mv--, new_verts = new_verts->next) {
+       for (int i = mesh->totvert - 1; i >= verts_len ; i--, new_mv--, new_verts = new_verts->next) {
                BLI_assert(new_verts->new_index == i);
                BLI_assert(new_verts->new_index != new_verts->orig_index);
                CustomData_copy_data(&mesh->vdata, &mesh->vdata, new_verts->orig_index, i, 1);
@@ -1647,13 +1827,12 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
 #endif
 }
 
-
 /* **** Depsgraph evaluation **** */
 
-void BKE_mesh_eval_geometry(EvaluationContext *UNUSED(eval_ctx),
+void BKE_mesh_eval_geometry(Depsgraph *depsgraph,
                             Mesh *mesh)
 {
-       DEG_debug_print_eval(__func__, mesh->id.name, mesh);
+       DEG_debug_print_eval(depsgraph, __func__, mesh->id.name, mesh);
        if (mesh->bb == NULL || (mesh->bb->flag & BOUNDBOX_DIRTY)) {
                BKE_mesh_texspace_calc(mesh);
        }