Geometry Nodes: multi-threading when modifying multiple geometry sets

Differential Revision: https://developer.blender.org/D12652
This commit is contained in:
Jacques Lucke 2021-09-28 10:17:00 +02:00
parent c7d94a7827
commit e7b9423623
1 changed files with 25 additions and 14 deletions

View File

@ -15,6 +15,7 @@
*/
#include "BLI_map.hh"
#include "BLI_task.hh"
#include "BKE_attribute.h"
#include "BKE_attribute_access.hh"
@ -458,26 +459,36 @@ void GeometrySet::gather_attributes_for_propagation(
delete dummy_component;
}
static void gather_mutable_geometry_sets(GeometrySet &geometry_set,
Vector<GeometrySet *> &r_geometry_sets)
{
r_geometry_sets.append(&geometry_set);
if (!geometry_set.has_instances()) {
return;
}
/* In the future this can be improved by deduplicating instance references across different
* instances. */
InstancesComponent &instances_component =
geometry_set.get_component_for_write<InstancesComponent>();
instances_component.ensure_geometry_instances();
for (const int handle : instances_component.references().index_range()) {
if (instances_component.references()[handle].type() == InstanceReference::Type::GeometrySet) {
GeometrySet &instance_geometry = instances_component.geometry_set_from_reference(handle);
gather_mutable_geometry_sets(instance_geometry, r_geometry_sets);
}
}
}
/**
* Modify every (recursive) instance separately. This is often more efficient than realizing all
* instances just to change the same thing on all of them.
*/
void GeometrySet::modify_geometry_sets(ForeachSubGeometryCallback callback)
{
callback(*this);
if (!this->has_instances()) {
return;
}
/* In the future this can be improved by deduplicating instance references across different
* instances. */
InstancesComponent &instances_component = this->get_component_for_write<InstancesComponent>();
instances_component.ensure_geometry_instances();
for (const int handle : instances_component.references().index_range()) {
if (instances_component.references()[handle].type() == InstanceReference::Type::GeometrySet) {
GeometrySet &instance_geometry = instances_component.geometry_set_from_reference(handle);
instance_geometry.modify_geometry_sets(callback);
}
}
Vector<GeometrySet *> geometry_sets;
gather_mutable_geometry_sets(*this, geometry_sets);
blender::threading::parallel_for_each(
geometry_sets, [&](GeometrySet *geometry_set) { callback(*geometry_set); });
}
/** \} */