Cleanup: Access attributes with new API instead of geometry components

Remove the boilerplate of using a local geometry component just to use
the attribute API that was necessary before b876ce2a4a.
This commit is contained in:
Hans Goudey 2022-07-19 22:34:32 -05:00
parent 215f805ce6
commit c3b9a4e001
7 changed files with 181 additions and 175 deletions

View File

@ -17,7 +17,7 @@ namespace blender::geometry {
* Merge selected points into other selected points within the \a merge_distance. The merged
* indices favor speed over accuracy, since the results will depend on the order of the points.
*/
PointCloud *point_merge_by_distance(const PointCloudComponent &src_points,
PointCloud *point_merge_by_distance(const PointCloud &src_points,
const float merge_distance,
const IndexMask selection);

View File

@ -13,13 +13,12 @@
namespace blender::geometry {
PointCloud *point_merge_by_distance(const PointCloudComponent &src_points,
PointCloud *point_merge_by_distance(const PointCloud &src_points,
const float merge_distance,
const IndexMask selection)
{
const PointCloud &src_pointcloud = *src_points.get_for_read();
bke::AttributeAccessor attributes = bke::pointcloud_attributes(src_pointcloud);
VArraySpan<float3> positions = attributes.lookup_or_default<float3>(
const bke::AttributeAccessor src_attributes = bke::pointcloud_attributes(src_points);
VArraySpan<float3> positions = src_attributes.lookup_or_default<float3>(
"position", ATTR_DOMAIN_POINT, float3(0));
const int src_size = positions.size();
@ -42,8 +41,8 @@ PointCloud *point_merge_by_distance(const PointCloudComponent &src_points,
/* Create the new point cloud and add it to a temporary component for the attribute API. */
const int dst_size = src_size - duplicate_count;
PointCloud *dst_pointcloud = BKE_pointcloud_new_nomain(dst_size);
PointCloudComponent dst_points;
dst_points.replace(dst_pointcloud, GeometryOwnershipType::Editable);
bke::MutableAttributeAccessor dst_attributes = bke::pointcloud_attributes_for_write(
*dst_pointcloud);
/* By default, every point is just "merged" with itself. Then fill in the results of the merge
* finding, converting from indices into the selection to indices into the full input point
@ -106,8 +105,6 @@ PointCloud *point_merge_by_distance(const PointCloudComponent &src_points,
point_merge_counts[dst_index]++;
}
const bke::AttributeAccessor src_attributes = *src_points.attributes();
bke::MutableAttributeAccessor dst_attributes = *dst_points.attributes_for_write();
Set<bke::AttributeIDRef> attribute_ids = src_attributes.all_ids();
/* Transfer the ID attribute if it exists, using the ID of the first merged point. */

View File

@ -43,13 +43,13 @@ static void copy_data_based_on_map(Span<T> src, MutableSpan<T> dst, Span<int> in
* Copies the attributes with a domain in `domains` to `result_component`.
*/
static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes,
const GeometryComponent &in_component,
GeometryComponent &result_component,
const bke::AttributeAccessor src_attributes,
bke::MutableAttributeAccessor dst_attributes,
const Span<eAttrDomain> domains)
{
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
GAttributeReader attribute = in_component.attributes()->lookup(attribute_id);
GAttributeReader attribute = src_attributes.lookup(attribute_id);
if (!attribute) {
continue;
}
@ -60,9 +60,8 @@ static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes
}
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
GSpanAttributeWriter result_attribute =
result_component.attributes_for_write()->lookup_or_add_for_write_only_span(
attribute_id, attribute.domain, data_type);
GSpanAttributeWriter result_attribute = dst_attributes.lookup_or_add_for_write_only_span(
attribute_id, attribute.domain, data_type);
if (!result_attribute) {
continue;
@ -83,14 +82,14 @@ static void copy_attributes(const Map<AttributeIDRef, AttributeKind> &attributes
* the mask to `result_component`.
*/
static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKind> &attributes,
const GeometryComponent &in_component,
GeometryComponent &result_component,
const bke::AttributeAccessor src_attributes,
bke::MutableAttributeAccessor dst_attributes,
const eAttrDomain domain,
const IndexMask mask)
{
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
GAttributeReader attribute = in_component.attributes()->lookup(attribute_id);
GAttributeReader attribute = src_attributes.lookup(attribute_id);
if (!attribute) {
continue;
}
@ -101,9 +100,8 @@ static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKin
}
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
GSpanAttributeWriter result_attribute =
result_component.attributes_for_write()->lookup_or_add_for_write_only_span(
attribute_id, attribute.domain, data_type);
GSpanAttributeWriter result_attribute = dst_attributes.lookup_or_add_for_write_only_span(
attribute_id, attribute.domain, data_type);
if (!result_attribute) {
continue;
@ -120,14 +118,14 @@ static void copy_attributes_based_on_mask(const Map<AttributeIDRef, AttributeKin
}
static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind> &attributes,
const GeometryComponent &in_component,
GeometryComponent &result_component,
const bke::AttributeAccessor src_attributes,
bke::MutableAttributeAccessor dst_attributes,
const eAttrDomain domain,
const Span<int> index_map)
{
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
GAttributeReader attribute = in_component.attributes()->lookup(attribute_id);
GAttributeReader attribute = src_attributes.lookup(attribute_id);
if (!attribute) {
continue;
}
@ -138,9 +136,8 @@ static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind
}
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(attribute.varray.type());
GSpanAttributeWriter result_attribute =
result_component.attributes_for_write()->lookup_or_add_for_write_only_span(
attribute_id, attribute.domain, data_type);
GSpanAttributeWriter result_attribute = dst_attributes.lookup_or_add_for_write_only_span(
attribute_id, attribute.domain, data_type);
if (!result_attribute) {
continue;
@ -157,8 +154,8 @@ static void copy_attributes_based_on_map(const Map<AttributeIDRef, AttributeKind
}
static void copy_face_corner_attributes(const Map<AttributeIDRef, AttributeKind> &attributes,
const GeometryComponent &in_component,
GeometryComponent &out_component,
const bke::AttributeAccessor src_attributes,
bke::MutableAttributeAccessor dst_attributes,
const int selected_loops_num,
const Span<int> selected_poly_indices,
const Mesh &mesh_in)
@ -174,7 +171,7 @@ static void copy_face_corner_attributes(const Map<AttributeIDRef, AttributeKind>
}
}
copy_attributes_based_on_mask(
attributes, in_component, out_component, ATTR_DOMAIN_CORNER, IndexMask(indices));
attributes, src_attributes, dst_attributes, ATTR_DOMAIN_CORNER, IndexMask(indices));
}
static void copy_masked_vertices_to_new_mesh(const Mesh &src_mesh,
@ -365,14 +362,15 @@ static void separate_point_cloud_selection(GeometrySet &geometry_set,
PointCloud *pointcloud = BKE_pointcloud_new_nomain(selection.size());
PointCloudComponent dst_points;
dst_points.replace(pointcloud, GeometryOwnershipType::Editable);
Map<AttributeIDRef, AttributeKind> attributes;
geometry_set.gather_attributes_for_propagation(
{GEO_COMPONENT_TYPE_POINT_CLOUD}, GEO_COMPONENT_TYPE_POINT_CLOUD, false, attributes);
copy_attributes_based_on_mask(attributes, src_points, dst_points, ATTR_DOMAIN_POINT, selection);
copy_attributes_based_on_mask(attributes,
bke::pointcloud_attributes(*src_points.get_for_read()),
bke::pointcloud_attributes_for_write(*pointcloud),
ATTR_DOMAIN_POINT,
selection);
geometry_set.replace_pointcloud(pointcloud);
}
@ -817,7 +815,7 @@ static void compute_selected_mesh_data_from_poly_selection(const Mesh &mesh,
* Keep the parts of the mesh that are in the selection.
*/
static void do_mesh_separation(GeometrySet &geometry_set,
const MeshComponent &in_component,
const Mesh &mesh_in,
const Span<bool> selection,
const eAttrDomain domain,
const GeometryNodeDeleteGeometryMode mode)
@ -828,9 +826,7 @@ static void do_mesh_separation(GeometrySet &geometry_set,
int selected_polys_num = 0;
int selected_loops_num = 0;
const Mesh &mesh_in = *in_component.get_for_read();
Mesh *mesh_out;
MeshComponent out_component;
Map<AttributeIDRef, AttributeKind> attributes;
geometry_set.gather_attributes_for_propagation(
@ -892,7 +888,6 @@ static void do_mesh_separation(GeometrySet &geometry_set,
0,
selected_loops_num,
selected_polys_num);
out_component.replace(mesh_out, GeometryOwnershipType::Editable);
/* Copy the selected parts of the mesh over to the new mesh. */
copy_masked_vertices_to_new_mesh(mesh_in, *mesh_out, vertex_map);
@ -901,18 +896,24 @@ static void do_mesh_separation(GeometrySet &geometry_set,
mesh_in, *mesh_out, vertex_map, edge_map, selected_poly_indices, new_loop_starts);
/* Copy attributes. */
copy_attributes_based_on_map(
attributes, in_component, out_component, ATTR_DOMAIN_POINT, vertex_map);
copy_attributes_based_on_map(
attributes, in_component, out_component, ATTR_DOMAIN_EDGE, edge_map);
copy_attributes_based_on_map(attributes,
bke::mesh_attributes(mesh_in),
bke::mesh_attributes_for_write(*mesh_out),
ATTR_DOMAIN_POINT,
vertex_map);
copy_attributes_based_on_map(attributes,
bke::mesh_attributes(mesh_in),
bke::mesh_attributes_for_write(*mesh_out),
ATTR_DOMAIN_EDGE,
edge_map);
copy_attributes_based_on_mask(attributes,
in_component,
out_component,
bke::mesh_attributes(mesh_in),
bke::mesh_attributes_for_write(*mesh_out),
ATTR_DOMAIN_FACE,
IndexMask(Vector<int64_t>(selected_poly_indices.as_span())));
copy_face_corner_attributes(attributes,
in_component,
out_component,
bke::mesh_attributes(mesh_in),
bke::mesh_attributes_for_write(*mesh_out),
selected_loops_num,
selected_poly_indices,
mesh_in);
@ -964,7 +965,6 @@ static void do_mesh_separation(GeometrySet &geometry_set,
0,
selected_loops_num,
selected_polys_num);
out_component.replace(mesh_out, GeometryOwnershipType::Editable);
/* Copy the selected parts of the mesh over to the new mesh. */
memcpy(mesh_out->mvert, mesh_in.mvert, mesh_in.totvert * sizeof(MVert));
@ -973,17 +973,23 @@ static void do_mesh_separation(GeometrySet &geometry_set,
mesh_in, *mesh_out, edge_map, selected_poly_indices, new_loop_starts);
/* Copy attributes. */
copy_attributes(attributes, in_component, out_component, {ATTR_DOMAIN_POINT});
copy_attributes_based_on_map(
attributes, in_component, out_component, ATTR_DOMAIN_EDGE, edge_map);
copy_attributes(attributes,
bke::mesh_attributes(mesh_in),
bke::mesh_attributes_for_write(*mesh_out),
{ATTR_DOMAIN_POINT});
copy_attributes_based_on_map(attributes,
bke::mesh_attributes(mesh_in),
bke::mesh_attributes_for_write(*mesh_out),
ATTR_DOMAIN_EDGE,
edge_map);
copy_attributes_based_on_mask(attributes,
in_component,
out_component,
bke::mesh_attributes(mesh_in),
bke::mesh_attributes_for_write(*mesh_out),
ATTR_DOMAIN_FACE,
IndexMask(Vector<int64_t>(selected_poly_indices.as_span())));
copy_face_corner_attributes(attributes,
in_component,
out_component,
bke::mesh_attributes(mesh_in),
bke::mesh_attributes_for_write(*mesh_out),
selected_loops_num,
selected_poly_indices,
mesh_in);
@ -1022,7 +1028,6 @@ static void do_mesh_separation(GeometrySet &geometry_set,
}
mesh_out = BKE_mesh_new_nomain_from_template(
&mesh_in, mesh_in.totvert, mesh_in.totedge, 0, selected_loops_num, selected_polys_num);
out_component.replace(mesh_out, GeometryOwnershipType::Editable);
/* Copy the selected parts of the mesh over to the new mesh. */
memcpy(mesh_out->mvert, mesh_in.mvert, mesh_in.totvert * sizeof(MVert));
@ -1030,16 +1035,18 @@ static void do_mesh_separation(GeometrySet &geometry_set,
copy_masked_polys_to_new_mesh(mesh_in, *mesh_out, selected_poly_indices, new_loop_starts);
/* Copy attributes. */
copy_attributes(
attributes, in_component, out_component, {ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE});
copy_attributes(attributes,
bke::mesh_attributes(mesh_in),
bke::mesh_attributes_for_write(*mesh_out),
{ATTR_DOMAIN_POINT, ATTR_DOMAIN_EDGE});
copy_attributes_based_on_mask(attributes,
in_component,
out_component,
bke::mesh_attributes(mesh_in),
bke::mesh_attributes_for_write(*mesh_out),
ATTR_DOMAIN_FACE,
IndexMask(Vector<int64_t>(selected_poly_indices.as_span())));
copy_face_corner_attributes(attributes,
in_component,
out_component,
bke::mesh_attributes(mesh_in),
bke::mesh_attributes_for_write(*mesh_out),
selected_loops_num,
selected_poly_indices,
mesh_in);
@ -1071,7 +1078,8 @@ static void separate_mesh_selection(GeometrySet &geometry_set,
const VArraySpan<bool> selection_span{selection};
do_mesh_separation(geometry_set, src_component, selection_span, selection_domain, mode);
do_mesh_separation(
geometry_set, *src_component.get_for_read(), selection_span, selection_domain, mode);
}
} // namespace blender::nodes::node_geo_delete_geometry_cc

View File

@ -143,12 +143,9 @@ static void transfer_attributes(
const Span<int> new_to_old_edges_map,
const Span<int> new_to_old_face_corners_map,
const Span<std::pair<int, int>> boundary_vertex_to_relevant_face_map,
const GeometryComponent &src_component,
GeometryComponent &dst_component)
const AttributeAccessor src_attributes,
MutableAttributeAccessor dst_attributes)
{
const AttributeAccessor src_attributes = *src_component.attributes();
MutableAttributeAccessor dst_attributes = *dst_component.attributes_for_write();
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
GAttributeReader src_attribute = src_attributes.lookup(attribute_id);
@ -875,16 +872,14 @@ static void calc_dual_mesh(GeometrySet &geometry_set,
}
Mesh *mesh_out = BKE_mesh_new_nomain(
vertex_positions.size(), new_edges.size(), 0, loops.size(), loop_lengths.size());
MeshComponent out_component;
out_component.replace(mesh_out, GeometryOwnershipType::Editable);
transfer_attributes(attributes,
vertex_types,
keep_boundaries,
new_to_old_edges_map,
new_to_old_face_corners_map,
boundary_vertex_to_relevant_face_map,
in_component,
out_component);
bke::mesh_attributes(mesh_in),
bke::mesh_attributes_for_write(*mesh_out));
int loop_start = 0;
for (const int i : IndexRange(mesh_out->totpoly)) {

View File

@ -141,15 +141,14 @@ static void threaded_id_offset_copy(const Span<int> offsets,
}
/** Create the copy indices for the duplication domain. */
static void create_duplicate_index_attribute(GeometryComponent &component,
static void create_duplicate_index_attribute(bke::MutableAttributeAccessor attributes,
const eAttrDomain output_domain,
const IndexMask selection,
const IndexAttributes &attribute_outputs,
const Span<int> offsets)
{
SpanAttributeWriter<int> duplicate_indices =
component.attributes_for_write()->lookup_or_add_for_write_only_span<int>(
attribute_outputs.duplicate_index.get(), output_domain);
SpanAttributeWriter<int> duplicate_indices = attributes.lookup_or_add_for_write_only_span<int>(
attribute_outputs.duplicate_index.get(), output_domain);
for (const int i : IndexRange(selection.size())) {
const IndexRange range = range_for_offsets_index(offsets, i);
MutableSpan<int> indices = duplicate_indices.span.slice(range);
@ -165,16 +164,15 @@ static void create_duplicate_index_attribute(GeometryComponent &component,
* and the duplicate number. This function is used for the point domain elements.
*/
static void copy_stable_id_point(const Span<int> offsets,
const GeometryComponent &src_component,
GeometryComponent &dst_component)
const bke::AttributeAccessor src_attributes,
bke::MutableAttributeAccessor dst_attributes)
{
GAttributeReader src_attribute = src_component.attributes()->lookup("id");
GAttributeReader src_attribute = src_attributes.lookup("id");
if (!src_attribute) {
return;
}
GSpanAttributeWriter dst_attribute =
dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
"id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span(
"id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
if (!dst_attribute) {
return;
}
@ -190,24 +188,23 @@ static void copy_attributes_without_id(GeometrySet &geometry_set,
const eAttrDomain domain,
const Span<int> offsets,
const IndexMask selection,
const GeometryComponent &src_component,
GeometryComponent &dst_component)
const bke::AttributeAccessor src_attributes,
bke::MutableAttributeAccessor dst_attributes)
{
const Map<AttributeIDRef, AttributeKind> attributes = gather_attributes_without_id(
geometry_set, component_type);
for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
GAttributeReader src_attribute = src_component.attributes()->lookup(attribute_id);
GAttributeReader src_attribute = src_attributes.lookup(attribute_id);
if (!src_attribute || src_attribute.domain != domain) {
continue;
}
eAttrDomain out_domain = src_attribute.domain;
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
GSpanAttributeWriter dst_attribute =
dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
attribute_id, out_domain, data_type);
GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span(
attribute_id, out_domain, data_type);
if (!dst_attribute) {
continue;
}
@ -232,19 +229,17 @@ static void copy_attributes_without_id(GeometrySet &geometry_set,
* copied with an offset fill, otherwise a mapping is used.
*/
static void copy_curve_attributes_without_id(const GeometrySet &geometry_set,
const CurveComponent &src_component,
const bke::CurvesGeometry &src_curves,
const IndexMask selection,
const Span<int> curve_offsets,
bke::CurvesGeometry &dst_curves,
CurveComponent &dst_component)
bke::CurvesGeometry &dst_curves)
{
Map<AttributeIDRef, AttributeKind> attributes = gather_attributes_without_id(
geometry_set, GEO_COMPONENT_TYPE_CURVE);
for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
GAttributeReader src_attribute = src_component.attributes()->lookup(attribute_id);
GAttributeReader src_attribute = src_curves.attributes().lookup(attribute_id);
if (!src_attribute) {
continue;
}
@ -253,7 +248,7 @@ static void copy_curve_attributes_without_id(const GeometrySet &geometry_set,
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
GSpanAttributeWriter dst_attribute =
dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
dst_curves.attributes_for_write().lookup_or_add_for_write_only_span(
attribute_id, out_domain, data_type);
if (!dst_attribute) {
continue;
@ -296,16 +291,14 @@ static void copy_curve_attributes_without_id(const GeometrySet &geometry_set,
static void copy_stable_id_curves(const bke::CurvesGeometry &src_curves,
const IndexMask selection,
const Span<int> curve_offsets,
const CurveComponent &src_component,
bke::CurvesGeometry &dst_curves,
CurveComponent &dst_component)
bke::CurvesGeometry &dst_curves)
{
GAttributeReader src_attribute = src_component.attributes()->lookup("id");
GAttributeReader src_attribute = src_curves.attributes().lookup("id");
if (!src_attribute) {
return;
}
GSpanAttributeWriter dst_attribute =
dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
dst_curves.attributes_for_write().lookup_or_add_for_write_only_span(
"id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
if (!dst_attribute) {
return;
@ -387,18 +380,16 @@ static void duplicate_curves(GeometrySet &geometry_set,
});
all_dst_offsets.last() = dst_points_num;
CurveComponent dst_component;
dst_component.replace(new_curves_id, GeometryOwnershipType::Editable);
copy_curve_attributes_without_id(geometry_set, curves, selection, curve_offsets, new_curves);
copy_curve_attributes_without_id(
geometry_set, src_component, curves, selection, curve_offsets, new_curves, dst_component);
copy_stable_id_curves(
curves, selection, curve_offsets, src_component, new_curves, dst_component);
copy_stable_id_curves(curves, selection, curve_offsets, new_curves);
if (attribute_outputs.duplicate_index) {
create_duplicate_index_attribute(
dst_component, ATTR_DOMAIN_CURVE, selection, attribute_outputs, curve_offsets);
create_duplicate_index_attribute(new_curves.attributes_for_write(),
ATTR_DOMAIN_CURVE,
selection,
attribute_outputs,
curve_offsets);
}
geometry_set.replace_curves(new_curves_id);
@ -420,15 +411,15 @@ static void copy_face_attributes_without_id(GeometrySet &geometry_set,
const Span<int> loop_mapping,
const Span<int> offsets,
const IndexMask selection,
const GeometryComponent &src_component,
GeometryComponent &dst_component)
const bke::AttributeAccessor src_attributes,
bke::MutableAttributeAccessor dst_attributes)
{
Map<AttributeIDRef, AttributeKind> attributes = gather_attributes_without_id(
geometry_set, GEO_COMPONENT_TYPE_MESH);
for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
GAttributeReader src_attribute = src_component.attributes()->lookup(attribute_id);
GAttributeReader src_attribute = src_attributes.lookup(attribute_id);
if (!src_attribute) {
continue;
}
@ -436,9 +427,8 @@ static void copy_face_attributes_without_id(GeometrySet &geometry_set,
eAttrDomain out_domain = src_attribute.domain;
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
GSpanAttributeWriter dst_attribute =
dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
attribute_id, out_domain, data_type);
GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span(
attribute_id, out_domain, data_type);
if (!dst_attribute) {
continue;
}
@ -480,16 +470,15 @@ static void copy_stable_id_faces(const Mesh &mesh,
const IndexMask selection,
const Span<int> poly_offsets,
const Span<int> vert_mapping,
const MeshComponent &src_component,
MeshComponent &dst_component)
const bke::AttributeAccessor src_attributes,
bke::MutableAttributeAccessor dst_attributes)
{
GAttributeReader src_attribute = src_component.attributes()->lookup("id");
GAttributeReader src_attribute = src_attributes.lookup("id");
if (!src_attribute) {
return;
}
GSpanAttributeWriter dst_attribute =
dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
"id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span(
"id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
if (!dst_attribute) {
return;
}
@ -599,23 +588,28 @@ static void duplicate_faces(GeometrySet &geometry_set,
}
}
MeshComponent dst_component;
dst_component.replace(new_mesh, GeometryOwnershipType::Editable);
copy_face_attributes_without_id(geometry_set,
edge_mapping,
vert_mapping,
loop_mapping,
offsets,
selection,
src_component,
dst_component);
bke::mesh_attributes(mesh),
bke::mesh_attributes_for_write(*new_mesh));
copy_stable_id_faces(mesh, selection, offsets, vert_mapping, src_component, dst_component);
copy_stable_id_faces(mesh,
selection,
offsets,
vert_mapping,
bke::mesh_attributes(mesh),
bke::mesh_attributes_for_write(*new_mesh));
if (attribute_outputs.duplicate_index) {
create_duplicate_index_attribute(
dst_component, ATTR_DOMAIN_FACE, selection, attribute_outputs, offsets);
create_duplicate_index_attribute(bke::mesh_attributes_for_write(*new_mesh),
ATTR_DOMAIN_FACE,
selection,
attribute_outputs,
offsets);
}
geometry_set.replace_mesh(new_mesh);
@ -635,15 +629,15 @@ static void copy_edge_attributes_without_id(GeometrySet &geometry_set,
const Span<int> point_mapping,
const Span<int> offsets,
const IndexMask selection,
const GeometryComponent &src_component,
GeometryComponent &dst_component)
const bke::AttributeAccessor src_attributes,
bke::MutableAttributeAccessor dst_attributes)
{
Map<AttributeIDRef, AttributeKind> attributes = gather_attributes_without_id(
geometry_set, GEO_COMPONENT_TYPE_MESH);
for (const Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
GAttributeReader src_attribute = src_component.attributes()->lookup(attribute_id);
GAttributeReader src_attribute = src_attributes.lookup(attribute_id);
if (!src_attribute) {
continue;
}
@ -651,9 +645,8 @@ static void copy_edge_attributes_without_id(GeometrySet &geometry_set,
const eAttrDomain out_domain = src_attribute.domain;
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
GSpanAttributeWriter dst_attribute =
dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
attribute_id, out_domain, data_type);
GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span(
attribute_id, out_domain, data_type);
if (!dst_attribute) {
continue;
}
@ -684,16 +677,15 @@ static void copy_edge_attributes_without_id(GeometrySet &geometry_set,
static void copy_stable_id_edges(const Mesh &mesh,
const IndexMask selection,
const Span<int> edge_offsets,
const MeshComponent &src_component,
MeshComponent &dst_component)
const bke::AttributeAccessor src_attributes,
bke::MutableAttributeAccessor dst_attributes)
{
GAttributeReader src_attribute = src_component.attributes()->lookup("id");
GAttributeReader src_attribute = src_attributes.lookup("id");
if (!src_attribute) {
return;
}
GSpanAttributeWriter dst_attribute =
dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
"id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
GSpanAttributeWriter dst_attribute = dst_attributes.lookup_or_add_for_write_only_span(
"id", ATTR_DOMAIN_POINT, CD_PROP_INT32);
if (!dst_attribute) {
return;
}
@ -777,17 +769,25 @@ static void duplicate_edges(GeometrySet &geometry_set,
}
});
MeshComponent dst_component;
dst_component.replace(new_mesh, GeometryOwnershipType::Editable);
copy_edge_attributes_without_id(geometry_set,
vert_orig_indices,
edge_offsets,
selection,
bke::mesh_attributes(mesh),
bke::mesh_attributes_for_write(*new_mesh));
copy_edge_attributes_without_id(
geometry_set, vert_orig_indices, edge_offsets, selection, src_component, dst_component);
copy_stable_id_edges(mesh, selection, edge_offsets, src_component, dst_component);
copy_stable_id_edges(mesh,
selection,
edge_offsets,
bke::mesh_attributes(mesh),
bke::mesh_attributes_for_write(*new_mesh));
if (attribute_outputs.duplicate_index) {
create_duplicate_index_attribute(
dst_component, ATTR_DOMAIN_EDGE, selection, attribute_outputs, edge_offsets);
create_duplicate_index_attribute(bke::mesh_attributes_for_write(*new_mesh),
ATTR_DOMAIN_EDGE,
selection,
attribute_outputs,
edge_offsets);
}
geometry_set.replace_mesh(new_mesh);
@ -839,9 +839,6 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
}
new_curve_offsets.last() = dst_num;
CurveComponent dst_component;
dst_component.replace(new_curves_id, GeometryOwnershipType::Editable);
Map<AttributeIDRef, AttributeKind> attributes = gather_attributes_without_id(
geometry_set, GEO_COMPONENT_TYPE_CURVE);
@ -856,7 +853,7 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
const eCustomDataType data_type = bke::cpp_type_to_custom_data_type(
src_attribute.varray.type());
GSpanAttributeWriter dst_attribute =
dst_component.attributes_for_write()->lookup_or_add_for_write_only_span(
new_curves.attributes_for_write().lookup_or_add_for_write_only_span(
attribute_id, domain, data_type);
if (!dst_attribute) {
continue;
@ -887,11 +884,14 @@ static void duplicate_points_curve(GeometrySet &geometry_set,
dst_attribute.finish();
}
copy_stable_id_point(offsets, src_component, dst_component);
copy_stable_id_point(offsets, src_curves.attributes(), new_curves.attributes_for_write());
if (attribute_outputs.duplicate_index) {
create_duplicate_index_attribute(
dst_component, ATTR_DOMAIN_POINT, selection, attribute_outputs, offsets.as_span());
create_duplicate_index_attribute(new_curves.attributes_for_write(),
ATTR_DOMAIN_POINT,
selection,
attribute_outputs,
offsets.as_span());
}
geometry_set.replace_curves(new_curves_id);
@ -927,21 +927,23 @@ static void duplicate_points_mesh(GeometrySet &geometry_set,
threaded_slice_fill(offsets.as_span(), selection, src_verts, dst_verts);
MeshComponent dst_component;
dst_component.replace(new_mesh, GeometryOwnershipType::Editable);
copy_attributes_without_id(geometry_set,
GEO_COMPONENT_TYPE_MESH,
ATTR_DOMAIN_POINT,
offsets,
selection,
src_component,
dst_component);
bke::mesh_attributes(mesh),
bke::mesh_attributes_for_write(*new_mesh));
copy_stable_id_point(offsets, src_component, dst_component);
copy_stable_id_point(
offsets, bke::mesh_attributes(mesh), bke::mesh_attributes_for_write(*new_mesh));
if (attribute_outputs.duplicate_index) {
create_duplicate_index_attribute(
dst_component, ATTR_DOMAIN_POINT, selection, attribute_outputs, offsets.as_span());
create_duplicate_index_attribute(bke::mesh_attributes_for_write(*new_mesh),
ATTR_DOMAIN_POINT,
selection,
attribute_outputs,
offsets.as_span());
}
geometry_set.replace_mesh(new_mesh);
@ -973,22 +975,24 @@ static void duplicate_points_pointcloud(GeometrySet &geometry_set,
Array<int> offsets = accumulate_counts_to_offsets(selection, counts);
PointCloud *pointcloud = BKE_pointcloud_new_nomain(offsets.last());
PointCloudComponent dst_component;
dst_component.replace(pointcloud, GeometryOwnershipType::Editable);
copy_attributes_without_id(geometry_set,
GEO_COMPONENT_TYPE_POINT_CLOUD,
ATTR_DOMAIN_POINT,
offsets,
selection,
src_points,
dst_component);
*src_points.attributes(),
bke::pointcloud_attributes_for_write(*pointcloud));
copy_stable_id_point(offsets, src_points, dst_component);
copy_stable_id_point(
offsets, *src_points.attributes(), bke::pointcloud_attributes_for_write(*pointcloud));
if (attribute_outputs.duplicate_index) {
create_duplicate_index_attribute(
dst_component, ATTR_DOMAIN_POINT, selection, attribute_outputs, offsets);
create_duplicate_index_attribute(bke::pointcloud_attributes_for_write(*pointcloud),
ATTR_DOMAIN_POINT,
selection,
attribute_outputs,
offsets);
}
geometry_set.replace_pointcloud(pointcloud);
}
@ -1085,12 +1089,15 @@ static void duplicate_instances(GeometrySet &geometry_set,
ATTR_DOMAIN_INSTANCE,
offsets,
selection,
src_instances,
dst_instances);
*src_instances.attributes(),
*dst_instances.attributes_for_write());
if (attribute_outputs.duplicate_index) {
create_duplicate_index_attribute(
dst_instances, ATTR_DOMAIN_INSTANCE, selection, attribute_outputs, offsets);
create_duplicate_index_attribute(*dst_instances.attributes_for_write(),
ATTR_DOMAIN_INSTANCE,
selection,
attribute_outputs,
offsets);
}
geometry_set = std::move(dst_geometry);

View File

@ -164,11 +164,10 @@ static CustomData &get_customdata(Mesh &mesh, const eAttrDomain domain)
static MutableSpan<int> get_orig_index_layer(Mesh &mesh, const eAttrDomain domain)
{
MeshComponent component;
component.replace(&mesh, GeometryOwnershipType::ReadOnly);
const bke::AttributeAccessor attributes = bke::mesh_attributes(mesh);
CustomData &custom_data = get_customdata(mesh, domain);
if (int *orig_indices = static_cast<int *>(CustomData_get_layer(&custom_data, CD_ORIGINDEX))) {
return {orig_indices, component.attribute_domain_size(domain)};
return {orig_indices, attributes.domain_size(domain)};
}
return {};
}

View File

@ -50,7 +50,7 @@ static PointCloud *pointcloud_merge_by_distance(const PointCloudComponent &src_p
return nullptr;
}
return geometry::point_merge_by_distance(src_points, merge_distance, selection);
return geometry::point_merge_by_distance(*src_points.get_for_read(), merge_distance, selection);
}
static std::optional<Mesh *> mesh_merge_by_distance_connected(const MeshComponent &mesh_component,