Geometry Nodes: Sort Children in Collection Info

When the 'Separate Children' option is selected, the children of
the selected collection are inserted into the geometry output
sorted alphabetically by name.

One item to note is that the rename function does not trigger a
depsgraph update. This means that the changes are not reflected
in the spreadsheet until another action triggers the update.

Differential Revision: https://developer.blender.org/D12907
This commit is contained in:
Johnny Matthews 2021-10-18 15:11:04 -05:00
parent ec8a9a0d65
commit 5f59bf0044
Notes: blender-bot 2023-02-13 17:23:09 +01:00
Referenced by issue #93683, Spreadsheet doesn't refresh after instance collection's names are changed in 3.0 stable.
Referenced by issue #92323, Sorted Collection info Instance - update problem
1 changed files with 23 additions and 3 deletions

View File

@ -25,13 +25,16 @@
#include "node_geometry_util.hh"
#include <algorithm>
namespace blender::nodes {
static void geo_node_collection_info_declare(NodeDeclarationBuilder &b)
{
b.add_input<decl::Collection>("Collection").hide_label();
b.add_input<decl::Bool>("Separate Children")
.description("Output each child of the collection as a separate instance");
.description(
"Output each child of the collection as a separate instance, sorted alphabetically");
b.add_input<decl::Bool>("Reset Children")
.description(
"Reset the transforms of every child instance in the output. Only used when Separate "
@ -52,6 +55,12 @@ static void geo_node_collection_info_node_init(bNodeTree *UNUSED(tree), bNode *n
node->storage = data;
}
struct InstanceListEntry {
int handle;
char *name;
float4x4 transform;
};
static void geo_node_collection_info_exec(GeoNodeExecParams params)
{
Collection *collection = params.get_input<Collection *>("Collection");
@ -85,6 +94,8 @@ static void geo_node_collection_info_exec(GeoNodeExecParams params)
}
instances.reserve(children_collections.size() + children_objects.size());
Vector<InstanceListEntry> entries;
entries.reserve(children_collections.size() + children_objects.size());
for (Collection *child_collection : children_collections) {
float4x4 transform = float4x4::identity();
@ -98,7 +109,7 @@ static void geo_node_collection_info_exec(GeoNodeExecParams params)
}
}
const int handle = instances.add_reference(*child_collection);
instances.add_instance(handle, transform);
entries.append({handle, &(child_collection->id.name[2]), transform});
}
for (Object *child_object : children_objects) {
const int handle = instances.add_reference(*child_object);
@ -112,7 +123,16 @@ static void geo_node_collection_info_exec(GeoNodeExecParams params)
}
mul_m4_m4_post(transform.values, child_object->obmat);
}
instances.add_instance(handle, transform);
entries.append({handle, &(child_object->id.name[2]), transform});
}
std::sort(entries.begin(),
entries.end(),
[](const InstanceListEntry &a, const InstanceListEntry &b) {
return BLI_strcasecmp_natural(a.name, b.name) <= 0;
});
for (const InstanceListEntry &entry : entries) {
instances.add_instance(entry.handle, entry.transform);
}
}
else {