Fix #114582: Replace unknown node types with an 'undefined' node #114803

Merged
Lukas Tönne merged 1 commits from LukasTonne/blender:replace-unknown-socket-types-4.x into main 2023-11-13 16:36:51 +01:00
1 changed files with 35 additions and 0 deletions

View File

@ -888,6 +888,29 @@ static void direct_link_node_socket_list(BlendDataReader *reader, ListBase *sock
}
}
/* 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);
}
void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
{
/* Special case for this pointer, do not rely on regular `lib_link` process here. Avoids needs
@ -946,6 +969,18 @@ void ntreeBlendReadData(BlendDataReader *reader, ID *owner_id, bNodeTree *ntree)
BLO_read_data_address(reader, &node->prop);
IDP_BlendDataRead(reader, &node->prop);
/* Unknown built-in node types cannot be read reliably, so replace them with 'undefined' type
* nodes. This keeps links and socket names but discards storage an 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());
continue;
}
if (node->type == CMP_NODE_MOVIEDISTORTION) {
/* Do nothing, this is runtime cache and hence handled by generic code using
* `IDTypeInfo.foreach_cache` callback. */