213 void (*convert_)(
const void *src,
void *dst);
218 from_type_(base_attribute->
cpp_type()),
220 base_attribute_(
std::move(base_attribute))
230 base_attribute_->get(index,
buffer);
231 convert_(
buffer, r_value);
241 return &CPPType::get<float>();
243 return &CPPType::get<float2>();
245 return &CPPType::get<float3>();
247 return &CPPType::get<int>();
249 return &CPPType::get<Color4f>();
251 return &CPPType::get<bool>();
260 if (
type.is<
float>()) {
269 if (
type.is<
int>()) {
275 if (
type.is<
bool>()) {
311 int highest_complexity = INT_MIN;
316 if (complexity > highest_complexity) {
317 highest_complexity = complexity;
318 most_complex_type = data_type;
322 return most_complex_type;
357 int highest_priority = INT_MIN;
362 if (priority > highest_priority) {
363 highest_priority = priority;
364 highest_priority_domain = domain;
368 return highest_priority_domain;
375 if (custom_data ==
nullptr) {
381 if (
data ==
nullptr) {
384 return as_read_attribute_(
data, domain_size);
394 if (custom_data ==
nullptr) {
399 if (
data ==
nullptr) {
403 if (
data != new_data) {
407 if (update_on_write_ !=
nullptr) {
410 return as_write_attribute_(
data, domain_size);
419 if (custom_data ==
nullptr) {
426 custom_data, stored_type_, domain_size, layer_index);
427 if (delete_success) {
430 return delete_success;
439 if (custom_data ==
nullptr) {
448 custom_data, stored_type_,
CD_DEFAULT,
nullptr, domain_size);
449 const bool success =
data !=
nullptr;
459 if (custom_data ==
nullptr) {
463 return data !=
nullptr;
470 if (custom_data ==
nullptr) {
473 const int domain_size =
component.attribute_domain_size(domain_);
475 if (layer.name != attribute_name) {
481 return this->layer_to_read_attribute<float>(layer, domain_size);
483 return this->layer_to_read_attribute<float2>(layer, domain_size);
485 return this->layer_to_read_attribute<float3>(layer, domain_size);
487 return this->layer_to_read_attribute<int>(layer, domain_size);
489 return this->layer_to_read_attribute<Color4f>(layer, domain_size);
491 return this->layer_to_read_attribute<bool>(layer, domain_size);
503 if (custom_data ==
nullptr) {
506 const int domain_size =
component.attribute_domain_size(domain_);
508 if (layer.name != attribute_name) {
515 return this->layer_to_write_attribute<float>(layer, domain_size);
517 return this->layer_to_write_attribute<float2>(layer, domain_size);
519 return this->layer_to_write_attribute<float3>(layer, domain_size);
521 return this->layer_to_write_attribute<int>(layer, domain_size);
523 return this->layer_to_write_attribute<Color4f>(layer, domain_size);
525 return this->layer_to_write_attribute<bool>(layer, domain_size);
537 if (custom_data ==
nullptr) {
540 const int domain_size =
component.attribute_domain_size(domain_);
556 if (domain_ != domain) {
559 if (!this->type_is_supported(data_type)) {
563 if (custom_data ==
nullptr) {
567 if (layer.name == attribute_name) {
571 const int domain_size =
component.attribute_domain_size(domain_);
573 attribute_name.
copy(attribute_name_c);
575 custom_data, data_type,
CD_DEFAULT,
nullptr, domain_size, attribute_name_c);
583 if (custom_data ==
nullptr) {
588 if (this->type_is_supported(data_type)) {
590 if (!
callback(layer.name, meta_data)) {
602 if (custom_data ==
nullptr) {
606 if (layer.type == stored_type_) {
607 if (layer.name == attribute_name) {
608 const int domain_size =
component.attribute_domain_size(domain_);
609 return as_read_attribute_(layer.data, domain_size);
620 if (custom_data ==
nullptr) {
624 if (layer.type == stored_type_) {
625 if (layer.name == attribute_name) {
626 const int domain_size =
component.attribute_domain_size(domain_);
627 void *data_old = layer.data;
629 custom_data, stored_type_, layer.name, domain_size);
630 if (data_old != data_new) {
633 return as_write_attribute_(layer.data, domain_size);
644 if (custom_data ==
nullptr) {
649 if (layer.
type == stored_type_) {
650 if (layer.
name == attribute_name) {
651 const int domain_size =
component.attribute_domain_size(domain_);
665 if (custom_data ==
nullptr) {
669 if (layer.type == stored_type_) {
671 if (!
callback(layer.name, meta_data)) {
700 if (providers ==
nullptr) {
716 if (providers ==
nullptr) {
721 if (builtin_provider !=
nullptr) {
726 ReadAttributePtr attribute = dynamic_provider->try_get_for_read(*
this, attribute_name);
737 if (attribute && attribute->domain() == new_domain) {
747 if (providers ==
nullptr) {
752 if (builtin_provider !=
nullptr) {
757 WriteAttributePtr attribute = dynamic_provider->try_get_for_write(*
this, attribute_name);
769 if (providers ==
nullptr) {
774 if (builtin_provider !=
nullptr) {
777 bool success =
false;
780 success = dynamic_provider->try_delete(*
this, attribute_name) || success;
794 if (providers ==
nullptr) {
799 if (builtin_provider !=
nullptr) {
800 if (builtin_provider->
domain() != domain) {
803 if (builtin_provider->
data_type() != data_type) {
810 if (dynamic_provider->try_create(*
this, attribute_name, domain, data_type)) {
821 attributes.
add(name);
835 if (providers ==
nullptr) {
844 if (provider->exists(*
this)) {
846 if (!
callback(provider->name(), meta_data)) {
849 handled_attribute_names.
add_new(provider->name());
853 const bool continue_loop = provider->foreach_attribute(
855 if (handled_attribute_names.
add(name)) {
856 return callback(name, meta_data);
860 if (!continue_loop) {
870 ReadAttributePtr attribute = this->attribute_try_get_for_read(attribute_name);
881 if (from_type == to_type) {
891 return std::make_unique<blender::bke::ConvertedReadAttribute>(std::move(attribute), to_type);
899 ReadAttributePtr attribute = this->attribute_try_get_for_read(attribute_name);
905 attribute = this->attribute_try_adapt_domain(std::move(attribute), domain);
913 if (attribute->cpp_type() != *cpp_type) {
926 if (!this->attribute_domain_supported(domain)) {
930 ReadAttributePtr attribute = this->attribute_try_get_for_read(attribute_name);
935 if (attribute->domain() != domain) {
936 attribute = this->attribute_try_adapt_domain(std::move(attribute), domain);
948 const void *default_value)
const
950 ReadAttributePtr attribute = this->attribute_try_get_for_read(attribute_name, domain, data_type);
954 return this->attribute_get_constant_for_read(domain, data_type, default_value);
960 BLI_assert(this->attribute_domain_supported(domain));
963 if (value ==
nullptr) {
966 const int domain_size = this->attribute_domain_size(domain);
967 return std::make_unique<blender::bke::ConstantReadAttribute>(
968 domain, domain_size, *cpp_type, value);
975 const void *value)
const
977 BLI_assert(this->attribute_domain_supported(domain));
978 if (value ==
nullptr || in_data_type == out_data_type) {
979 return this->attribute_get_constant_for_read(domain, out_data_type, value);
993 void *out_value = alloca(out_cpp_type->
size());
996 const int domain_size = this->attribute_domain_size(domain);
998 domain, domain_size, *out_cpp_type, out_value);
1007 const void *default_value)
1012 WriteAttributePtr attribute = this->attribute_try_get_for_write(attribute_name);
1016 this->attribute_try_create(attribute_name, domain, data_type);
1017 attribute = this->attribute_try_get_for_write(attribute_name);
1018 if (attribute && default_value !=
nullptr) {
1019 void *
data = attribute->get_span_for_write_only().data();
1021 attribute->apply_span();
1027 if (attribute->domain() == domain && attribute->cpp_type() == *cpp_type) {
1037 : attribute_(
std::move(attribute))
1044 std::string final_name,
1050 const int domain_size =
component.attribute_domain_size(domain);
1058 final_name, domain, data_type,
nullptr);
1060 src_attribute->get(i, new_span[i]);
1063 attribute_ = std::make_unique<blender::bke::TemporaryWriteAttribute>(
1064 domain, new_span,
component, std::move(final_name));
1072 CLOG_WARN(&
LOG,
"Trying to save an attribute that does not exist anymore.");
1079 if (attribute ==
nullptr) {
1092 name, attribute_->domain(), attribute_->custom_data_type())) {
1095 "Creating the '%s' attribute with type '%s' failed.",
1105 GMutableSpan new_span = new_attribute->get_span_for_write_only();
1110 new_attribute->apply_span();
1118 CLOG_ERROR(&
LOG,
"Forgot to call #save or #apply_span_and_save.");
1126 attribute_->apply_span();
CustomData interface, see also DNA_customdata_types.h.
bool CustomData_free_layer(struct CustomData *data, int type, int totelem, int index)
void * CustomData_duplicate_referenced_layer_named(struct CustomData *data, const int type, const char *name, const int totelem)
void * CustomData_add_layer_named(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem, const char *name)
void * CustomData_duplicate_referenced_layer(struct CustomData *data, const int type, const int totelem)
int CustomData_get_layer_index(const struct CustomData *data, int type)
void * CustomData_get_layer(const struct CustomData *data, int type)
void * CustomData_add_layer(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem)
General operations for point-clouds.
#define BLI_assert_unreachable()
#define POINTER_OFFSET(v, ofs)
#define CLOG_ERROR(clg_ref,...)
#define CLOG_WARN(clg_ref,...)
static uint8 component(Color32 c, uint i)
#define BUFFER_FOR_CPP_TYPE_VALUE(type, variable_name)
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum type
static ReadAttributePtr try_adapt_data_type(ReadAttributePtr attribute, const blender::fn::CPPType &to_type)
virtual blender::bke::ReadAttributePtr attribute_try_adapt_domain(blender::bke::ReadAttributePtr attribute, const AttributeDomain new_domain) const
virtual int attribute_domain_size(const AttributeDomain domain) const
blender::bke::WriteAttributePtr attribute_try_get_for_write(const blender::StringRef attribute_name)
bool attribute_exists(const blender::StringRef attribute_name) const
blender::bke::ReadAttributePtr attribute_get_constant_for_read(const AttributeDomain domain, const CustomDataType data_type, const void *value) const
blender::Set< std::string > attribute_names() const
bool attribute_try_delete(const blender::StringRef attribute_name)
blender::bke::ReadAttributePtr attribute_try_get_for_read(const blender::StringRef attribute_name) const
OutputAttributePtr attribute_try_get_for_output(const blender::StringRef attribute_name, const AttributeDomain domain, const CustomDataType data_type, const void *default_value=nullptr)
bool attribute_foreach(const AttributeForeachCallback callback) const
blender::bke::ReadAttributePtr attribute_get_constant_for_read_converted(const AttributeDomain domain, const CustomDataType in_data_type, const CustomDataType out_data_type, const void *value) const
blender::bke::ReadAttributePtr attribute_get_for_read(const blender::StringRef attribute_name, const AttributeDomain domain, const CustomDataType data_type, const void *default_value) const
bool attribute_try_create(const blender::StringRef attribute_name, const AttributeDomain domain, const CustomDataType data_type)
bool attribute_domain_supported(const AttributeDomain domain) const
void apply_span_and_save()
OutputAttributePtr()=default
void add_new(const Key &key)
constexpr bool is_empty() const
void copy(char *dst, const int64_t dst_size) const
constexpr const char * c_str() const
const WritableEnum writable_
const CreatableEnum createable_
AttributeDomain domain() const
virtual bool try_create(GeometryComponent &UNUSED(component)) const =0
virtual WriteAttributePtr try_get_for_write(GeometryComponent &component) const =0
virtual ReadAttributePtr try_get_for_read(const GeometryComponent &component) const =0
const AttributeDomain domain_
virtual bool try_delete(GeometryComponent &component) const =0
const DeletableEnum deletable_
CustomDataType data_type() const
bool exists(const GeometryComponent &component) const final
WriteAttributePtr try_get_for_write(GeometryComponent &component) const final
bool try_create(GeometryComponent &component) const final
bool try_delete(GeometryComponent &component) const final
ReadAttributePtr try_get_for_read(const GeometryComponent &component) const final
Span< const DynamicAttributesProvider * > dynamic_attribute_providers() const
const Map< std::string, const BuiltinAttributeProvider * > & builtin_attribute_providers() const
Span< AttributeDomain > supported_domains() const
void get_internal(const int64_t index, void *r_value) const override
ConvertedReadAttribute(ReadAttributePtr base_attribute, const CPPType &to_type)
bool try_delete(GeometryComponent &component, const StringRef attribute_name) const final
WriteAttributePtr try_get_for_write(GeometryComponent &component, const StringRef attribute_name) const final
ReadAttributePtr try_get_for_read(const GeometryComponent &component, const StringRef attribute_name) const final
bool foreach_attribute(const GeometryComponent &component, const AttributeForeachCallback callback) const final
bool try_create(GeometryComponent &component, const StringRef attribute_name, const AttributeDomain domain, const CustomDataType data_type) const final
bool try_delete(GeometryComponent &component, const StringRef attribute_name) const final
ReadAttributePtr try_get_for_read(const GeometryComponent &component, const StringRef attribute_name) const final
void foreach_domain(const FunctionRef< void(AttributeDomain)> callback) const final
WriteAttributePtr try_get_for_write(GeometryComponent &component, const StringRef attribute_name) const final
bool foreach_attribute(const GeometryComponent &component, const AttributeForeachCallback callback) const final
const CPPType & cpp_type_
virtual void get_internal(const int64_t index, void *r_value) const =0
virtual void initialize_span() const
fn::GSpan get_span() const
const CPPType & cpp_type() const
AttributeDomain domain() const
void set_internal(const int64_t index, const void *value) override
TemporaryWriteAttribute(AttributeDomain domain, GMutableSpan data, GeometryComponent &component, std::string final_name)
void apply_span_if_necessary() override
void initialize_span(const bool UNUSED(write_only)) override
GeometryComponent & component
void get_internal(const int64_t index, void *r_value) const override
~TemporaryWriteAttribute() override
AttributeDomain domain() const
virtual void set_internal(const int64_t index, const void *value)=0
void get(const int64_t index, void *r_value) const
virtual void initialize_span(const bool write_only)
virtual void apply_span_if_necessary()
fn::GMutableSpan get_span_for_write_only()
fn::GMutableSpan get_span()
const CPPType & cpp_type_
virtual ~WriteAttribute()
bool array_should_be_applied_
const CPPType & cpp_type() const
StringRefNull name() const
int64_t alignment() const
void fill_initialized(const void *value, void *dst, int64_t n) const
void construct_default_n(void *ptr, int64_t n) const
void destruct(void *ptr) const
void copy_to_initialized(const void *src, void *dst) const
void destruct_n(void *ptr, int64_t n) const
void copy_to_uninitialized(const void *src, void *dst) const
const void * default_value() const
void move_to_initialized_n(void *src, void *dst, int64_t n) const
const CPPType & type() const
bool is_convertible(const CPPType &from_type, const CPPType &to_type) const
void convert_to_uninitialized(const CPPType &from_type, const CPPType &to_type, const void *from_value, void *to_value) const
const ConversionFunctions * get_conversion_functions(fn::MFDataType from, fn::MFDataType to) const
DEGForeachIDComponentCallback callback
__kernel void ccl_constant KernelData ccl_global void ccl_global char ccl_global int ccl_global char ccl_global unsigned int ccl_global float * buffer
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void(* MEM_freeN)(void *vmemh)
void *(* MEM_mallocN_aligned)(size_t len, size_t alignment, const char *str)
CustomDataType cpp_type_to_custom_data_type(const CPPType &type)
AttributeDomain attribute_domain_highest_priority(Span< AttributeDomain > domains)
static int attribute_domain_priority(const AttributeDomain domain)
static int attribute_data_type_complexity(const CustomDataType data_type)
std::unique_ptr< WriteAttribute > WriteAttributePtr
const CPPType * custom_data_type_to_cpp_type(const CustomDataType type)
std::unique_ptr< ReadAttribute > ReadAttributePtr
CustomDataType attribute_data_type_highest_complexity(Span< CustomDataType > data_types)
const DataTypeConversions & get_implicit_type_conversions()
ConstCustomDataGetter get_const_custom_data
CustomDataGetter get_custom_data
UpdateCustomDataPointers update_custom_data_pointers
void(* convert_single_to_uninitialized)(const void *src, void *dst)