Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/attribute_access.cc
| Show First 20 Lines • Show All 237 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| 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 int domain_size = component.attribute_domain_size(domain_); | ||||
| const void *data = CustomData_get_layer(custom_data, stored_type_); | const void *data = CustomData_get_layer(custom_data, stored_type_); | ||||
| if (data == nullptr) { | if (data == nullptr) { | ||||
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. | |||||
| return {}; | return {}; | ||||
| } | } | ||||
| 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 | ||||
| { | { | ||||
| ▲ Show 20 Lines • Show All 116 Lines • ▼ Show 20 Lines | if (!attribute_id) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (attribute_id.is_anonymous()) { | if (attribute_id.is_anonymous()) { | ||||
| return layer.anonymous_id == &attribute_id.anonymous_id(); | return layer.anonymous_id == &attribute_id.anonymous_id(); | ||||
| } | } | ||||
| return layer.name == attribute_id.name(); | return layer.name == attribute_id.name(); | ||||
| } | } | ||||
| GVArrayPtr BuiltinNamedCustomDataLayerProvider::try_get_for_read( | |||||
| const GeometryComponent &component) const | |||||
| { | |||||
| const CustomData *custom_data = custom_data_access_.get_const_custom_data(component); | |||||
| if (custom_data == nullptr) { | |||||
| return {}; | |||||
| } | |||||
| const int domain_size = component.attribute_domain_size(domain_); | |||||
| const void *data = CustomData_get_layer_named(custom_data, data_type_, name_.c_str()); | |||||
| if (data == nullptr) { | |||||
| return {}; | |||||
| } | |||||
| return as_read_attribute_(data, domain_size); | |||||
| } | |||||
| GVMutableArrayPtr BuiltinNamedCustomDataLayerProvider::try_get_for_write( | |||||
| GeometryComponent &component) const | |||||
| { | |||||
| if (writable_ != Writable) { | |||||
| return {}; | |||||
| } | |||||
| CustomData *custom_data = custom_data_access_.get_custom_data(component); | |||||
| if (custom_data == nullptr) { | |||||
| return {}; | |||||
| } | |||||
| const int domain_size = component.attribute_domain_size(domain_); | |||||
| void *data = CustomData_get_layer(custom_data, data_type_); | |||||
| if (data == nullptr) { | |||||
| return {}; | |||||
| } | |||||
| void *new_data = CustomData_duplicate_referenced_layer_named( | |||||
| custom_data, data_type_, name_.c_str(), domain_size); | |||||
| if (data != new_data) { | |||||
| custom_data_access_.update_custom_data_pointers(component); | |||||
| data = new_data; | |||||
| } | |||||
| if (update_on_write_ != nullptr) { | |||||
| update_on_write_(component); | |||||
| } | |||||
| return as_write_attribute_(data, domain_size); | |||||
| } | |||||
| bool BuiltinNamedCustomDataLayerProvider::try_delete(GeometryComponent &component) const | |||||
| { | |||||
| if (deletable_ != Deletable) { | |||||
| return false; | |||||
| } | |||||
| CustomData *custom_data = custom_data_access_.get_custom_data(component); | |||||
| if (custom_data == nullptr) { | |||||
| return {}; | |||||
| } | |||||
| const int domain_size = component.attribute_domain_size(domain_); | |||||
| bool delete_success = false; | |||||
| for (const int i : IndexRange(custom_data->totlayer)) { | |||||
| CustomDataLayer &layer = custom_data->layers[i]; | |||||
| if (custom_data_layer_matches_attribute_id(layer, name_)) { | |||||
| delete_success = CustomData_free_layer(custom_data, data_type_, domain_size, i); | |||||
| } | |||||
| } | |||||
| if (delete_success) { | |||||
| custom_data_access_.update_custom_data_pointers(component); | |||||
| } | |||||
| return delete_success; | |||||
| } | |||||
| static bool add_named_custom_data_layer_from_attribute_init(CustomData &custom_data, | |||||
| const CustomDataType data_type, | |||||
| const StringRefNull name, | |||||
| const int domain_size, | |||||
| const AttributeInit &initializer) | |||||
| { | |||||
| switch (initializer.type) { | |||||
| case AttributeInit::Type::Default: { | |||||
| void *data = CustomData_add_layer_named( | |||||
| &custom_data, data_type, CD_DEFAULT, nullptr, domain_size, name.c_str()); | |||||
| return data != nullptr; | |||||
| } | |||||
| case AttributeInit::Type::VArray: { | |||||
| void *data = CustomData_add_layer_named( | |||||
| &custom_data, data_type, CD_DEFAULT, nullptr, domain_size, name.c_str()); | |||||
| if (data == nullptr) { | |||||
| return false; | |||||
| } | |||||
| const GVArray *varray = static_cast<const AttributeInitVArray &>(initializer).varray; | |||||
| varray->materialize_to_uninitialized(IndexRange(varray->size()), data); | |||||
| return true; | |||||
| } | |||||
| case AttributeInit::Type::MoveArray: { | |||||
| void *source_data = static_cast<const AttributeInitMove &>(initializer).data; | |||||
| void *data = CustomData_add_layer_named( | |||||
| &custom_data, data_type, CD_ASSIGN, source_data, domain_size, name.c_str()); | |||||
| if (data == nullptr) { | |||||
| MEM_freeN(source_data); | |||||
| return false; | |||||
| } | |||||
| return true; | |||||
| } | |||||
| } | |||||
| BLI_assert_unreachable(); | |||||
| return false; | |||||
| } | |||||
| bool BuiltinNamedCustomDataLayerProvider::try_create(GeometryComponent &component, | |||||
| const AttributeInit &initializer) const | |||||
| { | |||||
| if (createable_ != Creatable) { | |||||
| return false; | |||||
| } | |||||
| CustomData *custom_data = custom_data_access_.get_custom_data(component); | |||||
| if (custom_data == nullptr) { | |||||
| return false; | |||||
| } | |||||
| if (CustomData_get_layer_named(custom_data, data_type_, name_.c_str()) != nullptr) { | |||||
| /* Exists already. */ | |||||
| return false; | |||||
| } | |||||
| const int domain_size = component.attribute_domain_size(domain_); | |||||
| const bool success = add_named_custom_data_layer_from_attribute_init( | |||||
| *custom_data, data_type_, name_, domain_size, initializer); | |||||
| if (success) { | |||||
| custom_data_access_.update_custom_data_pointers(component); | |||||
| } | |||||
| return success; | |||||
| } | |||||
| bool BuiltinNamedCustomDataLayerProvider::exists(const GeometryComponent &component) const | |||||
| { | |||||
| const CustomData *custom_data = custom_data_access_.get_const_custom_data(component); | |||||
| if (custom_data == nullptr) { | |||||
| return false; | |||||
| } | |||||
| const void *data = CustomData_get_layer_named(custom_data, data_type_, name_.c_str()); | |||||
| return data != 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 {}; | ||||
| } | } | ||||
| const int domain_size = component.attribute_domain_size(domain_); | const int domain_size = component.attribute_domain_size(domain_); | ||||
| ▲ Show 20 Lines • Show All 982 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; | ||||
| } | } | ||||
| 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 CustomDataType data_type = cpp_type_to_custom_data_type(*type_); | |||||
| GVArrayPtr attribute = component.attribute_try_get_for_read("random_id", domain, data_type); | |||||
| 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 "Random 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 &UNUSED(other)) const | |||||
| { | |||||
Not Done Inline ActionsRandom ID -> ID JacquesLucke: `Random ID` -> `ID` | |||||
| /* All random ID attribute inputs are the same within the same evaluation context. */ | |||||
| return true; | |||||
| } | |||||
| 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.