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:
Diffstat (limited to 'source/blender/blenkernel/BKE_attribute_access.hh')
-rw-r--r--source/blender/blenkernel/BKE_attribute_access.hh541
1 files changed, 0 insertions, 541 deletions
diff --git a/source/blender/blenkernel/BKE_attribute_access.hh b/source/blender/blenkernel/BKE_attribute_access.hh
deleted file mode 100644
index 9648b5b7cde..00000000000
--- a/source/blender/blenkernel/BKE_attribute_access.hh
+++ /dev/null
@@ -1,541 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-
-#pragma once
-
-#include <mutex>
-
-#include "BKE_anonymous_attribute.hh"
-#include "BKE_attribute.h"
-
-#include "BLI_color.hh"
-#include "BLI_function_ref.hh"
-#include "BLI_generic_span.hh"
-#include "BLI_generic_virtual_array.hh"
-#include "BLI_math_vec_types.hh"
-
-/**
- * This file defines classes that help to provide access to attribute data on a #GeometryComponent.
- * The API for retrieving attributes is defined in `BKE_geometry_set.hh`, but this comment has some
- * general comments about the system.
- *
- * Attributes are stored in geometry data, though they can also be stored in instances. Their
- * storage is often tied to `CustomData`, which is a system to store "layers" of data with specific
- * types and names. However, since `CustomData` was added to Blender before attributes were
- * conceptualized, it combines the "legacy" style of task-specific attribute types with generic
- * types like "Float". The attribute API here only provides access to generic types.
- *
- * Attributes are retrieved from geometry components by providing an "id" (#AttributeIDRef). This
- * is most commonly just an attribute name. The attribute API on geometry components has some more
- * advanced capabilities:
- * 1. Read-only access: With a `const` geometry component, an attribute on the geometry cannot be
- * modified, so the `for_write` and `for_output` versions of the API are not available. This is
- * extremely important for writing coherent bug-free code. When an attribute is retrieved with
- * write access, via #WriteAttributeLookup or #OutputAttribute, the geometry component must be
- * tagged to clear caches that depend on the changed data.
- * 2. Domain interpolation: When retrieving an attribute, a domain (#eAttrDomain) can be
- * provided. If the attribute is stored on a different domain and conversion is possible, a
- * version of the data interpolated to the requested domain will be provided. These conversions
- * are implemented in each #GeometryComponent by `attribute_try_adapt_domain_impl`.
- * 3. Implicit type conversion: In addition to interpolating domains, attribute types can be
- * converted, using the conversions in `BKE_type_conversions.hh`. The #VArray / #GVArray system
- * makes it possible to only convert necessary indices on-demand.
- * 4. Anonymous attributes: The "id" used to look up an attribute can also be an anonymous
- * attribute reference. Currently anonymous attributes are only used in geometry nodes.
- * 5. Abstracted storage: Since the data returned from the API is usually a virtual array,
- * it doesn't have to be stored contiguously (even though that is generally preferred). This
- * allows accessing "legacy" attributes like `material_index`, which is stored in `MPoly`.
- */
-
-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();
- AttributeIDRef(StringRef name);
- AttributeIDRef(StringRefNull name);
- AttributeIDRef(const char *name);
- AttributeIDRef(const std::string &name);
- AttributeIDRef(const AnonymousAttributeID *anonymous_id);
-
- operator bool() const;
- uint64_t hash() const;
- bool is_named() const;
- bool is_anonymous() const;
- StringRef name() const;
- const AnonymousAttributeID &anonymous_id() const;
- bool should_be_kept() const;
-
- friend bool operator==(const AttributeIDRef &a, const AttributeIDRef &b);
- friend std::ostream &operator<<(std::ostream &stream, const AttributeIDRef &attribute_id);
-};
-
-bool allow_procedural_attribute_access(StringRef attribute_name);
-extern const char *no_procedural_access_message;
-
-} // 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
- * stored (uv map, vertex group, ...).
- */
-struct AttributeMetaData {
- eAttrDomain domain;
- eCustomDataType data_type;
-
- constexpr friend bool operator==(AttributeMetaData a, AttributeMetaData b)
- {
- return (a.domain == b.domain) && (a.data_type == b.data_type);
- }
-};
-
-struct AttributeKind {
- eAttrDomain domain;
- eCustomDataType data_type;
-};
-
-/**
- * Base class for the attribute initializer 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 {
- blender::GVArray varray;
-
- AttributeInitVArray(blender::GVArray varray)
- : AttributeInit(Type::VArray), varray(std::move(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 contiguous
- * 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)
- {
- }
-};
-
-/* Returns false when the iteration should be stopped. */
-using AttributeForeachCallback = blender::FunctionRef<bool(
- const blender::bke::AttributeIDRef &attribute_id, const AttributeMetaData &meta_data)>;
-
-namespace blender::bke {
-
-eCustomDataType attribute_data_type_highest_complexity(Span<eCustomDataType> data_types);
-/**
- * Domains with a higher "information density" have a higher priority,
- * in order to choose a domain that will not lose data through domain conversion.
- */
-eAttrDomain attribute_domain_highest_priority(Span<eAttrDomain> domains);
-
-/**
- * Used when looking up a "plain attribute" based on a name for reading from it.
- */
-struct ReadAttributeLookup {
- /* The virtual array that is used to read from this attribute. */
- GVArray varray;
- /* Domain the attribute lives on in the geometry. */
- eAttrDomain domain;
-
- /* Convenience function to check if the attribute has been found. */
- operator bool() const
- {
- return this->varray;
- }
-};
-
-/**
- * Used when looking up a "plain attribute" based on a name for reading from it and writing to it.
- */
-struct WriteAttributeLookup {
- /** The virtual array that is used to read from and write to the attribute. */
- GVMutableArray varray;
- /** Domain the attributes lives on in the geometry component. */
- eAttrDomain domain;
- /**
- * Call this after changing the attribute to invalidate caches that depend on this attribute.
- * \note Do not call this after the component the attribute is from has been destructed.
- */
- std::function<void()> tag_modified_fn;
-
- /* Convenience function to check if the attribute has been found. */
- operator bool() const
- {
- return this->varray;
- }
-};
-
-/**
- * An output attribute allows writing to an attribute (and optionally reading as well). It adds
- * some convenience features on top of `GVMutableArray` that are very commonly used.
- *
- * Supported convenience features:
- * - Implicit type conversion when writing to builtin attributes.
- * - Supports simple access to a span containing the attribute values (that avoids the use of
- * MutableVArraySpan in many cases).
- * - An output attribute can live side by side with an existing attribute with a different domain
- * or data type. The old attribute will only be overwritten when the #save function is called.
- *
- * \note The lifetime of an output attribute should not be longer than the lifetime of the
- * geometry component it comes from, since it can keep a reference to the component for use in
- * the #save method.
- */
-class OutputAttribute {
- public:
- using SaveFn = std::function<void(OutputAttribute &)>;
-
- private:
- GVMutableArray varray_;
- eAttrDomain domain_ = ATTR_DOMAIN_AUTO;
- SaveFn save_;
- std::unique_ptr<GMutableVArraySpan> optional_span_varray_;
- bool ignore_old_values_ = false;
- bool save_has_been_called_ = false;
-
- public:
- OutputAttribute();
- OutputAttribute(OutputAttribute &&other);
- OutputAttribute(GVMutableArray varray, eAttrDomain domain, SaveFn save, bool ignore_old_values);
-
- ~OutputAttribute();
-
- operator bool() const;
-
- GVMutableArray &operator*();
- GVMutableArray *operator->();
- GVMutableArray &varray();
- eAttrDomain domain() const;
- const CPPType &cpp_type() const;
- eCustomDataType custom_data_type() const;
-
- GMutableSpan as_span();
- template<typename T> MutableSpan<T> as_span();
-
- void save();
-};
-
-/**
- * Same as OutputAttribute, but should be used when the data type is known at compile time.
- */
-template<typename T> class OutputAttribute_Typed {
- private:
- OutputAttribute attribute_;
- VMutableArray<T> varray_;
-
- public:
- OutputAttribute_Typed();
- OutputAttribute_Typed(OutputAttribute attribute) : attribute_(std::move(attribute))
- {
- if (attribute_) {
- varray_ = attribute_.varray().template typed<T>();
- }
- }
-
- OutputAttribute_Typed(OutputAttribute_Typed &&other);
- ~OutputAttribute_Typed();
-
- OutputAttribute_Typed &operator=(OutputAttribute_Typed &&other)
- {
- if (this == &other) {
- return *this;
- }
- this->~OutputAttribute_Typed();
- new (this) OutputAttribute_Typed(std::move(other));
- return *this;
- }
-
- operator bool() const
- {
- return varray_;
- }
-
- VMutableArray<T> &operator*()
- {
- return varray_;
- }
-
- VMutableArray<T> *operator->()
- {
- return &varray_;
- }
-
- VMutableArray<T> &varray()
- {
- return varray_;
- }
-
- eAttrDomain domain() const
- {
- return attribute_.domain();
- }
-
- const CPPType &cpp_type() const
- {
- return CPPType::get<T>();
- }
-
- eCustomDataType custom_data_type() const
- {
- return cpp_type_to_custom_data_type(this->cpp_type());
- }
-
- MutableSpan<T> as_span()
- {
- return attribute_.as_span<T>();
- }
-
- void save()
- {
- attribute_.save();
- }
-};
-
-/* These are not defined in the class directly, because when defining them there, the external
- * template instantiation does not work, resulting in longer compile times. */
-template<typename T> inline OutputAttribute_Typed<T>::OutputAttribute_Typed() = default;
-template<typename T>
-inline OutputAttribute_Typed<T>::OutputAttribute_Typed(OutputAttribute_Typed &&other) = default;
-template<typename T> inline OutputAttribute_Typed<T>::~OutputAttribute_Typed() = default;
-
-/**
- * A basic container around DNA CustomData so that its users
- * don't have to implement special copy and move constructors.
- */
-class CustomDataAttributes {
- /**
- * #CustomData needs a size to be freed, and unfortunately it isn't stored in the struct
- * itself, so keep track of the size here so this class can implement its own destructor.
- * If the implementation of the attribute storage changes, this could be removed.
- */
- int size_;
-
- public:
- CustomData data;
-
- CustomDataAttributes();
- ~CustomDataAttributes();
- CustomDataAttributes(const CustomDataAttributes &other);
- CustomDataAttributes(CustomDataAttributes &&other);
- CustomDataAttributes &operator=(const CustomDataAttributes &other);
-
- void reallocate(int size);
-
- void clear();
-
- std::optional<blender::GSpan> get_for_read(const AttributeIDRef &attribute_id) const;
-
- /**
- * Return a virtual array for a stored attribute, or a single value virtual array with the
- * default value if the attribute doesn't exist. If no default value is provided, the default
- * value for the type will be used.
- */
- blender::GVArray get_for_read(const AttributeIDRef &attribute_id,
- eCustomDataType data_type,
- const void *default_value) const;
-
- template<typename T>
- blender::VArray<T> get_for_read(const AttributeIDRef &attribute_id, const T &default_value) const
- {
- const blender::CPPType &cpp_type = blender::CPPType::get<T>();
- const eCustomDataType type = blender::bke::cpp_type_to_custom_data_type(cpp_type);
- GVArray varray = this->get_for_read(attribute_id, type, &default_value);
- return varray.typed<T>();
- }
-
- std::optional<blender::GMutableSpan> get_for_write(const AttributeIDRef &attribute_id);
- bool create(const AttributeIDRef &attribute_id, eCustomDataType data_type);
- bool create_by_move(const AttributeIDRef &attribute_id, eCustomDataType data_type, void *buffer);
- bool remove(const AttributeIDRef &attribute_id);
-
- /**
- * Change the order of the attributes to match the order of IDs in the argument.
- */
- void reorder(Span<AttributeIDRef> new_order);
-
- bool foreach_attribute(const AttributeForeachCallback callback, eAttrDomain domain) const;
-};
-
-/* -------------------------------------------------------------------- */
-/** \name #AttributeIDRef Inline Methods
- * \{ */
-
-inline AttributeIDRef::AttributeIDRef() = default;
-
-inline AttributeIDRef::AttributeIDRef(StringRef name) : name_(name)
-{
-}
-
-inline AttributeIDRef::AttributeIDRef(StringRefNull name) : name_(name)
-{
-}
-
-inline AttributeIDRef::AttributeIDRef(const char *name) : name_(name)
-{
-}
-
-inline AttributeIDRef::AttributeIDRef(const std::string &name) : name_(name)
-{
-}
-
-/* The anonymous id is only borrowed, the caller has to keep a reference to it. */
-inline AttributeIDRef::AttributeIDRef(const AnonymousAttributeID *anonymous_id)
- : anonymous_id_(anonymous_id)
-{
-}
-
-inline bool operator==(const AttributeIDRef &a, const AttributeIDRef &b)
-{
- return a.anonymous_id_ == b.anonymous_id_ && a.name_ == b.name_;
-}
-
-inline AttributeIDRef::operator bool() const
-{
- return this->is_named() || this->is_anonymous();
-}
-
-inline uint64_t AttributeIDRef::hash() const
-{
- return get_default_hash_2(name_, anonymous_id_);
-}
-
-inline bool AttributeIDRef::is_named() const
-{
- return !name_.is_empty();
-}
-
-inline bool AttributeIDRef::is_anonymous() const
-{
- return anonymous_id_ != nullptr;
-}
-
-inline StringRef AttributeIDRef::name() const
-{
- BLI_assert(this->is_named());
- return name_;
-}
-
-inline const AnonymousAttributeID &AttributeIDRef::anonymous_id() const
-{
- BLI_assert(this->is_anonymous());
- return *anonymous_id_;
-}
-
-/**
- * \return True if the attribute should not be removed automatically as an optimization during
- * processing or copying. Anonymous attributes can be removed when they no longer have any
- * references.
- */
-inline bool AttributeIDRef::should_be_kept() const
-{
- return this->is_named() || BKE_anonymous_attribute_id_has_strong_references(anonymous_id_);
-}
-
-/** \} */
-
-/* -------------------------------------------------------------------- */
-/** \name #OutputAttribute Inline Methods
- * \{ */
-
-inline OutputAttribute::OutputAttribute() = default;
-inline OutputAttribute::OutputAttribute(OutputAttribute &&other) = default;
-
-inline OutputAttribute::OutputAttribute(GVMutableArray varray,
- eAttrDomain domain,
- SaveFn save,
- const bool ignore_old_values)
- : varray_(std::move(varray)),
- domain_(domain),
- save_(std::move(save)),
- ignore_old_values_(ignore_old_values)
-{
-}
-
-inline OutputAttribute::operator bool() const
-{
- return varray_;
-}
-
-inline GVMutableArray &OutputAttribute::operator*()
-{
- return varray_;
-}
-
-inline GVMutableArray *OutputAttribute::operator->()
-{
- return &varray_;
-}
-
-inline GVMutableArray &OutputAttribute::varray()
-{
- return varray_;
-}
-
-inline eAttrDomain OutputAttribute::domain() const
-{
- return domain_;
-}
-
-inline const CPPType &OutputAttribute::cpp_type() const
-{
- return varray_.type();
-}
-
-inline eCustomDataType OutputAttribute::custom_data_type() const
-{
- return cpp_type_to_custom_data_type(this->cpp_type());
-}
-
-template<typename T> inline MutableSpan<T> OutputAttribute::as_span()
-{
- return this->as_span().typed<T>();
-}
-
-/** \} */
-
-} // namespace blender::bke