[Bf-blender-cvs] [ce54f485567] master: BLI: Add generic utlity for gathering values with indices

Mattias Fredriksson noreply at git.blender.org
Sun Sep 18 05:12:28 CEST 2022


Commit: ce54f4855674059ef9124a27bff0741f97c75eec
Author: Mattias Fredriksson
Date:   Sat Sep 17 22:12:02 2022 -0500
Branches: master
https://developer.blender.org/rBce54f4855674059ef9124a27bff0741f97c75eec

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

===================================================================

M	source/blender/blenlib/BLI_array_utils.hh
M	source/blender/blenlib/intern/array_utils.cc
M	source/blender/geometry/intern/mesh_to_curve_convert.cc
M	source/blender/nodes/geometry/nodes/node_geo_mesh_to_points.cc

===================================================================

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();
     }
   }



More information about the Bf-blender-cvs mailing list