Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-10-04 21:27:11 +0300
committerHans Goudey <h.goudey@me.com>2022-10-04 21:27:24 +0300
commitd981418c8ce0016e1cd778f4ddaf558cb7b0e724 (patch)
tree139c474a1ced0477561892f89cbdacef760173ba /source/blender/blenloader/intern
parentea95d042455157fec7930e6cc1599bc46c920cca (diff)
Fix: Crash versioning transfer node with animation data
This versioning needs to be done after linking in order to affect animation data which might not be loaded in the regular "do_versions" loop. Animation data is removed in `nodeRemoveNode`. Fixes T101439
Diffstat (limited to 'source/blender/blenloader/intern')
-rw-r--r--source/blender/blenloader/intern/versioning_300.cc300
1 files changed, 151 insertions, 149 deletions
diff --git a/source/blender/blenloader/intern/versioning_300.cc b/source/blender/blenloader/intern/versioning_300.cc
index 348ce168f71..8a6c73a7a5b 100644
--- a/source/blender/blenloader/intern/versioning_300.cc
+++ b/source/blender/blenloader/intern/versioning_300.cc
@@ -670,6 +670,147 @@ static bool seq_speed_factor_set(Sequence *seq, void *user_data)
return true;
}
+static void version_geometry_nodes_replace_transfer_attribute_node(bNodeTree *ntree)
+{
+ using namespace blender;
+ /* Otherwise `ntree->typeInfo` is null. */
+ ntreeSetTypes(NULL, ntree);
+ LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
+ if (node->type != GEO_NODE_TRANSFER_ATTRIBUTE_DEPRECATED) {
+ continue;
+ }
+ bNodeSocket *old_geometry_socket = nodeFindSocket(node, SOCK_IN, "Source");
+ const NodeGeometryTransferAttribute *storage = (const NodeGeometryTransferAttribute *)
+ node->storage;
+ switch (storage->mode) {
+ case GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED: {
+ bNode *sample_nearest_surface = nodeAddStaticNode(
+ NULL, ntree, GEO_NODE_SAMPLE_NEAREST_SURFACE);
+ sample_nearest_surface->parent = node->parent;
+ sample_nearest_surface->custom1 = storage->data_type;
+ sample_nearest_surface->locx = node->locx;
+ sample_nearest_surface->locy = node->locy;
+ static auto socket_remap = []() {
+ Map<std::string, std::string> map;
+ map.add_new("Attribute", "Value_Vector");
+ map.add_new("Attribute_001", "Value_Float");
+ map.add_new("Attribute_002", "Value_Color");
+ map.add_new("Attribute_003", "Value_Bool");
+ map.add_new("Attribute_004", "Value_Int");
+ map.add_new("Source", "Mesh");
+ map.add_new("Source Position", "Sample Position");
+ return map;
+ }();
+ node_tree_relink_with_socket_id_map(*ntree, *node, *sample_nearest_surface, socket_remap);
+ break;
+ }
+ case GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST: {
+ /* These domains weren't supported by the index transfer mode, but were selectable. */
+ const eAttrDomain domain = ELEM(storage->domain, ATTR_DOMAIN_INSTANCE, ATTR_DOMAIN_CURVE) ?
+ ATTR_DOMAIN_POINT :
+ eAttrDomain(storage->domain);
+
+ /* Use a sample index node to retrieve the data with this node's index output. */
+ bNode *sample_index = nodeAddStaticNode(NULL, ntree, GEO_NODE_SAMPLE_INDEX);
+ NodeGeometrySampleIndex *sample_storage = static_cast<NodeGeometrySampleIndex *>(
+ sample_index->storage);
+ sample_storage->data_type = storage->data_type;
+ sample_storage->domain = domain;
+ sample_index->parent = node->parent;
+ sample_index->locx = node->locx + 25.0f;
+ sample_index->locy = node->locy;
+ if (old_geometry_socket->link) {
+ nodeAddLink(ntree,
+ old_geometry_socket->link->fromnode,
+ old_geometry_socket->link->fromsock,
+ sample_index,
+ nodeFindSocket(sample_index, SOCK_IN, "Geometry"));
+ }
+
+ bNode *sample_nearest = nodeAddStaticNode(NULL, ntree, GEO_NODE_SAMPLE_NEAREST);
+ sample_nearest->parent = node->parent;
+ sample_nearest->custom1 = storage->data_type;
+ sample_nearest->custom2 = domain;
+ sample_nearest->locx = node->locx - 25.0f;
+ sample_nearest->locy = node->locy;
+ if (old_geometry_socket->link) {
+ nodeAddLink(ntree,
+ old_geometry_socket->link->fromnode,
+ old_geometry_socket->link->fromsock,
+ sample_nearest,
+ nodeFindSocket(sample_nearest, SOCK_IN, "Geometry"));
+ }
+ static auto sample_nearest_remap = []() {
+ Map<std::string, std::string> map;
+ map.add_new("Source Position", "Sample Position");
+ return map;
+ }();
+ node_tree_relink_with_socket_id_map(*ntree, *node, *sample_nearest, sample_nearest_remap);
+
+ static auto sample_index_remap = []() {
+ Map<std::string, std::string> map;
+ map.add_new("Attribute", "Value_Vector");
+ map.add_new("Attribute_001", "Value_Float");
+ map.add_new("Attribute_002", "Value_Color");
+ map.add_new("Attribute_003", "Value_Bool");
+ map.add_new("Attribute_004", "Value_Int");
+ map.add_new("Source Position", "Sample Position");
+ return map;
+ }();
+ node_tree_relink_with_socket_id_map(*ntree, *node, *sample_index, sample_index_remap);
+
+ nodeAddLink(ntree,
+ sample_nearest,
+ nodeFindSocket(sample_nearest, SOCK_OUT, "Index"),
+ sample_index,
+ nodeFindSocket(sample_index, SOCK_IN, "Index"));
+ break;
+ }
+ case GEO_NODE_ATTRIBUTE_TRANSFER_INDEX: {
+ bNode *sample_index = nodeAddStaticNode(NULL, ntree, GEO_NODE_SAMPLE_INDEX);
+ NodeGeometrySampleIndex *sample_storage = static_cast<NodeGeometrySampleIndex *>(
+ sample_index->storage);
+ sample_storage->data_type = storage->data_type;
+ sample_storage->domain = storage->domain;
+ sample_storage->clamp = 1;
+ sample_index->parent = node->parent;
+ sample_index->locx = node->locx;
+ sample_index->locy = node->locy;
+ const bool index_was_linked = nodeFindSocket(node, SOCK_IN, "Index")->link != nullptr;
+ static auto socket_remap = []() {
+ Map<std::string, std::string> map;
+ map.add_new("Attribute", "Value_Vector");
+ map.add_new("Attribute_001", "Value_Float");
+ map.add_new("Attribute_002", "Value_Color");
+ map.add_new("Attribute_003", "Value_Bool");
+ map.add_new("Attribute_004", "Value_Int");
+ map.add_new("Source", "Geometry");
+ map.add_new("Index", "Index");
+ return map;
+ }();
+ node_tree_relink_with_socket_id_map(*ntree, *node, *sample_index, socket_remap);
+
+ if (!index_was_linked) {
+ /* Add an index input node, since the new node doesn't use an implicit input. */
+ bNode *index = nodeAddStaticNode(NULL, ntree, GEO_NODE_INPUT_INDEX);
+ index->parent = node->parent;
+ index->locx = node->locx - 25.0f;
+ index->locy = node->locy - 25.0f;
+ nodeAddLink(ntree,
+ index,
+ nodeFindSocket(index, SOCK_OUT, "Index"),
+ sample_index,
+ nodeFindSocket(sample_index, SOCK_IN, "Index"));
+ }
+ break;
+ }
+ }
+ /* The storage must be freed manually because the node type isn't defined anymore. */
+ MEM_freeN(node->storage);
+ nodeRemoveNode(NULL, ntree, node, false);
+ }
+}
+
void do_versions_after_linking_300(Main *bmain, ReportList * /*reports*/)
{
if (MAIN_VERSION_ATLEAST(bmain, 300, 0) && !MAIN_VERSION_ATLEAST(bmain, 300, 1)) {
@@ -933,6 +1074,16 @@ void do_versions_after_linking_300(Main *bmain, ReportList * /*reports*/)
}
}
+ if (!MAIN_VERSION_ATLEAST(bmain, 304, 1)) {
+ /* Split the transfer attribute node into multiple smaller nodes. */
+ FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
+ if (ntree->type == NTREE_GEOMETRY) {
+ version_geometry_nodes_replace_transfer_attribute_node(ntree);
+ }
+ }
+ FOREACH_NODETREE_END;
+ }
+
/**
* Versioning code until next subversion bump goes here.
*
@@ -1791,147 +1942,6 @@ static void version_fix_image_format_copy(Main *bmain, ImageFormatData *format)
}
}
-static void version_geometry_nodes_replace_transfer_attribute_node(bNodeTree *ntree)
-{
- using namespace blender;
- /* Otherwise `ntree->typeInfo` is null. */
- ntreeSetTypes(NULL, ntree);
- LISTBASE_FOREACH_MUTABLE (bNode *, node, &ntree->nodes) {
- if (node->type != GEO_NODE_TRANSFER_ATTRIBUTE_DEPRECATED) {
- continue;
- }
- bNodeSocket *old_geometry_socket = nodeFindSocket(node, SOCK_IN, "Source");
- const NodeGeometryTransferAttribute *storage = (const NodeGeometryTransferAttribute *)
- node->storage;
- switch (storage->mode) {
- case GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST_FACE_INTERPOLATED: {
- bNode *sample_nearest_surface = nodeAddStaticNode(
- NULL, ntree, GEO_NODE_SAMPLE_NEAREST_SURFACE);
- sample_nearest_surface->parent = node->parent;
- sample_nearest_surface->custom1 = storage->data_type;
- sample_nearest_surface->locx = node->locx;
- sample_nearest_surface->locy = node->locy;
- static auto socket_remap = []() {
- Map<std::string, std::string> map;
- map.add_new("Attribute", "Value_Vector");
- map.add_new("Attribute_001", "Value_Float");
- map.add_new("Attribute_002", "Value_Color");
- map.add_new("Attribute_003", "Value_Bool");
- map.add_new("Attribute_004", "Value_Int");
- map.add_new("Source", "Mesh");
- map.add_new("Source Position", "Sample Position");
- return map;
- }();
- node_tree_relink_with_socket_id_map(*ntree, *node, *sample_nearest_surface, socket_remap);
- break;
- }
- case GEO_NODE_ATTRIBUTE_TRANSFER_NEAREST: {
- /* These domains weren't supported by the index transfer mode, but were selectable. */
- const eAttrDomain domain = ELEM(storage->domain, ATTR_DOMAIN_INSTANCE, ATTR_DOMAIN_CURVE) ?
- ATTR_DOMAIN_POINT :
- eAttrDomain(storage->domain);
-
- /* Use a sample index node to retrieve the data with this node's index output. */
- bNode *sample_index = nodeAddStaticNode(NULL, ntree, GEO_NODE_SAMPLE_INDEX);
- NodeGeometrySampleIndex *sample_storage = static_cast<NodeGeometrySampleIndex *>(
- sample_index->storage);
- sample_storage->data_type = storage->data_type;
- sample_storage->domain = domain;
- sample_index->parent = node->parent;
- sample_index->locx = node->locx + 25.0f;
- sample_index->locy = node->locy;
- if (old_geometry_socket->link) {
- nodeAddLink(ntree,
- old_geometry_socket->link->fromnode,
- old_geometry_socket->link->fromsock,
- sample_index,
- nodeFindSocket(sample_index, SOCK_IN, "Geometry"));
- }
-
- bNode *sample_nearest = nodeAddStaticNode(NULL, ntree, GEO_NODE_SAMPLE_NEAREST);
- sample_nearest->parent = node->parent;
- sample_nearest->custom1 = storage->data_type;
- sample_nearest->custom2 = domain;
- sample_nearest->locx = node->locx - 25.0f;
- sample_nearest->locy = node->locy;
- if (old_geometry_socket->link) {
- nodeAddLink(ntree,
- old_geometry_socket->link->fromnode,
- old_geometry_socket->link->fromsock,
- sample_nearest,
- nodeFindSocket(sample_nearest, SOCK_IN, "Geometry"));
- }
- static auto sample_nearest_remap = []() {
- Map<std::string, std::string> map;
- map.add_new("Source Position", "Sample Position");
- return map;
- }();
- node_tree_relink_with_socket_id_map(*ntree, *node, *sample_nearest, sample_nearest_remap);
-
- static auto sample_index_remap = []() {
- Map<std::string, std::string> map;
- map.add_new("Attribute", "Value_Vector");
- map.add_new("Attribute_001", "Value_Float");
- map.add_new("Attribute_002", "Value_Color");
- map.add_new("Attribute_003", "Value_Bool");
- map.add_new("Attribute_004", "Value_Int");
- map.add_new("Source Position", "Sample Position");
- return map;
- }();
- node_tree_relink_with_socket_id_map(*ntree, *node, *sample_index, sample_index_remap);
-
- nodeAddLink(ntree,
- sample_nearest,
- nodeFindSocket(sample_nearest, SOCK_OUT, "Index"),
- sample_index,
- nodeFindSocket(sample_index, SOCK_IN, "Index"));
- break;
- }
- case GEO_NODE_ATTRIBUTE_TRANSFER_INDEX: {
- bNode *sample_index = nodeAddStaticNode(NULL, ntree, GEO_NODE_SAMPLE_INDEX);
- NodeGeometrySampleIndex *sample_storage = static_cast<NodeGeometrySampleIndex *>(
- sample_index->storage);
- sample_storage->data_type = storage->data_type;
- sample_storage->domain = storage->domain;
- sample_storage->clamp = 1;
- sample_index->parent = node->parent;
- sample_index->locx = node->locx;
- sample_index->locy = node->locy;
- const bool index_was_linked = nodeFindSocket(node, SOCK_IN, "Index")->link != nullptr;
- static auto socket_remap = []() {
- Map<std::string, std::string> map;
- map.add_new("Attribute", "Value_Vector");
- map.add_new("Attribute_001", "Value_Float");
- map.add_new("Attribute_002", "Value_Color");
- map.add_new("Attribute_003", "Value_Bool");
- map.add_new("Attribute_004", "Value_Int");
- map.add_new("Source", "Geometry");
- map.add_new("Index", "Index");
- return map;
- }();
- node_tree_relink_with_socket_id_map(*ntree, *node, *sample_index, socket_remap);
-
- if (!index_was_linked) {
- /* Add an index input node, since the new node doesn't use an implicit input. */
- bNode *index = nodeAddStaticNode(NULL, ntree, GEO_NODE_INPUT_INDEX);
- index->parent = node->parent;
- index->locx = node->locx - 25.0f;
- index->locy = node->locy - 25.0f;
- nodeAddLink(ntree,
- index,
- nodeFindSocket(index, SOCK_OUT, "Index"),
- sample_index,
- nodeFindSocket(sample_index, SOCK_IN, "Index"));
- }
- break;
- }
- }
- /* The storage must be freed manually because the node type isn't defined anymore. */
- MEM_freeN(node->storage);
- nodeRemoveNode(NULL, ntree, node, false);
- }
-}
-
/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
{
@@ -3574,14 +3584,6 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
}
}
}
-
- /* Split the transfer attribute node into multiple smaller nodes. */
- FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
- if (ntree->type == NTREE_GEOMETRY) {
- version_geometry_nodes_replace_transfer_attribute_node(ntree);
- }
- }
- FOREACH_NODETREE_END;
}
if (!MAIN_VERSION_ATLEAST(bmain, 304, 2)) {