This introduces the concept of an #AttributeFilter. It's used to tell a geometry algorithm which attributes it should process/propagate and which can be ignored. We already had something similar before named `AnonymousAttributePropagationInfo`. However, as the name implies, this was specific to anonymous attributes. This had some downsides: * A lot of code had to be aware of the concept of anonymous attributes even if it did nothing special with anonymous attributes. * For non-anonymous attributes we often had a separate `Set<std::string> skip` parameter. It's not nice to have to pass two kinds of filters around and to have to construct a `Set<std::string>` in many cases. `AttributeFilter` solves both of these downsides. Technically, `AttributeFilter` could also just be a `FunctionRef<bool(StringRef attribute_name)>`, but that also has some issues: * The `bool` return value is often ambiguous, i.e. it's not clear if it means that the attribute should be processed or not. Using an enum works better. * Passing function refs around and combining them works, but can very easily lead to dangling references. * The default value of a `FunctionRef` is "empty", i.e. it can't be called. It's generally more nice to not have a special case for the default value. Now the default `AttributeFilter` propagates all attributes without any extra handling on the call-site. Pull Request: https://projects.blender.org/blender/blender/pulls/127155
54 lines
1.4 KiB
C++
54 lines
1.4 KiB
C++
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
|
*
|
|
* 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"
|
|
|
|
#include "BKE_attribute_filter.hh"
|
|
|
|
namespace blender::bke {
|
|
|
|
/**
|
|
* 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;
|
|
};
|
|
|
|
/**
|
|
* Checks if the attribute name has the `.a_` prefix which indicates that it is an anonymous
|
|
* attribute. I.e. it is just internally used by Blender and the name should not be exposed to the
|
|
* user.
|
|
*
|
|
* Use #hash_to_anonymous_attribute_name to generate names for anonymous attributes.
|
|
*/
|
|
inline bool attribute_name_is_anonymous(const StringRef name)
|
|
{
|
|
return name.startswith(".a_");
|
|
}
|
|
|
|
class ProcessAllAttributeExceptAnonymous : public AttributeFilter {
|
|
public:
|
|
Result filter(const StringRef name) const override
|
|
{
|
|
if (attribute_name_is_anonymous(name)) {
|
|
return AttributeFilter::Result::AllowSkip;
|
|
}
|
|
return AttributeFilter::Result::Process;
|
|
}
|
|
};
|
|
|
|
} // namespace blender::bke
|