mirror of
https://github.com/blender/blender
synced 2026-09-29 04:37:17 +03:00
Cleanup: Replace "foreach" lambdas with attribute storage iterator
Use the iterator added in 3929b27af6
Pull Request: https://projects.blender.org/blender/blender/pulls/153222
This commit is contained in:
parent
2d76c0615a
commit
0b422e45b1
20 changed files with 115 additions and 156 deletions
|
|
@ -139,15 +139,6 @@ class AttributeStorage : public blender::AttributeStorage {
|
|||
AttributeStorage &operator=(AttributeStorage &&other);
|
||||
~AttributeStorage();
|
||||
|
||||
/**
|
||||
* Iterate over all attributes, with the order defined by the order of insertion. It is not safe
|
||||
* to add or remove attributes while iterating.
|
||||
*/
|
||||
void foreach(FunctionRef<void(Attribute &)> fn);
|
||||
void foreach(FunctionRef<void(const Attribute &)> fn) const;
|
||||
void foreach_with_stop(FunctionRef<bool(Attribute &)> fn);
|
||||
void foreach_with_stop(FunctionRef<bool(const Attribute &)> fn) const;
|
||||
|
||||
/** Return the number of attributes. */
|
||||
int count() const;
|
||||
|
||||
|
|
|
|||
|
|
@ -588,20 +588,18 @@ int BKE_attributes_length(const AttributeOwner &owner,
|
|||
if (include_anonymous && domain_mask == ATTR_DOMAIN_MASK_ALL && mask == CD_MASK_PROP_ALL) {
|
||||
return storage.count();
|
||||
}
|
||||
int length = 0;
|
||||
storage.foreach([&](const bke::Attribute &attr) {
|
||||
return std::count_if(storage.begin(), storage.end(), [&](const bke::Attribute &attr) {
|
||||
if (!(ATTR_DOMAIN_AS_MASK(attr.domain()) & domain_mask)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (!(CD_TYPE_AS_MASK(*bke::attr_type_to_custom_data_type(attr.data_type())) & mask)) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (!include_anonymous && bke::attribute_name_is_anonymous(attr.name())) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
length++;
|
||||
return true;
|
||||
});
|
||||
return length;
|
||||
}
|
||||
|
||||
AttrDomain BKE_attribute_domain(const Mesh &mesh, const BMesh &bm, const CustomDataLayer *layer)
|
||||
|
|
@ -782,25 +780,22 @@ std::optional<StringRef> BKE_attribute_from_index(AttributeOwner &owner,
|
|||
return storage.at_index(lookup_index).name();
|
||||
}
|
||||
int index = 0;
|
||||
std::optional<StringRef> result;
|
||||
storage.foreach_with_stop([&](const bke::Attribute &attr) {
|
||||
for (const bke::Attribute &attr : storage) {
|
||||
if (!(ATTR_DOMAIN_AS_MASK(attr.domain()) & domain_mask)) {
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
if (!(CD_TYPE_AS_MASK(*bke::attr_type_to_custom_data_type(attr.data_type())) & layer_mask)) {
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
if (!include_anonymous && bke::attribute_name_is_anonymous(attr.name())) {
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
if (index == lookup_index) {
|
||||
result = attr.name();
|
||||
return false;
|
||||
return attr.name();
|
||||
}
|
||||
index++;
|
||||
return true;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
int BKE_attribute_to_index(const AttributeOwner &owner,
|
||||
|
|
@ -841,25 +836,22 @@ int BKE_attribute_to_index(const AttributeOwner &owner,
|
|||
return storage.index_of(name);
|
||||
}
|
||||
int index = 0;
|
||||
bool found = false;
|
||||
storage.foreach_with_stop([&](const bke::Attribute &attr) {
|
||||
for (const bke::Attribute &attr : storage) {
|
||||
if (!(ATTR_DOMAIN_AS_MASK(attr.domain()) & domain_mask)) {
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
if (!(CD_TYPE_AS_MASK(*bke::attr_type_to_custom_data_type(attr.data_type())) & layer_mask)) {
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
if (!include_anonymous && bke::attribute_name_is_anonymous(attr.name())) {
|
||||
return true;
|
||||
continue;
|
||||
}
|
||||
if (attr.name() == name) {
|
||||
found = true;
|
||||
return false;
|
||||
return index;
|
||||
}
|
||||
index++;
|
||||
return true;
|
||||
});
|
||||
return found ? index : -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::optional<StringRef> BKE_id_attributes_active_color_name(const ID *id)
|
||||
|
|
|
|||
|
|
@ -304,22 +304,22 @@ LegacyMeshInterpolator::LegacyMeshInterpolator(const Mesh &src, Mesh &dst, const
|
|||
AttributeStorage &dst_attributes = dst.attribute_storage.wrap();
|
||||
const int src_domain_size = get_domain_size(src, domain);
|
||||
const int dst_domain_size = get_domain_size(dst, domain);
|
||||
src_attributes.foreach([&](const Attribute &src_attr) {
|
||||
for (const Attribute &src_attr : src_attributes) {
|
||||
if (src_attr.domain() != domain) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
Attribute *dst_attr = dst_attributes.lookup(src_attr.name());
|
||||
if (!dst_attr) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
if (dst_attr->domain() != domain) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
if (dst_attr->data_type() != src_attr.data_type()) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
if (dst_attr->storage_type() != AttrStorageType::Array) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
const CPPType &cpp_type = attribute_type_to_cpp_type(src_attr.data_type());
|
||||
switch (src_attr.storage_type()) {
|
||||
|
|
@ -336,7 +336,7 @@ LegacyMeshInterpolator::LegacyMeshInterpolator(const Mesh &src, Mesh &dst, const
|
|||
}
|
||||
auto &value = std::get<Attribute::ArrayData>(dst_attr->data_for_write());
|
||||
attrs_dst_.append({cpp_type, value.data, dst_domain_size});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void LegacyMeshInterpolator::copy(const int src_index, const int dst_index, const int count) const
|
||||
|
|
|
|||
|
|
@ -134,36 +134,6 @@ Attribute::SingleData Attribute::SingleData::from_default_value(const CPPType &t
|
|||
return from_value(GPointer(type, type.default_value()));
|
||||
}
|
||||
|
||||
void AttributeStorage::foreach(FunctionRef<void(Attribute &)> fn)
|
||||
{
|
||||
for (const std::unique_ptr<Attribute> &attribute : this->runtime->attributes) {
|
||||
fn(*attribute);
|
||||
}
|
||||
}
|
||||
void AttributeStorage::foreach(FunctionRef<void(const Attribute &)> fn) const
|
||||
{
|
||||
for (const std::unique_ptr<Attribute> &attribute : this->runtime->attributes) {
|
||||
fn(*attribute);
|
||||
}
|
||||
}
|
||||
|
||||
void AttributeStorage::foreach_with_stop(FunctionRef<bool(Attribute &)> fn)
|
||||
{
|
||||
for (const std::unique_ptr<Attribute> &attribute : this->runtime->attributes) {
|
||||
if (!fn(*attribute)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
void AttributeStorage::foreach_with_stop(FunctionRef<bool(const Attribute &)> fn) const
|
||||
{
|
||||
for (const std::unique_ptr<Attribute> &attribute : this->runtime->attributes) {
|
||||
if (!fn(*attribute)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AttrStorageType Attribute::storage_type() const
|
||||
{
|
||||
if (std::get_if<Attribute::ArrayData>(&data_)) {
|
||||
|
|
@ -218,9 +188,9 @@ AttributeStorage::AttributeStorage(const AttributeStorage &other)
|
|||
this->dna_attributes_num = 0;
|
||||
this->runtime = MEM_new<AttributeStorageRuntime>(__func__);
|
||||
this->runtime->attributes.reserve(other.runtime->attributes.size());
|
||||
other.foreach([&](const Attribute &attribute) {
|
||||
for (const Attribute &attribute : other) {
|
||||
this->runtime->attributes.add_new(std::make_unique<Attribute>(attribute));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
AttributeStorage &AttributeStorage::operator=(const AttributeStorage &other)
|
||||
|
|
@ -336,9 +306,9 @@ void AttributeStorage::rename(const StringRef old_name, std::string new_name)
|
|||
|
||||
void AttributeStorage::resize(const AttrDomain domain, const int64_t new_size)
|
||||
{
|
||||
this->foreach([&](Attribute &attr) {
|
||||
for (Attribute &attr : *this) {
|
||||
if (attr.domain() != domain) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
const CPPType &type = attribute_type_to_cpp_type(attr.data_type());
|
||||
switch (attr.storage_type()) {
|
||||
|
|
@ -354,12 +324,13 @@ void AttributeStorage::resize(const AttrDomain domain, const int64_t new_size)
|
|||
}
|
||||
|
||||
attr.assign_data(std::move(new_data));
|
||||
break;
|
||||
}
|
||||
case bke::AttrStorageType::Single: {
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void read_array_data(BlendDataReader &reader,
|
||||
|
|
@ -585,7 +556,7 @@ static void write_array_data(BlendWriter &writer,
|
|||
void attribute_storage_blend_write_prepare(AttributeStorage &data,
|
||||
AttributeStorage::BlendWriteData &write_data)
|
||||
{
|
||||
data.foreach([&](Attribute &attr) {
|
||||
for (Attribute &attr : data) {
|
||||
blender::Attribute attribute_dna{};
|
||||
attribute_dna.name = attr.name().c_str();
|
||||
attribute_dna.data_type = int16_t(attr.data_type());
|
||||
|
|
@ -614,7 +585,7 @@ void attribute_storage_blend_write_prepare(AttributeStorage &data,
|
|||
}
|
||||
|
||||
write_data.attributes.append(attribute_dna);
|
||||
});
|
||||
}
|
||||
data.runtime = nullptr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,8 +12,7 @@ namespace blender::bke::tests {
|
|||
TEST(attribute_storage, Empty)
|
||||
{
|
||||
AttributeStorage storage;
|
||||
int count = 0;
|
||||
storage.foreach([&](const Attribute & /*attribute*/) { count++; });
|
||||
const int count = std::distance(storage.begin(), storage.end());
|
||||
EXPECT_EQ(count, 0);
|
||||
}
|
||||
|
||||
|
|
@ -36,8 +35,7 @@ TEST(attribute_storage, Single)
|
|||
EXPECT_EQ(data.data, sharing_info->data.data());
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
storage.foreach([&](const Attribute & /*attribute*/) { count++; });
|
||||
const int count = std::distance(storage.begin(), storage.end());
|
||||
EXPECT_EQ(count, 1);
|
||||
}
|
||||
|
||||
|
|
@ -133,8 +131,7 @@ TEST(attribute_storage, MultipleShared)
|
|||
EXPECT_EQ(data_ptr[3], 1.0f);
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
storage.foreach([&](const Attribute & /*attribute*/) { count++; });
|
||||
const int count = std::distance(storage.begin(), storage.end());
|
||||
EXPECT_EQ(count, 5);
|
||||
}
|
||||
|
||||
|
|
@ -208,8 +205,7 @@ TEST(attribute_storage, UniqueNames)
|
|||
storage.add(
|
||||
storage.unique_name_calc("foo_2"), AttrDomain::Point, AttrType::Float, create_array_data());
|
||||
|
||||
int count = 0;
|
||||
storage.foreach([&](const Attribute & /*attribute*/) { count++; });
|
||||
const int count = std::distance(storage.begin(), storage.end());
|
||||
EXPECT_EQ(count, 6);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ static AttributeAccessorFunctions get_curves_accessor_functions()
|
|||
}
|
||||
|
||||
const AttributeStorage &storage = curves.attribute_storage.wrap();
|
||||
storage.foreach_with_stop([&](const Attribute &attr) {
|
||||
for (const Attribute &attr : storage) {
|
||||
const auto get_fn = [&]() {
|
||||
const int domain_size = get_domain_size(owner, attr.domain());
|
||||
return attribute_to_reader(attr, attr.domain(), domain_size);
|
||||
|
|
@ -366,8 +366,10 @@ static AttributeAccessorFunctions get_curves_accessor_functions()
|
|||
iter.is_builtin = builtin_attributes().contains(attr.name());
|
||||
iter.accessor = &accessor;
|
||||
fn(iter);
|
||||
return !iter.is_stopped();
|
||||
});
|
||||
if (iter.is_stopped()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
fn.lookup_validator = [](const void * /*owner*/, const StringRef name) -> AttributeValidator {
|
||||
const AttrBuiltinInfo *info = builtin_attributes().lookup_ptr(name);
|
||||
|
|
|
|||
|
|
@ -3806,9 +3806,9 @@ static void reorder_attribute_domain(bke::AttributeStorage &data,
|
|||
const bke::AttrDomain domain,
|
||||
const Span<int> new_by_old_map)
|
||||
{
|
||||
data.foreach([&](bke::Attribute &attr) {
|
||||
for (bke::Attribute &attr : data) {
|
||||
if (attr.domain() != domain) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
const CPPType &type = bke::attribute_type_to_cpp_type(attr.data_type());
|
||||
switch (attr.storage_type()) {
|
||||
|
|
@ -3819,12 +3819,13 @@ static void reorder_attribute_domain(bke::AttributeStorage &data,
|
|||
new_by_old_map,
|
||||
GMutableSpan(type, new_data.data, new_data.size));
|
||||
attr.assign_data(std::move(new_data));
|
||||
break;
|
||||
}
|
||||
case bke::AttrStorageType::Single: {
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void reorder_layer_data(GreasePencil &grease_pencil,
|
||||
|
|
@ -4137,7 +4138,7 @@ static void shrink_attribute_storage(bke::AttributeStorage &storage,
|
|||
const IndexRange range_before(index_to_remove);
|
||||
const IndexRange range_after(index_to_remove + 1, size - index_to_remove - 1);
|
||||
|
||||
storage.foreach([&](bke::Attribute &attr) {
|
||||
for (bke::Attribute &attr : storage) {
|
||||
const CPPType &type = bke::attribute_type_to_cpp_type(attr.data_type());
|
||||
switch (attr.storage_type()) {
|
||||
case bke::AttrStorageType::Array: {
|
||||
|
|
@ -4150,12 +4151,13 @@ static void shrink_attribute_storage(bke::AttributeStorage &storage,
|
|||
range_after.size());
|
||||
|
||||
attr.assign_data(std::move(new_data));
|
||||
break;
|
||||
}
|
||||
case bke::AttrStorageType::Single: {
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void update_active_node_from_node_to_remove(GreasePencil &grease_pencil,
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ static AttributeAccessorFunctions get_grease_pencil_accessor_functions()
|
|||
const AttributeAccessor &accessor) {
|
||||
const GreasePencil &grease_pencil = *static_cast<const GreasePencil *>(owner);
|
||||
const AttributeStorage &storage = grease_pencil.attribute_storage.wrap();
|
||||
storage.foreach_with_stop([&](const Attribute &attribute) {
|
||||
for (const Attribute &attribute : storage) {
|
||||
const auto get_fn = [&]() {
|
||||
const int domain_size = get_domain_size(owner, AttrDomain::Layer);
|
||||
return attribute_to_reader(attribute, AttrDomain::Layer, domain_size);
|
||||
|
|
@ -87,8 +87,10 @@ static AttributeAccessorFunctions get_grease_pencil_accessor_functions()
|
|||
iter.is_builtin = builtin_attributes().contains(attribute.name());
|
||||
iter.accessor = &accessor;
|
||||
fn(iter);
|
||||
return !iter.is_stopped();
|
||||
});
|
||||
if (iter.is_stopped()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
fn.lookup_validator = [](const void * /*owner*/, const StringRef name) -> AttributeValidator {
|
||||
const AttrBuiltinInfo *info = builtin_attributes().lookup_ptr(name);
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ static constexpr AttributeAccessorFunctions get_instances_accessor_functions()
|
|||
const AttributeAccessor &accessor) {
|
||||
const Instances &instances = *static_cast<const Instances *>(owner);
|
||||
const AttributeStorage &storage = instances.attribute_storage();
|
||||
storage.foreach_with_stop([&](const Attribute &attribute) {
|
||||
for (const Attribute &attribute : storage) {
|
||||
const auto get_fn = [&]() {
|
||||
return attribute_to_reader(attribute, AttrDomain::Instance, instances.instances_num());
|
||||
};
|
||||
|
|
@ -104,8 +104,10 @@ static constexpr AttributeAccessorFunctions get_instances_accessor_functions()
|
|||
iter.is_builtin = builtin_attributes().contains(attribute.name());
|
||||
iter.accessor = &accessor;
|
||||
fn(iter);
|
||||
return !iter.is_stopped();
|
||||
});
|
||||
if (iter.is_stopped()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
fn.lookup_validator = [](const void * /*owner*/, const StringRef name) -> AttributeValidator {
|
||||
const AttrBuiltinInfo *info = builtin_attributes().lookup_ptr(name);
|
||||
|
|
|
|||
|
|
@ -1449,12 +1449,12 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
|
|||
}
|
||||
|
||||
bke::MutableAttributeAccessor dst_attrs = me_dst->attributes_for_write();
|
||||
me_src->attribute_storage.wrap().foreach([&](const bke::Attribute &attr) {
|
||||
for (const bke::Attribute &attr : me_src->attribute_storage.wrap()) {
|
||||
if (dst_attrs.contains(attr.name())) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
dst_attrs.add(attr.name(), attr.domain(), attr.data_type(), bke::AttributeInitDefaultValue());
|
||||
});
|
||||
}
|
||||
|
||||
return me_dst;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -958,7 +958,7 @@ static AttributeAccessorFunctions get_mesh_accessor_functions()
|
|||
}
|
||||
|
||||
const AttributeStorage &storage = mesh.attribute_storage.wrap();
|
||||
storage.foreach_with_stop([&](const Attribute &attr) {
|
||||
for (const Attribute &attr : storage) {
|
||||
const auto get_fn = [&]() {
|
||||
const int domain_size = get_domain_size(owner, attr.domain());
|
||||
return attribute_to_reader(attr, attr.domain(), domain_size);
|
||||
|
|
@ -967,8 +967,10 @@ static AttributeAccessorFunctions get_mesh_accessor_functions()
|
|||
iter.is_builtin = builtin_attributes().contains(attr.name());
|
||||
iter.accessor = &accessor;
|
||||
fn(iter);
|
||||
return !iter.is_stopped();
|
||||
});
|
||||
if (iter.is_stopped()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
fn.lookup_validator = [](const void * /*owner*/, const StringRef name) -> AttributeValidator {
|
||||
const AttrBuiltinInfo *info = builtin_attributes().lookup_ptr(name);
|
||||
|
|
|
|||
|
|
@ -498,9 +498,9 @@ void mesh_calc_edges(Mesh &mesh,
|
|||
}
|
||||
|
||||
mesh.attribute_storage.wrap().remove(".edge_verts");
|
||||
mesh.attribute_storage.wrap().foreach([&](bke::Attribute &attr) {
|
||||
for (bke::Attribute &attr : mesh.attribute_storage.wrap()) {
|
||||
if (attr.domain() != bke::AttrDomain::Edge) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
switch (attr.storage_type()) {
|
||||
case AttrStorageType::Single: {
|
||||
|
|
@ -520,7 +520,7 @@ void mesh_calc_edges(Mesh &mesh,
|
|||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
const int orig_index_layer = CustomData_get_layer_index(&mesh.edge_data, CD_ORIGINDEX);
|
||||
|
|
|
|||
|
|
@ -2675,11 +2675,11 @@ void BKE_mesh_calc_edges_tessface(Mesh *mesh)
|
|||
/* free old CustomData and assign new one */
|
||||
CustomData_free(&mesh->edge_data);
|
||||
Set<StringRef> edge_attributes;
|
||||
mesh->attribute_storage.wrap().foreach([&](const bke::Attribute &attr) {
|
||||
for (const bke::Attribute &attr : mesh->attribute_storage.wrap()) {
|
||||
if (attr.domain() == bke::AttrDomain::Edge) {
|
||||
edge_attributes.add(attr.name());
|
||||
}
|
||||
});
|
||||
}
|
||||
for (const StringRef name : edge_attributes) {
|
||||
mesh->attribute_storage.wrap().remove(name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -370,7 +370,7 @@ static void remove_invalid_faces(Mesh &mesh, const IndexMask &valid_faces)
|
|||
const OffsetIndices new_faces = offset_indices::gather_selected_offsets(
|
||||
old_faces, valid_faces, new_face_offsets);
|
||||
|
||||
mesh.attribute_storage.wrap().foreach([&](bke::Attribute &attr) {
|
||||
for (bke::Attribute &attr : mesh.attribute_storage.wrap()) {
|
||||
const CPPType &type = attribute_type_to_cpp_type(attr.data_type());
|
||||
switch (attr.domain()) {
|
||||
case AttrDomain::Face: {
|
||||
|
|
@ -411,7 +411,7 @@ static void remove_invalid_faces(Mesh &mesh, const IndexMask &valid_faces)
|
|||
default:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (CustomDataLayer &layer : MutableSpan(mesh.face_data.layers, mesh.face_data.totlayer)) {
|
||||
if (layer.type == CD_ORIGINDEX) {
|
||||
|
|
@ -469,9 +469,9 @@ static void remove_invalid_edges(Mesh &mesh, const IndexMask &valid_edges)
|
|||
{
|
||||
const int valid_edges_num = valid_edges.size();
|
||||
|
||||
mesh.attribute_storage.wrap().foreach([&](bke::Attribute &attr) {
|
||||
for (bke::Attribute &attr : mesh.attribute_storage.wrap()) {
|
||||
if (attr.domain() != AttrDomain::Edge) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
const CPPType &type = attribute_type_to_cpp_type(attr.data_type());
|
||||
switch (attr.storage_type()) {
|
||||
|
|
@ -487,7 +487,7 @@ static void remove_invalid_edges(Mesh &mesh, const IndexMask &valid_edges)
|
|||
case AttrStorageType::Single:
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
for (CustomDataLayer &layer : MutableSpan(mesh.edge_data.layers, mesh.edge_data.totlayer)) {
|
||||
if (layer.type == CD_ORIGINDEX) {
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ static constexpr AttributeAccessorFunctions get_pointcloud_accessor_functions()
|
|||
const AttributeAccessor &accessor) {
|
||||
const PointCloud &pointcloud = *static_cast<const PointCloud *>(owner);
|
||||
const AttributeStorage &storage = pointcloud.attribute_storage.wrap();
|
||||
storage.foreach_with_stop([&](const Attribute &attribute) {
|
||||
for (const Attribute &attribute : storage) {
|
||||
const auto get_fn = [&]() {
|
||||
return attribute_to_reader(attribute, AttrDomain::Point, pointcloud.totpoint);
|
||||
};
|
||||
|
|
@ -108,8 +108,10 @@ static constexpr AttributeAccessorFunctions get_pointcloud_accessor_functions()
|
|||
iter.is_builtin = builtin_attributes().contains(attribute.name());
|
||||
iter.accessor = &accessor;
|
||||
fn(iter);
|
||||
return !iter.is_stopped();
|
||||
});
|
||||
if (iter.is_stopped()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
fn.lookup_validator = [](const void * /*owner*/, const StringRef name) -> AttributeValidator {
|
||||
const AttrBuiltinInfo *info = builtin_attributes().lookup_ptr(name);
|
||||
|
|
|
|||
|
|
@ -488,12 +488,12 @@ void BM_mesh_copy_init_customdata_from_mesh_array(BMesh *bm_dst,
|
|||
bke::GeometrySet::GatheredAttributes attribute_info;
|
||||
for (int i = 0; i < me_src_array_len; i++) {
|
||||
const Mesh *me_src = me_src_array[i];
|
||||
me_src->attribute_storage.wrap().foreach([&](const bke::Attribute &attr) {
|
||||
for (const bke::Attribute &attr : me_src->attribute_storage.wrap()) {
|
||||
if (BM_attribute_stored_in_bmesh_builtin(attr.name())) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
attribute_info.add(attr.name(), {attr.domain(), attr.data_type()});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
for (const int i : attribute_info.names.index_range()) {
|
||||
|
|
|
|||
|
|
@ -279,19 +279,19 @@ static CustomData get_mesh_to_bm_custom_data(const Mesh &mesh,
|
|||
{
|
||||
CustomData custom_data;
|
||||
CustomData_reset(&custom_data);
|
||||
mesh.attribute_storage.wrap().foreach([&](const bke::Attribute &attr) {
|
||||
for (const bke::Attribute &attr : mesh.attribute_storage.wrap()) {
|
||||
if (attr.domain() != domain) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
if (BM_attribute_stored_in_bmesh_builtin(attr.name())) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
const eCustomDataType data_type = *bke::attr_type_to_custom_data_type(attr.data_type());
|
||||
if ((CD_TYPE_AS_MASK(data_type) & cd_type_mask) == 0) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
CustomData_add_layer_named(&custom_data, data_type, CD_SET_DEFAULT, 0, attr.name());
|
||||
});
|
||||
}
|
||||
const CustomData &mesh_data = get_mesh_custom_data(mesh, domain);
|
||||
for (const CustomDataLayer &layer : Span(mesh_data.layers, mesh_data.totlayer)) {
|
||||
if ((CD_TYPE_AS_MASK(eCustomDataType(layer.type)) & cd_type_mask) == 0) {
|
||||
|
|
@ -1212,18 +1212,18 @@ static Vector<BMeshToMeshLayerInfo> bm_to_mesh_copy_info_calc(const CustomData &
|
|||
|
||||
per_type_index[type]++;
|
||||
}
|
||||
storage.foreach([&](bke::Attribute &attr) {
|
||||
for (bke::Attribute &attr : storage) {
|
||||
if (attr.domain() != domain) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
const eCustomDataType cd_type = *bke::attr_type_to_custom_data_type(attr.data_type());
|
||||
const int bm_layer_index = CustomData_get_named_layer_index(&bm_data, cd_type, attr.name());
|
||||
if (bm_layer_index == -1) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
const CustomDataLayer &bm_layer = bm_data.layers[bm_layer_index];
|
||||
if (bm_layer.flag & CD_FLAG_NOCOPY) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
BMeshToMeshLayerInfo info{};
|
||||
info.type = cd_type;
|
||||
|
|
@ -1231,7 +1231,7 @@ static Vector<BMeshToMeshLayerInfo> bm_to_mesh_copy_info_calc(const CustomData &
|
|||
info.mesh_data = std::get<bke::Attribute::ArrayData>(attr.data_for_write()).data;
|
||||
info.elem_size = bke::attribute_type_to_cpp_type(attr.data_type()).size;
|
||||
infos.append(info);
|
||||
});
|
||||
}
|
||||
return infos;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -495,8 +495,9 @@ static void um_arraystore_cd_free(BArrayCustomData *bcd, const int bs_index)
|
|||
static MultiValueMap<bke::AttrDomain, bke::Attribute *> get_attributes_by_domain(Mesh &mesh)
|
||||
{
|
||||
MultiValueMap<bke::AttrDomain, bke::Attribute *> result;
|
||||
mesh.attribute_storage.wrap().foreach(
|
||||
[&](bke::Attribute &attr) { result.add(attr.domain(), &attr); });
|
||||
for (bke::Attribute &attr : mesh.attribute_storage.wrap()) {
|
||||
result.add(attr.domain(), &attr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -628,7 +629,9 @@ static void um_arraystore_expand_clear(UndoMesh *um)
|
|||
um_arraystore_cd_clear(&mesh->edge_data);
|
||||
um_arraystore_cd_clear(&mesh->corner_data);
|
||||
um_arraystore_cd_clear(&mesh->face_data);
|
||||
mesh->attribute_storage.wrap().foreach([&](bke::Attribute &attr) { attr.assign_data({}); });
|
||||
for (bke::Attribute &attr : mesh->attribute_storage.wrap()) {
|
||||
attr.assign_data({});
|
||||
}
|
||||
if (mesh->face_offset_indices) {
|
||||
implicit_sharing::free_shared_data(&mesh->face_offset_indices,
|
||||
&mesh->runtime->face_offsets_sharing_info);
|
||||
|
|
|
|||
|
|
@ -615,12 +615,12 @@ std::optional<Mesh *> mesh_triangulate(const Mesh &src_mesh,
|
|||
* for original edges. New edges will be generated by #bke::mesh_calc_edges later.*/
|
||||
CustomData_merge(&src_mesh.vert_data, &mesh->vert_data, CD_MASK_MESH.vmask, mesh->verts_num);
|
||||
CustomData_merge(&src_mesh.edge_data, &mesh->edge_data, CD_MASK_MESH.emask, mesh->edges_num);
|
||||
src_mesh.attribute_storage.wrap().foreach([&](const bke::Attribute &attr) {
|
||||
for (const bke::Attribute &attr : src_mesh.attribute_storage.wrap()) {
|
||||
if (!ELEM(attr.domain(), bke::AttrDomain::Point, bke::AttrDomain::Edge)) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
mesh->attribute_storage.wrap().add(attr.name(), attr.domain(), attr.data_type(), attr.data());
|
||||
});
|
||||
}
|
||||
|
||||
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||
|
||||
|
|
|
|||
|
|
@ -247,15 +247,9 @@ namespace blender {
|
|||
static bool find_attr_with_pointer(const bke::AttributeStorage &storage,
|
||||
const bke::Attribute &attr)
|
||||
{
|
||||
bool found_attr = false;
|
||||
storage.foreach_with_stop([&](const bke::Attribute &attr_iter) {
|
||||
if (&attr_iter == &attr) {
|
||||
found_attr = true;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
return std::any_of(storage.begin(), storage.end(), [&](const bke::Attribute &attr_iter) {
|
||||
return &attr_iter == &attr;
|
||||
});
|
||||
return found_attr;
|
||||
}
|
||||
|
||||
static AttributeOwner owner_from_attribute_pointer_rna(PointerRNA *ptr)
|
||||
|
|
@ -847,18 +841,18 @@ void rna_AttributeGroup_iterator_begin(CollectionPropertyIterator *iter,
|
|||
|
||||
bke::AttributeStorage &storage = *owner.get_storage();
|
||||
Vector<bke::Attribute *, 16> attributes;
|
||||
storage.foreach([&](bke::Attribute &attr) {
|
||||
for (bke::Attribute &attr : storage) {
|
||||
if (!(ATTR_DOMAIN_AS_MASK(attr.domain()) & domain_mask)) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
if (!(CD_TYPE_AS_MASK(*bke::attr_type_to_custom_data_type(attr.data_type())) & cd_type_mask)) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
if (!include_anonymous && bke::attribute_name_is_anonymous(attr.name())) {
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
attributes.append(&attr);
|
||||
});
|
||||
}
|
||||
VectorData data = attributes.release();
|
||||
rna_iterator_array_begin(
|
||||
iter, ptr, data.data, sizeof(bke::Attribute *), data.size, true, nullptr);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue