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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user