diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index e29e7254a11..206b5fb571d 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -27,7 +27,7 @@ /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 66 +#define BLENDER_FILE_SUBVERSION 67 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and cancel loading the file, showing a warning to diff --git a/source/blender/blenloader/intern/versioning_500.cc b/source/blender/blenloader/intern/versioning_500.cc index b738bb29798..f29a380e8ce 100644 --- a/source/blender/blenloader/intern/versioning_500.cc +++ b/source/blender/blenloader/intern/versioning_500.cc @@ -177,6 +177,11 @@ static void initialize_closure_input_structure_types(bNodeTree &ntree) LISTBASE_FOREACH (bNode *, node, &ntree.nodes) { if (node->type_legacy == NODE_EVALUATE_CLOSURE) { auto *storage = static_cast(node->storage); + if (!storage) { + /* Can happen with certain files saved in 4.5 which did not officially support closures + * yet. */ + continue; + } for (const int i : blender::IndexRange(storage->input_items.items_num)) { NodeEvaluateClosureInputItem &item = storage->input_items.items[i]; if (item.structure_type == NODE_INTERFACE_SOCKET_STRUCTURE_TYPE_AUTO) { @@ -1923,6 +1928,41 @@ static void do_version_glare_menus_to_inputs(bNodeTree &ntree, bNode &node) quality_socket.default_value_typed()->value = storage.quality; } +static void initialize_missing_closure_and_bundle_node_storage(bNodeTree &ntree) +{ + /* When opening and saving 5.0 files with bundle/closure nodes in 4.5, the storage is lost, since + * Blender 4.5 does not officially support these features yet (they were experimental features + * though). This versioning code just adds back the storage so that it does not crash further + * down the line. */ + LISTBASE_FOREACH (bNode *, node, &ntree.nodes) { + if (node->storage) { + continue; + } + switch (node->type_legacy) { + case NODE_CLOSURE_INPUT: { + node->storage = MEM_callocN(__func__); + break; + } + case NODE_CLOSURE_OUTPUT: { + node->storage = MEM_callocN(__func__); + break; + } + case NODE_EVALUATE_CLOSURE: { + node->storage = MEM_callocN(__func__); + break; + } + case NODE_COMBINE_BUNDLE: { + node->storage = MEM_callocN(__func__); + break; + } + case NODE_SEPARATE_BUNDLE: { + node->storage = MEM_callocN(__func__); + break; + } + } + } +} + void do_versions_after_linking_500(FileData *fd, Main *bmain) { if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 9)) { @@ -2835,6 +2875,13 @@ void blo_do_versions_500(FileData * /*fd*/, Library * /*lib*/, Main *bmain) FOREACH_NODETREE_END; } + if (!MAIN_VERSION_FILE_ATLEAST(bmain, 500, 67)) { + FOREACH_NODETREE_BEGIN (bmain, ntree, id) { + initialize_missing_closure_and_bundle_node_storage(*ntree); + } + FOREACH_NODETREE_END; + } + /** * Always bump subversion in BKE_blender_version.h when adding versioning * code here, and wrap it inside a MAIN_VERSION_FILE_ATLEAST check.