diff options
author | Sergey Sharybin <sergey@blender.org> | 2022-02-02 14:20:03 +0300 |
---|---|---|
committer | Sergey Sharybin <sergey@blender.org> | 2022-02-03 12:02:20 +0300 |
commit | c8cca888518182914e6b4f1b98e0f7b861add08d (patch) | |
tree | dd93675a11be5b9240e6112c3513c88c87607686 /source/blender/blenkernel/intern | |
parent | 45d5773519bdd760d8ac1d8742a9471ebcbf5023 (diff) |
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
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 24 |
1 files changed, 15 insertions, 9 deletions
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) |