Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/attribute_access.cc
| Show First 20 Lines • Show All 339 Lines • ▼ Show 20 Lines | |||||
| GVArrayPtr BuiltinCustomDataLayerProvider::try_get_for_read( | GVArrayPtr BuiltinCustomDataLayerProvider::try_get_for_read( | ||||
| const GeometryComponent &component) const | const GeometryComponent &component) const | ||||
| { | { | ||||
| const CustomData *custom_data = custom_data_access_.get_const_custom_data(component); | const CustomData *custom_data = custom_data_access_.get_const_custom_data(component); | ||||
| if (custom_data == nullptr) { | if (custom_data == nullptr) { | ||||
| return {}; | return {}; | ||||
| } | } | ||||
| const int domain_size = component.attribute_domain_size(domain_); | const void *data; | ||||
| const void *data = CustomData_get_layer(custom_data, stored_type_); | if (stored_as_named_attribute_) { | ||||
JacquesLucke: Add a `stored_as_named_attribute_ = data_type_ == stored_type_` data member to the class… | |||||
Done Inline ActionsMuch better, good idea. HooglyBoogly: Much better, good idea. | |||||
| data = CustomData_get_layer_named(custom_data, stored_type_, name_.c_str()); | |||||
| } | |||||
| else { | |||||
| data = CustomData_get_layer(custom_data, stored_type_); | |||||
| } | |||||
| if (data == nullptr) { | if (data == nullptr) { | ||||
| return {}; | return {}; | ||||
| } | } | ||||
| const int domain_size = component.attribute_domain_size(domain_); | |||||
| return as_read_attribute_(data, domain_size); | return as_read_attribute_(data, domain_size); | ||||
| } | } | ||||
| GVMutableArrayPtr BuiltinCustomDataLayerProvider::try_get_for_write( | GVMutableArrayPtr BuiltinCustomDataLayerProvider::try_get_for_write( | ||||
| GeometryComponent &component) const | GeometryComponent &component) const | ||||
| { | { | ||||
| if (writable_ != Writable) { | if (writable_ != Writable) { | ||||
| return {}; | return {}; | ||||
| } | } | ||||
| CustomData *custom_data = custom_data_access_.get_custom_data(component); | CustomData *custom_data = custom_data_access_.get_custom_data(component); | ||||
| if (custom_data == nullptr) { | if (custom_data == nullptr) { | ||||
| return {}; | return {}; | ||||
| } | } | ||||
| const int domain_size = component.attribute_domain_size(domain_); | const int domain_size = component.attribute_domain_size(domain_); | ||||
| void *data = CustomData_get_layer(custom_data, stored_type_); | void *data = CustomData_get_layer(custom_data, stored_type_); | ||||
| if (data == nullptr) { | if (data == nullptr) { | ||||
| return {}; | return {}; | ||||
| } | } | ||||
| void *new_data = CustomData_duplicate_referenced_layer(custom_data, stored_type_, domain_size); | |||||
| void *new_data; | |||||
| if (stored_as_named_attribute_) { | |||||
| new_data = CustomData_duplicate_referenced_layer_named( | |||||
| custom_data, stored_type_, name_.c_str(), domain_size); | |||||
| } | |||||
| else { | |||||
| new_data = CustomData_duplicate_referenced_layer(custom_data, stored_type_, domain_size); | |||||
| } | |||||
| if (data != new_data) { | if (data != new_data) { | ||||
| custom_data_access_.update_custom_data_pointers(component); | custom_data_access_.update_custom_data_pointers(component); | ||||
| data = new_data; | data = new_data; | ||||
| } | } | ||||
| if (update_on_write_ != nullptr) { | if (update_on_write_ != nullptr) { | ||||
| update_on_write_(component); | update_on_write_(component); | ||||
| } | } | ||||
| return as_write_attribute_(data, domain_size); | return as_write_attribute_(data, domain_size); | ||||
| } | } | ||||
| bool BuiltinCustomDataLayerProvider::try_delete(GeometryComponent &component) const | bool BuiltinCustomDataLayerProvider::try_delete(GeometryComponent &component) const | ||||
| { | { | ||||
| if (deletable_ != Deletable) { | if (deletable_ != Deletable) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| CustomData *custom_data = custom_data_access_.get_custom_data(component); | CustomData *custom_data = custom_data_access_.get_custom_data(component); | ||||
| if (custom_data == nullptr) { | if (custom_data == nullptr) { | ||||
| return {}; | return {}; | ||||
| } | } | ||||
| const int domain_size = component.attribute_domain_size(domain_); | const int domain_size = component.attribute_domain_size(domain_); | ||||
| const int layer_index = CustomData_get_layer_index(custom_data, stored_type_); | int layer_index; | ||||
| if (stored_as_named_attribute_) { | |||||
| for (const int i : IndexRange(custom_data->totlayer)) { | |||||
| if (custom_data_layer_matches_attribute_id(custom_data->layers[i], name_)) { | |||||
| layer_index = i; | |||||
| break; | |||||
| } | |||||
| } | |||||
| } | |||||
| else { | |||||
| layer_index = CustomData_get_layer_index(custom_data, stored_type_); | |||||
| } | |||||
| const bool delete_success = CustomData_free_layer( | const bool delete_success = CustomData_free_layer( | ||||
| custom_data, stored_type_, domain_size, layer_index); | custom_data, stored_type_, domain_size, layer_index); | ||||
| if (delete_success) { | if (delete_success) { | ||||
| custom_data_access_.update_custom_data_pointers(component); | custom_data_access_.update_custom_data_pointers(component); | ||||
| } | } | ||||
| return delete_success; | return delete_success; | ||||
| } | } | ||||
| bool BuiltinCustomDataLayerProvider::try_create(GeometryComponent &component, | bool BuiltinCustomDataLayerProvider::try_create(GeometryComponent &component, | ||||
| const AttributeInit &initializer) const | const AttributeInit &initializer) const | ||||
| { | { | ||||
| if (createable_ != Creatable) { | if (createable_ != Creatable) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| CustomData *custom_data = custom_data_access_.get_custom_data(component); | CustomData *custom_data = custom_data_access_.get_custom_data(component); | ||||
| if (custom_data == nullptr) { | if (custom_data == nullptr) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| const int domain_size = component.attribute_domain_size(domain_); | |||||
| bool success; | |||||
| if (stored_as_named_attribute_) { | |||||
| if (CustomData_get_layer_named(custom_data, data_type_, name_.c_str())) { | |||||
| /* Exists already. */ | |||||
| return false; | |||||
| } | |||||
| success = add_custom_data_layer_from_attribute_init( | |||||
| name_, *custom_data, stored_type_, domain_size, initializer); | |||||
| } | |||||
| else { | |||||
| if (CustomData_get_layer(custom_data, stored_type_) != nullptr) { | if (CustomData_get_layer(custom_data, stored_type_) != nullptr) { | ||||
| /* Exists already. */ | /* Exists already. */ | ||||
| return false; | return false; | ||||
| } | } | ||||
| success = add_builtin_type_custom_data_layer_from_init( | |||||
| const int domain_size = component.attribute_domain_size(domain_); | |||||
| const bool success = add_builtin_type_custom_data_layer_from_init( | |||||
| *custom_data, stored_type_, domain_size, initializer); | *custom_data, stored_type_, domain_size, initializer); | ||||
| } | |||||
| if (success) { | if (success) { | ||||
| custom_data_access_.update_custom_data_pointers(component); | custom_data_access_.update_custom_data_pointers(component); | ||||
| } | } | ||||
| return success; | return success; | ||||
| } | } | ||||
| bool BuiltinCustomDataLayerProvider::exists(const GeometryComponent &component) const | bool BuiltinCustomDataLayerProvider::exists(const GeometryComponent &component) const | ||||
| { | { | ||||
| const CustomData *custom_data = custom_data_access_.get_const_custom_data(component); | const CustomData *custom_data = custom_data_access_.get_const_custom_data(component); | ||||
| if (custom_data == nullptr) { | if (custom_data == nullptr) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| const void *data = CustomData_get_layer(custom_data, stored_type_); | if (stored_as_named_attribute_) { | ||||
| return data != nullptr; | return CustomData_get_layer_named(custom_data, stored_type_, name_.c_str()) != nullptr; | ||||
| } | |||||
| return CustomData_get_layer(custom_data, stored_type_) != nullptr; | |||||
| } | } | ||||
| ReadAttributeLookup CustomDataAttributeProvider::try_get_for_read( | ReadAttributeLookup CustomDataAttributeProvider::try_get_for_read( | ||||
| const GeometryComponent &component, const AttributeIDRef &attribute_id) const | const GeometryComponent &component, const AttributeIDRef &attribute_id) const | ||||
| { | { | ||||
| const CustomData *custom_data = custom_data_access_.get_const_custom_data(component); | const CustomData *custom_data = custom_data_access_.get_const_custom_data(component); | ||||
| if (custom_data == nullptr) { | if (custom_data == nullptr) { | ||||
| return {}; | return {}; | ||||
| ▲ Show 20 Lines • Show All 906 Lines • ▼ Show 20 Lines | |||||
| bool AttributeFieldInput::is_equal_to(const fn::FieldNode &other) const | bool AttributeFieldInput::is_equal_to(const fn::FieldNode &other) const | ||||
| { | { | ||||
| if (const AttributeFieldInput *other_typed = dynamic_cast<const AttributeFieldInput *>(&other)) { | if (const AttributeFieldInput *other_typed = dynamic_cast<const AttributeFieldInput *>(&other)) { | ||||
| return name_ == other_typed->name_ && type_ == other_typed->type_; | return name_ == other_typed->name_ && type_ == other_typed->type_; | ||||
| } | } | ||||
| return false; | return false; | ||||
| } | } | ||||
| static StringRef get_random_id_attribute_name(const AttributeDomain domain) | |||||
| { | |||||
| switch (domain) { | |||||
| case ATTR_DOMAIN_POINT: | |||||
| return "random_point_id"; | |||||
| default: | |||||
| return ""; | |||||
| } | |||||
| } | |||||
| const GVArray *RandomIDAttributeFieldInput::get_varray_for_context(const fn::FieldContext &context, | |||||
| IndexMask mask, | |||||
| ResourceScope &scope) const | |||||
| { | |||||
| if (const GeometryComponentFieldContext *geometry_context = | |||||
| dynamic_cast<const GeometryComponentFieldContext *>(&context)) { | |||||
| const GeometryComponent &component = geometry_context->geometry_component(); | |||||
| const AttributeDomain domain = geometry_context->domain(); | |||||
| const StringRef name = get_random_id_attribute_name(domain); | |||||
| GVArrayPtr attribute = component.attribute_try_get_for_read(name, domain, CD_PROP_INT32); | |||||
| if (attribute) { | |||||
| BLI_assert(attribute->size() == component.attribute_domain_size(domain)); | |||||
| return scope.add(std::move(attribute)); | |||||
| } | |||||
| /* Use the index as the fallback if no random ID attribute exists. */ | |||||
| return fn::IndexFieldInput::get_index_varray(mask, scope); | |||||
| } | |||||
| return nullptr; | |||||
| } | |||||
| std::string RandomIDAttributeFieldInput::socket_inspection_name() const | |||||
| { | |||||
| return TIP_("Random ID / Index"); | |||||
Not Done Inline ActionsRandom ID -> ID JacquesLucke: `Random ID` -> `ID` | |||||
| } | |||||
| uint64_t RandomIDAttributeFieldInput::hash() const | |||||
| { | |||||
| /* All random ID attribute inputs are the same within the same evaluation context. */ | |||||
| return 92386459827; | |||||
| } | |||||
| bool RandomIDAttributeFieldInput::is_equal_to(const fn::FieldNode &other) const | |||||
| { | |||||
| /* All random ID attribute inputs are the same within the same evaluation context. */ | |||||
| return dynamic_cast<const RandomIDAttributeFieldInput *>(&other) != nullptr; | |||||
| } | |||||
| const GVArray *AnonymousAttributeFieldInput::get_varray_for_context( | const GVArray *AnonymousAttributeFieldInput::get_varray_for_context( | ||||
| const fn::FieldContext &context, IndexMask UNUSED(mask), ResourceScope &scope) const | const fn::FieldContext &context, IndexMask UNUSED(mask), ResourceScope &scope) const | ||||
| { | { | ||||
| if (const GeometryComponentFieldContext *geometry_context = | if (const GeometryComponentFieldContext *geometry_context = | ||||
| dynamic_cast<const GeometryComponentFieldContext *>(&context)) { | dynamic_cast<const GeometryComponentFieldContext *>(&context)) { | ||||
| const GeometryComponent &component = geometry_context->geometry_component(); | const GeometryComponent &component = geometry_context->geometry_component(); | ||||
| const AttributeDomain domain = geometry_context->domain(); | const AttributeDomain domain = geometry_context->domain(); | ||||
| const CustomDataType data_type = cpp_type_to_custom_data_type(*type_); | const CustomDataType data_type = cpp_type_to_custom_data_type(*type_); | ||||
| Show All 29 Lines | |||||
Add a stored_as_named_attribute_ = data_type_ == stored_type_ data member to the class instead of doing this comparison in many places.