Refactor: Reorder attribute owner checks to handle mesh first

On its own this change is just noise and not really worth it. The point
is to make a future diff for #122398 smaller and more legible. Also it's
semantically more consistent with the way we usually handle early
returns: the "special case" comes first, then the expected normal path
continues un-indented.
This commit is contained in:
Hans Goudey
2025-10-08 20:11:49 -04:00
committed by Hans Goudey
parent a015054589
commit 8a903c3eec
3 changed files with 298 additions and 300 deletions

View File

@@ -369,14 +369,15 @@ static bool attribute_name_exists(const AttributeOwner &owner, const StringRef n
std::string BKE_attribute_calc_unique_name(const AttributeOwner &owner, const StringRef name)
{
if (owner.type() != AttributeOwnerType::Mesh) {
blender::bke::AttributeStorage &storage = *owner.get_storage();
return storage.unique_name_calc(name);
if (owner.type() == AttributeOwnerType::Mesh) {
return BLI_uniquename_cb(
[&](const StringRef new_name) { return attribute_name_exists(owner, new_name); },
'.',
name.is_empty() ? DATA_("Attribute") : name);
}
return BLI_uniquename_cb(
[&](const StringRef new_name) { return attribute_name_exists(owner, new_name); },
'.',
name.is_empty() ? DATA_("Attribute") : name);
blender::bke::AttributeStorage &storage = *owner.get_storage();
return storage.unique_name_calc(name);
}
CustomDataLayer *BKE_attribute_new(AttributeOwner &owner,
@@ -789,59 +790,55 @@ std::optional<blender::StringRefNull> BKE_attributes_active_name_get(AttributeOw
if (active_index == -1) {
return std::nullopt;
}
if (owner.type() != AttributeOwnerType::Mesh) {
bke::AttributeStorage &storage = *owner.get_storage();
if (!IndexRange(storage.count()).contains(active_index)) {
return std::nullopt;
if (owner.type() == AttributeOwnerType::Mesh) {
if (active_index > BKE_attributes_length(owner, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL)) {
active_index = 0;
}
return storage.at_index(active_index).name();
}
if (active_index > BKE_attributes_length(owner, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL)) {
active_index = 0;
}
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
int index = 0;
for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
CustomData *customdata = info[domain].customdata;
if (customdata == nullptr) {
continue;
}
for (int i = 0; i < customdata->totlayer; i++) {
CustomDataLayer *layer = &customdata->layers[i];
if (CD_MASK_PROP_ALL & CD_TYPE_AS_MASK(eCustomDataType(layer->type))) {
if (index == active_index) {
if (blender::bke::allow_procedural_attribute_access(layer->name)) {
return layer->name;
const std::array<DomainInfo, ATTR_DOMAIN_NUM> info = get_domains(owner);
int index = 0;
for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
CustomData *customdata = info[domain].customdata;
if (customdata == nullptr) {
continue;
}
for (int i = 0; i < customdata->totlayer; i++) {
CustomDataLayer *layer = &customdata->layers[i];
if (CD_MASK_PROP_ALL & CD_TYPE_AS_MASK(eCustomDataType(layer->type))) {
if (index == active_index) {
if (blender::bke::allow_procedural_attribute_access(layer->name)) {
return layer->name;
}
return std::nullopt;
}
return std::nullopt;
index++;
}
index++;
}
}
return std::nullopt;
}
return std::nullopt;
bke::AttributeStorage &storage = *owner.get_storage();
if (!IndexRange(storage.count()).contains(active_index)) {
return std::nullopt;
}
return storage.at_index(active_index).name();
}
void BKE_attributes_active_set(AttributeOwner &owner, const StringRef name)
{
using namespace blender;
if (owner.type() != AttributeOwnerType::Mesh) {
bke::AttributeStorage &attributes = *owner.get_storage();
*BKE_attributes_active_index_p(owner) = attributes.index_of(name);
if (owner.type() == AttributeOwnerType::Mesh) {
const CustomDataLayer *layer = BKE_attribute_search(
owner, name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
BLI_assert(layer != nullptr);
const int index = BKE_attribute_to_index(owner, layer, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL);
*BKE_attributes_active_index_p(owner) = index;
return;
}
const CustomDataLayer *layer = BKE_attribute_search(
owner, name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
BLI_assert(layer != nullptr);
const int index = BKE_attribute_to_index(owner, layer, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL);
*BKE_attributes_active_index_p(owner) = index;
bke::AttributeStorage &attributes = *owner.get_storage();
*BKE_attributes_active_index_p(owner) = attributes.index_of(name);
}
void BKE_attributes_active_clear(AttributeOwner &owner)

View File

@@ -213,27 +213,27 @@ bool attribute_set_poll(bContext &C, const ID &object_data)
return false;
}
if (owner.type() != AttributeOwnerType::Mesh) {
bke::AttributeAccessor attributes = *owner.get_accessor();
std::optional<bke::AttributeMetaData> meta_data = attributes.lookup_meta_data(*name);
if (!meta_data) {
CTX_wm_operator_poll_msg_set(&C, "No active attribute");
return false;
}
if (ELEM(meta_data->data_type,
bke::AttrType::String,
bke::AttrType::Float4x4,
bke::AttrType::Quaternion))
{
if (owner.type() == AttributeOwnerType::Mesh) {
const CustomDataLayer *layer = BKE_attribute_search(
owner, *name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
if (ELEM(layer->type, CD_PROP_STRING, CD_PROP_FLOAT4X4, CD_PROP_QUATERNION)) {
CTX_wm_operator_poll_msg_set(&C, "The active attribute has an unsupported type");
return false;
}
return true;
}
const CustomDataLayer *layer = BKE_attribute_search(
owner, *name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
if (ELEM(layer->type, CD_PROP_STRING, CD_PROP_FLOAT4X4, CD_PROP_QUATERNION)) {
bke::AttributeAccessor attributes = *owner.get_accessor();
std::optional<bke::AttributeMetaData> meta_data = attributes.lookup_meta_data(*name);
if (!meta_data) {
CTX_wm_operator_poll_msg_set(&C, "No active attribute");
return false;
}
if (ELEM(meta_data->data_type,
bke::AttrType::String,
bke::AttrType::Float4x4,
bke::AttrType::Quaternion))
{
CTX_wm_operator_poll_msg_set(&C, "The active attribute has an unsupported type");
return false;
}
@@ -298,27 +298,18 @@ static wmOperatorStatus geometry_attribute_add_exec(bContext *C, wmOperator *op)
char name[MAX_NAME];
RNA_string_get(op->ptr, "name", name);
eCustomDataType type = eCustomDataType(RNA_enum_get(op->ptr, "data_type"));
bke::AttrDomain domain = bke::AttrDomain(RNA_enum_get(op->ptr, "domain"));
const eCustomDataType type = eCustomDataType(RNA_enum_get(op->ptr, "data_type"));
const bke::AttrDomain domain = bke::AttrDomain(RNA_enum_get(op->ptr, "domain"));
AttributeOwner owner = AttributeOwner::from_id(id);
if (owner.type() != AttributeOwnerType::Mesh) {
bke::MutableAttributeAccessor accessor = *owner.get_accessor();
if (!accessor.domain_supported(bke::AttrDomain(domain))) {
BKE_report(op->reports, RPT_ERROR, "Attribute domain not supported by this geometry type");
if (owner.type() == AttributeOwnerType::Mesh) {
CustomDataLayer *layer = BKE_attribute_new(owner, name, type, domain, op->reports);
if (layer == nullptr) {
return OPERATOR_CANCELLED;
}
bke::AttributeStorage &attributes = *owner.get_storage();
const int domain_size = accessor.domain_size(bke::AttrDomain(domain));
const CPPType &cpp_type = *bke::custom_data_type_to_cpp_type(type);
bke::Attribute &attr = attributes.add(
attributes.unique_name_calc(name),
bke::AttrDomain(domain),
*bke::custom_data_type_to_attr_type(type),
bke::Attribute::ArrayData::from_default_value(cpp_type, domain_size));
BKE_attributes_active_set(owner, attr.name());
BKE_attributes_active_set(owner, layer->name);
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
@@ -326,13 +317,22 @@ static wmOperatorStatus geometry_attribute_add_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
CustomDataLayer *layer = BKE_attribute_new(owner, name, type, domain, op->reports);
if (layer == nullptr) {
bke::MutableAttributeAccessor accessor = *owner.get_accessor();
if (!accessor.domain_supported(bke::AttrDomain(domain))) {
BKE_report(op->reports, RPT_ERROR, "Attribute domain not supported by this geometry type");
return OPERATOR_CANCELLED;
}
bke::AttributeStorage &attributes = *owner.get_storage();
const int domain_size = accessor.domain_size(bke::AttrDomain(domain));
BKE_attributes_active_set(owner, layer->name);
const CPPType &cpp_type = *bke::custom_data_type_to_cpp_type(type);
bke::Attribute &attr = attributes.add(
attributes.unique_name_calc(name),
bke::AttrDomain(domain),
*bke::custom_data_type_to_attr_type(type),
bke::Attribute::ArrayData::from_default_value(cpp_type, domain_size));
BKE_attributes_active_set(owner, attr.name());
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);

View File

@@ -332,61 +332,60 @@ static void rna_Attribute_name_get(PointerRNA *ptr, char *value)
{
using namespace blender;
AttributeOwner owner = owner_from_attribute_pointer_rna(ptr);
if (owner.type() != AttributeOwnerType::Mesh) {
const bke::Attribute *attr = ptr->data_as<bke::Attribute>();
attr->name().copy_unsafe(value);
if (owner.type() == AttributeOwnerType::Mesh) {
strcpy(value, ptr->data_as<CustomDataLayer>()->name);
return;
}
strcpy(value, ptr->data_as<CustomDataLayer>()->name);
const bke::Attribute *attr = ptr->data_as<bke::Attribute>();
attr->name().copy_unsafe(value);
}
static int rna_Attribute_name_length(PointerRNA *ptr)
{
using namespace blender;
AttributeOwner owner = owner_from_attribute_pointer_rna(ptr);
if (owner.type() != AttributeOwnerType::Mesh) {
const bke::Attribute *attr = ptr->data_as<bke::Attribute>();
return attr->name().size();
const CustomDataLayer *layer = ptr->data_as<CustomDataLayer>();
if (owner.type() == AttributeOwnerType::Mesh) {
return strlen(layer->name);
}
const CustomDataLayer *layer = ptr->data_as<CustomDataLayer>();
return strlen(layer->name);
const bke::Attribute *attr = ptr->data_as<bke::Attribute>();
return attr->name().size();
}
static void rna_Attribute_name_set(PointerRNA *ptr, const char *value)
{
using namespace blender;
AttributeOwner owner = owner_from_attribute_pointer_rna(ptr);
if (owner.type() != AttributeOwnerType::Mesh) {
const bke::Attribute *attr = ptr->data_as<bke::Attribute>();
BKE_attribute_rename(owner, attr->name(), value, nullptr);
if (owner.type() == AttributeOwnerType::Mesh) {
const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
BKE_attribute_rename(owner, layer->name, value, nullptr);
return;
}
const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
BKE_attribute_rename(owner, layer->name, value, nullptr);
const bke::Attribute *attr = ptr->data_as<bke::Attribute>();
BKE_attribute_rename(owner, attr->name(), value, nullptr);
}
static int rna_Attribute_name_editable(const PointerRNA *ptr, const char **r_info)
{
using namespace blender;
AttributeOwner owner = owner_from_attribute_pointer_rna(const_cast<PointerRNA *>(ptr));
if (owner.type() != AttributeOwnerType::Mesh) {
bke::Attribute *attr = ptr->data_as<bke::Attribute>();
if (BKE_attribute_required(owner, attr->name())) {
if (owner.type() == AttributeOwnerType::Mesh) {
CustomDataLayer *layer = static_cast<CustomDataLayer *>(ptr->data);
if (BKE_attribute_required(owner, layer->name)) {
*r_info = N_("Cannot modify name of required geometry attribute");
return false;
}
return true;
}
CustomDataLayer *layer = static_cast<CustomDataLayer *>(ptr->data);
if (BKE_attribute_required(owner, layer->name)) {
bke::Attribute *attr = ptr->data_as<bke::Attribute>();
if (BKE_attribute_required(owner, attr->name())) {
*r_info = N_("Cannot modify name of required geometry attribute");
return false;
}
return true;
}
@@ -480,12 +479,12 @@ static int rna_Attribute_domain_get(PointerRNA *ptr)
{
using namespace blender;
AttributeOwner owner = owner_from_attribute_pointer_rna(ptr);
if (owner.type() != AttributeOwnerType::Mesh) {
const bke::Attribute *attr = static_cast<const bke::Attribute *>(ptr->data);
return int(attr->domain());
if (owner.type() == AttributeOwnerType::Mesh) {
return int(BKE_attribute_domain(owner, static_cast<const CustomDataLayer *>(ptr->data)));
}
return int(BKE_attribute_domain(owner, static_cast<const CustomDataLayer *>(ptr->data)));
const bke::Attribute *attr = static_cast<const bke::Attribute *>(ptr->data);
return int(attr->domain());
}
static bool rna_Attribute_is_internal_get(PointerRNA *ptr)
@@ -504,64 +503,64 @@ static bool rna_Attribute_is_required_get(PointerRNA *ptr)
{
using namespace blender;
AttributeOwner owner = owner_from_attribute_pointer_rna(ptr);
if (owner.type() != AttributeOwnerType::Mesh) {
const bke::Attribute *attr = static_cast<const bke::Attribute *>(ptr->data);
return BKE_attribute_required(owner, attr->name());
if (owner.type() == AttributeOwnerType::Mesh) {
const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
return BKE_attribute_required(owner, layer->name);
}
const CustomDataLayer *layer = (const CustomDataLayer *)ptr->data;
return BKE_attribute_required(owner, layer->name);
const bke::Attribute *attr = static_cast<const bke::Attribute *>(ptr->data);
return BKE_attribute_required(owner, attr->name());
}
static void rna_Attribute_data_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
using namespace blender;
AttributeOwner owner = owner_from_attribute_pointer_rna(ptr);
if (owner.type() != AttributeOwnerType::Mesh) {
bke::MutableAttributeAccessor accessor = *owner.get_accessor();
bke::Attribute *attr = ptr->data_as<bke::Attribute>();
const int domain_size = accessor.domain_size(attr->domain());
const CPPType &type = bke::attribute_type_to_cpp_type(attr->data_type());
switch (attr->storage_type()) {
case bke::AttrStorageType::Array: {
const auto &data = std::get<bke::Attribute::ArrayData>(attr->data_for_write());
rna_iterator_array_begin(iter, ptr, data.data, type.size, domain_size, false, nullptr);
break;
}
case bke::AttrStorageType::Single: {
/* TODO: Access to single values is unimplemented for now. */
iter->valid = false;
break;
}
if (owner.type() == AttributeOwnerType::Mesh) {
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
if (!(CD_TYPE_AS_MASK(eCustomDataType(layer->type)) & CD_MASK_PROP_ALL)) {
iter->valid = false;
}
const int length = BKE_attribute_data_length(owner, layer);
const size_t struct_size = CustomData_get_elem_size(layer);
CustomData_ensure_data_is_mutable(layer, length);
rna_iterator_array_begin(iter, ptr, layer->data, struct_size, length, 0, nullptr);
return;
}
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
if (!(CD_TYPE_AS_MASK(eCustomDataType(layer->type)) & CD_MASK_PROP_ALL)) {
iter->valid = false;
bke::MutableAttributeAccessor accessor = *owner.get_accessor();
bke::Attribute *attr = ptr->data_as<bke::Attribute>();
const int domain_size = accessor.domain_size(attr->domain());
const CPPType &type = bke::attribute_type_to_cpp_type(attr->data_type());
switch (attr->storage_type()) {
case bke::AttrStorageType::Array: {
const auto &data = std::get<bke::Attribute::ArrayData>(attr->data_for_write());
rna_iterator_array_begin(iter, ptr, data.data, type.size, domain_size, false, nullptr);
break;
}
case bke::AttrStorageType::Single: {
/* TODO: Access to single values is unimplemented for now. */
iter->valid = false;
break;
}
}
const int length = BKE_attribute_data_length(owner, layer);
const size_t struct_size = CustomData_get_elem_size(layer);
CustomData_ensure_data_is_mutable(layer, length);
rna_iterator_array_begin(iter, ptr, layer->data, struct_size, length, 0, nullptr);
}
static int rna_Attribute_data_length(PointerRNA *ptr)
{
using namespace blender;
AttributeOwner owner = owner_from_attribute_pointer_rna(ptr);
if (owner.type() != AttributeOwnerType::Mesh) {
const bke::Attribute *attr = ptr->data_as<bke::Attribute>();
const bke::AttributeAccessor accessor = *owner.get_accessor();
return accessor.domain_size(attr->domain());
if (owner.type() == AttributeOwnerType::Mesh) {
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
return BKE_attribute_data_length(owner, layer);
}
CustomDataLayer *layer = (CustomDataLayer *)ptr->data;
return BKE_attribute_data_length(owner, layer);
const bke::Attribute *attr = ptr->data_as<bke::Attribute>();
const bke::AttributeAccessor accessor = *owner.get_accessor();
return accessor.domain_size(attr->domain());
}
static void rna_Attribute_update_data(Main * /*bmain*/, Scene * /*scene*/, PointerRNA *ptr)
@@ -660,75 +659,74 @@ static PointerRNA rna_AttributeGroupID_new(
{
using namespace blender;
AttributeOwner owner = AttributeOwner::from_id(id);
if (owner.type() != AttributeOwnerType::Mesh) {
const bke::AttributeAccessor accessor = *owner.get_accessor();
if (!accessor.domain_supported(AttrDomain(domain))) {
BKE_report(reports, RPT_ERROR, "Attribute domain not supported by this geometry type");
if (owner.type() == AttributeOwnerType::Mesh) {
CustomDataLayer *layer = BKE_attribute_new(
owner, name, eCustomDataType(type), AttrDomain(domain), reports);
if (!layer) {
return PointerRNA_NULL;
}
const int domain_size = accessor.domain_size(AttrDomain(domain));
bke::AttributeStorage &attributes = *owner.get_storage();
const CPPType &cpp_type = *bke::custom_data_type_to_cpp_type(eCustomDataType(type));
bke::Attribute &attr = attributes.add(
attributes.unique_name_calc(name),
AttrDomain(domain),
*bke::custom_data_type_to_attr_type(eCustomDataType(type)),
bke::Attribute::ArrayData::from_default_value(cpp_type, domain_size));
if ((GS(id->name) == ID_ME) && ELEM(layer->type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) {
Mesh *mesh = (Mesh *)id;
if (!mesh->active_color_attribute) {
mesh->active_color_attribute = BLI_strdup(layer->name);
}
if (!mesh->default_color_attribute) {
mesh->default_color_attribute = BLI_strdup(layer->name);
}
}
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
return RNA_pointer_create_discrete(id, &RNA_Attribute, &attr);
PointerRNA ptr = RNA_pointer_create_discrete(id, &RNA_Attribute, layer);
return ptr;
}
CustomDataLayer *layer = BKE_attribute_new(
owner, name, eCustomDataType(type), AttrDomain(domain), reports);
if (!layer) {
const bke::AttributeAccessor accessor = *owner.get_accessor();
if (!accessor.domain_supported(AttrDomain(domain))) {
BKE_report(reports, RPT_ERROR, "Attribute domain not supported by this geometry type");
return PointerRNA_NULL;
}
const int domain_size = accessor.domain_size(AttrDomain(domain));
if ((GS(id->name) == ID_ME) && ELEM(layer->type, CD_PROP_COLOR, CD_PROP_BYTE_COLOR)) {
Mesh *mesh = (Mesh *)id;
if (!mesh->active_color_attribute) {
mesh->active_color_attribute = BLI_strdup(layer->name);
}
if (!mesh->default_color_attribute) {
mesh->default_color_attribute = BLI_strdup(layer->name);
}
}
bke::AttributeStorage &attributes = *owner.get_storage();
const CPPType &cpp_type = *bke::custom_data_type_to_cpp_type(eCustomDataType(type));
bke::Attribute &attr = attributes.add(
attributes.unique_name_calc(name),
AttrDomain(domain),
*bke::custom_data_type_to_attr_type(eCustomDataType(type)),
bke::Attribute::ArrayData::from_default_value(cpp_type, domain_size));
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
PointerRNA ptr = RNA_pointer_create_discrete(id, &RNA_Attribute, layer);
return ptr;
return RNA_pointer_create_discrete(id, &RNA_Attribute, &attr);
}
static void rna_AttributeGroupID_remove(ID *id, ReportList *reports, PointerRNA *attribute_ptr)
{
using namespace blender;
AttributeOwner owner = AttributeOwner::from_id(id);
if (owner.type() != AttributeOwnerType::Mesh) {
const bke::Attribute *attr = static_cast<const bke::Attribute *>(attribute_ptr->data);
if (BKE_attribute_required(owner, attr->name())) {
BKE_report(reports, RPT_ERROR, "Attribute is required and cannot be removed");
return;
}
bke::MutableAttributeAccessor accessor = *owner.get_accessor();
accessor.remove(attr->name());
if (owner.type() == AttributeOwnerType::Mesh) {
const CustomDataLayer *layer = (const CustomDataLayer *)attribute_ptr->data;
BKE_attribute_remove(owner, layer->name, reports);
attribute_ptr->invalidate();
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
WM_main_add_notifier(NC_GEOM | ND_DATA, id);
return;
}
const CustomDataLayer *layer = (const CustomDataLayer *)attribute_ptr->data;
BKE_attribute_remove(owner, layer->name, reports);
const bke::Attribute *attr = static_cast<const bke::Attribute *>(attribute_ptr->data);
if (BKE_attribute_required(owner, attr->name())) {
BKE_report(reports, RPT_ERROR, "Attribute is required and cannot be removed");
return;
}
bke::MutableAttributeAccessor accessor = *owner.get_accessor();
accessor.remove(attr->name());
attribute_ptr->invalidate();
DEG_id_tag_update(id, ID_RECALC_GEOMETRY);
@@ -784,77 +782,77 @@ void rna_AttributeGroup_iterator_begin(CollectionPropertyIterator *iter, Pointer
using namespace blender;
memset(&iter->internal.array, 0, sizeof(iter->internal.array));
AttributeOwner owner = owner_from_pointer_rna(ptr);
if (owner.type() != AttributeOwnerType::Mesh) {
bke::AttributeStorage &storage = *owner.get_storage();
Vector<bke::Attribute *> attributes;
storage.foreach([&](bke::Attribute &attr) { attributes.append(&attr); });
VectorData data = attributes.release();
rna_iterator_array_begin(
iter, ptr, data.data, sizeof(bke::Attribute *), data.size, true, nullptr);
if (owner.type() == AttributeOwnerType::Mesh) {
rna_AttributeGroup_next_domain(owner, iter, ptr, rna_Attributes_layer_skip);
return;
}
rna_AttributeGroup_next_domain(owner, iter, ptr, rna_Attributes_layer_skip);
bke::AttributeStorage &storage = *owner.get_storage();
Vector<bke::Attribute *> attributes;
storage.foreach([&](bke::Attribute &attr) { attributes.append(&attr); });
VectorData data = attributes.release();
rna_iterator_array_begin(
iter, ptr, data.data, sizeof(bke::Attribute *), data.size, true, nullptr);
}
void rna_AttributeGroup_iterator_next(CollectionPropertyIterator *iter)
{
rna_iterator_array_next(iter);
AttributeOwner owner = owner_from_pointer_rna(&iter->parent);
if (owner.type() != AttributeOwnerType::Mesh) {
if (owner.type() == AttributeOwnerType::Mesh) {
if (!iter->valid) {
rna_AttributeGroup_next_domain(owner, iter, &iter->parent, rna_Attributes_layer_skip);
}
return;
}
if (!iter->valid) {
rna_AttributeGroup_next_domain(owner, iter, &iter->parent, rna_Attributes_layer_skip);
}
/* Everything stored in #AttributeStorage is an attribute. */
}
PointerRNA rna_AttributeGroup_iterator_get(CollectionPropertyIterator *iter)
{
using namespace blender;
AttributeOwner owner = owner_from_pointer_rna(&iter->parent);
if (owner.type() != AttributeOwnerType::Mesh) {
bke::Attribute *attr = *static_cast<bke::Attribute **>(rna_iterator_array_get(iter));
const eCustomDataType data_type = *bke::attr_type_to_custom_data_type(attr->data_type());
StructRNA *type = srna_by_custom_data_layer_type(data_type);
return RNA_pointer_create_with_parent(iter->parent, type, attr);
if (owner.type() == AttributeOwnerType::Mesh) {
CustomDataLayer *layer = static_cast<CustomDataLayer *>(rna_iterator_array_get(iter));
StructRNA *type = srna_by_custom_data_layer_type(eCustomDataType(layer->type));
if (type == nullptr) {
return PointerRNA_NULL;
}
return RNA_pointer_create_with_parent(iter->parent, type, layer);
}
CustomDataLayer *layer = static_cast<CustomDataLayer *>(rna_iterator_array_get(iter));
StructRNA *type = srna_by_custom_data_layer_type(eCustomDataType(layer->type));
if (type == nullptr) {
return PointerRNA_NULL;
}
return RNA_pointer_create_with_parent(iter->parent, type, layer);
bke::Attribute *attr = *static_cast<bke::Attribute **>(rna_iterator_array_get(iter));
const eCustomDataType data_type = *bke::attr_type_to_custom_data_type(attr->data_type());
StructRNA *type = srna_by_custom_data_layer_type(data_type);
return RNA_pointer_create_with_parent(iter->parent, type, attr);
}
void rna_AttributeGroup_color_iterator_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
using namespace blender;
AttributeOwner owner = owner_from_pointer_rna(ptr);
if (owner.type() != AttributeOwnerType::Mesh) {
bke::AttributeStorage &storage = *owner.get_storage();
Vector<bke::Attribute *> attributes;
storage.foreach([&](bke::Attribute &attr) {
if (!(ATTR_DOMAIN_AS_MASK(attr.domain()) & ATTR_DOMAIN_MASK_COLOR)) {
return;
}
if (!(CD_TYPE_AS_MASK(*bke::attr_type_to_custom_data_type(attr.data_type())) &
CD_MASK_COLOR_ALL))
{
return;
}
attributes.append(&attr);
});
VectorData data = attributes.release();
rna_iterator_array_begin(
iter, ptr, data.data, sizeof(bke::Attribute *), data.size, true, nullptr);
if (owner.type() == AttributeOwnerType::Mesh) {
memset(&iter->internal.array, 0, sizeof(iter->internal.array));
rna_AttributeGroup_next_domain(owner, iter, ptr, rna_Attributes_noncolor_layer_skip);
return;
}
memset(&iter->internal.array, 0, sizeof(iter->internal.array));
rna_AttributeGroup_next_domain(owner, iter, ptr, rna_Attributes_noncolor_layer_skip);
bke::AttributeStorage &storage = *owner.get_storage();
Vector<bke::Attribute *> attributes;
storage.foreach([&](bke::Attribute &attr) {
if (!(ATTR_DOMAIN_AS_MASK(attr.domain()) & ATTR_DOMAIN_MASK_COLOR)) {
return;
}
if (!(CD_TYPE_AS_MASK(*bke::attr_type_to_custom_data_type(attr.data_type())) &
CD_MASK_COLOR_ALL))
{
return;
}
attributes.append(&attr);
});
VectorData data = attributes.release();
rna_iterator_array_begin(
iter, ptr, data.data, sizeof(bke::Attribute *), data.size, true, nullptr);
}
void rna_AttributeGroup_color_iterator_next(CollectionPropertyIterator *iter)
@@ -862,95 +860,98 @@ void rna_AttributeGroup_color_iterator_next(CollectionPropertyIterator *iter)
using namespace blender;
rna_iterator_array_next(iter);
AttributeOwner owner = owner_from_pointer_rna(&iter->parent);
if (owner.type() != AttributeOwnerType::Mesh) {
if (owner.type() == AttributeOwnerType::Mesh) {
if (!iter->valid) {
AttributeOwner owner = owner_from_pointer_rna(&iter->parent);
rna_AttributeGroup_next_domain(
owner, iter, &iter->parent, rna_Attributes_noncolor_layer_skip);
}
return;
}
if (!iter->valid) {
AttributeOwner owner = owner_from_pointer_rna(&iter->parent);
rna_AttributeGroup_next_domain(owner, iter, &iter->parent, rna_Attributes_noncolor_layer_skip);
}
/* Not used for #AttributeStorage. */
}
PointerRNA rna_AttributeGroup_color_iterator_get(CollectionPropertyIterator *iter)
{
using namespace blender;
AttributeOwner owner = owner_from_pointer_rna(&iter->parent);
if (owner.type() != AttributeOwnerType::Mesh) {
bke::Attribute *attr = *static_cast<bke::Attribute **>(rna_iterator_array_get(iter));
const eCustomDataType data_type = *bke::attr_type_to_custom_data_type(attr->data_type());
StructRNA *type = srna_by_custom_data_layer_type(data_type);
return RNA_pointer_create_with_parent(iter->parent, type, attr);
if (owner.type() == AttributeOwnerType::Mesh) {
CustomDataLayer *layer = static_cast<CustomDataLayer *>(rna_iterator_array_get(iter));
StructRNA *type = srna_by_custom_data_layer_type(eCustomDataType(layer->type));
if (type == nullptr) {
return PointerRNA_NULL;
}
return RNA_pointer_create_with_parent(iter->parent, type, layer);
}
CustomDataLayer *layer = static_cast<CustomDataLayer *>(rna_iterator_array_get(iter));
StructRNA *type = srna_by_custom_data_layer_type(eCustomDataType(layer->type));
if (type == nullptr) {
return PointerRNA_NULL;
}
return RNA_pointer_create_with_parent(iter->parent, type, layer);
bke::Attribute *attr = *static_cast<bke::Attribute **>(rna_iterator_array_get(iter));
const eCustomDataType data_type = *bke::attr_type_to_custom_data_type(attr->data_type());
StructRNA *type = srna_by_custom_data_layer_type(data_type);
return RNA_pointer_create_with_parent(iter->parent, type, attr);
}
int rna_AttributeGroup_color_length(PointerRNA *ptr)
{
using namespace blender;
AttributeOwner owner = owner_from_pointer_rna(ptr);
if (owner.type() != AttributeOwnerType::Mesh) {
bke::AttributeStorage &storage = *owner.get_storage();
int count = 0;
storage.foreach([&](bke::Attribute &attr) {
if (!(ATTR_DOMAIN_AS_MASK(attr.domain()) & ATTR_DOMAIN_MASK_COLOR)) {
return;
}
if (!(CD_TYPE_AS_MASK(*bke::attr_type_to_custom_data_type(attr.data_type())) &
CD_MASK_COLOR_ALL))
{
return;
}
count++;
});
return count;
if (owner.type() == AttributeOwnerType::Mesh) {
return BKE_attributes_length(owner, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
}
return BKE_attributes_length(owner, ATTR_DOMAIN_MASK_COLOR, CD_MASK_COLOR_ALL);
bke::AttributeStorage &storage = *owner.get_storage();
int count = 0;
storage.foreach([&](bke::Attribute &attr) {
if (!(ATTR_DOMAIN_AS_MASK(attr.domain()) & ATTR_DOMAIN_MASK_COLOR)) {
return;
}
if (!(CD_TYPE_AS_MASK(*bke::attr_type_to_custom_data_type(attr.data_type())) &
CD_MASK_COLOR_ALL))
{
return;
}
count++;
});
return count;
}
int rna_AttributeGroup_length(PointerRNA *ptr)
{
using namespace blender;
AttributeOwner owner = owner_from_pointer_rna(ptr);
if (owner.type() != AttributeOwnerType::Mesh) {
bke::AttributeStorage &storage = *owner.get_storage();
int count = 0;
storage.foreach([&](bke::Attribute & /*attr*/) { count++; });
return count;
if (owner.type() == AttributeOwnerType::Mesh) {
return BKE_attributes_length(owner, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL);
}
return BKE_attributes_length(owner, ATTR_DOMAIN_MASK_ALL, CD_MASK_PROP_ALL);
bke::AttributeStorage &storage = *owner.get_storage();
int count = 0;
storage.foreach([&](bke::Attribute & /*attr*/) { count++; });
return count;
}
bool rna_AttributeGroup_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
{
using namespace blender;
AttributeOwner owner = owner_from_pointer_rna(ptr);
if (owner.type() != AttributeOwnerType::Mesh) {
bke::AttributeStorage &storage = *owner.get_storage();
bke::Attribute *attr = storage.lookup(key);
if (!attr) {
*r_ptr = PointerRNA_NULL;
return false;
if (owner.type() == AttributeOwnerType::Mesh) {
if (CustomDataLayer *layer = BKE_attribute_search_for_write(
owner, key, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL))
{
rna_pointer_create_with_ancestors(*ptr, &RNA_Attribute, layer, *r_ptr);
return true;
}
rna_pointer_create_with_ancestors(*ptr, &RNA_Attribute, attr, *r_ptr);
return true;
*r_ptr = PointerRNA_NULL;
return false;
}
if (CustomDataLayer *layer = BKE_attribute_search_for_write(
owner, key, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL))
{
rna_pointer_create_with_ancestors(*ptr, &RNA_Attribute, layer, *r_ptr);
return true;
bke::AttributeStorage &storage = *owner.get_storage();
bke::Attribute *attr = storage.lookup(key);
if (!attr) {
*r_ptr = PointerRNA_NULL;
return false;
}
*r_ptr = PointerRNA_NULL;
return false;
rna_pointer_create_with_ancestors(*ptr, &RNA_Attribute, attr, *r_ptr);
return true;
}
static int rna_AttributeGroupID_active_index_get(PointerRNA *ptr)
@@ -967,15 +968,15 @@ static PointerRNA rna_AttributeGroupID_active_get(PointerRNA *ptr)
if (!name) {
return PointerRNA_NULL;
}
if (owner.type() != AttributeOwnerType::Mesh) {
bke::AttributeStorage &storage = *owner.get_storage();
bke::Attribute *attr = storage.lookup(*name);
return RNA_pointer_create_with_parent(*ptr, &RNA_Attribute, attr);
if (owner.type() == AttributeOwnerType::Mesh) {
CustomDataLayer *layer = BKE_attribute_search_for_write(
owner, *name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
return RNA_pointer_create_with_parent(*ptr, &RNA_Attribute, layer);
}
CustomDataLayer *layer = BKE_attribute_search_for_write(
owner, *name, CD_MASK_PROP_ALL, ATTR_DOMAIN_MASK_ALL);
return RNA_pointer_create_with_parent(*ptr, &RNA_Attribute, layer);
bke::AttributeStorage &storage = *owner.get_storage();
bke::Attribute *attr = storage.lookup(*name);
return RNA_pointer_create_with_parent(*ptr, &RNA_Attribute, attr);
}
static void rna_AttributeGroupID_active_set(PointerRNA *ptr,
@@ -984,19 +985,19 @@ static void rna_AttributeGroupID_active_set(PointerRNA *ptr,
{
using namespace blender;
AttributeOwner owner = AttributeOwner::from_id(ptr->owner_id);
if (owner.type() != AttributeOwnerType::Mesh) {
bke::Attribute *attr = attribute_ptr.data_as<bke::Attribute>();
BKE_attributes_active_set(owner, attr->name());
if (owner.type() == AttributeOwnerType::Mesh) {
CustomDataLayer *layer = static_cast<CustomDataLayer *>(attribute_ptr.data);
if (layer) {
BKE_attributes_active_set(owner, layer->name);
}
else {
BKE_attributes_active_clear(owner);
}
return;
}
CustomDataLayer *layer = static_cast<CustomDataLayer *>(attribute_ptr.data);
if (layer) {
BKE_attributes_active_set(owner, layer->name);
}
else {
BKE_attributes_active_clear(owner);
}
bke::Attribute *attr = attribute_ptr.data_as<bke::Attribute>();
BKE_attributes_active_set(owner, attr->name());
}
static void rna_AttributeGroupID_active_index_set(PointerRNA *ptr, int value)
@@ -1037,12 +1038,12 @@ static int rna_AttributeGroupID_domain_size(ID *id, const int domain)
{
using namespace blender;
AttributeOwner owner = AttributeOwner::from_id(id);
if (owner.type() != AttributeOwnerType::Mesh) {
bke::AttributeAccessor attributes = *owner.get_accessor();
return attributes.domain_size(bke::AttrDomain(domain));
if (owner.type() == AttributeOwnerType::Mesh) {
return BKE_attribute_domain_size(owner, domain);
}
return BKE_attribute_domain_size(owner, domain);
bke::AttributeAccessor attributes = *owner.get_accessor();
return attributes.domain_size(bke::AttrDomain(domain));
}
static PointerRNA rna_AttributeGroupMesh_active_color_get(PointerRNA *ptr)