From d77cd0e8b5a66489617165db5eb067fb49507621 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 10 Sep 2025 17:33:42 +0200 Subject: [PATCH] Fix #145848: Crash when switching view layer after undoing ID deletion. The root of the issue is that depsgraph relies on `ID::session_uid` to identify and retrieve its own cached evaluation data for an ID, including the memory for the evaluated ID data (e.g. used as keys to retrieve IDInfo data stored in `DepsgraphNodeBuilder::id_info_hash_`). This breaks in undo case, when a previously deleted ID is re-read from the memfile, as it has not matching 'old' ID which address could be reused. So while keeping its previous `session_uid`, it has a completely new address, while the 'cow ID' retrieved from the depsgraph will still have its `orig_id` point to the old address. This commit fixes the issue by re-setting the `id_orig` pointer of the `id_cow` evaluated data, when it already exists and is re-used. This allows to keep the same `session_uid` for IDs on undo, even when they are 're-created'. However, it is somewhat more risky than !146028. Pull Request: https://projects.blender.org/blender/blender/pulls/146029 --- source/blender/depsgraph/intern/node/deg_node_id.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/blender/depsgraph/intern/node/deg_node_id.cc b/source/blender/depsgraph/intern/node/deg_node_id.cc index 47c7cfc9a2d..3954e2cfc85 100644 --- a/source/blender/depsgraph/intern/node/deg_node_id.cc +++ b/source/blender/depsgraph/intern/node/deg_node_id.cc @@ -67,6 +67,13 @@ void IDNode::init_copy_on_write(Depsgraph &depsgraph, ID *id_cow_hint) // BLI_assert(deg_eval_copy_is_needed(id_orig)); if (deg_eval_copy_is_needed(id_orig)) { id_cow = id_cow_hint; + + /* While `id_cow->orig_id == id` should be `true` most of the time (a same 'orig' ID should + * keep a same pointer in most cases), in can happen that the same 'orig' ID got a new + * address, e.g. after being deleted and re-loaded from memfile undo, without any update of + * the depsgraph in-between (e.g. when the depsgraph belongs to an inactive viewlayer). + * Ref. #145848. */ + id_cow->orig_id = this->id_orig; } else { id_cow = id_orig;