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:
parent
215f805ce6
commit
c3b9a4e001
|
@ -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);
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {};
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue