Commit: cb2565195e72ee4dc5c0b53b7cd5037b2169d55f
Author: Sybren A. Stüvel
Date:   Thu Aug 13 12:53:21 2020 +0200
Branches: master
https://developer.blender.org/rBcb2565195e72ee4dc5c0b53b7cd5037b2169d55f

Fix T65148: Drivers can't access shape keys

It was impossible for drivers to use shape key properties, modifiers
generate a new mesh. After mesh evaluation the shape keys are no longer
necessary, and because of this the `key` pointer was not copied. As
drivers work on evaluated data, however, they do need this `key`
pointer.

This commit makes the `key` pointer available in evaluated meshes, but
this is somewhat dangerous. There was an explicit reason why the key on
result was kept at null pointer: to have the evaluated mesh in a
consistent state. Assigning this pointer makes it potentially
inconsistent, as the evaluated mesh and the original shape key may have
different topologies.

Reviewed By: sergey

Differential Revision: https://developer.blender.org/D7785

===================================================================

M       source/blender/blenkernel/intern/DerivedMesh.c
M       source/blender/bmesh/CMakeLists.txt
M       source/blender/bmesh/intern/bmesh_mesh_convert.c

===================================================================

diff --git a/source/blender/blenkernel/intern/DerivedMesh.c 
b/source/blender/blenkernel/intern/DerivedMesh.c
index 63e7933dd56..0dc85dfaa18 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1810,6 +1810,12 @@ static void mesh_build_data(struct Depsgraph *depsgraph,
 
   BKE_object_boundbox_calc_from_mesh(ob, mesh_eval);
 
+  /* Make sure that drivers can target shapekey properties.
+   * Note that this causes a potential inconsistency, as the shapekey may have 
a
+   * different topology than the evaluated mesh. */
+  BLI_assert(mesh->key == NULL || DEG_is_evaluated_id(&mesh->key->id));
+  mesh_eval->key = mesh->key;
+
   if ((ob->mode & OB_MODE_ALL_SCULPT) && ob->sculpt) {
     if (DEG_is_active(depsgraph)) {
       BKE_sculpt_update_object_after_eval(depsgraph, ob);
diff --git a/source/blender/bmesh/CMakeLists.txt 
b/source/blender/bmesh/CMakeLists.txt
index b97b5cc95f2..0eeb0d21b5b 100644
--- a/source/blender/bmesh/CMakeLists.txt
+++ b/source/blender/bmesh/CMakeLists.txt
@@ -23,6 +23,7 @@ set(INC
   ../blenkernel
   ../blenlib
   ../blentranslation
+  ../depsgraph
   ../makesdna
   ../../../intern/atomic
   ../../../intern/eigen
diff --git a/source/blender/bmesh/intern/bmesh_mesh_convert.c 
b/source/blender/bmesh/intern/bmesh_mesh_convert.c
index 8db125970fd..4671df90d53 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_convert.c
+++ b/source/blender/bmesh/intern/bmesh_mesh_convert.c
@@ -90,6 +90,8 @@
 #include "BKE_key.h"
 #include "BKE_main.h"
 
+#include "DEG_depsgraph_query.h"
+
 #include "bmesh.h"
 #include "intern/bmesh_private.h" /* For element checking. */
 
@@ -231,7 +233,13 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const 
struct BMeshFromMeshPar
 
   /* -------------------------------------------------------------------- */
   /* Shape Key */
-  int tot_shape_keys = me->key ? BLI_listbase_count(&me->key->block) : 0;
+  int tot_shape_keys = 0;
+  if (me->key != NULL && DEG_is_original_id(&me->id)) {
+    /* Evaluated meshes can be topologically inconsistent with their shape 
keys.
+     * Shape keys are also already integrated into the state of the evaluated
+     * mesh, so considering them here would kind of apply them twice. */
+    tot_shape_keys = BLI_listbase_count(&me->key->block);
+  }
   if (is_new == false) {
     tot_shape_keys = min_ii(tot_shape_keys, 
CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY));
   }
@@ -239,7 +247,7 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const 
struct BMeshFromMeshPar
                                           BLI_array_alloca(shape_key_table, 
tot_shape_keys) :
                                           NULL;
 
-  if ((params->active_shapekey != 0) && (me->key != NULL)) {
+  if ((params->active_shapekey != 0) && tot_shape_keys > 0) {
     actkey = BLI_findlink(&me->key->block, params->active_shapekey - 1);
   }
   else {
@@ -298,7 +306,8 @@ void BM_mesh_bm_from_me(BMesh *bm, const Mesh *me, const 
struct BMeshFromMeshPar
   const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, 
CD_BWEIGHT);
   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);
-  const int cd_shape_key_offset = me->key ? CustomData_get_offset(&bm->vdata, 
CD_SHAPEKEY) : -1;
+  const int cd_shape_key_offset = tot_shape_keys ? 
CustomData_get_offset(&bm->vdata, CD_SHAPEKEY) :
+                                                   -1;
   const int cd_shape_keyindex_offset = is_new && (tot_shape_keys || 
params->add_key_index) ?
                                            CustomData_get_offset(&bm->vdata, 
CD_SHAPE_KEYINDEX) :
                                            -1;

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to