Merge branch 'master' into blender2.8
[blender.git] / source / blender / blenkernel / intern / mesh.c
index fd56534146d40dd28f31addba7d485420c35a61f..d5a87058ecb69008496cbde87cbb6dc654c677ac 100644 (file)
@@ -59,7 +59,6 @@
 #include "BKE_multires.h"
 #include "BKE_key.h"
 #include "BKE_mball.h"
-#include "BKE_depsgraph.h"
 /* these 2 are only used by conversion functions */
 #include "BKE_curve.h"
 /* -- */
@@ -67,6 +66,7 @@
 #include "BKE_editmesh.h"
 
 #include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
 
 /* Define for cases when you want extra validation of mesh
  * after certain modifications.
@@ -127,7 +127,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++;
                }
@@ -135,7 +135,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++;
                }
@@ -149,14 +149,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++;
@@ -324,7 +324,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);
@@ -335,7 +335,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) {
@@ -344,7 +344,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);
                        }
                }
@@ -388,6 +388,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.
  *
@@ -396,14 +438,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)
@@ -422,7 +461,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);
 }
@@ -442,6 +480,8 @@ void BKE_mesh_free(Mesh *me)
 {
        BKE_animdata_free(&me->id, false);
 
+       BKE_mesh_batch_cache_free(me);
+
        CustomData_free(&me->vdata, me->totvert);
        CustomData_free(&me->edata, me->totedge);
        CustomData_free(&me->fdata, me->totface);
@@ -529,6 +569,7 @@ void BKE_mesh_copy_data(Main *bmain, Mesh *me_dst, const Mesh *me_src, const int
        BKE_mesh_update_customdata_pointers(me_dst, do_tessface);
 
        me_dst->edit_btmesh = NULL;
+       me_dst->batch_cache = NULL;
 
        me_dst->mselect = MEM_dupallocN(me_dst->mselect);
        me_dst->bb = MEM_dupallocN(me_dst->bb);
@@ -586,33 +627,44 @@ bool BKE_mesh_uv_cdlayer_rename_index(Mesh *me, const int poly_index, const int
                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;
+       cdlp = (poly_index != -1) ? &pdata->layers[poly_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);
+       }
+
+       if (cdlp == NULL && cdlf == NULL) {
+               return false;
        }
 
        /* 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++) {
+       for (i = 1;
+            (cdlp && !STREQ(cdlu->name, cdlp->name)) ||
+            (cdlf && !STREQ(cdlu->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);
+                               if (cdlp) {
+                                       BLI_strncpy(cdlp->name, cdlu->name, sizeof(cdlp->name));
+                                       CustomData_set_layer_unique_name(pdata, poly_index);
+                               }
                                break;
                        case 1:
                                BLI_strncpy(cdlu->name, cdlp->name, sizeof(cdlu->name));
-                               CustomData_set_layer_unique_name(ldata, cdlu - ldata->layers);
+                               CustomData_set_layer_unique_name(ldata, loop_index);
                                break;
                        case 2:
                                if (cdlf) {
-                                       BLI_strncpy(cdlf->name, cdlp->name, sizeof(cdlf->name));
-                                       CustomData_set_layer_unique_name(fdata, cdlf - fdata->layers);
+                                       BLI_strncpy(cdlf->name, cdlu->name, sizeof(cdlf->name));
+                                       CustomData_set_layer_unique_name(fdata, face_index);
                                }
                                break;
                }
@@ -623,66 +675,44 @@ bool BKE_mesh_uv_cdlayer_rename_index(Mesh *me, const int poly_index, const int
 
 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;
-                               }
-                       }
-                       pidx = lidx;
-               }
-               else {
-                       if (lidx == -1) {
-                               lidx = pidx;
+               if (lidx == -1) {
+                       if (fidx == -1) {
+                               /* No layer found with this name! */
+                               return false;
                        }
-                       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, -1, lidx, fidx, new_name, do_tessface);
        }
 }
 
@@ -760,6 +790,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;
@@ -1383,7 +1425,6 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use
 
                if (alluv) {
                        const char *uvname = "Orco";
-                       me->mtpoly = CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname);
                        me->mloopuv = CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, me->totloop, uvname);
                }
 
@@ -1603,10 +1644,10 @@ void BKE_mesh_to_curve_nurblist(DerivedMesh *dm, ListBase *nurblist, const int e
        }
 }
 
