From e7b9423623d30ff962c926d4ccc6e27f3cba675c Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 28 Sep 2021 10:17:00 +0200 Subject: Geometry Nodes: multi-threading when modifying multiple geometry sets Differential Revision: https://developer.blender.org/D12652 --- source/blender/blenkernel/intern/geometry_set.cc | 29 ++++++++++++++++-------- 1 file changed, 20 insertions(+), 9 deletions(-) (limited to 'source/blender') diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc index 3abe2fd2213..e8e2f64d6e1 100644 --- a/source/blender/blenkernel/intern/geometry_set.cc +++ b/source/blender/blenkernel/intern/geometry_set.cc @@ -15,6 +15,7 @@ */ #include "BLI_map.hh" +#include "BLI_task.hh" #include "BKE_attribute.h" #include "BKE_attribute_access.hh" @@ -458,28 +459,38 @@ void GeometrySet::gather_attributes_for_propagation( delete dummy_component; } -/** - * 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) +static void gather_mutable_geometry_sets(GeometrySet &geometry_set, + Vector &r_geometry_sets) { - callback(*this); - if (!this->has_instances()) { + 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 = this->get_component_for_write(); + InstancesComponent &instances_component = + geometry_set.get_component_for_write(); 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); + 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) +{ + Vector geometry_sets; + gather_mutable_geometry_sets(*this, geometry_sets); + blender::threading::parallel_for_each( + geometry_sets, [&](GeometrySet *geometry_set) { callback(*geometry_set); }); +} + /** \} */ /* -------------------------------------------------------------------- */ -- cgit v1.2.3