diff --git a/source/blender/blenkernel/BKE_attribute.h b/source/blender/blenkernel/BKE_attribute.h index 4d6405355eb..7ee463abc0c 100644 --- a/source/blender/blenkernel/BKE_attribute.h +++ b/source/blender/blenkernel/BKE_attribute.h @@ -18,7 +18,8 @@ namespace blender::bke { enum class AttrDomain : int8_t; -} +class AttributeAccessor; +} // namespace blender::bke struct CustomData; struct CustomDataLayer; struct ID; @@ -73,8 +74,6 @@ class AttributeOwner { /* Attributes. */ -bool BKE_attributes_supported(const AttributeOwner &owner); - /** * Create a new attribute layer. */ diff --git a/source/blender/blenkernel/BKE_attribute.hh b/source/blender/blenkernel/BKE_attribute.hh index 48e1d6f3e75..575b84a492f 100644 --- a/source/blender/blenkernel/BKE_attribute.hh +++ b/source/blender/blenkernel/BKE_attribute.hh @@ -477,6 +477,11 @@ class AttributeAccessor { { } + /** + * Construct an #AttributeAccessor from an ID. + */ + static std::optional from_id(const ID &id); + /** * \return True, when the attribute is available. */ diff --git a/source/blender/blenkernel/intern/attribute.cc b/source/blender/blenkernel/intern/attribute.cc index 0c9b14391f6..96f167a691b 100644 --- a/source/blender/blenkernel/intern/attribute.cc +++ b/source/blender/blenkernel/intern/attribute.cc @@ -188,17 +188,6 @@ static std::optional get_attribute_acces } // namespace blender::bke -bool BKE_attributes_supported(const AttributeOwner &owner) -{ - const std::array info = get_domains(owner); - for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) { - if (info[domain].customdata) { - return true; - } - } - return false; -} - static bool bke_attribute_rename_if_exists(AttributeOwner &owner, const char *old_name, const char *new_name, diff --git a/source/blender/blenkernel/intern/attribute_access.cc b/source/blender/blenkernel/intern/attribute_access.cc index e0121516b63..730cffddec9 100644 --- a/source/blender/blenkernel/intern/attribute_access.cc +++ b/source/blender/blenkernel/intern/attribute_access.cc @@ -5,12 +5,17 @@ #include #include "BKE_attribute_math.hh" +#include "BKE_curves.hh" #include "BKE_customdata.hh" #include "BKE_deform.hh" #include "BKE_geometry_set.hh" #include "BKE_type_conversions.hh" +#include "DNA_ID.h" +#include "DNA_grease_pencil_types.h" +#include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "DNA_pointcloud_types.h" #include "BLI_array_utils.hh" #include "BLI_color.hh" @@ -582,6 +587,23 @@ static GVArray try_adapt_data_type(GVArray varray, const CPPType &to_type) return conversions.try_convert(std::move(varray), to_type); } +std::optional AttributeAccessor::from_id(const ID &id) +{ + switch (GS(id.name)) { + case ID_ME: + return reinterpret_cast(id).attributes(); + case ID_PT: + return reinterpret_cast(id).attributes(); + case ID_CV: + return reinterpret_cast(id).geometry.wrap().attributes(); + case ID_GP: + return reinterpret_cast(id).attributes(); + default: + return {}; + } + return {}; +} + GAttributeReader AttributeAccessor::lookup(const AttributeIDRef &attribute_id, const std::optional domain, const std::optional data_type) const diff --git a/source/blender/editors/geometry/geometry_attributes.cc b/source/blender/editors/geometry/geometry_attributes.cc index 7af68dda6b9..2c8ee0f5f16 100644 --- a/source/blender/editors/geometry/geometry_attributes.cc +++ b/source/blender/editors/geometry/geometry_attributes.cc @@ -211,15 +211,17 @@ bool attribute_set_poll(bContext &C, const ID &object_data) static bool geometry_attributes_poll(bContext *C) { + using namespace blender::bke; const Object *ob = object::context_object(C); const Main *bmain = CTX_data_main(C); - ID *data = (ob) ? static_cast(ob->data) : nullptr; - AttributeOwner owner = AttributeOwner::from_id(data); - if (!owner.is_valid()) { + if (!ob || !BKE_id_is_editable(bmain, &ob->id)) { return false; } - return (ob && BKE_id_is_editable(bmain, &ob->id) && data && BKE_id_is_editable(bmain, data)) && - BKE_attributes_supported(owner); + const ID *data = (ob) ? static_cast(ob->data) : nullptr; + if (!data || !BKE_id_is_editable(bmain, data)) { + return false; + } + return AttributeAccessor::from_id(*data).has_value(); } static bool geometry_attributes_remove_poll(bContext *C)