-void BKE_mesh_to_curve(Scene *scene, Object *ob)
+void BKE_mesh_to_curve(Depsgraph *depsgraph, Scene *scene, Object *ob)
 {
        /* make new mesh data from the original copy */
-       DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_MESH);
+       DerivedMesh *dm = mesh_get_derived_final(depsgraph, scene, ob, CD_MASK_MESH);
        ListBase nurblist = {NULL, NULL};
        bool needsFree = false;
 
@@ -2388,13 +2429,13 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
 
 /* settings: 1 - preview, 2 - render */
 Mesh *BKE_mesh_new_from_object(
-        Main *bmain, Scene *sce, Object *ob,
-        int apply_modifiers, int settings, int calc_tessface, int calc_undeformed)
+        Depsgraph *depsgraph, Main *bmain, Scene *sce, Object *ob,
+        int apply_modifiers, int calc_tessface, int calc_undeformed)
 {
        Mesh *tmpmesh;
        Curve *tmpcu = NULL, *copycu;
        int i;
-       const bool render = (settings == eModifierMode_Render);
+       const bool render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
        const bool cage = !apply_modifiers;
        bool do_mat_id_data_us = true;
 
@@ -2447,7 +2488,7 @@ Mesh *BKE_mesh_new_from_object(
                        copycu->editnurb = tmpcu->editnurb;
 
                        /* get updated display list, and convert to a mesh */
-                       BKE_displist_make_curveTypes_forRender(sce, tmpobj, &dispbase, &derivedFinal, false, render);
+                       BKE_displist_make_curveTypes_forRender(depsgraph, sce, tmpobj, &dispbase, &derivedFinal, false, render);
 
                        copycu->editfont = NULL;
                        copycu->editnurb = NULL;
@@ -2496,13 +2537,7 @@ Mesh *BKE_mesh_new_from_object(
 
                        if (render) {
                                ListBase disp = {NULL, NULL};
-                               /* TODO(sergey): This is gonna to work for until EvaluationContext
-                                *               only contains for_render flag. As soon as CoW is
-                                *               implemented, this is to be rethought.
-                                */
-                               EvaluationContext eval_ctx;
-                               DEG_evaluation_context_init(&eval_ctx, DAG_EVAL_RENDER);
-                               BKE_displist_make_mball_forRender(&eval_ctx, sce, ob, &disp);
+                               BKE_displist_make_mball_forRender(depsgraph, sce, ob, &disp);
                                BKE_mesh_from_metaball(&disp, tmpmesh);
                                BKE_displist_free(&disp);
                        }
@@ -2541,9 +2576,9 @@ Mesh *BKE_mesh_new_from_object(
 
                                /* Write the display mesh into the dummy mesh */
                                if (render)
-                                       dm = mesh_create_derived_render(sce, ob, mask);
+                                       dm = mesh_create_derived_render(depsgraph, sce, ob, mask);
                                else
-                                       dm = mesh_create_derived_view(sce, ob, mask);
+                                       dm = mesh_create_derived_view(depsgraph, sce, ob, mask);
 
                                tmpmesh = BKE_mesh_add(bmain, ((ID *)ob->data)->name + 2);
                                DM_to_mesh(dm, tmpmesh, ob, mask, true);
@@ -2634,7 +2669,7 @@ Mesh *BKE_mesh_new_from_object(
 
 /* **** Depsgraph evaluation **** */
 
-void BKE_mesh_eval_geometry(EvaluationContext *UNUSED(eval_ctx),
+void BKE_mesh_eval_geometry(Depsgraph *UNUSED(depsgraph),
                             Mesh *mesh)
 {
        DEG_debug_print_eval(__func__, mesh->id.name, mesh);
@@ -2642,3 +2677,20 @@ void BKE_mesh_eval_geometry(EvaluationContext *UNUSED(eval_ctx),
                BKE_mesh_texspace_calc(mesh);
        }
 }
+
+/* Draw Engine */
+void (*BKE_mesh_batch_cache_dirty_cb)(Mesh *me, int mode) = NULL;
+void (*BKE_mesh_batch_cache_free_cb)(Mesh *me) = NULL;
+
+void BKE_mesh_batch_cache_dirty(Mesh *me, int mode)
+{
+       if (me->batch_cache) {
+               BKE_mesh_batch_cache_dirty_cb(me, mode);
+       }
+}
+void BKE_mesh_batch_cache_free(Mesh *me)
+{
+       if (me->batch_cache) {
+               BKE_mesh_batch_cache_free_cb(me);
+       }
+}