Fix #117422: Move undefined type removal behind after-linking-versioning

There are still node versioning bits running after linking, for example
`version_geometry_nodes_replace_transfer_attribute_node`. This code
relies on node types being untouched at that point.

Move the unknown node type replacement from `ntreeSetTypes` into the
`ntreeUpdateAllNew` function. This is called _after_ late versioning.

Pull Request: https://projects.blender.org/blender/blender/pulls/117441
This commit is contained in:
Lukas Tönne
2024-01-23 15:15:08 +01:00
parent 481bc7a777
commit f72dbc1ef8

View File

@@ -1362,29 +1362,6 @@ static void ntree_set_typeinfo(bNodeTree *ntree, bNodeTreeType *typeinfo)
BKE_ntree_update_tag_all(ntree);
}
/* Build a set of built-in node types to check for known types. */
static blender::Set<int> get_known_node_types_set()
{
blender::Set<int> result;
NODE_TYPES_BEGIN (ntype) {
result.add(ntype->type);
}
NODE_TYPES_END;
return result;
}
static bool can_read_node_type(const int type)
{
/* Can always read custom node types. */
if (type == NODE_CUSTOM) {
return true;
}
/* Check known built-in types. */
static blender::Set<int> known_types = get_known_node_types_set();
return known_types.contains(type);
}
static void node_set_typeinfo(const bContext *C,
bNodeTree *ntree,
bNode *node,
@@ -1392,19 +1369,6 @@ static void node_set_typeinfo(const bContext *C,
{
/* for nodes saved in older versions storage can get lost, make undefined then */
if (node->flag & NODE_INIT) {
/* If the integer type is unknown then this is a node from a newer Blender version.
* These cannot be read reliably so replace the idname with an undefined type. This keeps links
* and socket names but discards storage and other type-specific data.
*/
if (!can_read_node_type(node->type)) {
node->type = NODE_CUSTOM;
/* This type name is arbitrary, it just has to be unique enough to not match a future node
* idname. Includes the old type identifier for debugging purposes. */
const std::string old_idname = node->idname;
BLI_snprintf(node->idname, sizeof(node->idname), "Undefined[%s]", old_idname.c_str());
typeinfo = nullptr;
}
if (typeinfo && typeinfo->storagename[0] && !node->storage) {
typeinfo = nullptr;
}
@@ -4094,8 +4058,57 @@ void BKE_node_instance_hash_remove_untagged(bNodeInstanceHash *hash,
namespace blender::bke {
/* Build a set of built-in node types to check for known types. */
static blender::Set<int> get_known_node_types_set()
{
blender::Set<int> result;
NODE_TYPES_BEGIN (ntype) {
result.add(ntype->type);
}
NODE_TYPES_END;
return result;
}
static bool can_read_node_type(const int type)
{
/* Can always read custom node types. */
if (type == NODE_CUSTOM) {
return true;
}
/* Check known built-in types. */
static blender::Set<int> known_types = get_known_node_types_set();
return known_types.contains(type);
}
static void node_replace_undefined_types(bNode *node)
{
/* If the integer type is unknown then this node cannot be read. */
if (!can_read_node_type(node->type)) {
node->type = NODE_CUSTOM;
/* This type name is arbitrary, it just has to be unique enough to not match a future node
* idname. Includes the old type identifier for debugging purposes. */
const std::string old_idname = node->idname;
BLI_snprintf(node->idname, sizeof(node->idname), "Undefined[%s]", old_idname.c_str());
node->typeinfo = &NodeTypeUndefined;
}
}
void ntreeUpdateAllNew(Main *main)
{
/* Replace unknown node types with "Undefined".
* This happens when loading files from newer Blender versions. Such nodes cannot be read
* reliably so replace the idname with an undefined type. This keeps links and socket names but
* discards storage and other type-specific data.
*
* Replacement has to happen after after-liblink-versioning, since some node types still get
* replaced in those late versioning steps. */
FOREACH_NODETREE_BEGIN (main, ntree, owner_id) {
LISTBASE_FOREACH (bNode *, node, &ntree->nodes) {
node_replace_undefined_types(node);
}
}
FOREACH_NODETREE_END;
/* Update all new node trees on file read or append, to add/remove sockets
* in groups nodes if the group changed, and handle any update flags that
* might have been set in file reading or versioning. */