[Bf-blender-cvs] [5239a774c5e] virtual-array-attributes: progress

Jacques Lucke noreply at git.blender.org
Mon Apr 12 18:27:56 CEST 2021


Commit: 5239a774c5e35b86ec5f5ba28ce32e16bebee0f4
Author: Jacques Lucke
Date:   Mon Apr 12 16:55:52 2021 +0200
Branches: virtual-array-attributes
https://developer.blender.org/rB5239a774c5e35b86ec5f5ba28ce32e16bebee0f4

progress

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

M	source/blender/blenkernel/BKE_attribute_access.hh
M	source/blender/blenkernel/BKE_geometry_set.hh
M	source/blender/blenkernel/intern/attribute_access.cc
M	source/blender/blenkernel/intern/attribute_access_intern.hh
M	source/blender/blenkernel/intern/geometry_component_pointcloud.cc
M	source/blender/functions/FN_generic_virtual_array.hh

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

diff --git a/source/blender/blenkernel/BKE_attribute_access.hh b/source/blender/blenkernel/BKE_attribute_access.hh
index 120b4e08b9c..c4fa16c626e 100644
--- a/source/blender/blenkernel/BKE_attribute_access.hh
+++ b/source/blender/blenkernel/BKE_attribute_access.hh
@@ -20,6 +20,7 @@
 
 #include "FN_cpp_type.hh"
 #include "FN_generic_span.hh"
+#include "FN_generic_virtual_array.hh"
 
 #include "BKE_attribute.h"
 
