tornavis/source/blender/blenkernel/BKE_anonymous_attribute_id.hh

98 lines
3.3 KiB
C++

/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include <atomic>
#include "BLI_implicit_sharing_ptr.hh"
#include "BLI_set.hh"
#include "BLI_string_ref.hh"
namespace blender::bke {
/**
* An #AnonymousAttributeID contains information about a specific anonymous attribute.
* Like normal attributes, anonymous attributes are also identified by their name, so one should
* not have to compare #AnonymousAttributeID pointers.
*
* Anonymous attributes don't need additional information besides their name, with a few
* exceptions:
* - The name of anonymous attributes is generated automatically, so it is generally not human
* readable (just random characters). #AnonymousAttributeID can provide more context as where a
* specific anonymous attribute was created which can simplify debugging.
* - [Not yet supported.] When anonymous attributes are contained in on-disk caches, we have to map
* those back to anonymous attributes at run-time. The issue is that (for various reasons) we
* might change how anonymous attribute names are generated in the future, which would lead to a
* mis-match between stored and new attribute names. To work around it, we should cache
* additional information for anonymous attributes on disk (like which node created it). This
* information can then be used to map stored attributes to their run-time counterpart.
*
* Once created, #AnonymousAttributeID is immutable. Also it is intrinsically reference counted so
* that it can have shared ownership. `std::shared_ptr` can't be used for that purpose here,
* because that is not available in C code. If possible, the #AnonymousAttributeIDPtr wrapper
* should be used to avoid manual reference counting in C++ code.
*/
class AnonymousAttributeID : public ImplicitSharingMixin {
protected:
std::string name_;
public:
virtual ~AnonymousAttributeID() = default;
StringRefNull name() const
{
return name_;
}
virtual std::string user_name() const;
private:
void delete_self() override
{
MEM_delete(this);
}
};
/** Wrapper for #AnonymousAttributeID that avoids manual reference counting. */
using AnonymousAttributeIDPtr = ImplicitSharingPtr<const AnonymousAttributeID>;
/**
* A set of anonymous attribute names that is passed around in geometry nodes.
*/
class AnonymousAttributeSet {
public:
/**
* This uses `std::shared_ptr` because attributes sets are passed around by value during geometry
* nodes evaluation, and this makes it very small if there is no name. Also it makes copying very
* cheap.
*/
std::shared_ptr<Set<std::string>> names;
};
/**
* Can be passed to algorithms which propagate attributes. It can tell the algorithm which
* anonymous attributes should be propagated and can be skipped.
*/
class AnonymousAttributePropagationInfo {
public:
/**
* This uses `std::shared_ptr` because it's usually initialized from an #AnonymousAttributeSet
* and then the set doesn't have to be copied.
*/
std::shared_ptr<Set<std::string>> names;
/**
* Propagate all anonymous attributes even if the set above is empty.
*/
bool propagate_all = true;
/**
* Return true when the anonymous attribute should be propagated and false otherwise.
*/
bool propagate(const AnonymousAttributeID &anonymous_id) const;
};
} // namespace blender::bke