[Bf-blender-cvs] [c8cca888518] blender-v3.1-release: Fix assert in original modifiers pointer update function

Sergey Sharybin noreply at git.blender.org
Thu Feb 3 10:02:27 CET 2022


Commit: c8cca888518182914e6b4f1b98e0f7b861add08d
Author: Sergey Sharybin
Date:   Wed Feb 2 12:20:03 2022 +0100
Branches: blender-v3.1-release
https://developer.blender.org/rBc8cca888518182914e6b4f1b98e0f7b861add08d

Fix assert in original modifiers pointer update function

The issue was happening with a specific file where the ID management
code was not fully copying all modifiers because of the extra check
in the `BKE_object_support_modifier_type_check()`.

While it is arguable that copy-on-write should be a 1:1 copy there is
no real need to maintain the per-modifier pointer to its original.
Use its SessionUUID to perform lookup in the original datablock.

Downside of this approach is that it is a linear lookup instead of
direct pointer access, but the upside is that there is less pointers
to manage and that the file with unsupported modifiers does behave
correct without any asserts.

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

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

M	source/blender/blenkernel/BKE_modifier.h
M	source/blender/blenkernel/intern/modifier.c
M	source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
M	source/blender/editors/armature/meshlaplacian.c
M	source/blender/editors/include/ED_armature.h
M	source/blender/makesdna/DNA_modifier_types.h
M	source/blender/makesrna/intern/rna_particle.c
M	source/blender/modifiers/intern/MOD_correctivesmooth.c
M	source/blender/modifiers/intern/MOD_meshdeform.c
M	source/blender/modifiers/intern/MOD_nodes.cc
M	source/blender/modifiers/intern/MOD_surfacedeform.c

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

diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 80889813b34..910b13b9b95 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -470,6 +470,8 @@ void BKE_modifiers_foreach_tex_link(struct Object *ob, TexWalkFunc walk, void *u
 
 struct ModifierData *BKE_modifiers_findby_type(const struct Object *ob, ModifierType type);
 struct ModifierData *BKE_modifiers_findby_name(const struct Object *ob, const char *name);
+struct ModifierData *BKE_modifiers_findby_session_uuid(const struct Object *ob,
+                                                       const SessionUUID *session_uuid);
 void BKE_modifiers_clear_errors(struct Object *ob);
 /**
  * used for buttons, to find out if the 'draw deformed in edit-mode option is there.
@@ -568,7 +570,8 @@ const char *BKE_modifier_path_relbase_from_global(struct Object *ob);
  * For a given modifier data, get corresponding original one.
  * If the modifier data is already original, return it as-is.
  */
-struct ModifierData *BKE_modifier_get_original(struct ModifierData *md);
+struct ModifierData *BKE_modifier_get_original(const struct Object *object,
+                                               struct ModifierData *md);
 struct ModifierData *BKE_modifier_get_evaluated(struct Depsgraph *depsgraph,
                                                 struct Object *object,
                                                 struct ModifierData *md);
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index e1fd8ff45d1..4f170535d18 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -290,6 +290,16 @@ ModifierData *BKE_modifiers_findby_name(const Object *ob, const char *name)
   return BLI_findstring(&(ob->modifiers), name, offsetof(ModifierData, name));
 }
 
+ModifierData *BKE_modifiers_findby_session_uuid(const Object *ob, const SessionUUID *session_uuid)
+{
+  LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
+    if (BLI_session_uuid_is_equal(&md->session_uuid, session_uuid)) {
+      return md;
+    }
+  }
+  return NULL;
+}
+
 void BKE_modifiers_clear_errors(Object *ob)
 {
   LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
@@ -439,9 +449,7 @@ void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *_for
 #ifndef NDEBUG
   if ((md->mode & eModifierMode_Virtual) == 0) {
     /* Ensure correct object is passed in. */
-    const Object *ob_orig = (Object *)DEG_get_original_id((ID *)&ob->id);
-    const ModifierData *md_orig = md->orig_modifier_data ? md->orig_modifier_data : md;
-    BLI_assert(BLI_findindex(&ob_orig->modifiers, md_orig) != -1);
+    BLI_assert(BKE_modifier_get_original(ob, md) != NULL);
   }
 #endif
 
@@ -1052,12 +1060,10 @@ Mesh *BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval,
   return me;
 }
 
-ModifierData *BKE_modifier_get_original(ModifierData *md)
+ModifierData *BKE_modifier_get_original(const Object *object, ModifierData *md)
 {
-  if (md->orig_modifier_data == NULL) {
-    return md;
-  }
-  return md->orig_modifier_data;
+  const Object *object_orig = DEG_get_original_object((Object *)object);
+  return BKE_modifiers_findby_session_uuid(object_orig, &md->session_uuid);
 }
 
 struct ModifierData *BKE_modifier_get_evaluated(Depsgraph *depsgraph,
@@ -1068,7 +1074,7 @@ struct ModifierData *BKE_modifier_get_evaluated(Depsgraph *depsgraph,
   if (object_eval == object) {
     return md;
   }
-  return BKE_modifiers_findby_name(object_eval, md->name);
+  return BKE_modifiers_findby_session_uuid(object_eval, &md->session_uuid);
 }
 
 void BKE_modifier_check_uuids_unique_and_report(const Object *object)
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index 8a3c5c5b776..c2b85caad66 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -674,12 +674,6 @@ void update_pose_orig_pointers(const bPose *pose_orig, bPose *pose_cow)
   update_list_orig_pointers(&pose_orig->chanbase, &pose_cow->chanbase, &bPoseChannel::orig_pchan);
 }
 
