diff options
author | Hans Goudey <h.goudey@me.com> | 2021-04-22 17:20:03 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2021-04-22 17:20:03 +0300 |
commit | d1ccc5b9694b7c737158f4d4bd83ae780b32d258 (patch) | |
tree | 18a8e6bef4dac90c72fc3337b84222b322b519bc /source/blender/blenkernel/BKE_geometry_set.hh | |
parent | 9fccbe2d1385df6dfbd3291d2b8950732e028f25 (diff) |
Geometry Nodes: Add initializer for attribute creation
Previously we always had to set attribute values after creating
the attribute. This patch adds an initializer argument to
`attribute_try_create` which can fill it in a few ways, which
are explained in code comments.
This fixes T87597.
Differential Revision: https://developer.blender.org/D11045
Diffstat (limited to 'source/blender/blenkernel/BKE_geometry_set.hh')
-rw-r--r-- | source/blender/blenkernel/BKE_geometry_set.hh | 65 |
1 files changed, 63 insertions, 2 deletions
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh index e9545cba1f1..027338a5d5c 100644 --- a/source/blender/blenkernel/BKE_geometry_set.hh +++ b/source/blender/blenkernel/BKE_geometry_set.hh @@ -70,6 +70,65 @@ using AttributeForeachCallback = blender::FunctionRef<bool(blender::StringRefNul const AttributeMetaData &meta_data)>; /** + * Base class for the attribute intializer types described below. + */ +struct AttributeInit { + enum class Type { + Default, + VArray, + MoveArray, + }; + Type type; + AttributeInit(const Type type) : type(type) + { + } +}; + +/** + * Create an attribute using the default value for the data type. + * The default values may depend on the attribute provider implementation. + */ +struct AttributeInitDefault : public AttributeInit { + AttributeInitDefault() : AttributeInit(Type::Default) + { + } +}; + +/** + * Create an attribute by copying data from an existing virtual array. The virtual array + * must have the same type as the newly created attribute. + * + * Note that this can be used to fill the new attribute with the default + */ +struct AttributeInitVArray : public AttributeInit { + const blender::fn::GVArray *varray; + + AttributeInitVArray(const blender::fn::GVArray *varray) + : AttributeInit(Type::VArray), varray(varray) + { + } +}; + +/** + * Create an attribute with a by passing ownership of a pre-allocated contiguous array of data. + * Sometimes data is created before a geometry component is available. In that case, it's + * preferable to move data directly to the created attribute to avoid a new allocation and a copy. + * + * Note that this will only have a benefit for attributes that are stored directly as contigious + * arrays, so not for some built-in attributes. + * + * The array must be allocated with MEM_*, since `attribute_try_create` will free the array if it + * can't be used directly, and that is generally how Blender expects custom data to be allocated. + */ +struct AttributeInitMove : public AttributeInit { + void *data = nullptr; + + AttributeInitMove(void *data) : AttributeInit(Type::MoveArray), data(data) + { + } +}; + +/** * This is the base class for specialized geometry component types. */ class GeometryComponent { @@ -137,11 +196,13 @@ class GeometryComponent { /* Returns true when the attribute has been created. */ bool attribute_try_create(const blender::StringRef attribute_name, const AttributeDomain domain, - const CustomDataType data_type); + const CustomDataType data_type, + const AttributeInit &initializer); /* Try to create the builtin attribute with the given name. No data type or domain has to be * provided, because those are fixed for builtin attributes. */ - bool attribute_try_create_builtin(const blender::StringRef attribute_name); + bool attribute_try_create_builtin(const blender::StringRef attribute_name, + const AttributeInit &initializer); blender::Set<std::string> attribute_names() const; bool attribute_foreach(const AttributeForeachCallback callback) const; |