74 if (type.
is<
float>()) {
92 if (type.
is<
bool>()) {
95 if (type.
is<int8_t>()) {
153 if (type.
is<
float>()) {
162 if (type.
is<
int>()) {
171 if (type.
is<
bool>()) {
174 if (type.
is<int8_t>()) {
197 "This attribute cannot be accessed in a procedural context");
219 if (attribute_name ==
".reference_index") {
268 int highest_complexity = INT_MIN;
271 for (
const AttrType data_type : data_types) {
273 if (complexity > highest_complexity) {
274 highest_complexity = complexity;
275 most_complex_type = data_type;
279 return most_complex_type;
312 int highest_priority = INT_MIN;
317 if (priority > highest_priority) {
318 highest_priority = priority;
319 highest_priority_domain = domain;
323 return highest_priority_domain;
329 const int domain_size,
339 const int domain_size,
344 &custom_data, data_type, layer_data, domain_size, attribute_id, sharing_info);
350 const int domain_num,
352 const GPointer custom_default_value_ptr)
354 const int old_layer_num = custom_data.
totlayer;
355 switch (initializer.
type) {
358 custom_data, data_type,
CD_CONSTRUCT, domain_num, attribute_id);
362 if (
const void *default_value = custom_default_value_ptr.
get()) {
363 const CPPType &type = *custom_default_value_ptr.
type();
365 custom_data, data_type,
CD_CONSTRUCT, domain_num, attribute_id);
370 custom_data, data_type,
CD_SET_DEFAULT, domain_num, attribute_id);
376 custom_data, data_type,
CD_CONSTRUCT, domain_num, attribute_id);
377 if (
data !=
nullptr) {
386 custom_data, data_type, attribute_id, domain_num,
data,
nullptr);
395 const_cast<void *
>(
init.data),
400 return old_layer_num < custom_data.
totlayer;
403bool BuiltinCustomDataLayerProvider::layer_exists(
const CustomData &custom_data)
const
410 const CustomData *custom_data = custom_data_access_.get_const_custom_data(owner);
411 if (custom_data ==
nullptr) {
417 const int element_num = custom_data_access_.get_element_num(owner);
418 if (element_num == 0) {
419 if (this->layer_exists(*custom_data)) {
435 CustomData *custom_data = custom_data_access_.get_custom_data(owner);
436 if (custom_data ==
nullptr) {
440 std::function<void()> tag_modified_fn;
441 if (update_on_change_ !=
nullptr) {
442 tag_modified_fn = [owner,
update = update_on_change_]() {
update(owner); };
447 const int element_num = custom_data_access_.get_element_num(owner);
448 if (element_num == 0) {
449 if (this->layer_exists(*custom_data)) {
456 if (
data ==
nullptr) {
468 CustomData *custom_data = custom_data_access_.get_custom_data(owner);
469 if (custom_data ==
nullptr) {
474 if (update_on_change_ !=
nullptr) {
475 update_on_change_(owner);
485 CustomData *custom_data = custom_data_access_.get_custom_data(owner);
486 if (custom_data ==
nullptr) {
490 const int element_num = custom_data_access_.get_element_num(owner);
502 if (update_on_change_ !=
nullptr) {
503 update_on_change_(owner);
513 const CustomData *custom_data = custom_data_access_.get_const_custom_data(owner);
514 if (custom_data ==
nullptr) {
523 const CustomData *custom_data = custom_data_access_.get_const_custom_data(owner);
524 if (custom_data ==
nullptr) {
527 const int element_num = custom_data_access_.get_element_num(owner);
529 if (layer.name != attribute_id) {
533 if (type ==
nullptr) {
536 GSpan data{*type, layer.data, element_num};
545 CustomData *custom_data = custom_data_access_.get_custom_data(owner);
546 if (custom_data ==
nullptr) {
549 const int element_num = custom_data_access_.get_element_num(owner);
551 if (layer.name != attribute_id) {
558 if (type ==
nullptr) {
561 std::function<void()> tag_modified_fn;
562 if (custom_data_access_.get_tag_modified_function !=
nullptr) {
563 tag_modified_fn = custom_data_access_.get_tag_modified_function(owner, attribute_id);
573 CustomData *custom_data = custom_data_access_.get_custom_data(owner);
574 if (custom_data ==
nullptr) {
581 if (custom_data_access_.get_tag_modified_function !=
nullptr) {
582 if (
const std::function<
void()>
fn = custom_data_access_.get_tag_modified_function(
583 owner, attribute_id))
600 if (domain_ != domain) {
603 if (!this->type_is_supported(data_type)) {
606 CustomData *custom_data = custom_data_access_.get_custom_data(owner);
607 if (custom_data ==
nullptr) {
611 if (layer.name == attribute_id) {
615 const int element_num = custom_data_access_.get_element_num(owner);
617 attribute_id, *custom_data, data_type, element_num, initializer, {});
622 if (custom_data_access_.get_tag_modified_function !=
nullptr) {
623 if (
const std::function<
void()>
fn = custom_data_access_.get_tag_modified_function(
624 owner, attribute_id))
636 const CustomData *custom_data = custom_data_access_.get_const_custom_data(owner);
637 if (custom_data ==
nullptr) {
642 if (this->type_is_supported(cd_type)) {
643 const auto get_fn = [&]() {
646 GSpan data{*type, layer.data, custom_data_access_.get_element_num(owner)};
668 return conversions.
try_convert(std::move(varray), to_type);
675 return reinterpret_cast<const Mesh &
>(
id).attributes();
677 return reinterpret_cast<const PointCloud &
>(
id).attributes();
689 const std::optional<AttrDomain> domain,
690 const std::optional<AttrType> data_type,
696 if (domain.has_value()) {
697 if (attribute.
domain != domain) {
699 attribute.
domain = *domain;
706 if (data_type.has_value()) {
720 const std::optional<AttrDomain> domain,
721 const std::optional<AttrType> data_type)
const
736 const void *default_value)
const
744 if (default_value ==
nullptr) {
754 if (attribute_id == iter.
name) {
765 std::optional<AttributeMetaData> meta_data;
767 if (attribute_id == iter.
name) {
807 if (!this->finish_called) {
808 std::cerr <<
"Forgot to call `finish()` for '" << this->name <<
"'.\n";
820 auto checker = std::make_shared<FinishCallChecker>();
821 checker->name = attribute_id;
824 if (checker->real_finish_fn) {
825 checker->real_finish_fn();
827 checker->finish_called =
true;
849 std::optional<AttributeMetaData> meta_data = this->
lookup_meta_data(attribute_id);
850 if (meta_data.has_value()) {
851 if (meta_data->domain == domain && meta_data->data_type == data_type) {
856 if (this->
add(attribute_id, domain, data_type, initializer)) {
869 attribute_id, domain, data_type, initializer);
890 if (old_attribute_id == new_attribute_id) {
893 if (this->
contains(new_attribute_id)) {
897 if (!old_attribute) {
902 if (!this->
add(new_attribute_id,
906 *old_attribute.sharing_info}))
912 if (!this->
add(new_attribute_id,
920 this->
remove(old_attribute_id);
971 const int src_size = src_attributes.
domain_size(src_domain);
973 if (iter.
domain != src_domain) {
1008 copy_attributes(src_attributes, src_domain, dst_domain, attribute_filter, dst_attributes);
1012 if (iter.
domain != src_domain) {
1042 if (selection.
size() == src_offsets.
size()) {
1046 copy_attributes(src_attributes, src_domain, dst_domain, attribute_filter, dst_attributes);
1051 if (iter.
domain != src_domain) {
1080 if (iter.
domain != src_domain) {
1128 if (iter.
domain != src_domain) {
1138 const bool dst_already_exists = dst_attributes.
contains(iter.
name);
1144 if (!dst_already_exists) {
1180 if (iter.
domain != domain) {
1217 if (
normals.sharing_info->is_mutable()) {
1228 {new_data,
normals.varray.size()});
1230 attributes.
remove(
"custom_normal");
#define ATTR_DOMAIN_AS_MASK(domain)
Low-level operations for curves.
CustomData interface, see also DNA_customdata_types.h.
void * CustomData_get_layer_named_for_write(CustomData *data, eCustomDataType type, blender::StringRef name, int totelem)
void * CustomData_add_layer_named(CustomData *data, eCustomDataType type, eCDAllocType alloctype, int totelem, blender::StringRef name)
bool CustomData_free_layer(CustomData *data, eCustomDataType type, int index)
int CustomData_get_named_layer_index(const CustomData *data, eCustomDataType type, blender::StringRef name)
bool CustomData_has_layer_named(const CustomData *data, eCustomDataType type, blender::StringRef name)
const void * CustomData_add_layer_named_with_data(CustomData *data, eCustomDataType type, void *layer_data, int totelem, blender::StringRef name, const blender::ImplicitSharingInfo *sharing_info)
bool CustomData_free_layer_named(CustomData *data, blender::StringRef name)
#define BLI_assert_unreachable()
ID and Library types, which are fundamental for SDNA.
BMesh const char void * data
SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const
static const CPPType & get()
void fill_assign_n(const void *value, void *dst, int64_t n) const
void fill_construct_n(const void *value, void *dst, int64_t n) const
const void * default_value() const
GMutableSpan slice(const int64_t start, int64_t size) const
const CPPType & type() const
const CPPType * type() const
const void * data() const
GSpan get_internal_span() const
const CPPType & type() const
void materialize_to_uninitialized(void *dst) const
IndexRange index_range() const
static GVArray from_single(const CPPType &type, int64_t size, const void *value)
static GVArray from_span(GSpan span)
static GVArray from_single_ref(const CPPType &type, int64_t size, const void *value)
static GVMutableArray from_span(GMutableSpan span)
constexpr bool is_empty() const
constexpr bool startswith(StringRef prefix) const
void append(const T &value)
GAttributeReader lookup_or_default(StringRef attribute_id, AttrDomain domain, AttrType data_type, const void *default_value=nullptr) const
bool is_builtin(const StringRef attribute_id) const
void foreach_attribute(const FunctionRef< void(const AttributeIter &)> fn) const
GPointer get_builtin_default(const StringRef attribute_id) const
bool contains(StringRef attribute_id) const
static std::optional< AttributeAccessor > from_id(const ID &id)
GVArray adapt_domain(const GVArray &varray, const AttrDomain from_domain, const AttrDomain to_domain) const
GAttributeReader lookup(const StringRef attribute_id) const
Set< StringRefNull > all_ids() const
int domain_size(const AttrDomain domain) const
std::optional< AttributeMetaData > lookup_meta_data(StringRef attribute_id) const
const AttributeAccessorFunctions * fn_
GAttributeReader get() const
const AttributeAccessor * accessor
const eCustomDataType data_type_
const GPointer default_value_
const DeletableEnum deletable_
GAttributeWriter try_get_for_write(void *owner) const final
bool try_create(void *owner, const AttributeInit &initializer) const final
bool try_delete(void *owner) const final
bool exists(const void *owner) const final
GAttributeReader try_get_for_read(const void *owner) const final
GAttributeWriter try_get_for_write(void *owner, StringRef attribute_id) const final
bool try_delete(void *owner, StringRef attribute_id) const final
GAttributeReader try_get_for_read(const void *owner, StringRef attribute_id) const final
bool foreach_attribute(const void *owner, FunctionRef< void(const AttributeIter &)> fn) const final
bool try_create(void *owner, StringRef attribute_id, AttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer) const final
GVArray try_convert(GVArray varray, const CPPType &to_type) const
GAttributeWriter lookup_for_write(StringRef attribute_id)
bool add(const StringRef attribute_id, const AttrDomain domain, const AttrType data_type, const AttributeInit &initializer)
GSpanAttributeWriter lookup_or_add_for_write_span(StringRef attribute_id, AttrDomain domain, AttrType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
bool remove(const StringRef attribute_id)
GAttributeWriter lookup_or_add_for_write(StringRef attribute_id, AttrDomain domain, AttrType data_type, const AttributeInit &initializer=AttributeInitDefaultValue())
bool rename(StringRef old_attribute_id, StringRef new_attribute_id)
GSpanAttributeWriter lookup_or_add_for_write_only_span(StringRef attribute_id, AttrDomain domain, AttrType data_type)
GSpanAttributeWriter lookup_for_write_span(StringRef attribute_id)
static std::shared_ptr< FieldOperation > from(std::shared_ptr< const mf::MultiFunction > function, Vector< GField > inputs={})
static float normals[][3]
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
bool indices_are_range(Span< int > indices, IndexRange range)
void copy_group_to_group(OffsetIndices< int > src_offsets, OffsetIndices< int > dst_offsets, const IndexMask &selection, GSpan src, GMutableSpan dst)
void gather(const GVArray &src, const IndexMask &indices, GMutableSpan dst, int64_t grain_size=4096)
void gather(GSpan src, Span< int > map, GMutableSpan dst)
void gather_to_groups(OffsetIndices< int > dst_offsets, const IndexMask &src_selection, GSpan src, GMutableSpan dst)
void gather_group_to_group(OffsetIndices< int > src_offsets, OffsetIndices< int > dst_offsets, const IndexMask &selection, GSpan src, GMutableSpan dst)
bool attribute_name_is_anonymous(const StringRef name)
Vector< AttributeTransferData > retrieve_attributes_for_transfer(const AttributeAccessor src_attributes, MutableAttributeAccessor dst_attributes, AttrDomainMask domain_mask, const AttributeFilter &attribute_filter={})
void fill_attribute_range_default(MutableAttributeAccessor dst_attributes, AttrDomain domain, const AttributeFilter &attribute_filter, IndexRange range)
void gather_attributes_to_groups(AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, OffsetIndices< int > dst_offsets, const IndexMask &src_selection, MutableAttributeAccessor dst_attributes)
static GVArray try_adapt_data_type(GVArray varray, const CPPType &to_type)
const DataTypeConversions & get_implicit_type_conversions()
static int attribute_domain_priority(const AttrDomain domain)
bool allow_procedural_attribute_access(StringRef attribute_name)
std::optional< AttrType > custom_data_type_to_attr_type(eCustomDataType data_type)
eCustomDataType cpp_type_to_custom_data_type(const CPPType &type)
void copy_attributes(const AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, MutableAttributeAccessor dst_attributes)
static bool add_custom_data_layer_from_attribute_init(const StringRef attribute_id, CustomData &custom_data, const eCustomDataType data_type, const int domain_num, const AttributeInit &initializer, const GPointer custom_default_value_ptr)
const char * no_procedural_access_message
void gather_attributes(AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, const IndexMask &selection, MutableAttributeAccessor dst_attributes)
static int attribute_data_type_complexity(const AttrType data_type)
AttrType attribute_data_type_highest_complexity(Span< AttrType > data_types)
AttrDomain attribute_domain_highest_priority(Span< AttrDomain > domains)
void transform_custom_normal_attribute(const float4x4 &transform, MutableAttributeAccessor &attributes)
static void * add_generic_custom_data_layer(CustomData &custom_data, const eCustomDataType data_type, const eCDAllocType alloctype, const int domain_size, const StringRef attribute_id)
const CPPType * custom_data_type_to_cpp_type(eCustomDataType type)
void gather_attributes_group_to_group(AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, OffsetIndices< int > src_offsets, OffsetIndices< int > dst_offsets, const IndexMask &selection, MutableAttributeAccessor dst_attributes)
void copy_attributes_group_to_group(AttributeAccessor src_attributes, AttrDomain src_domain, AttrDomain dst_domain, const AttributeFilter &attribute_filter, OffsetIndices< int > src_offsets, OffsetIndices< int > dst_offsets, const IndexMask &selection, MutableAttributeAccessor dst_attributes)
static const void * add_generic_custom_data_layer_with_existing_data(CustomData &custom_data, const eCustomDataType data_type, const StringRef attribute_id, const int domain_size, void *layer_data, const ImplicitSharingInfo *sharing_info)
static GAttributeReader adapt_domain_and_type_if_necessary(GAttributeReader attribute, const std::optional< AttrDomain > domain, const std::optional< AttrType > data_type, const AttributeAccessor &accessor)
AttrType cpp_type_to_attribute_type(const CPPType &type)
const CPPType & attribute_type_to_cpp_type(AttrType type)
QuaternionBase< float > Quaternion
void transform_normals(const float3x3 &transform, MutableSpan< float3 > normals)
MatBase< float, 4, 4 > float4x4
VecBase< int32_t, 2 > int2
VecBase< float, 2 > float2
MatBase< float, 3, 3 > float3x3
ColorSceneLinear4f< eAlpha::Premultiplied > ColorGeometry4f
VecBase< float, 3 > float3
blender::VecBase< int16_t, 2 > short2
ColorSceneLinearByteEncoded4b< eAlpha::Premultiplied > ColorGeometry4b
static void update(bNodeTree *ntree)
static void init(bNodeTree *, bNode *node)
const ImplicitSharingInfoHandle * sharing_info
bool allow_skip(const StringRef name) const
const fn::multi_function::MultiFunction * function
fn::GField validate_field_if_necessary(const fn::GField &field) const
std::function< void()> real_finish_fn
const ImplicitSharingInfo * sharing_info
std::function< void()> tag_modified_fn