-void update_modifiers_orig_pointers(const Object *object_orig, Object *object_cow)
-{
-  update_list_orig_pointers(
-      &object_orig->modifiers, &object_cow->modifiers, &ModifierData::orig_modifier_data);
-}
-
 void update_nla_strips_orig_pointers(const ListBase *strips_orig, ListBase *strips_cow)
 {
   NlaStrip *strip_orig = reinterpret_cast<NlaStrip *>(strips_orig->first);
@@ -766,7 +760,6 @@ void update_id_after_copy(const Depsgraph *depsgraph,
         BKE_gpencil_update_orig_pointers(object_orig, object_cow);
       }
       update_particles_after_copy(depsgraph, object_orig, object_cow);
-      update_modifiers_orig_pointers(object_orig, object_cow);
       update_proxy_pointers_after_copy(depsgraph, object_orig, object_cow);
       break;
     }
diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c
index 787d7cbaab0..14f47a84286 100644
--- a/source/blender/editors/armature/meshlaplacian.c
+++ b/source/blender/editors/armature/meshlaplacian.c
@@ -1742,14 +1742,15 @@ static void harmonic_coordinates_bind(MeshDeformModifierData *mmd, MeshDeformBin
   free_bvhtree_from_mesh(&mdb->bvhdata);
 }
 
-void ED_mesh_deform_bind_callback(MeshDeformModifierData *mmd,
+void ED_mesh_deform_bind_callback(Object *object,
+                                  MeshDeformModifierData *mmd,
                                   Mesh *cagemesh,
                                   float *vertexcos,
                                   int totvert,
                                   float cagemat[4][4])
 {
   MeshDeformModifierData *mmd_orig = (MeshDeformModifierData *)BKE_modifier_get_original(
-      &mmd->modifier);
+      object, &mmd->modifier);
   MeshDeformBind mdb;
   MVert *mvert;
   int a;
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 7631bd35e79..11b7c85ec58 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -368,7 +368,8 @@ void ED_pose_bone_select_tag_update(struct Object *ob);
 void ED_pose_bone_select(struct Object *ob, struct bPoseChannel *pchan, bool select);
 
 /* meshlaplacian.c */
-void ED_mesh_deform_bind_callback(struct MeshDeformModifierData *mmd,
+void ED_mesh_deform_bind_callback(struct Object *object,
+                                  struct MeshDeformModifierData *mmd,
                                   struct Mesh *cagemesh,
                                   float *vertexcos,
                                   int totvert,
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index 1d0796bda8b..8e38d52a4d7 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -128,15 +128,11 @@ typedef struct ModifierData {
 
   char *error;
 
-  /** Pointer to a #ModifierData in the original domain. */
-  struct ModifierData *orig_modifier_data;
-
   /** Runtime field which contains unique identifier of the modifier. */
   SessionUUID session_uuid;
 
   /** Runtime field which contains runtime data which is specific to a modifier type. */
   void *runtime;
-  void *_pad1;
 } ModifierData;
 
 typedef enum {
@@ -1012,7 +1008,8 @@ typedef struct MeshDeformModifierData {
   float *bindcos;
 
   /* runtime */
-  void (*bindfunc)(struct MeshDeformModifierData *mmd,
+  void (*bindfunc)(struct Object *object,
+                   struct MeshDeformModifierData *mmd,
                    struct Mesh *cagemesh,
                    float *vertexcos,
                    int totvert,
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index ff22a7758bb..23ec5148f00 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -249,7 +249,8 @@ static void rna_ParticleHairKey_location_object_get(PointerRNA *ptr, float *valu
  *
  * Such trickery is needed to allow modification of hair keys in the original object using
  * evaluated particle and object to access proper hair matrix. */
-static int hair_key_index_get(/*const*/ HairKey *hair_key,
+static int hair_key_index_get(const Object *object,
+                              /*const*/ HairKey *hair_key,
                               /*const*/ ParticleSystemModifierData *modifier,
                               /*const*/ ParticleData *particle)
 {
@@ -261,7 +262,7 @@ static int hair_key_index_get(/*const*/ HairKey *hair_key,
   const int particle_index = particle - particle_system->particles;
 
   const ParticleSystemModifierData *original_modifier = (ParticleSystemModifierData *)
-      BKE_modifier_get_original(&modifier->modifier);
+      BKE_modifier_get_original(object, &modifier->modifier);
   const ParticleSystem *original_particle_system = original_modifier->psys;
   const ParticleData *original_particle = &original_particle_system->particles[particle_index];
 
@@ -288,7 +289,7 @@ static void hair_key_location_object_set(HairKey *hair_key,
                                                                   NULL;
 
   if (hair_mesh != NULL) {
-    const int hair_key_index = hair_key_index_get(hair_key, modifier, particle);
+    const int hair_key_index = hair_key_index_get(object, hair_key, modifier, particle);
     if (hair_key_index == -1) {
       return;
     }
@@ -368,7 +369,7 @@ static void rna_ParticleHairKey_co_object_set(ID *id,
   /* Mark particle system as edited, so then particle_system_update() does not reset the hair
    * keys from path. This behavior is similar to how particle edit mode sets flags. */
   ParticleSystemModifierData *orig_modifier = (ParticleSystemModifierData *)
-      BKE_modifier_get_original(&modifier->modifier);
+      BKE_modifier_get_original(object, &modifier->modifier);
   orig_modifier->psys->flag |= PSYS_EDITED;
 
   hair_key_location_object_set(hair_key, object, modifi

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list