diff options
author | Mattias Fredriksson <Osares> | 2022-09-18 06:12:02 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2022-09-18 06:12:02 +0300 |
commit | ce54f4855674059ef9124a27bff0741f97c75eec (patch) | |
tree | aa81be7e4a224d1e06e687d414007a534a6a87c8 /source | |
parent | 095516403c48ad1586d732ba2fc8d641827f7572 (diff) |
BLI: Add generic utlity for gathering values with indices
Add new functions to `array_utils` namespace called `gather(..)`.
Versions of `GVArray::materialize_compressed_to_uninitialized(..)` with
threading have been reimplemented locally in multiple geometry node
contexts. The purpose of this patch is therefore to:
* Assemble these implementations in a single file.
* Provide a naming convention that is easier to recognize.
Differential Revision: https://developer.blender.org/D15786
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenlib/BLI_array_utils.hh | 75 | ||||
-rw-r--r-- | source/blender/blenlib/intern/array_utils.cc | 13 | ||||
-rw-r--r-- | source/blender/geometry/intern/mesh_to_curve_convert.cc | 16 | ||||
-rw-r--r-- | source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc | 20 |
4 files changed, 93 insertions, 31 deletions
diff --git a/source/blender/blenlib/BLI_array_utils.hh b/source/blender/blenlib/BLI_array_utils.hh index cf2f948b0b4..95b3bde10f4 100644 --- a/source/blender/blenlib/BLI_array_utils.hh +++ b/source/blender/blenlib/BLI_array_utils.hh @@ -6,6 +6,7 @@ #include "BLI_generic_virtual_array.hh" #include "BLI_index_mask.hh" #include "BLI_task.hh" +#include "BLI_virtual_array.hh" namespace blender::array_utils { @@ -25,6 +26,7 @@ inline void copy(const Span<T> src, MutableSpan<T> dst, const int64_t grain_size = 4096) { + BLI_assert(src.size() == dst.size()); threading::parallel_for(selection.index_range(), grain_size, [&](const IndexRange range) { for (const int64_t index : selection.slice(range)) { dst[index] = src[index]; @@ -32,4 +34,77 @@ inline void copy(const Span<T> src, }); } +/** + * Fill the destination span by gathering indexed values from the `src` array. + */ +void gather(const GVArray &src, IndexMask indices, GMutableSpan dst, int64_t grain_size = 4096); + +/** + * Fill the destination span by gathering indexed values from the `src` array. + */ +template<typename T> +inline void gather(const VArray<T> &src, + const IndexMask indices, + MutableSpan<T> dst, + const int64_t grain_size = 4096) +{ + BLI_assert(indices.size() == dst.size()); + threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) { + src.materialize_compressed_to_uninitialized(indices.slice(range), dst.slice(range).data()); + }); +} + +/** + * Fill the destination span by gathering indexed values from the `src` array. + */ +template<typename T, typename IndexT> +inline void gather(const Span<T> src, + const IndexMask indices, + MutableSpan<T> dst, + const int64_t grain_size = 4096) +{ + BLI_assert(indices.size() == dst.size()); + threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) { + for (const int64_t i : range) { + dst[i] = src[indices[i]]; + } + }); +} + +/** + * Fill the destination span by gathering indexed values from the `src` array. + */ +template<typename T, typename IndexT> +inline void gather(const Span<T> src, + const Span<IndexT> indices, + MutableSpan<T> dst, + const int64_t grain_size = 4096) +{ + BLI_assert(indices.size() == dst.size()); + threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) { + for (const int64_t i : range) { + dst[i] = src[indices[i]]; + } + }); +} + +/** + * Fill the destination span by gathering indexed values from the `src` array. + */ +template<typename T, typename IndexT> +inline void gather(const VArray<T> &src, + const Span<IndexT> indices, + MutableSpan<T> dst, + const int64_t grain_size = 4096) +{ + BLI_assert(indices.size() == dst.size()); + devirtualize_varray(src, [&](const auto &src) { + threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) { + for (const int64_t i : range) { + dst[i] = src[indices[i]]; + } + }); + }); +} + } // namespace blender::array_utils diff --git a/source/blender/blenlib/intern/array_utils.cc b/source/blender/blenlib/intern/array_utils.cc index a0fc8810199..a837d6aceec 100644 --- a/source/blender/blenlib/intern/array_utils.cc +++ b/source/blender/blenlib/intern/array_utils.cc @@ -1,7 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "BLI_array_utils.hh" -#include "BLI_task.hh" namespace blender::array_utils { @@ -17,4 +16,16 @@ void copy(const GVArray &src, }); } +void gather(const GVArray &src, + const IndexMask indices, + GMutableSpan dst, + const int64_t grain_size) +{ + BLI_assert(src.type() == dst.type()); + BLI_assert(indices.size() == dst.size()); + threading::parallel_for(indices.index_range(), grain_size, [&](const IndexRange range) { + src.materialize_compressed_to_uninitialized(indices.slice(range), dst.slice(range).data()); + }); +} + } // namespace blender::array_utils diff --git a/source/blender/geometry/intern/mesh_to_curve_convert.cc b/source/blender/geometry/intern/mesh_to_curve_convert.cc index 22961504015..c2a9b16c8b6 100644 --- a/source/blender/geometry/intern/mesh_to_curve_convert.cc +++ b/source/blender/geometry/intern/mesh_to_curve_convert.cc @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ #include "BLI_array.hh" +#include "BLI_array_utils.hh" #include "BLI_devirtualize_parameters.hh" #include "BLI_set.hh" #include "BLI_task.hh" @@ -18,19 +19,6 @@ namespace blender::geometry { -template<typename T> -static void copy_with_map(const VArray<T> &src, Span<int> map, MutableSpan<T> dst) -{ - devirtualize_varray(src, [&](const auto &src) { - threading::parallel_for(map.index_range(), 1024, [&](const IndexRange range) { - for (const int i : range) { - const int vert_index = map[i]; - dst[i] = src[vert_index]; - } - }); - }); -} - bke::CurvesGeometry create_curve_from_vert_indices(const Mesh &mesh, const Span<int> vert_indices, const Span<int> curve_offsets, @@ -71,7 +59,7 @@ bke::CurvesGeometry create_curve_from_vert_indices(const Mesh &mesh, using T = decltype(dummy); bke::SpanAttributeWriter<T> attribute = curves_attributes.lookup_or_add_for_write_only_span<T>(attribute_id, ATTR_DOMAIN_POINT); - copy_with_map<T>(mesh_attribute.typed<T>(), vert_indices, attribute.span); + array_utils::gather<T>(mesh_attribute.typed<T>(), vert_indices, attribute.span); attribute.finish(); }); } diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc index a1d6695b33b..ce06ccbda75 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ +#include "BLI_array_utils.hh" #include "BLI_task.hh" #include "DNA_mesh_types.h" @@ -44,17 +45,6 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node) node->storage = data; } -static void materialize_compressed_to_uninitialized_threaded(const GVArray &src, - const IndexMask mask, - GMutableSpan dst) -{ - BLI_assert(src.type() == dst.type()); - BLI_assert(mask.size() == dst.size()); - threading::parallel_for(mask.index_range(), 4096, [&](IndexRange range) { - src.materialize_compressed_to_uninitialized(mask.slice(range), dst.slice(range).data()); - }); -} - static void geometry_set_mesh_to_points(GeometrySet &geometry_set, Field<float3> &position_field, Field<float> &radius_field, @@ -88,14 +78,12 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, GSpanAttributeWriter position = dst_attributes.lookup_or_add_for_write_only_span( "position", ATTR_DOMAIN_POINT, CD_PROP_FLOAT3); - materialize_compressed_to_uninitialized_threaded( - evaluator.get_evaluated(0), selection, position.span); + array_utils::gather(evaluator.get_evaluated(0), selection, position.span); position.finish(); GSpanAttributeWriter radius = dst_attributes.lookup_or_add_for_write_only_span( "radius", ATTR_DOMAIN_POINT, CD_PROP_FLOAT); - materialize_compressed_to_uninitialized_threaded( - evaluator.get_evaluated(1), selection, radius.span); + array_utils::gather(evaluator.get_evaluated(1), selection, radius.span); radius.finish(); Map<AttributeIDRef, AttributeKind> attributes; @@ -112,7 +100,7 @@ static void geometry_set_mesh_to_points(GeometrySet &geometry_set, GSpanAttributeWriter dst = dst_attributes.lookup_or_add_for_write_only_span( attribute_id, ATTR_DOMAIN_POINT, data_type); if (dst && src) { - materialize_compressed_to_uninitialized_threaded(src, selection, dst.span); + array_utils::gather(src, selection, dst.span); dst.finish(); } } |