Fix: Geometry Nodes: links removed after syncing bundle/closure nodes

This makes sure that sockets keep their old identifiers so that links remain intact.

Pull Request: https://projects.blender.org/blender/blender/pulls/140956
This commit is contained in:
Jacques Lucke
2025-06-25 09:55:00 +02:00
parent 27e716a165
commit 72110757b6

View File

@@ -61,20 +61,41 @@ void sync_sockets_evaluate_closure(SpaceNode &snode,
}
const nodes::ClosureSignature &signature = signatures[0];
auto &storage = *static_cast<NodeGeometryEvaluateClosure *>(evaluate_closure_node.storage);
Map<std::string, int> old_input_identifiers;
Map<std::string, int> old_output_identifiers;
for (const int i : IndexRange(storage.input_items.items_num)) {
const NodeGeometryEvaluateClosureInputItem &item = storage.input_items.items[i];
old_input_identifiers.add_new(StringRef(item.name), item.identifier);
}
for (const int i : IndexRange(storage.output_items.items_num)) {
const NodeGeometryEvaluateClosureOutputItem &item = storage.output_items.items[i];
old_output_identifiers.add_new(StringRef(item.name), item.identifier);
}
nodes::socket_items::clear<nodes::EvaluateClosureInputItemsAccessor>(evaluate_closure_node);
nodes::socket_items::clear<nodes::EvaluateClosureOutputItemsAccessor>(evaluate_closure_node);
for (const nodes::ClosureSignature::Item &item : signature.inputs) {
const StringRefNull name = item.key.identifiers()[0];
nodes::socket_items::add_item_with_socket_type_and_name<
nodes::EvaluateClosureInputItemsAccessor>(
evaluate_closure_node, item.type->type, name.c_str());
NodeGeometryEvaluateClosureInputItem &new_item =
*nodes::socket_items::add_item_with_socket_type_and_name<
nodes::EvaluateClosureInputItemsAccessor>(
evaluate_closure_node, item.type->type, name.c_str());
if (const std::optional<int> old_identifier = old_input_identifiers.lookup_try(name)) {
new_item.identifier = *old_identifier;
}
}
for (const nodes::ClosureSignature::Item &item : signature.outputs) {
const StringRefNull name = item.key.identifiers()[0];
nodes::socket_items::add_item_with_socket_type_and_name<
nodes::EvaluateClosureOutputItemsAccessor>(
evaluate_closure_node, item.type->type, name.c_str());
NodeGeometryEvaluateClosureOutputItem &new_item =
*nodes::socket_items::add_item_with_socket_type_and_name<
nodes::EvaluateClosureOutputItemsAccessor>(
evaluate_closure_node, item.type->type, name.c_str());
if (const std::optional<int> old_identifier = old_output_identifiers.lookup_try(name)) {
new_item.identifier = *old_identifier;
}
}
BKE_ntree_update_tag_node_property(snode.edittree, &evaluate_closure_node);
}
@@ -111,11 +132,24 @@ void sync_sockets_separate_bundle(SpaceNode &snode,
}
const nodes::BundleSignature &signature = signatures[0];
auto &storage = *static_cast<NodeGeometrySeparateBundle *>(separate_bundle_node.storage);
Map<std::string, int> old_identifiers;
for (const int i : IndexRange(storage.items_num)) {
const NodeGeometrySeparateBundleItem &item = storage.items[i];
old_identifiers.add_new(StringRef(item.name), item.identifier);
}
nodes::socket_items::clear<nodes::SeparateBundleItemsAccessor>(separate_bundle_node);
for (const nodes::BundleSignature::Item &item : signature.items) {
const StringRefNull name = item.key.identifiers()[0];
nodes::socket_items::add_item_with_socket_type_and_name<nodes ::SeparateBundleItemsAccessor>(
separate_bundle_node, item.type->type, name.c_str());
NodeGeometrySeparateBundleItem &new_item =
*nodes::socket_items::add_item_with_socket_type_and_name<
nodes ::SeparateBundleItemsAccessor>(
separate_bundle_node, item.type->type, name.c_str());
if (const std::optional<int> old_identifier = old_identifiers.lookup_try(name)) {
new_item.identifier = *old_identifier;
}
}
BKE_ntree_update_tag_node_property(snode.edittree, &separate_bundle_node);
}
@@ -150,11 +184,24 @@ void sync_sockets_combine_bundle(SpaceNode &snode, bNode &combine_bundle_node, R
}
const nodes::BundleSignature &signature = signatures[0];
auto &storage = *static_cast<NodeGeometryCombineBundle *>(combine_bundle_node.storage);
Map<std::string, int> old_identifiers;
for (const int i : IndexRange(storage.items_num)) {
const NodeGeometryCombineBundleItem &item = storage.items[i];
old_identifiers.add_new(StringRef(item.name), item.identifier);
}
nodes::socket_items::clear<nodes::CombineBundleItemsAccessor>(combine_bundle_node);
for (const nodes::BundleSignature::Item &item : signature.items) {
const StringRefNull name = item.key.identifiers()[0];
nodes::socket_items::add_item_with_socket_type_and_name<nodes ::CombineBundleItemsAccessor>(
combine_bundle_node, item.type->type, name.c_str());
NodeGeometryCombineBundleItem &new_item =
*nodes::socket_items::add_item_with_socket_type_and_name<
nodes ::CombineBundleItemsAccessor>(
combine_bundle_node, item.type->type, name.c_str());
if (const std::optional<int> old_identifier = old_identifiers.lookup_try(name)) {
new_item.identifier = *old_identifier;
}
}
BKE_ntree_update_tag_node_property(snode.edittree, &combine_bundle_node);
@@ -194,22 +241,42 @@ void sync_sockets_closure(SpaceNode &snode,
}
const nodes::ClosureSignature &signature = signatures[0];
auto &storage = *static_cast<NodeGeometryClosureOutput *>(closure_output_node.storage);
Map<std::string, int> old_input_identifiers;
Map<std::string, int> old_output_identifiers;
for (const int i : IndexRange(storage.input_items.items_num)) {
const NodeGeometryClosureInputItem &item = storage.input_items.items[i];
old_input_identifiers.add_new(StringRef(item.name), item.identifier);
}
for (const int i : IndexRange(storage.output_items.items_num)) {
const NodeGeometryClosureOutputItem &item = storage.output_items.items[i];
old_output_identifiers.add_new(StringRef(item.name), item.identifier);
}
nodes::socket_items::clear<nodes::ClosureInputItemsAccessor>(closure_output_node);
nodes::socket_items::clear<nodes::ClosureOutputItemsAccessor>(closure_output_node);
for (const nodes::ClosureSignature::Item &item : signature.inputs) {
const StringRefNull name = item.key.identifiers()[0];
NodeGeometryClosureInputItem &input_item =
NodeGeometryClosureInputItem &new_item =
*nodes::socket_items::add_item_with_socket_type_and_name<nodes::ClosureInputItemsAccessor>(
closure_output_node, item.type->type, name.c_str());
if (item.structure_type) {
input_item.structure_type = int(*item.structure_type);
new_item.structure_type = int(*item.structure_type);
}
if (const std::optional<int> old_identifier = old_input_identifiers.lookup_try(name)) {
new_item.identifier = *old_identifier;
}
}
for (const nodes::ClosureSignature::Item &item : signature.outputs) {
const StringRefNull name = item.key.identifiers()[0];
nodes::socket_items::add_item_with_socket_type_and_name<nodes::ClosureOutputItemsAccessor>(
closure_output_node, item.type->type, name.c_str());
NodeGeometryClosureOutputItem &new_item =
*nodes::socket_items::add_item_with_socket_type_and_name<
nodes::ClosureOutputItemsAccessor>(closure_output_node, item.type->type, name.c_str());
if (const std::optional<int> old_identifier = old_output_identifiers.lookup_try(name)) {
new_item.identifier = *old_identifier;
}
}
BKE_ntree_update_tag_node_property(snode.edittree, &closure_input_node);
BKE_ntree_update_tag_node_property(snode.edittree, &closure_output_node);