Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Goudey <h.goudey@me.com>2022-09-06 21:20:03 +0300
committerHans Goudey <h.goudey@me.com>2022-09-06 21:23:41 +0300
commitced56dbc5396521e9fe51c0b59041f6577cd6135 (patch)
tree55f22d622b21d104baa561c46f7ce9359d12ef13
parent394c0b5ae4d9b28e8624ea831e20e011a687f71e (diff)
Fix: Restore fix for empty attributes after recent commit
3484c6d4f116409 removed parts of 6e5eb46d7339591 by mistake, returning no attribute when attribute data wasn't found. However, we want that attributes can exist even on empty geometry. This commit restores the fix and tries to make it more explicit to avoid the same mistake again. Differential Revision: https://developer.blender.org/D15899
-rw-r--r--source/blender/blenkernel/intern/attribute_access.cc58
-rw-r--r--source/blender/blenkernel/intern/attribute_access_intern.hh3
2 files changed, 39 insertions, 22 deletions
diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc
index e144e65ced6..6ca3a286a5e 100644
--- a/source/blender/blenkernel/intern/attribute_access.cc
+++ b/source/blender/blenkernel/intern/attribute_access.cc
@@ -266,6 +266,14 @@ static bool custom_data_layer_matches_attribute_id(const CustomDataLayer &layer,
return layer.name == attribute_id.name();
}
+bool BuiltinCustomDataLayerProvider::layer_exists(const CustomData &custom_data) const
+{
+ if (stored_as_named_attribute_) {
+ return CustomData_get_named_layer_index(&custom_data, stored_type_, name_.c_str()) != -1;
+ }
+ return CustomData_has_layer(&custom_data, stored_type_);
+}
+
GVArray BuiltinCustomDataLayerProvider::try_get_for_read(const void *owner) const
{
const CustomData *custom_data = custom_data_access_.get_const_custom_data(owner);
@@ -273,26 +281,25 @@ GVArray BuiltinCustomDataLayerProvider::try_get_for_read(const void *owner) cons
return {};
}
- const void *data = nullptr;
- bool found_attribute = false;
- for (const CustomDataLayer &layer : Span(custom_data->layers, custom_data->totlayer)) {
- if (stored_as_named_attribute_) {
- if (layer.name == name_) {
- data = layer.data;
- found_attribute = true;
- break;
- }
- }
- else if (layer.type == stored_type_) {
- data = layer.data;
- found_attribute = true;
- break;
+ /* When the number of elements is zero, layers might have null data but still exist. */
+ const int element_num = custom_data_access_.get_element_num(owner);
+ if (element_num == 0) {
+ if (this->layer_exists(*custom_data)) {
+ return as_read_attribute_(nullptr, 0);
}
+ return {};
+ }
+
+ const void *data = nullptr;
+ if (stored_as_named_attribute_) {
+ data = CustomData_get_layer_named(custom_data, stored_type_, name_.c_str());
+ }
+ else {
+ data = CustomData_get_layer(custom_data, stored_type_);
}
- if (!found_attribute) {
+ if (data == nullptr) {
return {};
}
- const int element_num = custom_data_access_.get_element_num(owner);
return as_read_attribute_(data, element_num);
}
@@ -305,7 +312,20 @@ GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner)
if (custom_data == nullptr) {
return {};
}
+
+ std::function<void()> tag_modified_fn;
+ if (update_on_change_ != nullptr) {
+ tag_modified_fn = [owner, update = update_on_change_]() { update(owner); };
+ }
+
+ /* When the number of elements is zero, layers might have null data but still exist. */
const int element_num = custom_data_access_.get_element_num(owner);
+ if (element_num == 0) {
+ if (this->layer_exists(*custom_data)) {
+ return {as_write_attribute_(nullptr, 0), domain_, std::move(tag_modified_fn)};
+ }
+ return {};
+ }
void *data = nullptr;
if (stored_as_named_attribute_) {
@@ -318,12 +338,6 @@ GAttributeWriter BuiltinCustomDataLayerProvider::try_get_for_write(void *owner)
if (data == nullptr) {
return {};
}
-
- std::function<void()> tag_modified_fn;
- if (update_on_change_ != nullptr) {
- tag_modified_fn = [owner, update = update_on_change_]() { update(owner); };
- }
-
return {as_write_attribute_(data, element_num), domain_, std::move(tag_modified_fn)};
}
diff --git a/source/blender/blenkernel/intern/attribute_access_intern.hh b/source/blender/blenkernel/intern/attribute_access_intern.hh
index d8550c596f2..8050f45da94 100644
--- a/source/blender/blenkernel/intern/attribute_access_intern.hh
+++ b/source/blender/blenkernel/intern/attribute_access_intern.hh
@@ -258,6 +258,9 @@ class BuiltinCustomDataLayerProvider final : public BuiltinAttributeProvider {
bool try_delete(void *owner) const final;
bool try_create(void *owner, const AttributeInit &initializer) const final;
bool exists(const void *owner) const final;
+
+ private:
+ bool layer_exists(const CustomData &custom_data) const;
};
/**