Fix #145133: Invalid node link node pointer in certain file

Somehow the file in this report ended up with a node pointer that
disagreed with the socket pointer. Since we use the latter for drawing,
that's a better source of truth. This commit adds a versioning step
that corrects the node pointer. If this happens again we may need
to run the versioning again at some point, but that's not clear.

Pull Request: https://projects.blender.org/blender/blender/pulls/145409
This commit is contained in:
Hans Goudey
2025-09-02 16:24:26 +02:00
committed by Hans Goudey
parent 588052f97f
commit dbf777569b
2 changed files with 45 additions and 1 deletions

View File

@@ -132,6 +132,8 @@ static void update_directly_linked_links_and_sockets(const bNodeTree &ntree)
link->fromnode->runtime->has_available_linked_outputs = true;
link->tonode->runtime->has_available_linked_inputs = true;
}
BLI_assert(link->fromsock->runtime->owner_node == link->fromnode);
BLI_assert(link->tosock->runtime->owner_node == link->tonode);
}
for (bNodeSocket *socket : tree_runtime.input_sockets) {
if (socket->flag & SOCK_MULTI_INPUT) {

View File

@@ -2172,6 +2172,42 @@ static void remove_in_and_out_node_interface(bNodeTree &node_tree)
remove_in_and_out_node_panel_recursive(node_tree.tree_interface.root_panel);
}
static void repair_node_link_node_pointers(FileData &fd, bNodeTree &node_tree)
{
using namespace blender;
Map<bNodeSocket *, bNode *> socket_to_node;
LISTBASE_FOREACH (bNode *, node, &node_tree.nodes) {
LISTBASE_FOREACH (bNodeSocket *, socket, &node->inputs) {
socket_to_node.add(socket, node);
}
LISTBASE_FOREACH (bNodeSocket *, socket, &node->outputs) {
socket_to_node.add(socket, node);
}
}
LISTBASE_FOREACH (bNodeLink *, link, &node_tree.links) {
bool fixed = false;
bNode *to_node = socket_to_node.lookup(link->tosock);
if (to_node != link->tonode) {
link->tonode = to_node;
fixed = true;
}
bNode *from_node = socket_to_node.lookup(link->fromsock);
if (from_node != link->fromnode) {
link->fromnode = from_node;
fixed = true;
}
if (fixed) {
BLO_reportf_wrap(fd.reports,
RPT_WARNING,
"Repairing invalid state in node link from %s:%s to %s:%s",
link->fromnode->name,
link->fromsock->identifier,
link->tonode->name,
link->tosock->identifier);
}
}
}
static void sequencer_remove_listbase_pointers(Scene &scene)
{
Editing *ed = scene.ed;
@@ -2186,7 +2222,7 @@ static void sequencer_remove_listbase_pointers(Scene &scene)
blender::seq::meta_stack_set(&scene, last_meta_stack->parent_strip);
}
void blo_do_versions_500(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
void blo_do_versions_500(FileData *fd, Library * /*lib*/, Main *bmain)
{
using namespace blender;
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 1)) {
@@ -2950,6 +2986,12 @@ void blo_do_versions_500(FileData * /*fd*/, Library * /*lib*/, Main *bmain)
}
}
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 69)) {
LISTBASE_FOREACH (bNodeTree *, ntree, &bmain->nodetrees) {
repair_node_link_node_pointers(*fd, *ntree);
}
}
/**
* Always bump subversion in BKE_blender_version.h when adding versioning
* code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.