@@ -30,289 +31,79 @@
 namespace blender::bke {
 
 using fn::CPPType;
+using fn::GVArray;
+using fn::GVMutableArray;
 
 const CPPType *custom_data_type_to_cpp_type(const CustomDataType type);
 CustomDataType cpp_type_to_custom_data_type(const CPPType &type);
 CustomDataType attribute_data_type_highest_complexity(Span<CustomDataType> data_types);
 AttributeDomain attribute_domain_highest_priority(Span<AttributeDomain> domains);
 
-/**
- * This class offers an indirection for reading an attribute.
- * This is useful for the following reasons:
- * - Blender does not store all attributes the same way.
- *   The simplest case are custom data layers with primitive types.
- *   A bit more complex are mesh attributes like the position of vertices,
- *   which are embedded into the MVert struct.
- *   Even more complex to access are vertex weights.
- * - Sometimes attributes are stored on one domain, but we want to access
- *   the attribute on a different domain. Therefore, we have to interpolate
- *   between the domains.
- */
-class ReadAttribute {
- protected:
-  const AttributeDomain domain_;
-  const CPPType &cpp_type_;
-  const CustomDataType custom_data_type_;
-  const int64_t size_;
-
-  /* Protects the span below, so that no two threads initialize it at the same time. */
-  mutable std::mutex span_mutex_;
-  /* When it is not null, it points to the attribute array or a temporary array that contains all
-   * the attribute values. */
-  mutable void *array_buffer_ = nullptr;
-  /* Is true when the buffer above is owned by the attribute accessor. */
-  mutable bool array_is_temporary_ = false;
-
- public:
-  ReadAttribute(AttributeDomain domain, const CPPType &cpp_type, const int64_t size)
-      : domain_(domain),
-        cpp_type_(cpp_type),
-        custom_data_type_(cpp_type_to_custom_data_type(cpp_type)),
-        size_(size)
-  {
-  }
-
-  virtual ~ReadAttribute();
-
-  AttributeDomain domain() const
-  {
-    return domain_;
-  }
-
-  const CPPType &cpp_type() const
-  {
-    return cpp_type_;
-  }
-
-  CustomDataType custom_data_type() const
-  {
-    return custom_data_type_;
-  }
-
-  int64_t size() const
-  {
-    return size_;
-  }
+struct ReadAttributeLookup {
+  std::unique_ptr<GVArray> varray;
+  AttributeDomain domain;
 
-  void get(const int64_t index, void *r_value) const
+  operator bool() const
   {
-    BLI_assert(index < size_);
-    this->get_internal(index, r_value);
+    return this->varray.get() != nullptr;
   }
-
-  /* Get a span that contains all attribute values. */
-  fn::GSpan get_span() const;
-
-  template<typename T> Span<T> get_span() const
-  {
-    return this->get_span().typed<T>();
-  }
-
- protected:
-  /* r_value is expected to be uninitialized. */
-  virtual void get_internal(const int64_t index, void *r_value) const = 0;
-
-  virtual void initialize_span() const;
 };
 
-/**
- * This exists for similar reasons as the ReadAttribute class, except that
- * it does not deal with interpolation between domains.
- */
-class WriteAttribute {
- protected:
-  const AttributeDomain domain_;
-  const CPPType &cpp_type_;
-  const CustomDataType custom_data_type_;
-  const int64_t size_;
-
-  /* When not null, this points either to the attribute array or to a temporary array. */
-  void *array_buffer_ = nullptr;
-  /* True, when the buffer points to a temporary array. */
-  bool array_is_temporary_ = false;
-  /* This helps to protect against forgetting to apply changes done to the array. */
-  bool array_should_be_applied_ = false;
-
- public:
-  WriteAttribute(AttributeDomain domain, const CPPType &cpp_type, const int64_t size)
-      : domain_(domain),
-        cpp_type_(cpp_type),
-        custom_data_type_(cpp_type_to_custom_data_type(cpp_type)),
-        size_(size)
-  {
-  }
-
-  virtual ~WriteAttribute();
-
-  AttributeDomain domain() const
-  {
-    return domain_;
-  }
-
-  const CPPType &cpp_type() const
-  {
-    return cpp_type_;
-  }
-
-  CustomDataType custom_data_type() const
-  {
-    return custom_data_type_;
-  }
-
-  int64_t size() const
-  {
-    return size_;
-  }
+struct WriteAttributeLookup {
+  std::unique_ptr<GVMutableArray> varray;
+  AttributeDomain domain;
 
-  void get(const int64_t index, void *r_value) const
+  operator bool() const
   {
-    BLI_assert(index < size_);
-    this->get_internal(index, r_value);
+    return this->varray.get() != nullptr;
   }
-
-  void set(const int64_t index, const void *value)
-  {
-    BLI_assert(index < size_);
-    this->set_internal(index, value);
-  }
-
-  /* Get a span that new attribute values can be written into. When all values have been changed,
-   * #apply_span has to be called. */
-  fn::GMutableSpan get_span();
-  /* The span returned by this method might not contain the current attribute values. */
-  fn::GMutableSpan get_span_for_write_only();
-  /* Write the changes to the span into the actual attribute, if they aren't already. */
-  void apply_span();
-
-  template<typename T> MutableSpan<T> get_span()
-  {
-    return this->get_span().typed<T>();
-  }
-
-  template<typename T> MutableSpan<T> get_span_for_write_only()
-  {
-    return this->get_span_for_write_only().typed<T>();
-  }
-
- protected:
-  virtual void get_internal(const int64_t index, void *r_value) const = 0;
-  virtual void set_internal(const int64_t index, const void *value) = 0;
-
-  virtual void initialize_span(const bool write_only);
-  virtual void apply_span_if_necessary();
 };
 
-using ReadAttributePtr = std::unique_ptr<ReadAttribute>;
-using WriteAttributePtr = std::unique_ptr<WriteAttribute>;
-
-/* This provides type safe access to an attribute.
- * The underlying ReadAttribute is owned optionally. */
-template<typename T> class TypedReadAttribute {
- private:
-  std::unique_ptr<const ReadAttribute> owned_attribute_;
-  const ReadAttribute *attribute_;
-
+class MaybeUnsavedWriteAttribute {
  public:
-  TypedReadAttribute(ReadAttributePtr attribute) : TypedReadAttribute(*attribute)
-  {
-    owned_attribute_ = std::move(attribute);
-    BLI_assert(owned_attribute_);
-  }
+  using SaveF = std::function<void(MaybeUnsavedWriteAttribute &)>;
 
-  TypedReadAttribute(const ReadAttribute &attribute) : attribute_(&attribute)
-  {
-    BLI_assert(attribute_->cpp_type().is<T>());
-  }
-
-  int64_t size() const
-  {
-    return attribute_->size();
-  }
-
-  T operator[](const int64_t index) const
-  {
-    BLI_assert(index < attribute_->size());
-    T value;
-    value.~T();
-    attribute_->get(index, &value);
-    return value;
-  }
-
-  /* Get a span to that contains all attribute values for faster and more convenient access. */
-  Span<T> get_span() const
-  {
-    return attribute_->get_span().template typed<T>();
-  }
-};
-
-/* This provides type safe access to an attribute.
- * The underlying WriteAttribute is owned optionally. */
-template<typename T> class TypedWriteAttribute {
  private:
-  std::unique_ptr<WriteAttribute> owned_attribute_;
-  WriteAttribute *attribute_;
+  std::unique_ptr<GVMutableArray> varray_;
+  AttributeDomain domain_;
+  SaveF save_;
 
  public:
-  TypedWriteAttribute(WriteAttributePtr attribute) : TypedWriteAttribute(*attribute)
-  {
-    owned_attribute_ = std::move(attribute);
-    BLI_assert(owned_attribute_);
-  }
+  MaybeUnsavedWriteAttribute() = default;
 
-  TypedWriteAttribute(WriteAttribute &attribute) : attribute_(&attribute)
+  MaybeUnsavedWriteAttribute(std::unique_ptr<GVMutableArray> varray,
+                             AttributeDomain domain,
+                             SaveF save)
+      : varray_(std::move(varray)), domain_(domain), save_(std::move(save))
   {
-    BLI_assert(attribute_->cpp_type().is<T>());
   }
 
-  int64_t size() const
+  operator bool() const
   {
-    return attribute_->size();
+    return varray_.get() != nullptr;
   }
 
-  T operator[](const int64_t index) const
+  GVMutableArray &varray()
   {
-    BLI_assert(index < attribute_->size());
-    T value;
-    value.~T();
-    attribute_->get(index, &value);
-    return value;
+    return *varray_;
   }
 
-  void set(const int64_t index, const T &value)
+  AttributeDomain domain() const
   {
-    attribute_->set(index, &value);
+    return domain_;
   }
 
-  /* Get a span that new values can be written into. Once all values have been updated #apply_span
-   * has to be called. */
-  MutableSpan<T> get_span()
-  {
-    return attribute_->get_span().typed<T>();
-  }
-  /* The span returned by this method might not contain the current attribute values. */
-  MutableSpan<T> get_span_for_write_only()
+  const CPPType &cpp_type() const
   {
-    return attribute_->get_span_for_write_only().typed<T>();
+    return varray_->type();
   }
 
-  /* Write back all changes to the actual attribute, if necessary. */
-  void apply_span()
+  CustomDataType custom_data_type() const
   {
-    attribute_->apply_span();
+    return cpp_type_to_custom_data_type(this->cpp_type());
   }
-};
 
-using BooleanReadAttribute = TypedReadAttribute<bool>;
-using FloatReadAttribute = TypedReadAttribute<float>;
-using Float2ReadAttribute = TypedReadAttribute<float2>;
-using Float3ReadAttribute = TypedReadAttribute<float3>;
-using Int32ReadAttribute = TypedReadAttribute<int>;
-using Color4fReadAttribute = TypedReadAttribute<Color4f>;
-using BooleanWriteAttribute = TypedWriteAttribute<bool>;
-using FloatWriteAttribute = TypedWriteAttribute<float>;
-using Float2WriteAttribute = TypedWriteAttribute<float2>;
-using Float3WriteAttribute = TypedWriteAttribute<float3>;
-using Int32WriteAttribute = TypedWriteAttribute<int>;
-using Color4fWriteAttribute = TypedWriteAttribute<Color4f>;
+  void save_if_necessary();
+};
 
 }  // namespace blender::bke
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh
index d94b2e7902b..e9c6793b63d 10064

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list