Geometry Nodes: Index of Nearest: Use span for non-single ids

If the Group ID input isn't a single value, it's likely to be a span,
so making sure that's true should generally be free, at least in
most cases. This brought a test with 1 million points from 37
to 34 ms, roughtly an 8% improvement.
This commit is contained in:
Hans Goudey
2023-04-26 12:26:38 -04:00
parent 45cecb101c
commit 4346314351

View File

@@ -64,6 +64,7 @@ class IndexOfNearestFieldInput final : public bke::GeometryFieldInput {
GVArray get_varray_for_context(const bke::GeometryFieldContext &context,
const IndexMask mask) const final
{
SCOPED_TIMER_AVERAGED(__func__);
if (!context.attributes()) {
return {};
}
@@ -73,21 +74,22 @@ class IndexOfNearestFieldInput final : public bke::GeometryFieldInput {
evaluator.add(group_field_);
evaluator.evaluate();
const VArraySpan<float3> positions = evaluator.get_evaluated<float3>(0);
const VArray<int> group = evaluator.get_evaluated<int>(1);
const VArray<int> group_ids = evaluator.get_evaluated<int>(1);
Array<int> result;
if (group.is_single()) {
if (group_ids.is_single()) {
result.reinitialize(mask.min_array_size());
KDTree_3d *tree = build_kdtree(positions, IndexRange(domain_size));
find_neighbors(*tree, positions, mask, result);
BLI_kdtree_3d_free(tree);
return VArray<int>::ForContainer(std::move(result));
}
const VArraySpan<int> group_ids_span(group_ids);
VectorSet<int> group_indexing;
for (const int index : mask) {
const int group_id = group[index];
const int group_id = group_ids_span[index];
group_indexing.add(group_id);
}
@@ -111,7 +113,7 @@ class IndexOfNearestFieldInput final : public bke::GeometryFieldInput {
const auto build_group_masks = [&](const IndexMask mask,
MutableSpan<Vector<int64_t>> r_groups) {
for (const int index : mask) {
const int group_id = group[index];
const int group_id = group_ids_span[index];
const int index_of_group = group_indexing.index_of_try(group_id);
if (index_of_group != -1) {
r_groups[index_of_group].append(index);