42 stream << attribute_id.
name();
55 "This attribute can not be accessed in a procedural context";
59 return !attribute_name.
startswith(
".selection");
94 int highest_complexity = INT_MIN;
99 if (complexity > highest_complexity) {
100 highest_complexity = complexity;
101 most_complex_type = data_type;
105 return most_complex_type;
136 int highest_priority = INT_MIN;
141 if (priority > highest_priority) {
142 highest_priority = priority;
143 highest_priority_domain = domain;
147 return highest_priority_domain;
163 switch (initializer.
type) {
166 return data !=
nullptr;
170 if (
data ==
nullptr) {
181 if (
data ==
nullptr) {
202 attribute_id.
name().
copy(attribute_name_c);
204 &custom_data, data_type, alloctype, layer_data,
domain_num, attribute_name_c);
208 &custom_data, data_type, alloctype, layer_data,
domain_num, &anonymous_id);
217 const int old_layer_num = custom_data.
totlayer;
218 switch (initializer.
type) {
227 if (
data !=
nullptr) {
237 if (source_data !=
nullptr &&
data ==
nullptr) {
243 return old_layer_num < custom_data.
totlayer;
255 return layer.
name == attribute_id.
name();
261 if (custom_data ==
nullptr) {
265 const void *
data =
nullptr;
266 bool found_attribute =
false;
268 if (stored_as_named_attribute_) {
269 if (layer.name ==
name_) {
271 found_attribute =
true;
275 else if (layer.type == stored_type_) {
277 found_attribute =
true;
281 if (!found_attribute) {
285 return as_read_attribute_(
data, element_num);
294 if (custom_data ==
nullptr) {
299 void *
data =
nullptr;
300 bool found_attribute =
false;
302 if (stored_as_named_attribute_) {
303 if (layer.name ==
name_) {
305 found_attribute =
true;
309 else if (layer.type == stored_type_) {
311 found_attribute =
true;
315 if (!found_attribute) {
319 if (
data !=
nullptr) {
321 if (stored_as_named_attribute_) {
323 custom_data, stored_type_,
name_.c_str(), element_num);
329 if (
data != new_data) {
337 std::function<
void()> tag_modified_fn;
338 if (update_on_change_ !=
nullptr) {
339 tag_modified_fn = [owner,
update = update_on_change_]() {
update(owner); };
342 return {as_write_attribute_(
data, element_num),
domain_, std::move(tag_modified_fn)};
351 if (custom_data ==
nullptr) {
356 if (update_on_change_ !=
nullptr) {
357 update_on_change_(owner);
362 if (stored_as_named_attribute_) {
392 if (custom_data ==
nullptr) {
398 if (stored_as_named_attribute_) {
404 name_, *custom_data, stored_type_, element_num, initializer);
412 *custom_data, stored_type_, element_num, initializer);
425 if (custom_data ==
nullptr) {
428 if (stored_as_named_attribute_) {
438 if (custom_data ==
nullptr) {
447 if (
type ==
nullptr) {
460 if (custom_data ==
nullptr) {
470 custom_data, layer.type, layer.name, element_num);
474 custom_data, layer.type, &attribute_id.
anonymous_id(), element_num);
477 if (
type ==
nullptr) {
489 if (custom_data ==
nullptr) {
511 if (domain_ != domain) {
514 if (!this->type_is_supported(data_type)) {
518 if (custom_data ==
nullptr) {
528 attribute_id, *custom_data, data_type, element_num, initializer);
536 if (custom_data ==
nullptr) {
541 if (this->type_is_supported(data_type)) {
544 if (!
callback(attribute_id, meta_data)) {
556 if (custom_data ==
nullptr) {
560 if (layer.type == stored_type_) {
563 return {as_read_attribute_(layer.data,
domain_num), domain_};
574 if (custom_data ==
nullptr) {
578 if (layer.type == stored_type_) {
581 void *data_old = layer.data;
583 custom_data, stored_type_, layer.name, element_num);
584 if (data_old != data_new) {
589 return {as_write_attribute_(layer.data, element_num), domain_};
600 if (custom_data ==
nullptr) {
605 if (layer.
type == stored_type_) {
623 if (custom_data ==
nullptr) {
627 if (layer.type == stored_type_) {
629 if (!
callback(layer.name, meta_data)) {
669 if (
this != &other) {
683 return GSpan(*cpp_type, layer.data, size_);
691 const void *default_value)
const
699 *
type,
domain_num, (default_value ==
nullptr) ?
type->default_value() : default_value);
769 if (!
callback(attribute_id, meta_data)) {
789 const int old_index = old_order.
lookup(new_order[i]);
790 layers[i] = old_layers[old_index];
812 if (
const GeometryComponentFieldContext *geometry_context =
813 dynamic_cast<const GeometryComponentFieldContext *
>(&
context)) {
815 const eAttrDomain domain = geometry_context->domain();
826 if (
auto attributes =
component.attributes()) {
827 return attributes->lookup(name_, domain, data_type);
834 std::stringstream ss;
835 ss <<
'"' << name_ <<
'"' <<
TIP_(
" attribute from geometry");
847 return name_ == other_typed->name_ &&
type_ == other_typed->type_;
869 if (
auto attributes =
component.attributes()) {
881 return TIP_(
"ID / Index");
901 return component.attributes()->lookup(anonymous_id_.
get(), domain, data_type);
906 std::stringstream ss;
920 return anonymous_id_.
get() == other_typed->anonymous_id_.get() &&
type_ == other_typed->type_;
926 const std::optional<eAttrDomain> domain,
927 const std::optional<eCustomDataType> data_type)
const
934 if (domain.has_value()) {
942 if (data_type.has_value()) {
957 const void *default_value)
const
959 GVArray varray = this->
lookup(attribute_id, domain, data_type);
965 if (default_value ==
nullptr) {
976 ids.
add(attribute_id);
986 if (
id.is_anonymous()) {
987 anonymous_ids.
append(&
id.anonymous_id());
1000 struct FinishCallChecker {
1002 bool finish_called =
false;
1003 std::function<
void()> real_finish_fn;
1005 ~FinishCallChecker()
1007 if (!this->finish_called) {
1008 std::cerr <<
"Forgot to call `finish()` for '" << this->name <<
"'.\n";
1020 auto checker = std::make_shared<FinishCallChecker>();
1022 checker->name = attribute_id.
name();
1027 checker->real_finish_fn =
attribute.tag_modified_fn;
1028 attribute.tag_modified_fn = [checker]() {
1029 if (checker->real_finish_fn) {
1030 checker->real_finish_fn();
1032 checker->finish_called =
true;
1045 std::optional<AttributeMetaData> meta_data = this->
lookup_meta_data(attribute_id);
1046 if (meta_data.has_value()) {
1047 if (meta_data->domain == domain && meta_data->data_type == data_type) {
1052 if (this->
add(attribute_id, domain, data_type, initializer)) {
1065 attribute_id, domain, data_type, initializer);
1094 if (
id.is_named() && skip.
contains(
id.name())) {
1097 if (!
id.should_be_kept()) {
1106 attributes.
append({std::move(
src), meta_data, std::move(dst)});
const char * BKE_anonymous_attribute_id_debug_name(const AnonymousAttributeID *anonymous_id)
#define ATTR_DOMAIN_AS_MASK(domain)
CustomData interface, see also DNA_customdata_types.h.
bool CustomData_free_layer_named(struct CustomData *data, const char *name, const int totelem)
void CustomData_free(struct CustomData *data, int totelem)
bool CustomData_free_layer(struct CustomData *data, int type, int totelem, int index)
void * CustomData_duplicate_referenced_layer_anonymous(CustomData *data, int type, const struct AnonymousAttributeID *anonymous_id, int totelem)
void CustomData_copy(const struct CustomData *source, struct CustomData *dest, eCustomDataMask mask, eCDAllocType alloctype, int totelem)
void * CustomData_duplicate_referenced_layer_named(struct CustomData *data, int type, const char *name, int totelem)
void * CustomData_add_layer_named(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem, const char *name)
void * CustomData_get_layer_named(const struct CustomData *data, int type, const char *name)
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)
void * CustomData_add_layer_anonymous(struct CustomData *data, int type, eCDAllocType alloctype, void *layer, int totelem, const struct AnonymousAttributeID *anonymous_id)
void CustomData_realloc(struct CustomData *data, int totelem)
void * CustomData_duplicate_referenced_layer(struct CustomData *data, int type, int totelem)
void CustomData_reset(struct CustomData *data)
void CustomData_update_typemap(struct CustomData *data)
General operations for point clouds.
#define BLI_assert_unreachable()
static uint8 component(Color32 c, uint i)
_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
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
IndexRange index_range() const
const CPPType & type() const
void materialize_to_uninitialized(void *dst) const
IndexRange index_range() const
static GVArray ForSingleRef(const CPPType &type, int64_t size, const void *value)
static GVArray ForSpan(GSpan span)
static GVArray ForSingle(const CPPType &type, int64_t size, const void *value)
static GVMutableArray ForSpan(GMutableSpan span)
const Value & lookup(const Key &key) const
void add_new(const Key &key, const Value &value)
constexpr IndexRange index_range() const
bool contains(const Key &key) const
constexpr int64_t size() const
void copy(char *dst, int64_t dst_size) const
constexpr bool startswith(StringRef prefix) const
void append(const T &value)
GVArray adapt_domain(const GVArray &varray, const eAttrDomain from_domain, const eAttrDomain to_domain) const
int domain_size(const eAttrDomain domain) const
Set< AttributeIDRef > all_ids() const
std::optional< AttributeMetaData > lookup_meta_data(const AttributeIDRef &attribute_id) const
GAttributeReader lookup(const AttributeIDRef &attribute_id) const
GVArray lookup_or_default(const AttributeIDRef &attribute_id, const eAttrDomain domain, const eCustomDataType data_type, const void *default_value=nullptr) const
bool for_all(const AttributeForeachCallback fn) const
const AttributeAccessorFunctions * fn_
bool is_anonymous() const
const AnonymousAttributeID & anonymous_id() const
const WritableEnum writable_
const CreatableEnum createable_
const eCustomDataType data_type_
const eAttrDomain domain_
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
GVArray try_get_for_read(const void *owner) const final
bool try_delete(void *owner, const AttributeIDRef &attribute_id) const final
GAttributeWriter try_get_for_write(void *owner, const AttributeIDRef &attribute_id) const final
bool try_create(void *owner, const AttributeIDRef &attribute_id, eAttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer) const final
bool foreach_attribute(const void *owner, const AttributeForeachCallback callback) const final
GAttributeReader try_get_for_read(const void *owner, const AttributeIDRef &attribute_id) const final
std::optional< blender::GSpan > get_for_read(const AttributeIDRef &attribute_id) const
bool create(const AttributeIDRef &attribute_id, eCustomDataType data_type)
CustomDataAttributes & operator=(const CustomDataAttributes &other)
std::optional< blender::GMutableSpan > get_for_write(const AttributeIDRef &attribute_id)
void reallocate(int size)
bool create_by_move(const AttributeIDRef &attribute_id, eCustomDataType data_type, void *buffer)
void reorder(Span< AttributeIDRef > new_order)
bool foreach_attribute(const AttributeForeachCallback callback, eAttrDomain domain) const
bool remove(const AttributeIDRef &attribute_id)
GVArray try_convert(GVArray varray, const CPPType &to_type) const
bool add(const AttributeIDRef &attribute_id, const eAttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer)
GAttributeWriter lookup_for_write(const AttributeIDRef &attribute_id)
GSpanAttributeWriter lookup_or_add_for_write_only_span(const AttributeIDRef &attribute_id, const eAttrDomain domain, const eCustomDataType data_type)
bool remove(const AttributeIDRef &attribute_id)
GAttributeWriter lookup_or_add_for_write(const AttributeIDRef &attribute_id, const eAttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefault())
GSpanAttributeWriter lookup_or_add_for_write_span(const AttributeIDRef &attribute_id, const eAttrDomain domain, const eCustomDataType data_type, const AttributeInit &initializer=AttributeInitDefault())
GAttributeWriter try_get_for_write(void *owner, const AttributeIDRef &attribute_id) const final
void foreach_domain(const FunctionRef< void(eAttrDomain)> callback) const final
GAttributeReader try_get_for_read(const void *owner, const AttributeIDRef &attribute_id) const final
bool foreach_attribute(const void *owner, const AttributeForeachCallback callback) const final
bool try_delete(void *owner, const AttributeIDRef &attribute_id) const final
const AnonymousAttributeID * get() const
DEGForeachIDComponentCallback callback
SyclQueue void void * src
SyclQueue void void size_t num_bytes void
ccl_global float * buffer
void(* MEM_freeN)(void *vmemh)
ccl_device_inline float4 mask(const int4 &mask, const float4 &a)
static int domain_num(const CurvesGeometry &curves, const eAttrDomain domain)
const blender::CPPType * custom_data_type_to_cpp_type(const eCustomDataType type)
static void * add_generic_custom_data_layer(CustomData &custom_data, const eCustomDataType data_type, const eCDAllocType alloctype, void *layer_data, const int domain_num, const AttributeIDRef &attribute_id)
static bool custom_data_layer_matches_attribute_id(const CustomDataLayer &layer, const AttributeIDRef &attribute_id)
Vector< AttributeTransferData > retrieve_attributes_for_transfer(const bke::AttributeAccessor src_attributes, bke::MutableAttributeAccessor dst_attributes, eAttrDomainMask domain_mask, const Set< std::string > &skip={})
std::ostream & operator<<(std::ostream &stream, const AssetCatalogPath &path_to_append)
const DataTypeConversions & get_implicit_type_conversions()
eAttrDomain attribute_domain_highest_priority(Span< eAttrDomain > domains)
bool allow_procedural_attribute_access(StringRef attribute_name)
const char * no_procedural_access_message
static blender::GVArray try_adapt_data_type(blender::GVArray varray, const blender::CPPType &to_type)
eCustomDataType attribute_data_type_highest_complexity(Span< eCustomDataType > data_types)
static int attribute_domain_priority(const eAttrDomain domain)
static bool add_custom_data_layer_from_attribute_init(const AttributeIDRef &attribute_id, CustomData &custom_data, const eCustomDataType data_type, const int domain_num, const AttributeInit &initializer)
static StringRef get_random_id_attribute_name(const eAttrDomain domain)
static AttributeIDRef attribute_id_from_custom_data_layer(const CustomDataLayer &layer)
eCustomDataType cpp_type_to_custom_data_type(const blender::CPPType &type)
static int attribute_data_type_complexity(const eCustomDataType data_type)
static bool add_builtin_type_custom_data_layer_from_init(CustomData &custom_data, const eCustomDataType data_type, const int domain_num, const AttributeInit &initializer)
static Type to_type(const eGPUType type)
vec_base< float, 3 > float3
uint64_t get_default_hash_2(const T1 &v1, const T2 &v2)
static void update(bNodeTree *ntree)
unsigned __int64 uint64_t
const struct AnonymousAttributeID * anonymous_id
GAttributeWriter(* lookup_for_write)(void *owner, const AttributeIDRef &attribute_id)
GetElementNum get_element_num
ConstCustomDataGetter get_const_custom_data
CustomDataGetter get_custom_data
UpdateCustomDataPointers update_custom_data_pointers