Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2021-09-09 13:54:20 +0300
committerJacques Lucke <jacques@blender.org>2021-09-09 13:54:20 +0300
commitbf47fb40fd6f0ee9386e9936cf213a1049c55b61 (patch)
treec8bbe7c00b27ac845e4adbc214b7f29ec670a9f3 /source/blender/blenkernel/BKE_attribute_access.hh
parent0f6be4e1520087bfe6d1dc98b61d65686ae09b3f (diff)
Geometry Nodes: fields and anonymous attributes
This implements the initial core framework for fields and anonymous attributes (also see T91274). The new functionality is hidden behind the "Geometry Nodes Fields" feature flag. When enabled in the user preferences, the following new nodes become available: `Position`, `Index`, `Normal`, `Set Position` and `Attribute Capture`. Socket inspection has not been updated to work with fields yet. Besides these changes at the user level, this patch contains the ground work for: * building and evaluating fields at run-time (`FN_fields.hh`) and * creating and accessing anonymous attributes on geometry (`BKE_anonymous_attribute.h`). For evaluating fields we use a new so called multi-function procedure (`FN_multi_function_procedure.hh`). It allows composing multi-functions in arbitrary ways and supports efficient evaluation as is required by fields. See `FN_multi_function_procedure.hh` for more details on how this evaluation mechanism can be used. A new `AttributeIDRef` has been added which allows handling named and anonymous attributes in the same way in many places. Hans and I worked on this patch together. Differential Revision: https://developer.blender.org/D12414
Diffstat (limited to 'source/blender/blenkernel/BKE_attribute_access.hh')
-rw-r--r--source/blender/blenkernel/BKE_attribute_access.hh98
1 files changed, 88 insertions, 10 deletions
diff --git a/source/blender/blenkernel/BKE_attribute_access.hh b/source/blender/blenkernel/BKE_attribute_access.hh
index c3f7dbd4bd9..9d309d8a1c1 100644
--- a/source/blender/blenkernel/BKE_attribute_access.hh
+++ b/source/blender/blenkernel/BKE_attribute_access.hh
@@ -22,6 +22,7 @@
#include "FN_generic_span.hh"
#include "FN_generic_virtual_array.hh"
+#include "BKE_anonymous_attribute.hh"
#include "BKE_attribute.h"
#include "BLI_color.hh"
@@ -29,6 +30,81 @@
#include "BLI_float3.hh"
#include "BLI_function_ref.hh"
+namespace blender::bke {
+
+/**
+ * Identifies an attribute that is either named or anonymous.
+ * It does not own the identifier, so it is just a reference.
+ */
+class AttributeIDRef {
+ private:
+ StringRef name_;
+ const AnonymousAttributeID *anonymous_id_ = nullptr;
+
+ public:
+ AttributeIDRef() = default;
+
+ AttributeIDRef(StringRef name) : name_(name)
+ {
+ }
+
+ AttributeIDRef(StringRefNull name) : name_(name)
+ {
+ }
+
+ AttributeIDRef(const char *name) : name_(name)
+ {
+ }
+
+ AttributeIDRef(const std::string &name) : name_(name)
+ {
+ }
+
+ /* The anonymous id is only borrowed, the caller has to keep a reference to it. */
+ AttributeIDRef(const AnonymousAttributeID *anonymous_id) : anonymous_id_(anonymous_id)
+ {
+ }
+
+ operator bool() const
+ {
+ return this->is_named() || this->is_anonymous();
+ }
+
+ friend bool operator==(const AttributeIDRef &a, const AttributeIDRef &b)
+ {
+ return a.anonymous_id_ == b.anonymous_id_ && a.name_ == b.name_;
+ }
+
+ uint64_t hash() const
+ {
+ return get_default_hash_2(name_, anonymous_id_);
+ }
+
+ bool is_named() const
+ {
+ return !name_.is_empty();
+ }
+
+ bool is_anonymous() const
+ {
+ return anonymous_id_ != nullptr;
+ }
+
+ StringRef name() const
+ {
+ BLI_assert(this->is_named());
+ return name_;
+ }
+
+ const AnonymousAttributeID &anonymous_id() const
+ {
+ BLI_assert(this->is_anonymous());
+ return *anonymous_id_;
+ }
+};
+
+} // namespace blender::bke
+
/**
* Contains information about an attribute in a geometry component.
* More information can be added in the future. E.g. whether the attribute is builtin and how it is
@@ -104,8 +180,8 @@ struct AttributeInitMove : public AttributeInit {
};
/* Returns false when the iteration should be stopped. */
-using AttributeForeachCallback = blender::FunctionRef<bool(blender::StringRefNull attribute_name,
- const AttributeMetaData &meta_data)>;
+using AttributeForeachCallback = blender::FunctionRef<bool(
+ const blender::bke::AttributeIDRef &attribute_id, const AttributeMetaData &meta_data)>;
namespace blender::bke {
@@ -333,26 +409,28 @@ class CustomDataAttributes {
void reallocate(const int size);
- std::optional<blender::fn::GSpan> get_for_read(const blender::StringRef name) const;
+ std::optional<blender::fn::GSpan> get_for_read(const AttributeIDRef &attribute_id) const;
- blender::fn::GVArrayPtr get_for_read(const StringRef name,
+ blender::fn::GVArrayPtr get_for_read(const AttributeIDRef &attribute_id,
const CustomDataType data_type,
const void *default_value) const;
template<typename T>
- blender::fn::GVArray_Typed<T> get_for_read(const blender::StringRef name,
+ blender::fn::GVArray_Typed<T> get_for_read(const AttributeIDRef &attribute_id,
const T &default_value) const
{
const blender::fn::CPPType &cpp_type = blender::fn::CPPType::get<T>();
const CustomDataType type = blender::bke::cpp_type_to_custom_data_type(cpp_type);
- GVArrayPtr varray = this->get_for_read(name, type, &default_value);
+ GVArrayPtr varray = this->get_for_read(attribute_id, type, &default_value);
return blender::fn::GVArray_Typed<T>(std::move(varray));
}
- std::optional<blender::fn::GMutableSpan> get_for_write(const blender::StringRef name);
- bool create(const blender::StringRef name, const CustomDataType data_type);
- bool create_by_move(const blender::StringRef name, const CustomDataType data_type, void *buffer);
- bool remove(const blender::StringRef name);
+ std::optional<blender::fn::GMutableSpan> get_for_write(const AttributeIDRef &attribute_id);
+ bool create(const AttributeIDRef &attribute_id, const CustomDataType data_type);
+ bool create_by_move(const AttributeIDRef &attribute_id,
+ const CustomDataType data_type,
+ void *buffer);
+ bool remove(const AttributeIDRef &attribute_id);
bool foreach_attribute(const AttributeForeachCallback callback,
const AttributeDomain domain) const;