Fix usage of mesh_get_eval_final in vertex selection.
authorAlexander Gavrilov <angavrilov@gmail.com>
Sat, 1 Dec 2018 11:46:55 +0000 (14:46 +0300)
committerAlexander Gavrilov <angavrilov@gmail.com>
Sat, 1 Dec 2018 11:46:55 +0000 (14:46 +0300)
It's a very bad idea to call this on non-COW instances - see T58150.
Also, when rebuilding mesh it's better to accumulate mask flags to
avoid possible repeated rebuilds from different users.

source/blender/blenkernel/intern/DerivedMesh.c
source/blender/editors/mesh/meshtools.c

index a34d9642a9036a162ee9d36f92a98c09cdab116d..55898381fde5b27df5152cc42c79cb7feb1ccc55 100644 (file)
@@ -2153,6 +2153,9 @@ DerivedMesh *mesh_get_derived_final(
 Mesh *mesh_get_eval_final(
         struct Depsgraph *depsgraph, Scene *scene, Object *ob, CustomDataMask dataMask)
 {
 Mesh *mesh_get_eval_final(
         struct Depsgraph *depsgraph, Scene *scene, Object *ob, CustomDataMask dataMask)
 {
+       /* Evaluation meshes on original instances aren't cleaned up properly, causing crashes. */
+       BLI_assert(ob->id.tag & LIB_TAG_COPIED_ON_WRITE);
+
        /* if there's no evaluated mesh or the last data mask used doesn't include
         * the data we need, rebuild the derived mesh
         */
        /* if there's no evaluated mesh or the last data mask used doesn't include
         * the data we need, rebuild the derived mesh
         */
@@ -2163,7 +2166,7 @@ Mesh *mesh_get_eval_final(
            ((dataMask & ob->lastDataMask) != dataMask) ||
            (need_mapping && !ob->lastNeedMapping))
        {
            ((dataMask & ob->lastDataMask) != dataMask) ||
            (need_mapping && !ob->lastNeedMapping))
        {
-               mesh_build_data(depsgraph, scene, ob, dataMask, false, need_mapping);
+               mesh_build_data(depsgraph, scene, ob, dataMask | ob->lastDataMask, false, need_mapping || ob->lastNeedMapping);
        }
 
        if (ob->runtime.mesh_eval) { BLI_assert(!(ob->runtime.mesh_eval->runtime.cd_dirty_vert & CD_MASK_NORMAL)); }
        }
 
        if (ob->runtime.mesh_eval) { BLI_assert(!(ob->runtime.mesh_eval->runtime.cd_dirty_vert & CD_MASK_NORMAL)); }
index c9ce8ed54fca3a4ead65035c20e97f892bf9e937..1ba49537afd04e2960c0a7f2213e18dfd288ad01 100644 (file)
@@ -66,6 +66,7 @@
 
 #include "DEG_depsgraph.h"
 #include "DEG_depsgraph_build.h"
 
 #include "DEG_depsgraph.h"
 #include "DEG_depsgraph_build.h"
+#include "DEG_depsgraph_query.h"
 
 #include "ED_mesh.h"
 #include "ED_object.h"
 
 #include "ED_mesh.h"
 #include "ED_object.h"
@@ -1080,11 +1081,12 @@ bool ED_mesh_pick_face_vert(bContext *C, Object *ob, const int mval[2], unsigned
        BLI_assert(me && GS(me->id.name) == ID_ME);
 
        if (ED_mesh_pick_face(C, ob, mval, &poly_index, size)) {
        BLI_assert(me && GS(me->id.name) == ID_ME);
 
        if (ED_mesh_pick_face(C, ob, mval, &poly_index, size)) {
-               Scene *scene = CTX_data_scene(C);
+               Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
+               Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
                struct ARegion *ar = CTX_wm_region(C);
 
                /* derived mesh to find deformed locations */
                struct ARegion *ar = CTX_wm_region(C);
 
                /* derived mesh to find deformed locations */
-               Mesh *me_eval = mesh_get_eval_final(depsgraph, scene, ob, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX);
+               Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, CD_MASK_BAREMESH | CD_MASK_ORIGINDEX);
 
                int v_idx_best = ORIGINDEX_NONE;
 
 
                int v_idx_best = ORIGINDEX_NONE;
 
@@ -1209,8 +1211,11 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int
                (*index)--;
        }
        else {
                (*index)--;
        }
        else {
+               Scene *scene_eval = DEG_get_evaluated_scene(vc.depsgraph);
+               Object *ob_eval = DEG_get_evaluated_object(vc.depsgraph, ob);
+
                /* derived mesh to find deformed locations */
                /* derived mesh to find deformed locations */
-               Mesh *me_eval = mesh_get_eval_final(vc.depsgraph, vc.scene, ob, CD_MASK_BAREMESH);
+               Mesh *me_eval = mesh_get_eval_final(vc.depsgraph, scene_eval, ob_eval, CD_MASK_BAREMESH);
                ARegion *ar = vc.ar;
                RegionView3D *rv3d = ar->regiondata;
 
                ARegion *ar = vc.ar;
                RegionView3D *rv3d = ar->regiondata;