[Bf-blender-cvs] [55b130f0f34] temp-multi-function-eval-varray: progress

Jacques Lucke noreply at git.blender.org
Wed Apr 6 16:18:13 CEST 2022


Commit: 55b130f0f34d2cb9e769308dfe2a48dfb4a77928
Author: Jacques Lucke
Date:   Wed Apr 6 13:13:27 2022 +0200
Branches: temp-multi-function-eval-varray
https://developer.blender.org/rB55b130f0f34d2cb9e769308dfe2a48dfb4a77928

progress

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

M	source/blender/blenlib/BLI_virtual_array.hh
M	source/blender/blenlib/tests/BLI_virtual_array_test.cc

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

diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh
index 58a1cbefc40..bca0eb914a5 100644
--- a/source/blender/blenlib/BLI_virtual_array.hh
+++ b/source/blender/blenlib/BLI_virtual_array.hh
@@ -107,7 +107,7 @@ template<typename T> class VArrayImpl {
 
   /**
    * Copy values from the virtual array into the provided span. The index of the value in the
-   * virtual is the same as the index in the span.
+   * virtual array is the same as the index in the span.
    */
   virtual void materialize(IndexMask mask, MutableSpan<T> r_span) const
   {
@@ -146,6 +146,11 @@ template<typename T> class VArrayImpl {
     }
   }
 
+  /**
+   * Copy values from the virtual array into the provided span. Contrary to #materialize, the index
+   * in virtual array is not the same as the index in the output span. Instead, the span is filled
+   * without gaps.
+   */
   virtual void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const
   {
     BLI_assert(mask.size() == r_span.size());
@@ -172,6 +177,9 @@ template<typename T> class VArrayImpl {
     }
   }
 
+  /**
+   * Same as #materialize_compressed but #r_span is expected to be uninitialized.
+   */
   virtual void materialize_compressed_to_uninitialized(IndexMask mask, MutableSpan<T> r_span) const
   {
     BLI_assert(mask.size() == r_span.size());
@@ -426,6 +434,29 @@ template<typename T, typename GetFunc> class VArrayImpl_For_Func final : public
     T *dst = r_span.data();
     mask.foreach_index([&](const int64_t i) { new (dst + i) T(get_func_(i)); });
   }
+
+  void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const override
+  {
+    BLI_assert(mask.size() == r_span.size());
+    T *dst = r_span.data();
+    mask.to_best_mask_type([&](auto best_mask) {
+      for (const int64_t i : IndexRange(best_mask.size())) {
+        dst[i] = get_func_(best_mask[i]);
+      }
+    });
+  }
+
+  void materialize_compressed_to_uninitialized(IndexMask mask,
+                                               MutableSpan<T> r_span) const override
+  {
+    BLI_assert(mask.size() == r_span.size());
+    T *dst = r_span.data();
+    mask.to_best_mask_type([&](auto best_mask) {
+      for (const int64_t i : IndexRange(best_mask.size())) {
+        new (dst + i) T(get_func_(best_mask[i]));
+      }
+    });
+  }
 };
 
 /**
@@ -474,6 +505,29 @@ class VArrayImpl_For_DerivedSpan final : public VMutableArrayImpl<ElemT> {
     mask.foreach_index([&](const int64_t i) { new (dst + i) ElemT(GetFunc(data_[i])); });
   }
 
+  void materialize_compressed(IndexMask mask, MutableSpan<ElemT> r_span) const override
+  {
+    BLI_assert(mask.size() == r_span.size());
+    ElemT *dst = r_span.data();
+    mask.to_best_mask_type([&](auto best_mask) {
+      for (const int64_t i : IndexRange(best_mask.size())) {
+        dst[i] = GetFunc(data_[best_mask[i]]);
+      }
+    });
+  }
+
+  void materialize_compressed_to_uninitialized(IndexMask mask,
+                                               MutableSpan<ElemT> r_span) const override
+  {
+    BLI_assert(mask.size() == r_span.size());
+    ElemT *dst = r_span.data();
+    mask.to_best_mask_type([&](auto best_mask) {
+      for (const int64_t i : IndexRange(best_mask.size())) {
+        new (dst + i) ElemT(GetFunc(data_[best_mask[i]]));
+      }
+    });
+  }
+
   bool may_have_ownership() const override
   {
     return false;
@@ -792,6 +846,7 @@ template<typename T> class VArrayCommon {
     impl_->materialize_to_uninitialized(mask, r_span);
   }
 
+  /** Copy some elements of the virtual array into a span. */
   void materialize_compressed(IndexMask mask, MutableSpan<T> r_span) const
   {
     impl_->materialize_compressed(mask, r_span);
diff --git a/source/blender/blenlib/tests/BLI_virtual_array_test.cc b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
index 92cad693b4c..90c7f1078a5 100644
--- a/source/blender/blenlib/tests/BLI_virtual_array_test.cc
+++ b/source/blender/blenlib/tests/BLI_virtual_array_test.cc
@@ -180,4 +180,46 @@ TEST(virtual_array, MutableToImmutable)
   }
 }
 
+TEST(virtual_array, MaterializeCompressed)
+{
+  {
+    std::array<int, 10> array = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90};
+    VArray<int> varray = VArray<int>::ForSpan(array);
+    std::array<int, 3> compressed_array;
+    varray.materialize_compressed({3, 6, 7}, compressed_array);
+    EXPECT_EQ(compressed_array[0], 30);
+    EXPECT_EQ(compressed_array[1], 60);
+    EXPECT_EQ(compressed_array[2], 70);
+    varray.materialize_compressed_to_uninitialized({2, 8, 9}, compressed_array);
+    EXPECT_EQ(compressed_array[0], 20);
+    EXPECT_EQ(compressed_array[1], 80);
+    EXPECT_EQ(compressed_array[2], 90);
+  }
+  {
+    VArray<int> varray = VArray<int>::ForSingle(4, 10);
+    std::array<int, 3> compressed_array;
+    varray.materialize_compressed({2, 6, 7}, compressed_array);
+    EXPECT_EQ(compressed_array[0], 4);
+    EXPECT_EQ(compressed_array[1], 4);
+    EXPECT_EQ(compressed_array[2], 4);
+    compressed_array.fill(0);
+    varray.materialize_compressed_to_uninitialized({0, 1, 2}, compressed_array);
+    EXPECT_EQ(compressed_array[0], 4);
+    EXPECT_EQ(compressed_array[1], 4);
+    EXPECT_EQ(compressed_array[2], 4);
+  }
+  {
+    VArray<int> varray = VArray<int>::ForFunc(10, [](const int64_t i) { return (int)(i * i); });
+    std::array<int, 3> compressed_array;
+    varray.materialize_compressed({5, 7, 8}, compressed_array);
+    EXPECT_EQ(compressed_array[0], 25);
+    EXPECT_EQ(compressed_array[1], 49);
+    EXPECT_EQ(compressed_array[2], 64);
+    varray.materialize_compressed_to_uninitialized({1, 2, 3}, compressed_array);
+    EXPECT_EQ(compressed_array[0], 1);
+    EXPECT_EQ(compressed_array[1], 4);
+    EXPECT_EQ(compressed_array[2], 9);
+  }
+}
+
 }  // namespace blender::tests



More information about the Bf-blender-cvs mailing list